Re: [PATCH 3/5] drm/amdgpu: Prevent race between late signaled fences and GPU reset.
Am 22.06.22 um 19:31 schrieb Andrey Grodzovsky: Just a ping You need to give me at least some time to look into this. Andrey On 2022-06-21 15:45, Andrey Grodzovsky wrote: On 2022-06-21 03:25, Christian König wrote: Am 21.06.22 um 00:03 schrieb Andrey Grodzovsky: Problem: After we start handling timed out jobs we assume there fences won't be signaled but we cannot be sure and sometimes they fire late. We need to prevent concurrent accesses to fence array from amdgpu_fence_driver_clear_job_fences during GPU reset and amdgpu_fence_process from a late EOP interrupt. Fix: Before accessing fence array in GPU disable EOP interrupt and flush all pending interrupt handlers for amdgpu device's interrupt line. Signed-off-by: Andrey Grodzovsky --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 4 drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 26 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | 1 + 3 files changed, 31 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 2b92281dd0c1..c99541685804 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -4605,6 +4605,8 @@ int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev, amdgpu_virt_fini_data_exchange(adev); } + amdgpu_fence_driver_isr_toggle(adev, true); + /* block all schedulers and reset given job's ring */ for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { struct amdgpu_ring *ring = adev->rings[i]; @@ -4620,6 +4622,8 @@ int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev, amdgpu_fence_driver_force_completion(ring); } + amdgpu_fence_driver_isr_toggle(adev, false); + if (job && job->vm) drm_sched_increase_karma(>base); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c index a9ae3beaa1d3..d6d54ba4c185 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c @@ -532,6 +532,32 @@ void amdgpu_fence_driver_hw_fini(struct amdgpu_device *adev) } } +void amdgpu_fence_driver_isr_toggle(struct amdgpu_device *adev, bool stop) +{ + int i; + + for (i = 0; i < AMDGPU_MAX_RINGS; i++) { + struct amdgpu_ring *ring = adev->rings[i]; + + if (!ring || !ring->fence_drv.initialized || !ring->fence_drv.irq_src) + continue; + + if (stop) + amdgpu_irq_put(adev, ring->fence_drv.irq_src, + ring->fence_drv.irq_type); + else + amdgpu_irq_get(adev, ring->fence_drv.irq_src, + ring->fence_drv.irq_type); That won't work like this. This increments/decrements the reference count for the IRQ, but doesn't guarantee in any way that they are stopped/started. I understand that, i just assumed that the fence driver is the only holder of this interrupt source (e.g. regCP_INT_CNTL_RING0) ? I'm not 100% sure of that. The original idea was to enable/disable interrupt sources as they came along. I can disable amdgpu interrupt line totally using disable_irq - would this be better ? Yes, that's what I thought as well. + } + + /* TODO Only waits for irq handlers on other CPUs, maybe local_irq_save + * local_irq_local_irq_restore are needed here for local interrupts ? + * + */ Well that comment made me smile. Think for a moment what the local CPU would be doing if an interrupt would run :) No, I understand this of course, I am ok to be interrupted by interrupt handler at this point, what i am trying to do is to prevent amdgpu_fence_process to run concurrently with amdgpu_fence_driver_clear_job_fences - that is what this function is trying to prevent - i disable and flush pending EOP ISR handlers before the call to clear fences and re-enable after. That should be sufficient. When a local interrupt would run the code here wouldn't be executing. I guess we can also introduce a spinlock to serialize them ? Yiqing reported seeing a race between them so we have to do something. A spinlock would be an absolute NAK because we have been working quite hard to remove them (for multiple reasons). Christian. Andrey Cheers, Christian. + if (stop) + synchronize_irq(adev->irq.irq); +} + void amdgpu_fence_driver_sw_fini(struct amdgpu_device *adev) { unsigned int i, j; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h index 7d89a52091c0..82c178a9033a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h @@ -143,6 +143,7 @@ signed long amdgpu_fence_wait_polling(struct amdgpu_ring *ring, uint32_t wait_seq, signed long timeout); unsigned amdgpu_fence_count_emitted(struct amdgpu_ring *ring); +void
Re: [PATCH 5/5] drm/amdgpu: Follow up change to previous drm scheduler change.
Am 22.06.22 um 19:19 schrieb Andrey Grodzovsky: On 2022-06-22 03:17, Christian König wrote: Am 21.06.22 um 22:00 schrieb Andrey Grodzovsky: On 2022-06-21 03:28, Christian König wrote: Am 21.06.22 um 00:03 schrieb Andrey Grodzovsky: Align refcount behaviour for amdgpu_job embedded HW fence with classic pointer style HW fences by increasing refcount each time emit is called so amdgpu code doesn't need to make workarounds using amdgpu_job.job_run_counter to keep the HW fence refcount balanced. Could we now also remove job_run_counter? Christian. I am afraid not, job counter is needed since at all times the refcount on the embedded fence cannot drop to zero because this will free the job itself before the end of it's life cycle. We have to be able to differentiate in amdgpu_fence_emit between first ever call where we init the embedded fence's refcount from scratch using kref_init to repeating calls when refcount already > 0 and we just fake increase the refcount to align behavior with pointer style fences in other drivers. Well what we should probably rather do is move the init out of emit instead. The only down side I can see is that the sequence number isn't know on initial init and so needs to be zero or something like that. Regards, Christian. Not sure how this help, the problem is not there but in amdgpu_job_run, for embedded fence and resubmit job in pending list amdgpu_job_run will be called twice or even 3 times with recheck guilty job sequence. I am supposed to do dma_fence_init to embeded HW fence only on first call while on second and third only update sequence_num and increase refcount. How can i differentiate between first and non first calls without job_run_counter ? Yeah, good point. We should really stop re-submitting jobs altogether in the kernel and move that whole functionality into userspace. Christian. Andrey I guess we could assume that embedded fence is all zeroes before first dma_fence_init if assuming the job itself was allocated using kzalloc and so u can look at dma_fence_ops == NULL or maybe seqno == 0 as a hint if that the fist call or not but it's a risky assumption in my opinion. Andrey Also since in the previous patch we resumed setting s_fence->parent to NULL in drm_sched_stop switch to directly checking if job->hw_fence is signaled to short circuit reset if already signed. Signed-off-by: Andrey Grodzovsky Tested-by: Yiqing Yao --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c | 2 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 23 -- drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 7 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 4 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c index 513c57f839d8..447bd92c4856 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c @@ -684,6 +684,8 @@ int amdgpu_amdkfd_submit_ib(struct amdgpu_device *adev, goto err_ib_sched; } + /* Drop the initial kref_init count (see drm_sched_main as example) */ + dma_fence_put(f); ret = dma_fence_wait(f, false); err_ib_sched: diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index c99541685804..f9718119834f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -5009,16 +5009,28 @@ static void amdgpu_device_recheck_guilty_jobs( /* clear job's guilty and depend the folowing step to decide the real one */ drm_sched_reset_karma(s_job); - /* for the real bad job, it will be resubmitted twice, adding a dma_fence_get - * to make sure fence is balanced */ - dma_fence_get(s_job->s_fence->parent); drm_sched_resubmit_jobs_ext(>sched, 1); + if (!s_job->s_fence->parent) { + DRM_WARN("Failed to get a HW fence for job!"); + continue; + } + ret = dma_fence_wait_timeout(s_job->s_fence->parent, false, ring->sched.timeout); if (ret == 0) { /* timeout */ DRM_ERROR("Found the real bad job! ring:%s, job_id:%llx\n", ring->sched.name, s_job->id); + + /* Clear this failed job from fence array */ + amdgpu_fence_driver_clear_job_fences(ring); + + /* Since the job won't signal and we go for + * another resubmit drop this parent pointer + */ + dma_fence_put(s_job->s_fence->parent); + s_job->s_fence->parent = NULL; + /* set guilty */ drm_sched_increase_karma(s_job); retry: @@ -5047,7 +5059,6 @@ static void amdgpu_device_recheck_guilty_jobs( /* got the hw fence, signal finished fence */ atomic_dec(ring->sched.score); -
Re: [PATCH] drm: bridge: sii8620: fix possible off-by-one
On 2022/5/18 15:57, Andrzej Hajda wrote: On 18.05.2022 08:58, Hangyu Hua wrote: The next call to sii8620_burst_get_tx_buf will result in off-by-one When ctx->burst.tx_count + size == ARRAY_SIZE(ctx->burst.tx_buf). The same thing happens in sii8620_burst_get_rx_buf. This patch also change tx_count and tx_buf to rx_count and rx_buf in sii8620_burst_get_rx_buf. It is unreasonable to check tx_buf's size and use rx_buf. Fixes: e19e9c692f81 ("drm/bridge/sii8620: add support for burst eMSC transmissions") Signed-off-by: Hangyu Hua Reviewed-by: Andrzej Hajda Regards Andrzej --- drivers/gpu/drm/bridge/sil-sii8620.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c index ec7745c31da0..ab0bce4a988c 100644 --- a/drivers/gpu/drm/bridge/sil-sii8620.c +++ b/drivers/gpu/drm/bridge/sil-sii8620.c @@ -605,7 +605,7 @@ static void *sii8620_burst_get_tx_buf(struct sii8620 *ctx, int len) u8 *buf = >burst.tx_buf[ctx->burst.tx_count]; int size = len + 2; - if (ctx->burst.tx_count + size > ARRAY_SIZE(ctx->burst.tx_buf)) { + if (ctx->burst.tx_count + size >= ARRAY_SIZE(ctx->burst.tx_buf)) { dev_err(ctx->dev, "TX-BLK buffer exhausted\n"); ctx->error = -EINVAL; return NULL; @@ -622,7 +622,7 @@ static u8 *sii8620_burst_get_rx_buf(struct sii8620 *ctx, int len) u8 *buf = >burst.rx_buf[ctx->burst.rx_count]; int size = len + 1; - if (ctx->burst.tx_count + size > ARRAY_SIZE(ctx->burst.tx_buf)) { + if (ctx->burst.rx_count + size >= ARRAY_SIZE(ctx->burst.rx_buf)) { dev_err(ctx->dev, "RX-BLK buffer exhausted\n"); ctx->error = -EINVAL; return NULL; Hi guys, Another patches for this module that I submitted at the same time as this one have been merged. Is this patch forgotten to merge? Thanks, Hangyu
Re: [PATCH] drm: i915: fix a possible refcount leak in intel_dp_add_mst_connector()
On 2022/5/16 15:19, Hangyu Hua wrote: If drm_connector_init fails, intel_connector_free will be called to take care of proper free. So it is necessary to drop the refcount of port before intel_connector_free. Fixes: 091a4f91942a ("drm/i915: Handle drm-layer errors in intel_dp_add_mst_connector") Signed-off-by: Hangyu Hua --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index e30e698aa684..f7d46ea3afb9 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -841,6 +841,7 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo ret = drm_connector_init(dev, connector, _dp_mst_connector_funcs, DRM_MODE_CONNECTOR_DisplayPort); if (ret) { + drm_dp_mst_put_port_malloc(port); intel_connector_free(intel_connector); return NULL; } Gentel ping.
Re: [PATCH] gpu: drm: fix possible memory leak in drm_addmap_core()
On 2022/5/23 09:57, Hangyu Hua wrote: On 2022/5/9 13:44, Hangyu Hua wrote: map->handle need to be handled correctly when map->type is _DRM_SHM or _DRM_CONSISTENT just like map->type is _DRM_REGISTERS. Fixes: 8d153f7107ff ("drm: update user token hashing and map handles") Signed-off-by: Hangyu Hua --- drivers/gpu/drm/drm_bufs.c | 18 ++ 1 file changed, 18 insertions(+) diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c index fcca21e8efac..2b3f504c5f9c 100644 --- a/drivers/gpu/drm/drm_bufs.c +++ b/drivers/gpu/drm/drm_bufs.c @@ -344,6 +344,15 @@ static int drm_addmap_core(struct drm_device *dev, resource_size_t offset, if (!list) { if (map->type == _DRM_REGISTERS) iounmap(map->handle); + else if (map->type == _DRM_SHM) { + dev->sigdata.lock = dev->master->lock.hw_lock = NULL; + vfree(map->handle); + } else if (map->type == _DRM_CONSISTENT) { + dma_free_coherent(dev->dev, + map->size, + map->handle, + map->offset); + } kfree(map); return -EINVAL; } @@ -361,6 +370,15 @@ static int drm_addmap_core(struct drm_device *dev, resource_size_t offset, if (ret) { if (map->type == _DRM_REGISTERS) iounmap(map->handle); + else if (map->type == _DRM_SHM) { + dev->sigdata.lock = dev->master->lock.hw_lock = NULL; + vfree(map->handle); + } else if (map->type == _DRM_CONSISTENT) { + dma_free_coherent(dev->dev, + map->size, + map->handle, + map->offset); + } kfree(map); kfree(list); mutex_unlock(>struct_mutex); Gentel ping. Gentel ping.
Re: [PATCH] drm/i915/guc/slpc: Use non-blocking H2G for waitboost
On Wed, 22 Jun 2022 17:32:25 -0700, Vinay Belgaumkar wrote: > > @@ -208,12 +232,14 @@ static int slpc_force_min_freq(struct intel_guc_slpc > *slpc, u32 freq) >*/ > > with_intel_runtime_pm(>runtime_pm, wakeref) { > - ret = slpc_set_param(slpc, > - SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ, > - freq); > + /* Non-blocking request will avoid stalls */ > + ret = slpc_set_param_nb(slpc, > + > SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ, > + freq); > if (ret) > - i915_probe_error(i915, "Unable to force min freq to %u: > %d", > - freq, ret); > + drm_notice(>drm, > +"Failed to send set_param for min freq(%d): > (%d)\n", > +freq, ret); I am still thinking if we should replace drm_notice() by i915_probe_error() since drm_notice() will basically hide any issues of boost/de-boost's getting dropped. Another idea here might be to maintain a counter, say "slpc->failed_boosts" which we increment each time slpc_set_param_nb() fails and dump that counter via intel_guc_slpc_print_info(). Anyway for now this is: Reviewed-by: Ashutosh Dixit
[PATCH] drm/i915/guc/slpc: Use non-blocking H2G for waitboost
SLPC min/max frequency updates require H2G calls. We are seeing timeouts when GuC channel is backed up and it is unable to respond in a timely fashion causing warnings and affecting CI. This is seen when waitboosting happens during a stress test. this patch updates the waitboost path to use a non-blocking H2G call instead, which returns as soon as the message is successfully transmitted. v2: Use drm_notice to report any errors that might occur while sending the waitboost H2G request (Tvrtko) v3: Add drm_notice inside force_min_freq (Ashutosh) Cc: Ashutosh Dixit Signed-off-by: Vinay Belgaumkar --- drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c | 42 + 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c index 2df31af70d63..ec9c4ca0f615 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c @@ -98,6 +98,30 @@ static u32 slpc_get_state(struct intel_guc_slpc *slpc) return data->header.global_state; } +static int guc_action_slpc_set_param_nb(struct intel_guc *guc, u8 id, u32 value) +{ + u32 request[] = { + GUC_ACTION_HOST2GUC_PC_SLPC_REQUEST, + SLPC_EVENT(SLPC_EVENT_PARAMETER_SET, 2), + id, + value, + }; + int ret; + + ret = intel_guc_send_nb(guc, request, ARRAY_SIZE(request), 0); + + return ret > 0 ? -EPROTO : ret; +} + +static int slpc_set_param_nb(struct intel_guc_slpc *slpc, u8 id, u32 value) +{ + struct intel_guc *guc = slpc_to_guc(slpc); + + GEM_BUG_ON(id >= SLPC_MAX_PARAM); + + return guc_action_slpc_set_param_nb(guc, id, value); +} + static int guc_action_slpc_set_param(struct intel_guc *guc, u8 id, u32 value) { u32 request[] = { @@ -208,12 +232,14 @@ static int slpc_force_min_freq(struct intel_guc_slpc *slpc, u32 freq) */ with_intel_runtime_pm(>runtime_pm, wakeref) { - ret = slpc_set_param(slpc, -SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ, -freq); + /* Non-blocking request will avoid stalls */ + ret = slpc_set_param_nb(slpc, + SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ, + freq); if (ret) - i915_probe_error(i915, "Unable to force min freq to %u: %d", -freq, ret); + drm_notice(>drm, + "Failed to send set_param for min freq(%d): (%d)\n", + freq, ret); } return ret; @@ -222,6 +248,7 @@ static int slpc_force_min_freq(struct intel_guc_slpc *slpc, u32 freq) static void slpc_boost_work(struct work_struct *work) { struct intel_guc_slpc *slpc = container_of(work, typeof(*slpc), boost_work); + int err; /* * Raise min freq to boost. It's possible that @@ -231,8 +258,9 @@ static void slpc_boost_work(struct work_struct *work) */ mutex_lock(>lock); if (atomic_read(>num_waiters)) { - slpc_force_min_freq(slpc, slpc->boost_freq); - slpc->num_boosts++; + err = slpc_force_min_freq(slpc, slpc->boost_freq); + if (!err) + slpc->num_boosts++; } mutex_unlock(>lock); } -- 2.35.1
[PATCH v2 1/3] drm/msm/dp: Reorganize code to avoid forward declaration
Let's move these functions around to avoid having to forward declare dp_ctrl_on_stream_phy_test_report(). Also remove dp_ctrl_reinitialize_mainlink() forward declaration because we're doing that sort of task. Reviewed-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov Signed-off-by: Stephen Boyd --- drivers/gpu/drm/msm/dp/dp_ctrl.c | 104 +++ 1 file changed, 50 insertions(+), 54 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c index 703249384e7c..bd445e683cfc 100644 --- a/drivers/gpu/drm/msm/dp/dp_ctrl.c +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c @@ -1238,8 +1238,6 @@ static int dp_ctrl_link_train_2(struct dp_ctrl_private *ctrl, return -ETIMEDOUT; } -static int dp_ctrl_reinitialize_mainlink(struct dp_ctrl_private *ctrl); - static int dp_ctrl_link_train(struct dp_ctrl_private *ctrl, int *training_step) { @@ -1534,38 +1532,6 @@ static int dp_ctrl_link_maintenance(struct dp_ctrl_private *ctrl) return ret; } -static int dp_ctrl_on_stream_phy_test_report(struct dp_ctrl *dp_ctrl); - -static int dp_ctrl_process_phy_test_request(struct dp_ctrl_private *ctrl) -{ - int ret = 0; - - if (!ctrl->link->phy_params.phy_test_pattern_sel) { - drm_dbg_dp(ctrl->drm_dev, - "no test pattern selected by sink\n"); - return ret; - } - - /* -* The global reset will need DP link related clocks to be -* running. Add the global reset just before disabling the -* link clocks and core clocks. -*/ - ret = dp_ctrl_off(>dp_ctrl); - if (ret) { - DRM_ERROR("failed to disable DP controller\n"); - return ret; - } - - ret = dp_ctrl_on_link(>dp_ctrl); - if (!ret) - ret = dp_ctrl_on_stream_phy_test_report(>dp_ctrl); - else - DRM_ERROR("failed to enable DP link controller\n"); - - return ret; -} - static bool dp_ctrl_send_phy_test_pattern(struct dp_ctrl_private *ctrl) { bool success = false; @@ -1618,6 +1584,56 @@ static bool dp_ctrl_send_phy_test_pattern(struct dp_ctrl_private *ctrl) return success; } +static int dp_ctrl_on_stream_phy_test_report(struct dp_ctrl *dp_ctrl) +{ + int ret; + struct dp_ctrl_private *ctrl; + + ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl); + + ctrl->dp_ctrl.pixel_rate = ctrl->panel->dp_mode.drm_mode.clock; + + ret = dp_ctrl_enable_stream_clocks(ctrl); + if (ret) { + DRM_ERROR("Failed to start pixel clocks. ret=%d\n", ret); + return ret; + } + + dp_ctrl_send_phy_test_pattern(ctrl); + + return 0; +} + +static int dp_ctrl_process_phy_test_request(struct dp_ctrl_private *ctrl) +{ + int ret = 0; + + if (!ctrl->link->phy_params.phy_test_pattern_sel) { + drm_dbg_dp(ctrl->drm_dev, + "no test pattern selected by sink\n"); + return ret; + } + + /* +* The global reset will need DP link related clocks to be +* running. Add the global reset just before disabling the +* link clocks and core clocks. +*/ + ret = dp_ctrl_off(>dp_ctrl); + if (ret) { + DRM_ERROR("failed to disable DP controller\n"); + return ret; + } + + ret = dp_ctrl_on_link(>dp_ctrl); + if (!ret) + ret = dp_ctrl_on_stream_phy_test_report(>dp_ctrl); + else + DRM_ERROR("failed to enable DP link controller\n"); + + return ret; +} + void dp_ctrl_handle_sink_request(struct dp_ctrl *dp_ctrl) { struct dp_ctrl_private *ctrl; @@ -1815,26 +1831,6 @@ static int dp_ctrl_link_retrain(struct dp_ctrl_private *ctrl) return dp_ctrl_setup_main_link(ctrl, _step); } -static int dp_ctrl_on_stream_phy_test_report(struct dp_ctrl *dp_ctrl) -{ - int ret; - struct dp_ctrl_private *ctrl; - - ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl); - - ctrl->dp_ctrl.pixel_rate = ctrl->panel->dp_mode.drm_mode.clock; - - ret = dp_ctrl_enable_stream_clocks(ctrl); - if (ret) { - DRM_ERROR("Failed to start pixel clocks. ret=%d\n", ret); - return ret; - } - - dp_ctrl_send_phy_test_pattern(ctrl); - - return 0; -} - int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl, bool force_link_train) { int ret = 0; -- https://chromeos.dev
[PATCH v2 3/3] drm/msm/dp: Get rid of dp_ctrl_on_stream_phy_test_report()
This API isn't really more than a couple lines now that we don't store the pixel_rate to the struct member. Inline it into the caller. Cc: Kuogee Hsieh Signed-off-by: Stephen Boyd --- drivers/gpu/drm/msm/dp/dp_ctrl.c | 44 1 file changed, 17 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c index feb26d4d6e97..e475f4ca078a 100644 --- a/drivers/gpu/drm/msm/dp/dp_ctrl.c +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c @@ -1564,36 +1564,15 @@ static bool dp_ctrl_send_phy_test_pattern(struct dp_ctrl_private *ctrl) return success; } -static int dp_ctrl_on_stream_phy_test_report(struct dp_ctrl *dp_ctrl) +static int dp_ctrl_process_phy_test_request(struct dp_ctrl_private *ctrl) { int ret; - struct dp_ctrl_private *ctrl; unsigned long pixel_rate; - ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl); - - pixel_rate = ctrl->panel->dp_mode.drm_mode.clock; - dp_ctrl_set_clock_rate(ctrl, DP_STREAM_PM, "stream_pixel", pixel_rate * 1000); - - ret = dp_power_clk_enable(ctrl->power, DP_STREAM_PM, true); - if (ret) { - DRM_ERROR("Unable to start pixel clocks. ret=%d\n", ret); - return ret; - } - - dp_ctrl_send_phy_test_pattern(ctrl); - - return 0; -} - -static int dp_ctrl_process_phy_test_request(struct dp_ctrl_private *ctrl) -{ - int ret = 0; - if (!ctrl->link->phy_params.phy_test_pattern_sel) { drm_dbg_dp(ctrl->drm_dev, "no test pattern selected by sink\n"); - return ret; + return 0; } /* @@ -1608,12 +1587,23 @@ static int dp_ctrl_process_phy_test_request(struct dp_ctrl_private *ctrl) } ret = dp_ctrl_on_link(>dp_ctrl); - if (!ret) - ret = dp_ctrl_on_stream_phy_test_report(>dp_ctrl); - else + if (ret) { DRM_ERROR("failed to enable DP link controller\n"); + return ret; + } - return ret; + pixel_rate = ctrl->panel->dp_mode.drm_mode.clock; + dp_ctrl_set_clock_rate(ctrl, DP_STREAM_PM, "stream_pixel", pixel_rate * 1000); + + ret = dp_power_clk_enable(ctrl->power, DP_STREAM_PM, true); + if (ret) { + DRM_ERROR("Failed to start pixel clocks. ret=%d\n", ret); + return ret; + } + + dp_ctrl_send_phy_test_pattern(ctrl); + + return 0; } void dp_ctrl_handle_sink_request(struct dp_ctrl *dp_ctrl) -- https://chromeos.dev
[PATCH v2 2/3] drm/msm/dp: Remove pixel_rate from struct dp_ctrl
This struct member is stored to in the function that calls the function which uses it. That's possible with a function argument instead of storing to a struct member. Pass the pixel_rate as an argument instead to simplify the code. Note that dp_ctrl_link_maintenance() was storing the pixel_rate but never using it so we just remove the assignment from there. Cc: Kuogee Hsieh Signed-off-by: Stephen Boyd --- dp_ctrl_on_link() almost doesn't even use the pixel_clk either. It just prints the value. I kept it around because maybe it is useful? But if not, then we can remove even more code. drivers/gpu/drm/msm/dp/dp_ctrl.c | 60 drivers/gpu/drm/msm/dp/dp_ctrl.h | 1 - 2 files changed, 22 insertions(+), 39 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c index bd445e683cfc..feb26d4d6e97 100644 --- a/drivers/gpu/drm/msm/dp/dp_ctrl.c +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c @@ -1357,25 +1357,7 @@ static int dp_ctrl_enable_mainlink_clocks(struct dp_ctrl_private *ctrl) if (ret) DRM_ERROR("Unable to start link clocks. ret=%d\n", ret); - drm_dbg_dp(ctrl->drm_dev, "link rate=%d pixel_clk=%d\n", - ctrl->link->link_params.rate, ctrl->dp_ctrl.pixel_rate); - - return ret; -} - -static int dp_ctrl_enable_stream_clocks(struct dp_ctrl_private *ctrl) -{ - int ret = 0; - - dp_ctrl_set_clock_rate(ctrl, DP_STREAM_PM, "stream_pixel", - ctrl->dp_ctrl.pixel_rate * 1000); - - ret = dp_power_clk_enable(ctrl->power, DP_STREAM_PM, true); - if (ret) - DRM_ERROR("Unabled to start pixel clocks. ret=%d\n", ret); - - drm_dbg_dp(ctrl->drm_dev, "link rate=%d pixel_clk=%d\n", - ctrl->link->link_params.rate, ctrl->dp_ctrl.pixel_rate); + drm_dbg_dp(ctrl->drm_dev, "link rate=%d\n", ctrl->link->link_params.rate); return ret; } @@ -1517,8 +1499,6 @@ static int dp_ctrl_link_maintenance(struct dp_ctrl_private *ctrl) ctrl->link->phy_params.p_level = 0; ctrl->link->phy_params.v_level = 0; - ctrl->dp_ctrl.pixel_rate = ctrl->panel->dp_mode.drm_mode.clock; - ret = dp_ctrl_setup_main_link(ctrl, _step); if (ret) goto end; @@ -1588,14 +1568,16 @@ static int dp_ctrl_on_stream_phy_test_report(struct dp_ctrl *dp_ctrl) { int ret; struct dp_ctrl_private *ctrl; + unsigned long pixel_rate; ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl); - ctrl->dp_ctrl.pixel_rate = ctrl->panel->dp_mode.drm_mode.clock; + pixel_rate = ctrl->panel->dp_mode.drm_mode.clock; + dp_ctrl_set_clock_rate(ctrl, DP_STREAM_PM, "stream_pixel", pixel_rate * 1000); - ret = dp_ctrl_enable_stream_clocks(ctrl); + ret = dp_power_clk_enable(ctrl->power, DP_STREAM_PM, true); if (ret) { - DRM_ERROR("Failed to start pixel clocks. ret=%d\n", ret); + DRM_ERROR("Unable to start pixel clocks. ret=%d\n", ret); return ret; } @@ -1704,11 +1686,12 @@ int dp_ctrl_on_link(struct dp_ctrl *dp_ctrl) { int rc = 0; struct dp_ctrl_private *ctrl; - u32 rate = 0; + u32 rate; int link_train_max_retries = 5; u32 const phy_cts_pixel_clk_khz = 148500; u8 link_status[DP_LINK_STATUS_SIZE]; unsigned int training_step; + unsigned long pixel_rate; if (!dp_ctrl) return -EINVAL; @@ -1716,25 +1699,24 @@ int dp_ctrl_on_link(struct dp_ctrl *dp_ctrl) ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl); rate = ctrl->panel->link_info.rate; + pixel_rate = ctrl->panel->dp_mode.drm_mode.clock; dp_power_clk_enable(ctrl->power, DP_CORE_PM, true); if (ctrl->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN) { drm_dbg_dp(ctrl->drm_dev, "using phy test link parameters\n"); - if (!ctrl->panel->dp_mode.drm_mode.clock) - ctrl->dp_ctrl.pixel_rate = phy_cts_pixel_clk_khz; + if (!pixel_rate) + pixel_rate = phy_cts_pixel_clk_khz; } else { ctrl->link->link_params.rate = rate; ctrl->link->link_params.num_lanes = ctrl->panel->link_info.num_lanes; - ctrl->dp_ctrl.pixel_rate = ctrl->panel->dp_mode.drm_mode.clock; } - drm_dbg_dp(ctrl->drm_dev, "rate=%d, num_lanes=%d, pixel_rate=%d\n", + drm_dbg_dp(ctrl->drm_dev, "rate=%d, num_lanes=%d, pixel_rate=%lu\n", ctrl->link->link_params.rate, ctrl->link->link_params.num_lanes, - ctrl->dp_ctrl.pixel_rate); - + pixel_rate); rc = dp_ctrl_enable_mainlink_clocks(ctrl); if (rc) @@ -1836,6 +1818,7 @@ int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl, bool
[PATCH v2 0/3] drm/msm/dp: More cleanups for force link train
These patches do a little cleanup on the v9 patch[1] from Kuogee. Changes from v1: * Reduce code even more in second patch * Pick up tags on first patch Stephen Boyd (3): drm/msm/dp: Reorganize code to avoid forward declaration drm/msm/dp: Remove pixel_rate from struct dp_ctrl drm/msm/dp: Get rid of dp_ctrl_on_stream_phy_test_report() drivers/gpu/drm/msm/dp/dp_ctrl.c | 148 --- drivers/gpu/drm/msm/dp/dp_ctrl.h | 1 - 2 files changed, 59 insertions(+), 90 deletions(-) [1] https://lore.kernel.org/r/1655411200-7255-1-git-send-email-quic_khs...@quicinc.com base-commit: f2906aa863381afb0015a9eb7fefad885d4e5a56 prerequisite-patch-id: 2fc33a2830ec84d922023fddb585728c48a59525 -- https://chromeos.dev
Re: DMA-buf and uncached system memory
Hi Nicolas, On Wed, 22 Jun 2022 at 20:39, Nicolas Dufresne wrote: > Le mardi 16 février 2021 à 10:25 +0100, Daniel Vetter a écrit : > > So I think if AMD also guarantees to drop clean cachelines just do the > > same thing we do right now for intel integrated + discrete amd, but in > > reserve. It's fragile, but it does work. > > Sorry to disrupt, but if you pass V4L2 vmalloc data to Intel display driver, > you > also get nice dirt on the screen. If you have a UVC webcam that produces a > pixel > format compatible with your display, you can reproduce the issue quite easily > with: > > gst-launch-1.0 v4l2src device=/dev/video0 ! kmssink > > p.s. some frame-rate are less likely to exhibit the issue, make sure you > create > movement to see it. Right, this is because the UVC data in a vmalloc() area is not necessarily flushed from the CPU cache, and the importer expects it will be. > The only solution I could think of (not implemented) was to detect in the > attach() call what the importers can do (with dev->coherent_dma_mask if I > recall), and otherwise flush the cache immediately and start flushing the > cache > from now on signalling it for DQBUF (in vb2 workqueue or dqbuf ioctl, I don't > have an idea yet). I bet this idea is inapplicable to were you have fences, we > don't have that in v4l2. > > This idea was hinted by Robert Becket (now in CC), but perhaps I picked it up > wrong, explaining it wrong, etc. I'm no expert, just noticed there wasn't > really > a good plan for that, so one needs to make one up. I'm not aware oh an > importer > could know how the memory was allocated by the exporter, and worst, how an > importer could figure-out that the export is going to produce buffer with hot > CPU cache (UVC driver does memcpy from USB chunks of variable size to produce > a > fixed size image). This is exactly what Christian was saying above. Cheers, Daniel
Re: [PATCH v5 01/13] mm: add zone device coherent type memory support
On 6/21/2022 11:16 AM, David Hildenbrand wrote: On 21.06.22 18:08, Sierra Guiza, Alejandro (Alex) wrote: On 6/21/2022 7:25 AM, David Hildenbrand wrote: On 21.06.22 13:55, Alistair Popple wrote: David Hildenbrand writes: On 21.06.22 13:25, Felix Kuehling wrote: Am 6/17/22 um 23:19 schrieb David Hildenbrand: On 17.06.22 21:27, Sierra Guiza, Alejandro (Alex) wrote: On 6/17/2022 12:33 PM, David Hildenbrand wrote: On 17.06.22 19:20, Sierra Guiza, Alejandro (Alex) wrote: On 6/17/2022 4:40 AM, David Hildenbrand wrote: On 31.05.22 22:00, Alex Sierra wrote: Device memory that is cache coherent from device and CPU point of view. This is used on platforms that have an advanced system bus (like CAPI or CXL). Any page of a process can be migrated to such memory. However, no one should be allowed to pin such memory so that it can always be evicted. Signed-off-by: Alex Sierra Acked-by: Felix Kuehling Reviewed-by: Alistair Popple [hch: rebased ontop of the refcount changes, removed is_dev_private_or_coherent_page] Signed-off-by: Christoph Hellwig --- include/linux/memremap.h | 19 +++ mm/memcontrol.c | 7 --- mm/memory-failure.c | 8 ++-- mm/memremap.c| 10 ++ mm/migrate_device.c | 16 +++- mm/rmap.c| 5 +++-- 6 files changed, 49 insertions(+), 16 deletions(-) diff --git a/include/linux/memremap.h b/include/linux/memremap.h index 8af304f6b504..9f752ebed613 100644 --- a/include/linux/memremap.h +++ b/include/linux/memremap.h @@ -41,6 +41,13 @@ struct vmem_altmap { * A more complete discussion of unaddressable memory may be found in * include/linux/hmm.h and Documentation/vm/hmm.rst. * + * MEMORY_DEVICE_COHERENT: + * Device memory that is cache coherent from device and CPU point of view. This + * is used on platforms that have an advanced system bus (like CAPI or CXL). A + * driver can hotplug the device memory using ZONE_DEVICE and with that memory + * type. Any page of a process can be migrated to such memory. However no one Any page might not be right, I'm pretty sure. ... just thinking about special pages like vdso, shared zeropage, ... pinned pages ... Well, you cannot migrate long term pages, that's what I meant :) + * should be allowed to pin such memory so that it can always be evicted. + * * MEMORY_DEVICE_FS_DAX: * Host memory that has similar access semantics as System RAM i.e. DMA * coherent and supports page pinning. In support of coordinating page @@ -61,6 +68,7 @@ struct vmem_altmap { enum memory_type { /* 0 is reserved to catch uninitialized type fields */ MEMORY_DEVICE_PRIVATE = 1, + MEMORY_DEVICE_COHERENT, MEMORY_DEVICE_FS_DAX, MEMORY_DEVICE_GENERIC, MEMORY_DEVICE_PCI_P2PDMA, @@ -143,6 +151,17 @@ static inline bool folio_is_device_private(const struct folio *folio) In general, this LGTM, and it should be correct with PageAnonExclusive I think. However, where exactly is pinning forbidden? Long-term pinning is forbidden since it would interfere with the device memory manager owning the device-coherent pages (e.g. evictions in TTM). However, normal pinning is allowed on this device type. I don't see updates to folio_is_pinnable() in this patch. Device coherent type pages should return true here, as they are pinnable pages. That function is only called for long-term pinnings in try_grab_folio(). So wouldn't try_grab_folio() simply pin these pages? What am I missing? As far as I understand this return NULL for long term pin pages. Otherwise they get refcount incremented. I don't follow. You're saying a) folio_is_pinnable() returns true for device coherent pages and that b) device coherent pages don't get long-term pinned Yet, the code says struct folio *try_grab_folio(struct page *page, int refs, unsigned int flags) { if (flags & FOLL_GET) return try_get_folio(page, refs); else if (flags & FOLL_PIN) { struct folio *folio; /* * Can't do FOLL_LONGTERM + FOLL_PIN gup fast path if not in a * right zone, so fail and let the caller fall back to the slow * path. */ if (unlikely((flags & FOLL_LONGTERM) && !is_pinnable_page(page))) return NULL; ... return folio; } } What prevents these pages from getting long-term pinned as stated in this patch? Long-term pinning is handled by __gup_longterm_locked, which migrates pages returned by __get_user_pages_locked that cannot be long-term pinned. try_grab_folio is OK to grab the pages. Anything that can't be long-term pinned will be migrated afterwards, and __get_user_pages_locked will be retried. The migration of DEVICE_COHERENT pages was implemented by Alistair in
Re: [PATCH v5 01/13] mm: add zone device coherent type memory support
On 6/21/2022 7:16 PM, Alistair Popple wrote: David Hildenbrand writes: On 21.06.22 18:08, Sierra Guiza, Alejandro (Alex) wrote: On 6/21/2022 7:25 AM, David Hildenbrand wrote: On 21.06.22 13:55, Alistair Popple wrote: David Hildenbrand writes: On 21.06.22 13:25, Felix Kuehling wrote: Am 6/17/22 um 23:19 schrieb David Hildenbrand: On 17.06.22 21:27, Sierra Guiza, Alejandro (Alex) wrote: On 6/17/2022 12:33 PM, David Hildenbrand wrote: On 17.06.22 19:20, Sierra Guiza, Alejandro (Alex) wrote: On 6/17/2022 4:40 AM, David Hildenbrand wrote: On 31.05.22 22:00, Alex Sierra wrote: Device memory that is cache coherent from device and CPU point of view. This is used on platforms that have an advanced system bus (like CAPI or CXL). Any page of a process can be migrated to such memory. However, no one should be allowed to pin such memory so that it can always be evicted. Signed-off-by: Alex Sierra Acked-by: Felix Kuehling Reviewed-by: Alistair Popple [hch: rebased ontop of the refcount changes, removed is_dev_private_or_coherent_page] Signed-off-by: Christoph Hellwig --- include/linux/memremap.h | 19 +++ mm/memcontrol.c | 7 --- mm/memory-failure.c | 8 ++-- mm/memremap.c| 10 ++ mm/migrate_device.c | 16 +++- mm/rmap.c| 5 +++-- 6 files changed, 49 insertions(+), 16 deletions(-) diff --git a/include/linux/memremap.h b/include/linux/memremap.h index 8af304f6b504..9f752ebed613 100644 --- a/include/linux/memremap.h +++ b/include/linux/memremap.h @@ -41,6 +41,13 @@ struct vmem_altmap { * A more complete discussion of unaddressable memory may be found in * include/linux/hmm.h and Documentation/vm/hmm.rst. * + * MEMORY_DEVICE_COHERENT: + * Device memory that is cache coherent from device and CPU point of view. This + * is used on platforms that have an advanced system bus (like CAPI or CXL). A + * driver can hotplug the device memory using ZONE_DEVICE and with that memory + * type. Any page of a process can be migrated to such memory. However no one Any page might not be right, I'm pretty sure. ... just thinking about special pages like vdso, shared zeropage, ... pinned pages ... Well, you cannot migrate long term pages, that's what I meant :) + * should be allowed to pin such memory so that it can always be evicted. + * * MEMORY_DEVICE_FS_DAX: * Host memory that has similar access semantics as System RAM i.e. DMA * coherent and supports page pinning. In support of coordinating page @@ -61,6 +68,7 @@ struct vmem_altmap { enum memory_type { /* 0 is reserved to catch uninitialized type fields */ MEMORY_DEVICE_PRIVATE = 1, + MEMORY_DEVICE_COHERENT, MEMORY_DEVICE_FS_DAX, MEMORY_DEVICE_GENERIC, MEMORY_DEVICE_PCI_P2PDMA, @@ -143,6 +151,17 @@ static inline bool folio_is_device_private(const struct folio *folio) In general, this LGTM, and it should be correct with PageAnonExclusive I think. However, where exactly is pinning forbidden? Long-term pinning is forbidden since it would interfere with the device memory manager owning the device-coherent pages (e.g. evictions in TTM). However, normal pinning is allowed on this device type. I don't see updates to folio_is_pinnable() in this patch. Device coherent type pages should return true here, as they are pinnable pages. That function is only called for long-term pinnings in try_grab_folio(). So wouldn't try_grab_folio() simply pin these pages? What am I missing? As far as I understand this return NULL for long term pin pages. Otherwise they get refcount incremented. I don't follow. You're saying a) folio_is_pinnable() returns true for device coherent pages and that b) device coherent pages don't get long-term pinned Yet, the code says struct folio *try_grab_folio(struct page *page, int refs, unsigned int flags) { if (flags & FOLL_GET) return try_get_folio(page, refs); else if (flags & FOLL_PIN) { struct folio *folio; /* * Can't do FOLL_LONGTERM + FOLL_PIN gup fast path if not in a * right zone, so fail and let the caller fall back to the slow * path. */ if (unlikely((flags & FOLL_LONGTERM) && !is_pinnable_page(page))) return NULL; ... return folio; } } What prevents these pages from getting long-term pinned as stated in this patch? Long-term pinning is handled by __gup_longterm_locked, which migrates pages returned by __get_user_pages_locked that cannot be long-term pinned. try_grab_folio is OK to grab the pages. Anything that can't be long-term pinned will be migrated afterwards, and __get_user_pages_locked will be retried. The migration of DEVICE_COHERENT pages was
Re: [PATCH v2 1/2] agp/intel: Rename intel-gtt symbols
On Fri, Jun 17, 2022 at 04:05:58PM -0700, Lucas De Marchi wrote: Exporting the symbols like intel_gtt_* creates some confusion inside i915 that has symbols named similarly. In an attempt to isolate platforms needing intel-gtt.ko, commit 7a5c922377b4 ("drm/i915/gt: Split intel-gtt functions by arch") moved way too much inside gt/intel_gt_gmch.c, even the functions that don't callout to this module. Rename the symbols to make the separation clear. Signed-off-by: Lucas De Marchi Reviewed-by: Tvrtko Ursulin I was in doubt if drm-intel-gt-next would be the most appropriate to push this patch to, but after checking the last 20 commits (which goes back to 2015) touching drivers/char/agp/intel-gtt.c, 17 of them came from drm-intel-next/drm-intel-gt-next/drm-intel-next-queued Applied both patches to drm-intel-gt-next. thanks Lucas De Marchi
Re: [RFC 0/3] drm/amd/display: Introduce KUnit to Display Mode Library
Hi, First of all, thanks a lot for exploring the introduction of kunit inside amdgpu. See my inline comments On 2022-06-18 05:08, David Gow wrote: On Sat, Jun 18, 2022 at 4:24 AM Maíra Canal wrote: On 6/17/22 04:55, David Gow wrote: On Fri, Jun 17, 2022 at 6:41 AM Maíra Canal wrote: Hi David, Thank you for your feedback! On 6/16/22 11:39, David Gow wrote: On Wed, Jun 8, 2022 at 9:08 AM Maíra Canal wrote: As kunit_test_suites() defines itself as an init_module(), it conflicts with the existing one at amdgpu_drv. So, if we use kunit_test_suites(), we won't be able to compile the tests as modules and, therefore, won't be able to use IGT to run the tests. This problem with kunit_test_suites() was already discussed in the KUnit mailing list, as can be seen in [7]. I'm not sure I fully understand why these tests need to be part of the amdgpu module, though admittedly I've not played with IGT much. Would it be possible to compile these tests as separate modules, which could depend on amdgpu (or maybe include the DML stuff directly), and therefore not have this conflict? I definitely was able to get these tests working under kunit_tool (albeit as built-ins) by using kunit_test_suites(). If each suite were built as a separate module (or indeed, even if all the tests were in one module, with one list of suites), then it should be possible to avoid the init_module() conflict. That'd also make it possible to run these tests without actually needing the driver to initialise, which seems like it might require actual hardware(?) In the Display code for amdgpu, we heavily rely on IGT for automated tests. We have some internal CI where we run a large set of IGT tests per patch, and I'm sure many other DRM developers also use IGT. In this sense, if we can have an interface inside IGT that can easily run those kunit tests, we can enable kunit tests in our CI pipeline almost for free :) We already have a prototype for this sort of integration at: https://patchwork.freedesktop.org/series/105294/ Initially, we tried the kunit_test_suites() approach. And it did work pretty well for the kunit_tool (although we didn't test any hardware-specific unit test). But when compiling the test as a module, we would get a linking error, pointing out multiple definitions of 'init_module'/'cleanup_module' at kunit_test_suites(). At this point, we thought about a couple of options to resolve this problem: - Add EXPORT_SYMBOL to the functions we would test. But, this doesn't scale pretty well, because it would pollute AMDGPU code as the tests expand. - Take the Thunderbolt path and add the tests to the driver stack. We end up taking the Thunderbolt path as it would be more maintainable. Compiling the tests as a module is essential to make the tests run at IGT, as IGT essentially loads the module, runs it, and parses the output (a very very simplified explanation of what IGT does). IGT is a very known tool for DRI developers, so we believe that IGT support is crucial for this project. If you have any other options on how to make the module compilation viable without using the 'thunderbolt'-style, we would be glad to hear your suggestions. As you point out, there are really two separate problems with splitting the tests out totally: - It's ugly and pollutes the symbol namespace to have EXPORT_SYMBOL() everywhere. - It's impossible to have multiple init_module() "calls" in the same module. The first of these is, I think, the harder to solve generally. (There are some ways to mitigate the namespace pollution part of it by either hiding the EXPORT_SYMBOL() directives behind #ifdef CONFIG_KUNIT or similar, or by using symbol namespaces: https://www.kernel.org/doc/html/latest/core-api/symbol-namespaces.html -- or both -- but they don't solve the issue entirely.) That being said, it's as much a matter of taste as anything, so if keeping things in the amdgpu module works well, don't let me stop you. Either way should work, and have their own advantages and disadvantages. I want to avoid making changes inside the dc code [1] (or keep it minimal) for enabling kunit. Aligned with the IGT comment, I'm more inclined to a solution where we treat the kunit tests for DML as a module. However, I'm not sure yet if it is possible to have something like that... Does it make things easier if we have a single module that handles the dml-kunit interface, and we can control which test to invoke via kernel parameter? 1. https://gitlab.freedesktop.org/agd5f/linux/-/tree/amd-staging-drm-next/drivers/gpu/drm/amd/display/dc The latter is just a quirk of the current KUnit implementation of kunit_test_suites(). This multiple-definition issue will go away in the not-too-distant future. So my suggestion here would be to make sure any changes you make to work around the issue with multiple init_module definitions are easy to remove. I suspect you could probably significantly simplify the whole dml_test.{c,h}
Re: [PATCH V2 2/2] drm: xlnx: dsi: Add Xilinx MIPI DSI-Tx subsystem driver
Hi GVRao, Thank you for the patch. On Thu, Jun 16, 2022 at 07:47:36PM +0530, Venkateshwar Rao Gannavarapu wrote: > The Xilinx MIPI DSI Tx Subsystem soft IP is used to display video > data from AXI-4 stream interface. > > It supports upto 4 lanes, optional register interface for the DPHY > and multiple RGB color formats. > This is a MIPI-DSI host driver and provides DSI bus for panels. > This driver also helps to communicate with its panel using panel > framework. > > Signed-off-by: Venkateshwar Rao Gannavarapu > > --- > drivers/gpu/drm/xlnx/Kconfig| 12 ++ > drivers/gpu/drm/xlnx/Makefile | 1 + > drivers/gpu/drm/xlnx/xlnx_dsi.c | 429 > > 3 files changed, 442 insertions(+) > create mode 100644 drivers/gpu/drm/xlnx/xlnx_dsi.c > > diff --git a/drivers/gpu/drm/xlnx/Kconfig b/drivers/gpu/drm/xlnx/Kconfig > index f9cf93c..a75bd76 100644 > --- a/drivers/gpu/drm/xlnx/Kconfig > +++ b/drivers/gpu/drm/xlnx/Kconfig > @@ -1,3 +1,15 @@ > +config DRM_XLNX_DSI > + tristate "Xilinx DRM DSI Subsystem Driver" > + depends on ARCH_ZYNQMP || COMPILE_TEST > + depends on DRM && OF > + select DRM_KMS_HELPER > + select DRM_MIPI_DSI > + select DRM_PANEL_BRIDGE You can drop DRM_PANEL_BRIDGE, the driver doesn't need it. > + help > + DRM bridge driver for Xilinx programmable DSI subsystem controller. > + choose this option if you hava a Xilinx MIPI-DSI Tx subsytem in s/choose/Choose/ > + video pipeline. > + > config DRM_ZYNQMP_DPSUB > tristate "ZynqMP DisplayPort Controller Driver" > depends on ARCH_ZYNQMP || COMPILE_TEST > diff --git a/drivers/gpu/drm/xlnx/Makefile b/drivers/gpu/drm/xlnx/Makefile > index 51c24b7..f90849b 100644 > --- a/drivers/gpu/drm/xlnx/Makefile > +++ b/drivers/gpu/drm/xlnx/Makefile > @@ -1,2 +1,3 @@ > +obj-$(CONFIG_DRM_XLNX_DSI) += xlnx_dsi.o > zynqmp-dpsub-y := zynqmp_disp.o zynqmp_dpsub.o zynqmp_dp.o > obj-$(CONFIG_DRM_ZYNQMP_DPSUB) += zynqmp-dpsub.o > diff --git a/drivers/gpu/drm/xlnx/xlnx_dsi.c b/drivers/gpu/drm/xlnx/xlnx_dsi.c > new file mode 100644 > index 000..39d8947 > --- /dev/null > +++ b/drivers/gpu/drm/xlnx/xlnx_dsi.c > @@ -0,0 +1,429 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Xilinx FPGA MIPI DSI Tx Controller driver. > + * > + * Copyright (C) 2022 Xilinx, Inc. > + * > + * Author: Venkateshwar Rao Gannavarapu > > + */ > + > +#include > +#include > +#include I'd add at least platform_device.h to avoid depending on indirect inclusion of headers. > + > +#include > +#include > +#include > +#include > +#include > +#include Not needed. > +#include > + > +/* DSI Tx IP registers */ > +#define XDSI_CCR 0x00 > +#define XDSI_CCR_COREENB BIT(0) > +#define XDSI_CCR_SOFTRST BIT(1) > +#define XDSI_CCR_CRREADY BIT(2) > +#define XDSI_CCR_CMDMODE BIT(3) > +#define XDSI_CCR_DFIFORSTBIT(4) > +#define XDSI_CCR_CMDFIFORST BIT(5) > +#define XDSI_PCR 0x04 > +#define XDSI_PCR_LANES_MASK 3 > +#define XDSI_PCR_VIDEOMODE(x)(((x) & 0x3) << 3) > +#define XDSI_PCR_VIDEOMODE_MASK GENMASK(4, 3) > +#define XDSI_PCR_VIDEOMODE_SHIFT 3 > +#define XDSI_PCR_BLLPTYPE(x) ((x) << 5) > +#define XDSI_PCR_BLLPMODE(x) ((x) << 6) > +#define XDSI_PCR_PIXELFORMAT_MASKGENMASK(12, 11) > +#define XDSI_PCR_PIXELFORMAT_SHIFT 11 > +#define XDSI_PCR_EOTPENABLE(x) ((x) << 13) > +#define XDSI_GIER0x20 > +#define XDSI_ISR 0x24 > +#define XDSI_IER 0x28 > +#define XDSI_STR 0x2C > +#define XDSI_STR_RDY_SHPKT BIT(6) > +#define XDSI_STR_RDY_LNGPKT BIT(7) > +#define XDSI_STR_DFIFO_FULL BIT(8) > +#define XDSI_STR_DFIFO_EMPTY BIT(9) > +#define XDSI_STR_WAITFR_DATA BIT(10) > +#define XDSI_STR_CMD_EXE_PGS BIT(11) > +#define XDSI_STR_CCMD_PROC BIT(12) > +#define XDSI_CMD 0x30 > +#define XDSI_CMD_QUEUE_PACKET(x) ((x) & GENMASK(23, 0)) > +#define XDSI_DFR 0x34 > +#define XDSI_TIME1 0x50 > +#define XDSI_TIME1_BLLP_BURST(x) ((x) & GENMASK(15, 0)) > +#define XDSI_TIME1_HSA(x)(((x) & GENMASK(15, 0)) << 16) > +#define XDSI_TIME2 0x54 > +#define XDSI_TIME2_VACT(x) ((x) & GENMASK(15, 0)) > +#define XDSI_TIME2_HACT(x) (((x) & GENMASK(15, 0)) << 16) > +#define XDSI_HACT_MULTIPLIER GENMASK(1, 0) > +#define XDSI_TIME3 0x58 > +#define XDSI_TIME3_HFP(x)((x) & GENMASK(15, 0)) > +#define XDSI_TIME3_HBP(x)(((x) & GENMASK(15, 0)) << 16) > +#define XDSI_TIME4 0x5c > +#define XDSI_TIME4_VFP(x)((x) & GENMASK(7, 0)) > +#define XDSI_TIME4_VBP(x)(((x) & GENMASK(7, 0)) << 8) > +#define XDSI_TIME4_VSA(x)(((x) &
[pull] amdgpu drm-fixes-5.19
Hi Dave, Daniel, Fixes for 5.19. The following changes since commit a111daf0c53ae91e71fd2bfe7497862d14132e3e: Linux 5.19-rc3 (2022-06-19 15:06:47 -0500) are available in the Git repository at: https://gitlab.freedesktop.org/agd5f/linux.git tags/amd-drm-fixes-5.19-2022-06-22 for you to fetch changes up to e84131a88a8cdcd6fe9f234ed98e3f8ca049142b: amd/display/dc: Fix COLOR_ENCODING and COLOR_RANGE doing nothing for DCN20+ (2022-06-22 17:17:16 -0400) amd-drm-fixes-5.19-2022-06-22: amdgpu: - Adjust GTT size logic - eDP fix for RMB - DCN 3.15 fix - DP training fix - Color encoding fix for DCN2+ Alex Deucher (1): drm/amdgpu: Adjust logic around GTT size (v3) George Shen (1): drm/amd/display: Fix typo in override_lane_settings Joshua Ashton (1): amd/display/dc: Fix COLOR_ENCODING and COLOR_RANGE doing nothing for DCN20+ Mario Limonciello (1): drm/amd: Revert "drm/amd/display: keep eDP Vdd on when eDP stream is already enabled" Qingqing Zhuo (1): drm/amd/display: Fix DC warning at driver load drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c| 20 -- .../amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c | 2 +- drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 2 +- .../amd/display/dc/dce110/dce110_hw_sequencer.c| 24 ++ drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp.c | 3 +++ drivers/gpu/drm/amd/display/dc/dcn201/dcn201_dpp.c | 3 +++ drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c | 3 +++ 7 files changed, 27 insertions(+), 30 deletions(-)
Re: [v3 5/5] drm/msm/disp/dpu1: add PSR support for eDP interface in dpu driver
Hi Vinod, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on drm/drm-next] [also build test WARNING on drm-exynos/exynos-drm-next drm-tip/drm-tip tegra-drm/drm/tegra/for-next linus/master v5.19-rc3 next-20220622] [cannot apply to drm-intel/for-linux-next airlied/drm-next] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/intel-lab-lkp/linux/commits/Vinod-Polimera/drm-msm-dp-Add-basic-PSR-support-for-eDP/20220621-195406 base: git://anongit.freedesktop.org/drm/drm drm-next config: arm64-randconfig-r025-20220622 (https://download.01.org/0day-ci/archive/20220623/202206230551.h0oxev2e-...@intel.com/config) compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project 8b8d126598ce7bd5243da7f94f69fa1104288bee) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # install arm64 cross compiling tool for clang build # apt-get install binutils-aarch64-linux-gnu # https://github.com/intel-lab-lkp/linux/commit/2c3c31343481a4faf2402cf513c85fb7d75ce205 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Vinod-Polimera/drm-msm-dp-Add-basic-PSR-support-for-eDP/20220621-195406 git checkout 2c3c31343481a4faf2402cf513c85fb7d75ce205 # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=arm64 SHELL=/bin/bash If you fix the issue, kindly add following tag where applicable Reported-by: kernel test robot All warnings (new ones prefixed by >>): >> drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c:1064:3: warning: add explicit >> braces to avoid dangling else [-Wdangling-else] drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask) ^ include/drm/drm_encoder.h:314:3: note: expanded from macro 'drm_for_each_encoder_mask' for_each_if ((encoder_mask) & drm_encoder_mask(encoder)) ^ include/drm/drm_util.h:63:53: note: expanded from macro 'for_each_if' #define for_each_if(condition) if (!(condition)) {} else ^ 1 warning generated. vim +1064 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 25fdd5933e4c0f Jeykumar Sankaran 2018-06-27 1032 25fdd5933e4c0f Jeykumar Sankaran 2018-06-27 1033 static void dpu_crtc_enable(struct drm_crtc *crtc, 351f950db4ab28 Maxime Ripard 2020-10-08 1034 struct drm_atomic_state *state) 25fdd5933e4c0f Jeykumar Sankaran 2018-06-27 1035 { e12e5263bf1d8d Rob Clark 2020-09-07 1036 struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc); 25fdd5933e4c0f Jeykumar Sankaran 2018-06-27 1037 struct drm_encoder *encoder; 35c719da95c0d2 Rob Clark 2020-08-11 1038 bool request_bandwidth = false; 2c3c31343481a4 Vinod Polimera2022-06-21 1039 struct drm_crtc_state *old_crtc_state; 25fdd5933e4c0f Jeykumar Sankaran 2018-06-27 1040 2c3c31343481a4 Vinod Polimera2022-06-21 1041 old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc); b77d0f0d4ee757 Sean Paul 2018-11-16 1042 pm_runtime_get_sync(crtc->dev->dev); b77d0f0d4ee757 Sean Paul 2018-11-16 1043 25fdd5933e4c0f Jeykumar Sankaran 2018-06-27 1044 DRM_DEBUG_KMS("crtc%d\n", crtc->base.id); 25fdd5933e4c0f Jeykumar Sankaran 2018-06-27 1045 241b507c166fef Rob Clark 2019-08-20 1046 drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask) { 241b507c166fef Rob Clark 2019-08-20 1047 /* in video mode, we hold an extra bandwidth reference 241b507c166fef Rob Clark 2019-08-20 1048* as we cannot drop bandwidth at frame-done if any 241b507c166fef Rob Clark 2019-08-20 1049* crtc is being used in video mode. 241b507c166fef Rob Clark 2019-08-20 1050*/ 241b507c166fef Rob Clark 2019-08-20 1051 if (dpu_encoder_get_intf_mode(encoder) == INTF_MODE_VIDEO) 241b507c166fef Rob Clark 2019-08-20 1052 request_bandwidth = true; 25fdd5933e4c0f Jeykumar Sankaran 2018-06-27 1053 dpu_encoder_register_frame_event_callback(encoder, 25fdd5933e4c0f Jeykumar Sankaran 2018-06-27 1054 dpu_crtc_frame_event_cb, (void *)crtc); 241b507c166fef Rob Clark 2019-08-20 1055 } 241b507c166fef Rob Clark 2019-08-20 1056 241b507c166fef Rob Clark 2019-08-20 1057 if (r
Re: [PATCH] drm/i915/guc/slpc: Use non-blocking H2G for waitboost
On Wed, 22 Jun 2022 13:30:23 -0700, Belgaumkar, Vinay wrote: > On 6/21/2022 5:26 PM, Dixit, Ashutosh wrote: > > On Sat, 14 May 2022 23:05:06 -0700, Vinay Belgaumkar wrote: > > The issue I have is what happens when we de-boost (restore min freq to its > > previous value in intel_guc_slpc_dec_waiters()). It would seem that that > > call is fairly important to get the min freq down when there are no pending > > requests. Therefore what do we do in that case? > > > > This is the function: > > > > void intel_guc_slpc_dec_waiters(struct intel_guc_slpc *slpc) > > { > > mutex_lock(>lock); > > if (atomic_dec_and_test(>num_waiters)) > > slpc_force_min_freq(slpc, slpc->min_freq_softlimit); > > mutex_unlock(>lock); > > } > > > > > > 1. First it would seem that at the minimum we need a similar drm_notice() > > in intel_guc_slpc_dec_waiters(). That would mean we need to put the > > drm_notice() back in slpc_force_min_freq() (replacing > > i915_probe_error()) rather than in slpc_boost_work() above? > Sure. > > > > 2. Further, if de-boosting is important then maybe as was being discussed > > in v1 of this patch (see the bottom of > > https://patchwork.freedesktop.org/patch/485004/?series=103598=1) do > > we need to use intel_guc_send_busy_loop() in the > > intel_guc_slpc_dec_waiters() code path? > > Using a busy_loop here would essentially be the same as blocking, right? Well blocking waits for a response from GuC (so all previous requests need to be processed by GuC) whereas busy_loop() just waits for space to be available at the back of the queue (so just a few, or maybe just one, request have to be processed by GuC). > And it could still fail/timeout with blocking as well (which is the problem > we are trying to solve here). intel_guc_send_busy_loop() has an infinite wait without a drm_err()!! :) > De-boosting is important, but in the worst case scenario, lets say this > request was not processed by GuC. This would happen only if the system > were really busy, which would mean there is a high likelihood we would > boost/de-boost again anyways and it would probably go through at that > point. Not sure of this. The system was busy but now might have gone idle which is why we are trying to de-boost. But GuC queue might still be full so we may drop the de-boost request. Or if the system has gone really idle there will be space in the GuC queue. Also the problem with intel_guc_send_busy_loop() is that it just has a sleep in it, so others might be adding requests in the GuC queue while busy_loop() was sleeping (to avoid such situations we'd need a SW queue in front of the real GuC queue). So I am ok if we don't want to add intel_guc_send_busy_loop() for now and "wait and watch". Unless John suggests otherwise since I don't have any idea how likely is this to happen. If we change drm_notice to drm_err the CI will quick tell us if this happening. Anyway, so at least let's move drm_notice (or drm_err) into slpc_force_min_freq() and I can ok the patch. Thanks. > > At least we need to do 1. But for 2. we might as well just put > > intel_guc_send_busy_loop() in guc_action_slpc_set_param_nb()? In both cases > > (boost and de-boost) intel_guc_send_busy_loop() would be called from a work > > item so looks doable (the way we were previously doing the blocking call > > from the two places). Thoughts? > > > > Thanks. > > -- > > Ashutosh
[drm-misc:drm-misc-next 2/4] drivers/gpu/drm/hyperv/hyperv_drm_modeset.c:25:48: error: invalid use of undefined type 'struct drm_framebuffer'
tree: git://anongit.freedesktop.org/drm/drm-misc drm-misc-next head: 009a3a52791f31c57d755a73f6bc66fbdd8bd76c commit: 720cf96d8fecde29b72e1101f8a567a0ce99594f [2/4] drm: Drop drm_framebuffer.h from drm_crtc.h config: x86_64-allyesconfig (https://download.01.org/0day-ci/archive/20220623/202206230540.nploqsbg-...@intel.com/config) compiler: gcc-11 (Debian 11.3.0-3) 11.3.0 reproduce (this is a W=1 build): git remote add drm-misc git://anongit.freedesktop.org/drm/drm-misc git fetch --no-tags drm-misc drm-misc-next git checkout 720cf96d8fecde29b72e1101f8a567a0ce99594f # save the config file mkdir build_dir && cp config build_dir/.config make W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash If you fix the issue, kindly add following tag where applicable Reported-by: kernel test robot Note: the drm-misc/drm-misc-next HEAD 009a3a52791f31c57d755a73f6bc66fbdd8bd76c builds fine. It only hurts bisectability. All errors (new ones prefixed by >>): In file included from include/linux/list.h:5, from include/linux/preempt.h:11, from include/linux/spinlock.h:55, from include/linux/mmzone.h:8, from include/linux/gfp.h:6, from include/linux/mm.h:7, from include/linux/hyperv.h:17, from drivers/gpu/drm/hyperv/hyperv_drm_modeset.c:6: drivers/gpu/drm/hyperv/hyperv_drm_modeset.c: In function 'hyperv_blit_to_vram_rect': >> drivers/gpu/drm/hyperv/hyperv_drm_modeset.c:25:48: error: invalid use of >> undefined type 'struct drm_framebuffer' 25 | struct hyperv_drm_device *hv = to_hv(fb->dev); |^~ include/linux/container_of.h:18:33: note: in definition of macro 'container_of' 18 | void *__mptr = (void *)(ptr); \ | ^~~ drivers/gpu/drm/hyperv/hyperv_drm_modeset.c:25:40: note: in expansion of macro 'to_hv' 25 | struct hyperv_drm_device *hv = to_hv(fb->dev); |^ In file included from include/linux/bits.h:22, from include/linux/ratelimit_types.h:5, from include/linux/printk.h:9, from include/asm-generic/bug.h:22, from arch/x86/include/asm/bug.h:87, from include/linux/bug.h:5, from include/linux/mmdebug.h:5, from include/linux/mm.h:6, from include/linux/hyperv.h:17, from drivers/gpu/drm/hyperv/hyperv_drm_modeset.c:6: >> drivers/gpu/drm/hyperv/hyperv_drm_modeset.c:25:48: error: invalid use of >> undefined type 'struct drm_framebuffer' 25 | struct hyperv_drm_device *hv = to_hv(fb->dev); |^~ include/linux/build_bug.h:78:56: note: in definition of macro '__static_assert' 78 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg) |^~~~ include/linux/container_of.h:19:9: note: in expansion of macro 'static_assert' 19 | static_assert(__same_type(*(ptr), ((type *)0)->member) || \ | ^ include/linux/container_of.h:19:23: note: in expansion of macro '__same_type' 19 | static_assert(__same_type(*(ptr), ((type *)0)->member) || \ | ^~~ drivers/gpu/drm/hyperv/hyperv_drm.h:40:21: note: in expansion of macro 'container_of' 40 | #define to_hv(_dev) container_of(_dev, struct hyperv_drm_device, dev) | ^~~~ drivers/gpu/drm/hyperv/hyperv_drm_modeset.c:25:40: note: in expansion of macro 'to_hv' 25 | struct hyperv_drm_device *hv = to_hv(fb->dev); |^ >> drivers/gpu/drm/hyperv/hyperv_drm_modeset.c:25:48: error: invalid use of >> undefined type 'struct drm_framebuffer' 25 | struct hyperv_drm_device *hv = to_hv(fb->dev); |^~ include/linux/build_bug.h:78:56: note: in definition of macro '__static_assert' 78 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg) |^~~~ include/linux/container_of.h:19:9: note: in expansion of macro 'static_assert' 19 | static_assert(__same_type(*(ptr), ((type *)0)->member) || \ | ^ include/linux/container_of.h:20:23: note: in expansion of macro '__same_type' 20 | __same_type(*(ptr), void), \ | ^~~
[Bug 216119] 087451f372bf76d breaks hibernation on amdgpu Radeon R9 390
https://bugzilla.kernel.org/show_bug.cgi?id=216119 --- Comment #19 from Harald Judt (h.j...@gmx.at) --- Yes, I definitely removed the patch from comment 11 before testing the new patch set. I will try the other combinations later this week, I am a bit short on time at the moment. -- You may reply to this email to add a comment. You are receiving this mail because: You are watching the assignee of the bug.
Re: [PATCH V2 1/2] dt-bindings: display: xlnx: Add DSI 2.0 Tx subsystem documentation
Hi GVRao, Thank you for the patch. On Thu, Jun 16, 2022 at 07:47:35PM +0530, Venkateshwar Rao Gannavarapu wrote: > This patch adds dt binding for Xilinx DSI-TX subsystem. > > The Xilinx MIPI DSI (Display serial interface) Transmitter Subsystem > implements the Mobile Industry Processor Interface (MIPI) based display > interface. It supports the interface with the programmable logic (FPGA). > > Signed-off-by: Venkateshwar Rao Gannavarapu > > --- > .../bindings/display/xlnx/xlnx,dsi-tx.yaml | 101 > + > 1 file changed, 101 insertions(+) > create mode 100644 > Documentation/devicetree/bindings/display/xlnx/xlnx,dsi-tx.yaml > > diff --git a/Documentation/devicetree/bindings/display/xlnx/xlnx,dsi-tx.yaml > b/Documentation/devicetree/bindings/display/xlnx/xlnx,dsi-tx.yaml > new file mode 100644 > index 000..644934d > --- /dev/null > +++ b/Documentation/devicetree/bindings/display/xlnx/xlnx,dsi-tx.yaml > @@ -0,0 +1,101 @@ > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/display/xlnx/xlnx,dsi-tx.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: Xilinx DSI Transmitter subsystem Device Tree Bindings > + > +maintainers: > + - Venkateshwar Rao Gannavarapu > + > +description: | > + The Xilinx DSI Transmitter Subsystem implements the Mobile Industry > + Processor Interface based display interface. It supports the interface > + with the programmable logic (FPGA). > + > + For more details refer to PG238 Xilinx MIPI DSI-V2.0 Tx Subsystem. > + > +properties: > + compatible: > +const: xlnx,dsi-tx-v2.0 > + > + reg: > +maxItems: 1 > + > + clocks: > +items: > + - description: AXI Lite CPU clock > + - description: D-PHY clock > + > + clock-names: > +items: > + - const: s_axis_aclk > + - const: dphy_clk_200M > + > + ports: > +$ref: /schemas/graph.yaml#/properties/ports > + > +properties: > + port@0: > +$ref: /schemas/graph.yaml#/properties/port > +description: > + This port should be the input endpoint. Port and endpoint are two different things. You can just write "Input port of the DSI encoder". > + > + port@1: > +$ref: /schemas/graph.yaml#/properties/port > +description: > + This port should be the output endpoint. And here, "Output port of the DSI encoder". > + > +required: > + - "#address-cells" > + - "#size-cells" I think those should be listed in the properties above, with fixed values. > + - compatible > + - reg > + - clocks > + - clock-names > + - ports > + > +additionalProperties: false > + > +examples: > + - | > +dsi0: dsi_tx@8002 { > +compatible = "xlnx,dsi-tx-v2.0"; > +reg = <0x8002 0x2>; > +clocks = <_clk_0>, <_clk_1>; > +clock-names = "s_axis_aclk", "dphy_clk_200M"; > +#address-cells = <1>; > +#size-cells = <0>; > + > +ports { > + #address-cells = <1>; > + #size-cells = <0>; > + > + port@0 { > +reg = <0>; > +mipi_dsi_in: endpoint { > +remote-endpoint = <_disp>; > +}; > + }; > + > + port@1 { > +reg = <1>; > +mipi_dsi_out: endpoint { > +remote-endpoint = <_in>; > +}; > + }; > +}; > + > +panel@0 { > + compatible = "auo,b101uan01"; > + reg = <0>; > + port { > +panel_in: endpoint { > +remote-endpoint = <_dsi_out>; > +}; > + }; > +}; Does this example validate (with `make dt_binding_check DT_SCHEMA_FILES=Documentation/devicetree/bindings/display/xlnx/xlnx,dsi-tx.yaml`) without listing the panel node in the properties ? > +}; > + > +... -- Regards, Laurent Pinchart
Re: [PATCH v15 1/3] phy: qcom-edp: add regulator_set_load to edp phy
Quoting Kuogee Hsieh (2022-06-21 10:01:29) > This patch add regulator_set_load() before enable regulator at > eDP phy driver. > > Signed-off-by: Kuogee Hsieh > Reviewed-by: Douglas Anderson > Reviewed-by: Dmitry Baryshkov > --- Reviewed-by: Stephen Boyd
Re: [Intel-gfx] [PATCH] drm/i915/guc/slpc: Add a new SLPC selftest
On Fri, 10 Jun 2022 16:47:12 -0700, Vinay Belgaumkar wrote: > > This test will validate we can achieve actual frequency of RP0. Pcode > grants frequencies based on what GuC is requesting. However, thermal > throttling can limit what is being granted. Add a test to request for > max, but don't fail the test if RP0 is not granted due to throttle > reasons. > > Also optimize the selftest by using a common run_test function to avoid > code duplication. The refactoring does change the order of operations (changing the freq vs spawning the spinner) but should be fine I think. > Rename the "clamp" tests to vary_max_freq and vary_min_freq. Either is ok, but maybe "clamp" names were ok I think since they verify req freq is clamped at min/max. > > v2: Fix compile warning > > Fixes 8ee2c227822e ("drm/i915/guc/slpc: Add SLPC selftest") > Signed-off-by: Vinay Belgaumkar > --- > drivers/gpu/drm/i915/gt/selftest_slpc.c | 323 > 1 file changed, 158 insertions(+), 165 deletions(-) > > diff --git a/drivers/gpu/drm/i915/gt/selftest_slpc.c > b/drivers/gpu/drm/i915/gt/selftest_slpc.c > index b768cea5943d..099129aae9a5 100644 > --- a/drivers/gpu/drm/i915/gt/selftest_slpc.c > +++ b/drivers/gpu/drm/i915/gt/selftest_slpc.c > @@ -8,6 +8,11 @@ > #define delay_for_h2g() usleep_range(H2G_DELAY, H2G_DELAY + 1) > #define FREQUENCY_REQ_UNIT DIV_ROUND_CLOSEST(GT_FREQUENCY_MULTIPLIER, \ > GEN9_FREQ_SCALER) > +enum test_type { > + VARY_MIN, > + VARY_MAX, > + MAX_GRANTED > +}; > > static int slpc_set_min_freq(struct intel_guc_slpc *slpc, u32 freq) > { > @@ -36,147 +41,120 @@ static int slpc_set_max_freq(struct intel_guc_slpc > *slpc, u32 freq) > return ret; > } > > -static int live_slpc_clamp_min(void *arg) > +static int vary_max_freq(struct intel_guc_slpc *slpc, struct intel_rps *rps, > + u32 *max_act_freq) Please run checkpatch, indentation seems off. > { > - struct drm_i915_private *i915 = arg; > - struct intel_gt *gt = to_gt(i915); > - struct intel_guc_slpc *slpc = >uc.guc.slpc; > - struct intel_rps *rps = >rps; > - struct intel_engine_cs *engine; > - enum intel_engine_id id; > - struct igt_spinner spin; > + u32 step, max_freq, req_freq; > + u32 act_freq; > u32 slpc_min_freq, slpc_max_freq; > int err = 0; > > - if (!intel_uc_uses_guc_slpc(>uc)) > - return 0; > - > - if (igt_spinner_init(, gt)) > - return -ENOMEM; > + slpc_min_freq = slpc->min_freq; > + slpc_max_freq = slpc->rp0_freq; nit but we don't really need such variables since we don't change their values, we should just use slpc->min_freq, slpc->rp0_freq directly. I'd change this in all places in this patch. > > - if (intel_guc_slpc_get_max_freq(slpc, _max_freq)) { > - pr_err("Could not get SLPC max freq\n"); > - return -EIO; > - } > - > - if (intel_guc_slpc_get_min_freq(slpc, _min_freq)) { > - pr_err("Could not get SLPC min freq\n"); > - return -EIO; Why do we need these two function calls? Can't we just use slpc->rp0_freq and slpc->min_freq as we are doing in the vary_min/max_freq() functions above? Also, as mentioned below I think here we should just do: slpc_set_max_freq(slpc, slpc->rp0_freq); slpc_set_min_freq(slpc, slpc->min_freq); to restore freq to a known state before starting the test (just in case a previous test changed the values). > - } > - > - if (slpc_min_freq == slpc_max_freq) { > - pr_err("Min/Max are fused to the same value\n"); > - return -EINVAL; What if they are actually equal? I think basically the max/min freq test loops will just not be entered (so effectively the tests will just skip). The granted freq test will be fine. So I think we can just delete this if statement? (It is showing deleted above in the patch but is in the new code somewhere too). > - } > - > - intel_gt_pm_wait_for_idle(gt); > - intel_gt_pm_get(gt); > - for_each_engine(engine, gt, id) { > - struct i915_request *rq; > - u32 step, min_freq, req_freq; > - u32 act_freq, max_act_freq; > - > - if (!intel_engine_can_store_dword(engine)) > - continue; > + /* Go from max to min in 5 steps */ > + step = (slpc_max_freq - slpc_min_freq) / NUM_STEPS; > + *max_act_freq = slpc_min_freq; > + for (max_freq = slpc_max_freq; max_freq > slpc_min_freq; > + max_freq -= step) { > + err = slpc_set_max_freq(slpc, max_freq); > + if (err) > + break; > > - /* Go from min to max in 5 steps */ > - step = (slpc_max_freq - slpc_min_freq) / NUM_STEPS; > - max_act_freq = slpc_min_freq; > - for (min_freq = slpc_min_freq; min_freq < slpc_max_freq; > -
Re: [PATCH] drm/i915/guc/slpc: Use non-blocking H2G for waitboost
On 6/21/2022 5:26 PM, Dixit, Ashutosh wrote: On Sat, 14 May 2022 23:05:06 -0700, Vinay Belgaumkar wrote: SLPC min/max frequency updates require H2G calls. We are seeing timeouts when GuC channel is backed up and it is unable to respond in a timely fashion causing warnings and affecting CI. This is seen when waitboosting happens during a stress test. this patch updates the waitboost path to use a non-blocking H2G call instead, which returns as soon as the message is successfully transmitted. Overall I am ok moving waitboost to use the non-blocking H2G. We can consider increasing the timeout in wait_for_ct_request_update() to be a separate issue for blocking cases and we can handle that separately. Still there a couple of issues with this patch mentioned below. v2: Use drm_notice to report any errors that might occur while sending the waitboost H2G request (Tvrtko) Signed-off-by: Vinay Belgaumkar --- drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c | 44 + 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c index 1db833da42df..e5e869c96262 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c @@ -98,6 +98,30 @@ static u32 slpc_get_state(struct intel_guc_slpc *slpc) return data->header.global_state; } +static int guc_action_slpc_set_param_nb(struct intel_guc *guc, u8 id, u32 value) +{ + u32 request[] = { + GUC_ACTION_HOST2GUC_PC_SLPC_REQUEST, + SLPC_EVENT(SLPC_EVENT_PARAMETER_SET, 2), + id, + value, + }; + int ret; + + ret = intel_guc_send_nb(guc, request, ARRAY_SIZE(request), 0); + + return ret > 0 ? -EPROTO : ret; +} + +static int slpc_set_param_nb(struct intel_guc_slpc *slpc, u8 id, u32 value) +{ + struct intel_guc *guc = slpc_to_guc(slpc); + + GEM_BUG_ON(id >= SLPC_MAX_PARAM); + + return guc_action_slpc_set_param_nb(guc, id, value); +} + static int guc_action_slpc_set_param(struct intel_guc *guc, u8 id, u32 value) { u32 request[] = { @@ -208,12 +232,10 @@ static int slpc_force_min_freq(struct intel_guc_slpc *slpc, u32 freq) */ with_intel_runtime_pm(>runtime_pm, wakeref) { - ret = slpc_set_param(slpc, -SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ, -freq); - if (ret) - i915_probe_error(i915, "Unable to force min freq to %u: %d", -freq, ret); + /* Non-blocking request will avoid stalls */ + ret = slpc_set_param_nb(slpc, + SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ, + freq); } return ret; @@ -222,6 +244,8 @@ static int slpc_force_min_freq(struct intel_guc_slpc *slpc, u32 freq) static void slpc_boost_work(struct work_struct *work) { struct intel_guc_slpc *slpc = container_of(work, typeof(*slpc), boost_work); + struct drm_i915_private *i915 = slpc_to_i915(slpc); + int err; /* * Raise min freq to boost. It's possible that @@ -231,8 +255,12 @@ static void slpc_boost_work(struct work_struct *work) */ mutex_lock(>lock); if (atomic_read(>num_waiters)) { - slpc_force_min_freq(slpc, slpc->boost_freq); - slpc->num_boosts++; + err = slpc_force_min_freq(slpc, slpc->boost_freq); + if (!err) + slpc->num_boosts++; + else + drm_notice(>drm, "Failed to send waitboost request (%d)\n", + err); The issue I have is what happens when we de-boost (restore min freq to its previous value in intel_guc_slpc_dec_waiters()). It would seem that that call is fairly important to get the min freq down when there are no pending requests. Therefore what do we do in that case? This is the function: void intel_guc_slpc_dec_waiters(struct intel_guc_slpc *slpc) { mutex_lock(>lock); if (atomic_dec_and_test(>num_waiters)) slpc_force_min_freq(slpc, slpc->min_freq_softlimit); mutex_unlock(>lock); } 1. First it would seem that at the minimum we need a similar drm_notice() in intel_guc_slpc_dec_waiters(). That would mean we need to put the drm_notice() back in slpc_force_min_freq() (replacing i915_probe_error()) rather than in slpc_boost_work() above? Sure. 2. Further, if de-boosting is important then maybe as was being discussed in v1 of this patch (see the bottom of https://patchwork.freedesktop.org/patch/485004/?series=103598=1) do we need to use intel_guc_send_busy_loop() in the intel_guc_slpc_dec_waiters() code path? Using a busy_loop here would
Re: [PATCH v2] drm/msm/dp: reset drm_dev to NULL at dp_display_unbind()
On 6/22/2022 1:06 PM, Stephen Boyd wrote: Quoting Kuogee Hsieh (2022-06-22 12:55:31) During msm initialize phase, dp_display_unbind() will be called to undo initializations had been done by dp_display_bind() previously if there is error happen at msm_drm_bind. Under this kind of circumstance, drm_device may not be populated completed which causes system crash at drm_dev_dbg(). This patch reset drm_dev to NULL so that following drm_dev_dbg() will not refer to any internal fields of drm_device to prevent system from crashing. Below are panic stack trace, [ 53.584904] Unable to handle kernel paging request at virtual address 70018001 . [ 53.702212] Hardware name: Qualcomm Technologies, Inc. sc7280 CRD platform (rev5+) (DT) [ 53.710445] pstate: 2049 (nzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 53.717596] pc : string_nocheck+0x1c/0x64 [ 53.721738] lr : string+0x54/0x60 [ 53.725162] sp : ffc013d6b650 [ 53.728590] pmr_save: 00e0 [ 53.731743] x29: ffc013d6b650 x28: 0002 x27: 00ff [ 53.739083] x26: ffc013d6b710 x25: ffd07a066ae0 x24: ffd07a419f97 [ 53.746420] x23: ffd07a419f99 x22: ff81fef360d4 x21: ff81fef364d4 [ 53.753760] x20: ffc013d6b6f8 x19: ffd07a06683c x18: [ 53.761093] x17: 4020386678302f30 x16: 00b0 x15: ffd0797523c8 [ 53.768429] x14: 0004 x13: ff00 x12: ffd07a066b2c [ 53.775780] x11: x10: 013c x9 : [ 53.783117] x8 : ff81fef364d4 x7 : x6 : [ 53.790445] x5 : x4 : 0a00ff04 x3 : 0a00ff04 [ 53.797783] x2 : 70018001 x1 : x0 : ff81fef360d4 [ 53.805136] Call trace: [ 53.807667] string_nocheck+0x1c/0x64 [ 53.811439] string+0x54/0x60 [ 53.814498] vsnprintf+0x374/0x53c [ 53.818009] pointer+0x3dc/0x40c [ 53.821340] vsnprintf+0x398/0x53c [ 53.824854] vscnprintf+0x3c/0x88 [ 53.828274] __trace_array_vprintk+0xcc/0x2d4 [ 53.832768] trace_array_printk+0x8c/0xb4 [ 53.836900] drm_trace_printf+0x74/0x9c [ 53.840875] drm_dev_dbg+0xfc/0x1b8 [ 53.844480] dp_pm_suspend+0x70/0xf8 [ 53.848164] dpm_run_callback+0x60/0x1a0 [ 53.85] __device_suspend+0x304/0x3f4 [ 53.856363] dpm_suspend+0xf8/0x3a8 [ 53.859959] dpm_suspend_start+0x8c/0xc0 Fixes: a65c95ff88f2 ("drm/msm/dp: stop event kernel thread when DP unbind") Commit doesn't exist. I guess it's Fixes: 570d3e5d28db ("drm/msm/dp: stop event kernel thread when DP unbind") it is my bad, i keep using our internal commit id. Will be careful next time.
Re: [PATCH v2] drm/msm/dp: reset drm_dev to NULL at dp_display_unbind()
Quoting Kuogee Hsieh (2022-06-22 12:55:31) > During msm initialize phase, dp_display_unbind() will be called to undo > initializations had been done by dp_display_bind() previously if there is > error happen at msm_drm_bind. Under this kind of circumstance, drm_device > may not be populated completed which causes system crash at drm_dev_dbg(). > This patch reset drm_dev to NULL so that following drm_dev_dbg() will not > refer to any internal fields of drm_device to prevent system from crashing. > Below are panic stack trace, > > [ 53.584904] Unable to handle kernel paging request at virtual address > 70018001 > . > [ 53.702212] Hardware name: Qualcomm Technologies, Inc. sc7280 CRD platform > (rev5+) (DT) > [ 53.710445] pstate: 2049 (nzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) > [ 53.717596] pc : string_nocheck+0x1c/0x64 > [ 53.721738] lr : string+0x54/0x60 > [ 53.725162] sp : ffc013d6b650 > [ 53.728590] pmr_save: 00e0 > [ 53.731743] x29: ffc013d6b650 x28: 0002 x27: > 00ff > [ 53.739083] x26: ffc013d6b710 x25: ffd07a066ae0 x24: > ffd07a419f97 > [ 53.746420] x23: ffd07a419f99 x22: ff81fef360d4 x21: > ff81fef364d4 > [ 53.753760] x20: ffc013d6b6f8 x19: ffd07a06683c x18: > > [ 53.761093] x17: 4020386678302f30 x16: 00b0 x15: > ffd0797523c8 > [ 53.768429] x14: 0004 x13: ff00 x12: > ffd07a066b2c > [ 53.775780] x11: x10: 013c x9 : > > [ 53.783117] x8 : ff81fef364d4 x7 : x6 : > > [ 53.790445] x5 : x4 : 0a00ff04 x3 : > 0a00ff04 > [ 53.797783] x2 : 70018001 x1 : x0 : > ff81fef360d4 > [ 53.805136] Call trace: > [ 53.807667] string_nocheck+0x1c/0x64 > [ 53.811439] string+0x54/0x60 > [ 53.814498] vsnprintf+0x374/0x53c > [ 53.818009] pointer+0x3dc/0x40c > [ 53.821340] vsnprintf+0x398/0x53c > [ 53.824854] vscnprintf+0x3c/0x88 > [ 53.828274] __trace_array_vprintk+0xcc/0x2d4 > [ 53.832768] trace_array_printk+0x8c/0xb4 > [ 53.836900] drm_trace_printf+0x74/0x9c > [ 53.840875] drm_dev_dbg+0xfc/0x1b8 > [ 53.844480] dp_pm_suspend+0x70/0xf8 > [ 53.848164] dpm_run_callback+0x60/0x1a0 > [ 53.85] __device_suspend+0x304/0x3f4 > [ 53.856363] dpm_suspend+0xf8/0x3a8 > [ 53.859959] dpm_suspend_start+0x8c/0xc0 > > Fixes: a65c95ff88f2 ("drm/msm/dp: stop event kernel thread when DP unbind") Commit doesn't exist. I guess it's Fixes: 570d3e5d28db ("drm/msm/dp: stop event kernel thread when DP unbind")
Re: Using generic fbdev helpers breaks hibernation
Thanks Thomas. I think this got me on the right track. Alex On Tue, Jun 21, 2022 at 6:25 AM Thomas Zimmermann wrote: > > Hi > > Am 21.06.22 um 00:02 schrieb Alex Deucher: > > Maybe someone more familiar with the generic drm fbdev helpers can > > help me understand why they don't work with hibernation, at least with > > AMD GPUs. We converted amdgpu to use the generic helpers instead of > > rolling our own in this patch[1], but it seems to have broken > > hibernation[2]. amdgpu has always set mode_config.prefer_shadow = 1, > > but that seems to be the cause of the hibernation breakage with the > > generic helpers. I've been staring at the code for a while now but I > > can't see why this fails. Any pointers? > > I don't the actual reason, but when I tried to convert radeon to generic > fbdev emulation, I had to modify the fbdev code a bit. I don't see how > this would apply to amdgpu, but you can find the patchset attached. See > patches 1 and 2. > > Best regards > Thomas > > > > > Thanks, > > > > Alex > > > > [1] - > > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=087451f372bf76d971184caa258807b7c35aac8f > > [2] - https://bugzilla.kernel.org/show_bug.cgi?id=216119 > > -- > Thomas Zimmermann > Graphics Driver Developer > SUSE Software Solutions Germany GmbH > Maxfeldstr. 5, 90409 Nürnberg, Germany > (HRB 36809, AG Nürnberg) > Geschäftsführer: Ivo Totev
[PATCH v2] drm/msm/dp: reset drm_dev to NULL at dp_display_unbind()
During msm initialize phase, dp_display_unbind() will be called to undo initializations had been done by dp_display_bind() previously if there is error happen at msm_drm_bind. Under this kind of circumstance, drm_device may not be populated completed which causes system crash at drm_dev_dbg(). This patch reset drm_dev to NULL so that following drm_dev_dbg() will not refer to any internal fields of drm_device to prevent system from crashing. Below are panic stack trace, [ 53.584904] Unable to handle kernel paging request at virtual address 70018001 . [ 53.702212] Hardware name: Qualcomm Technologies, Inc. sc7280 CRD platform (rev5+) (DT) [ 53.710445] pstate: 2049 (nzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 53.717596] pc : string_nocheck+0x1c/0x64 [ 53.721738] lr : string+0x54/0x60 [ 53.725162] sp : ffc013d6b650 [ 53.728590] pmr_save: 00e0 [ 53.731743] x29: ffc013d6b650 x28: 0002 x27: 00ff [ 53.739083] x26: ffc013d6b710 x25: ffd07a066ae0 x24: ffd07a419f97 [ 53.746420] x23: ffd07a419f99 x22: ff81fef360d4 x21: ff81fef364d4 [ 53.753760] x20: ffc013d6b6f8 x19: ffd07a06683c x18: [ 53.761093] x17: 4020386678302f30 x16: 00b0 x15: ffd0797523c8 [ 53.768429] x14: 0004 x13: ff00 x12: ffd07a066b2c [ 53.775780] x11: x10: 013c x9 : [ 53.783117] x8 : ff81fef364d4 x7 : x6 : [ 53.790445] x5 : x4 : 0a00ff04 x3 : 0a00ff04 [ 53.797783] x2 : 70018001 x1 : x0 : ff81fef360d4 [ 53.805136] Call trace: [ 53.807667] string_nocheck+0x1c/0x64 [ 53.811439] string+0x54/0x60 [ 53.814498] vsnprintf+0x374/0x53c [ 53.818009] pointer+0x3dc/0x40c [ 53.821340] vsnprintf+0x398/0x53c [ 53.824854] vscnprintf+0x3c/0x88 [ 53.828274] __trace_array_vprintk+0xcc/0x2d4 [ 53.832768] trace_array_printk+0x8c/0xb4 [ 53.836900] drm_trace_printf+0x74/0x9c [ 53.840875] drm_dev_dbg+0xfc/0x1b8 [ 53.844480] dp_pm_suspend+0x70/0xf8 [ 53.848164] dpm_run_callback+0x60/0x1a0 [ 53.85] __device_suspend+0x304/0x3f4 [ 53.856363] dpm_suspend+0xf8/0x3a8 [ 53.859959] dpm_suspend_start+0x8c/0xc0 Fixes: a65c95ff88f2 ("drm/msm/dp: stop event kernel thread when DP unbind") Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov Reviewed-by: Stephen Boyd --- drivers/gpu/drm/msm/dp/dp_display.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 2b72639..02fff70 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -316,6 +316,8 @@ static void dp_display_unbind(struct device *dev, struct device *master, dp_power_client_deinit(dp->power); dp_aux_unregister(dp->aux); + dp->drm_dev = NULL; + dp->aux->drm_dev = NULL; priv->dp[dp->id] = NULL; } -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[PULL] drm-intel-next
Hi Dave and Daniel, Here goes the first pull request targeting 5.20. Kudos to Jani and Ville for a good driver clean-up. And many other fixes and improvements from the team. drm-intel-next-2022-06-22: - General driver clean-up (Jani, Ville, Julia) - DG2 enabling (Anusha, Vandita) - Fix sparse warnings (Imre, Jani) - DMC MMIO range checks (Anusha) - Audio related fixes (Jani) - Runtime PM fixes (Anshuman) - PSR fixes (Jouni, Jose) - Media freq factor and per-gt enhancements (Ashutosh, Dale) - DSI fixes for ICL+ (Jani) - Disable DMC flip queue handlers (Imre) - ADL_P voltage swing updates (Balasubramani) - Use more the VBT for panel information (Ville, Animesh) - Fix on Type-C ports with TBT mode (Vivek) - Improve fastset and allow seamless M/N changes (Ville) - Accept more fixed modes with VRR/DMRRS panels (Ville) - FBC fix (Jose) - Remove noise logs (Luca) - Disable connector polling for a headless SKU (Jouni) - Sanitize display underrun reporting (Ville) - ADL-S display PLL w/a (Ville) Thanks, Rodrigo. The following changes since commit 949665a6e237a6fd49ff207e3876d71b20b7e9f2: drm/i915: Respect VBT seamless DRRS min refresh rate (2022-05-05 18:27:53 +0300) are available in the Git repository at: git://anongit.freedesktop.org/drm/drm-intel tags/drm-intel-next-2022-06-22 for you to fetch changes up to 6434cf630086eea2d091f122f5802582a05d9d1c: drm/i915/bios: calculate panel type as per child device index in VBT (2022-06-20 19:56:06 +0300) - General driver clean-up (Jani, Ville, Julia) - DG2 enabling (Anusha, Vandita) - Fix sparse warnings (Imre, Jani) - DMC MMIO range checks (Anusha) - Audio related fixes (Jani) - Runtime PM fixes (Anshuman) - PSR fixes (Jouni, Jose) - Media freq factor and per-gt enhancements (Ashutosh, Dale) - DSI fixes for ICL+ (Jani) - Disable DMC flip queue handlers (Imre) - ADL_P voltage swing updates (Balasubramani) - Use more the VBT for panel information (Ville, Animesh) - Fix on Type-C ports with TBT mode (Vivek) - Improve fastset and allow seamless M/N changes (Ville) - Accept more fixed modes with VRR/DMRRS panels (Ville) - FBC fix (Jose) - Remove noise logs (Luca) - Disable connector polling for a headless SKU (Jouni) - Sanitize display underrun reporting (Ville) - ADL-S display PLL w/a (Ville) Animesh Manna (1): drm/i915/bios: calculate panel type as per child device index in VBT Anshuman Gupta (1): drm/i915: Use drm_dbg for rpm logging Anusha Srivatsa (2): drm/i915/dmc: Load DMC on DG2 drm/i915/dmc: Add MMIO range restrictions Ashutosh Dixit (2): drm/i915: Introduce has_media_ratio_mode drm/i915/pcode: Extend pcode functions for multiple gt's Balasubramani Vivekanandan (2): drm/i915/display/adl_p: Updates to HDMI combo PHY voltage swing table drm/i915/display/adlp: More updates to voltage swing table Dale B Stimson (1): drm/i915/pcode: Add a couple of pcode helpers Imre Deak (2): drm/i915: Fix 'mixing different enum types' warnings in intel_display_power.c drm/i915/d12+: Disable DMC firmware flip queue handlers Jani Nikula (26): drm/i915: remove unused GEM_DEBUG_DECL() and GEM_DEBUG_BUG_ON() drm/i915: remove single-use GEM_DEBUG_EXEC() drm/i915/audio: fix audio code enable/disable pipe logging drm/i915/reg: fix undefined behavior due to shift overflowing the constant drm/i915/dsi: fix VBT send packet port selection for ICL+ drm/i915/display: stop using BUG() drm/i915/regs: split out intel audio register definitions drm/i915/tasklet: separate local hacks around struct tasklet_struct drm/i915/drv: drop intel_bios.h include drm/i915/utils: throw out unused stuff drm/i915/pxp: fix sparse warning for not declared symbol drm/i915/overlay: remove redundant GEM_BUG_ON() drm/i915/bios: use dvi and hdmi support helpers drm/i915/bios: no need to pass i915 to parse_ddi_port() drm/i915/bios: split ddi port parsing and debug printing drm/i915/wm: move wm state verification to intel_pm.c drm/i915/dpll: move shared dpll state verification to intel_dpll_mgr.c drm/i915/mpllb: use I915_STATE_WARN() for state mismatch warnings drm/i915/mpllb: move mpllb state check to intel_snps_phy.c drm/i915/display: split out modeset verification code drm/i915/display: split out crtc state dump to a separate file drm/i915/display: change who adds [] around crtc state dump context string drm/i915/display: rename dev_priv -> i915 in crtc state dump drm/i915/display: some struct drm_i915_private *i915 conversions drm/i915/display: split out hw state readout and sanitize drm/i915/display: convert modeset setup to struct drm_i915_private *i915 Jason A. Donenfeld (1): drm/i915/display: Re-add check for low voltage sku for max dp
Re: [PATCH] drm/amd/pm: Fix a typo in comments
Thanks for the patch. This was already fixed last month. Alex On Wed, Jun 22, 2022 at 1:52 AM Zhang Jiaming wrote: > > There is a spelling mistake in comments. > Replace 'paramater' with 'parameter'. > > Signed-off-by: Zhang Jiaming > --- > drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/arcturus_ppsmc.h | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/arcturus_ppsmc.h > b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/arcturus_ppsmc.h > index 45f5d29bc705..15b313baa0ee 100644 > --- a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/arcturus_ppsmc.h > +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/arcturus_ppsmc.h > @@ -120,7 +120,7 @@ > #define PPSMC_MSG_ReadSerialNumTop320x40 > #define PPSMC_MSG_ReadSerialNumBottom32 0x41 > > -/* paramater for MSG_LightSBR > +/* parameter for MSG_LightSBR > * 1 -- Enable light secondary bus reset, only do nbio respond without > further handling, > * leave driver to handle the real reset > * 0 -- Disable LightSBR, default behavior, SMU will pass the reset to PSP > -- > 2.25.1 >
Re: [PATCH] drm/msm/dp: reset drm_dev to NULL at dp_display_unbind()
Quoting Kuogee Hsieh (2022-06-22 09:54:05) > During msm initialize phase, dp_display_unbind() will be called to undo > initializations had been done by dp_display_bind() previously if there is > error happen at msm_drm_bind. Under this kind of circumstance, drm_device > may not be populated completed which causes system crash at drm_dev_dbg(). > This patch reset drm_dev to NULL so that following drm_dev_dbg() will not > refer to any internal fields of drm_device to prevent system from crashing. > Below are panic stack trace, > > [ 53.584904] Unable to handle kernel paging request at virtual address > 70018001 > . > [ 53.702212] Hardware name: Qualcomm Technologies, Inc. sc7280 CRD platform > (rev5+) (DT) > [ 53.710445] pstate: 2049 (nzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) > [ 53.717596] pc : string_nocheck+0x1c/0x64 > [ 53.721738] lr : string+0x54/0x60 > [ 53.725162] sp : ffc013d6b650 > [ 53.728590] pmr_save: 00e0 > [ 53.731743] x29: ffc013d6b650 x28: 0002 x27: > 00ff > [ 53.739083] x26: ffc013d6b710 x25: ffd07a066ae0 x24: > ffd07a419f97 > [ 53.746420] x23: ffd07a419f99 x22: ff81fef360d4 x21: > ff81fef364d4 > [ 53.753760] x20: ffc013d6b6f8 x19: ffd07a06683c x18: > > [ 53.761093] x17: 4020386678302f30 x16: 00b0 x15: > ffd0797523c8 > [ 53.768429] x14: 0004 x13: ff00 x12: > ffd07a066b2c > [ 53.775780] x11: x10: 013c x9 : > > [ 53.783117] x8 : ff81fef364d4 x7 : x6 : > > [ 53.790445] x5 : x4 : 0a00ff04 x3 : > 0a00ff04 > [ 53.797783] x2 : 70018001 x1 : x0 : > ff81fef360d4 > [ 53.805136] Call trace: > [ 53.807667] string_nocheck+0x1c/0x64 > [ 53.811439] string+0x54/0x60 > [ 53.814498] vsnprintf+0x374/0x53c > [ 53.818009] pointer+0x3dc/0x40c > [ 53.821340] vsnprintf+0x398/0x53c > [ 53.824854] vscnprintf+0x3c/0x88 > [ 53.828274] __trace_array_vprintk+0xcc/0x2d4 > [ 53.832768] trace_array_printk+0x8c/0xb4 > [ 53.836900] drm_trace_printf+0x74/0x9c > [ 53.840875] drm_dev_dbg+0xfc/0x1b8 > [ 53.844480] dp_pm_suspend+0x70/0xf8 > [ 53.848164] dpm_run_callback+0x60/0x1a0 > [ 53.85] __device_suspend+0x304/0x3f4 > [ 53.856363] dpm_suspend+0xf8/0x3a8 > [ 53.859959] dpm_suspend_start+0x8c/0xc0 > > Signed-off-by: Kuogee Hsieh > --- Any fixes tag? Reviewed-by: Stephen Boyd
Re: DMA-buf and uncached system memory
Le mardi 16 février 2021 à 10:25 +0100, Daniel Vetter a écrit : > So I think if AMD also guarantees to drop clean cachelines just do the > same thing we do right now for intel integrated + discrete amd, but in > reserve. It's fragile, but it does work. Sorry to disrupt, but if you pass V4L2 vmalloc data to Intel display driver, you also get nice dirt on the screen. If you have a UVC webcam that produces a pixel format compatible with your display, you can reproduce the issue quite easily with: gst-launch-1.0 v4l2src device=/dev/video0 ! kmssink p.s. some frame-rate are less likely to exhibit the issue, make sure you create movement to see it. The only solution I could think of (not implemented) was to detect in the attach() call what the importers can do (with dev->coherent_dma_mask if I recall), and otherwise flush the cache immediately and start flushing the cache from now on signalling it for DQBUF (in vb2 workqueue or dqbuf ioctl, I don't have an idea yet). I bet this idea is inapplicable to were you have fences, we don't have that in v4l2. This idea was hinted by Robert Becket (now in CC), but perhaps I picked it up wrong, explaining it wrong, etc. I'm no expert, just noticed there wasn't really a good plan for that, so one needs to make one up. I'm not aware oh an importer could know how the memory was allocated by the exporter, and worst, how an importer could figure-out that the export is going to produce buffer with hot CPU cache (UVC driver does memcpy from USB chunks of variable size to produce a fixed size image). Nicolas
Re: [PATCH v2 03/68] drm/encoder: Introduce drmm_encoder_init
Hi Maxime, I love your patch! Perhaps something to improve: [auto build test WARNING on next-20220622] [also build test WARNING on v5.19-rc3] [cannot apply to drm-misc/drm-misc-next drm-intel/for-linux-next drm-tip/drm-tip linus/master anholt/for-next v5.19-rc3 v5.19-rc2 v5.19-rc1] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/intel-lab-lkp/linux/commits/Maxime-Ripard/drm-vc4-Fix-hotplug-for-vc4/20220622-223842 base:ac0ba5454ca85162c08dc429fef1999e077ca976 config: riscv-rv32_defconfig (https://download.01.org/0day-ci/archive/20220623/202206230352.n3jm0ucd-...@intel.com/config) compiler: riscv32-linux-gcc (GCC) 11.3.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/intel-lab-lkp/linux/commit/241f292ab7ccd70b2f6259d1155de8d1bfdd5c9c git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Maxime-Ripard/drm-vc4-Fix-hotplug-for-vc4/20220622-223842 git checkout 241f292ab7ccd70b2f6259d1155de8d1bfdd5c9c # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.3.0 make.cross W=1 O=build_dir ARCH=riscv SHELL=/bin/bash drivers/gpu/drm/ If you fix the issue, kindly add following tag where applicable Reported-by: kernel test robot All warnings (new ones prefixed by >>): drivers/gpu/drm/drm_encoder.c: In function 'drmm_encoder_init': >> drivers/gpu/drm/drm_encoder.c:269:9: warning: function 'drmm_encoder_init' >> might be a candidate for 'gnu_printf' format attribute >> [-Wsuggest-attribute=format] 269 | ret = __drm_encoder_init(dev, encoder, funcs, encoder_type, name, ap); | ^~~ vim +269 drivers/gpu/drm/drm_encoder.c 239 240 /** 241 * drmm_encoder_init - Initialize a preallocated encoder 242 * @dev: drm device 243 * @encoder: the encoder to init 244 * @funcs: callbacks for this encoder (optional) 245 * @encoder_type: user visible type of the encoder 246 * @name: printf style format string for the encoder name, or NULL for default name 247 * 248 * Initializes a preallocated encoder. Encoder should be subclassed as 249 * part of driver encoder objects. Cleanup is automatically handled 250 * through registering drm_encoder_cleanup() with drmm_add_action(). The 251 * encoder structure should be allocated with drmm_kzalloc(). 252 * 253 * The @drm_encoder_funcs.destroy hook must be NULL. 254 * 255 * Returns: 256 * Zero on success, error code on failure. 257 */ 258 int drmm_encoder_init(struct drm_device *dev, struct drm_encoder *encoder, 259const struct drm_encoder_funcs *funcs, 260int encoder_type, const char *name, ...) 261 { 262 va_list ap; 263 int ret; 264 265 if (WARN_ON(funcs && funcs->destroy)) 266 return -EINVAL; 267 268 va_start(ap, name); > 269 ret = __drm_encoder_init(dev, encoder, funcs, encoder_type, > name, ap); 270 va_end(ap); 271 if (ret) 272 return ret; 273 274 ret = drmm_add_action_or_reset(dev, drmm_encoder_alloc_release, encoder); 275 if (ret) 276 return ret; 277 278 return 0; 279 } 280 EXPORT_SYMBOL(drmm_encoder_init); 281 -- 0-DAY CI Kernel Test Service https://01.org/lkp
Re: [PATCH] gpu/drm/radeon: Fix typo in comments
Applied. Thanks! On Wed, Jun 22, 2022 at 10:24 AM Jiang Jian wrote: > > Remove the repeated word 'and' from comments > > Signed-off-by: Jiang Jian > --- > drivers/gpu/drm/radeon/r300_reg.h | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/radeon/r300_reg.h > b/drivers/gpu/drm/radeon/r300_reg.h > index 60d5413bafa1..9d341cff63ee 100644 > --- a/drivers/gpu/drm/radeon/r300_reg.h > +++ b/drivers/gpu/drm/radeon/r300_reg.h > @@ -1103,7 +1103,7 @@ > * The destination register index is in FPI1 (color) and FPI3 (alpha) > * together with enable bits. > * There are separate enable bits for writing into temporary registers > - * (DSTC_REG_* /DSTA_REG) and and program output registers (DSTC_OUTPUT_* > + * (DSTC_REG_* /DSTA_REG) and program output registers (DSTC_OUTPUT_* > * /DSTA_OUTPUT). You can write to both at once, or not write at all (the > * same index must be used for both). > * > -- > 2.17.1 >
Re: [Intel-gfx] [PATCH v3 3/3] drm/doc/rfc: VM_BIND uapi definition
On Wed, Jun 22, 2022 at 09:44:47AM -0700, Niranjana Vishwanathapura wrote: On Wed, Jun 22, 2022 at 04:57:17PM +0100, Tvrtko Ursulin wrote: On 22/06/2022 16:12, Niranjana Vishwanathapura wrote: On Wed, Jun 22, 2022 at 09:10:07AM +0100, Tvrtko Ursulin wrote: On 22/06/2022 04:56, Niranjana Vishwanathapura wrote: VM_BIND and related uapi definitions v2: Reduce the scope to simple Mesa use case. v3: Expand VM_UNBIND documentation and add I915_GEM_VM_BIND/UNBIND_FENCE_VALID and I915_GEM_VM_BIND_TLB_FLUSH flags. Signed-off-by: Niranjana Vishwanathapura --- Documentation/gpu/rfc/i915_vm_bind.h | 243 +++ 1 file changed, 243 insertions(+) create mode 100644 Documentation/gpu/rfc/i915_vm_bind.h diff --git a/Documentation/gpu/rfc/i915_vm_bind.h b/Documentation/gpu/rfc/i915_vm_bind.h new file mode 100644 index ..fa23b2d7ec6f --- /dev/null +++ b/Documentation/gpu/rfc/i915_vm_bind.h @@ -0,0 +1,243 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2022 Intel Corporation + */ + +/** + * DOC: I915_PARAM_HAS_VM_BIND + * + * VM_BIND feature availability. + * See typedef drm_i915_getparam_t param. + */ +#define I915_PARAM_HAS_VM_BIND 57 + +/** + * DOC: I915_VM_CREATE_FLAGS_USE_VM_BIND + * + * Flag to opt-in for VM_BIND mode of binding during VM creation. + * See struct drm_i915_gem_vm_control flags. + * + * The older execbuf2 ioctl will not support VM_BIND mode of operation. + * For VM_BIND mode, we have new execbuf3 ioctl which will not accept any + * execlist (See struct drm_i915_gem_execbuffer3 for more details). + * + */ +#define I915_VM_CREATE_FLAGS_USE_VM_BIND (1 << 0) + +/* VM_BIND related ioctls */ +#define DRM_I915_GEM_VM_BIND 0x3d +#define DRM_I915_GEM_VM_UNBIND 0x3e +#define DRM_I915_GEM_EXECBUFFER3 0x3f + +#define DRM_IOCTL_I915_GEM_VM_BIND DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_VM_BIND, struct drm_i915_gem_vm_bind) +#define DRM_IOCTL_I915_GEM_VM_UNBIND DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_VM_UNBIND, struct drm_i915_gem_vm_bind) +#define DRM_IOCTL_I915_GEM_EXECBUFFER3 DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER3, struct drm_i915_gem_execbuffer3) + +/** + * struct drm_i915_gem_vm_bind_fence - Bind/unbind completion notification. + * + * A timeline out fence for vm_bind/unbind completion notification. + */ +struct drm_i915_gem_vm_bind_fence { + /** @handle: User's handle for a drm_syncobj to signal. */ + __u32 handle; + + /** @rsvd: Reserved, MBZ */ + __u32 rsvd; + + /** + * @value: A point in the timeline. + * Value must be 0 for a binary drm_syncobj. A Value of 0 for a + * timeline drm_syncobj is invalid as it turns a drm_syncobj into a + * binary one. + */ + __u64 value; +}; + +/** + * struct drm_i915_gem_vm_bind - VA to object mapping to bind. + * + * This structure is passed to VM_BIND ioctl and specifies the mapping of GPU + * virtual address (VA) range to the section of an object that should be bound + * in the device page table of the specified address space (VM). + * The VA range specified must be unique (ie., not currently bound) and can + * be mapped to whole object or a section of the object (partial binding). + * Multiple VA mappings can be created to the same section of the object + * (aliasing). + * + * The @start, @offset and @length should be 4K page aligned. However the DG2 + * and XEHPSDV has 64K page size for device local-memory and has compact page + * table. On those platforms, for binding device local-memory objects, the + * @start should be 2M aligned, @offset and @length should be 64K aligned. Should some error codes be documented and has the ability to programmatically probe the alignment restrictions been considered? Currently what we have internally is that -EINVAL is returned if the sart, offset and length are not aligned. If the specified mapping already exits, we return -EEXIST. If there are conflicts in the VA range and VA range can't be reserved, then -ENOSPC is returned. I can add this documentation here. But I am worried that there will be more suggestions/feedback about error codes while reviewing the code patch series, and we have to revisit it again. I'd still suggest documenting those three. It makes sense to explain to userspace what behaviour they will see if they get it wrong. Ok. I have posted v4 with the fixes. I have simplified the error code a bit by removing EEXIST which is just a special case of ENOSPC. Niranjana + * Also, on those platforms, it is not allowed to bind an device local-memory + * object and a system memory object in a single 2M section of VA range. Text should be clear whether "not allowed" means there will be an error returned, or it will appear to work but bad things will happen. Yah, error returned, will fix. + */ +struct drm_i915_gem_vm_bind { + /** @vm_id: VM (address space) id to bind */ + __u32 vm_id; + + /**
[PATCH v3 3/3] drm/doc/rfc: VM_BIND uapi definition
VM_BIND and related uapi definitions v2: Reduce the scope to simple Mesa use case. v3: Expand VM_UNBIND documentation and add I915_GEM_VM_BIND/UNBIND_FENCE_VALID and I915_GEM_VM_BIND_TLB_FLUSH flags. v4: Remove I915_GEM_VM_BIND_TLB_FLUSH flag and add additional documentation for vm_bind/unbind. Signed-off-by: Niranjana Vishwanathapura --- Documentation/gpu/rfc/i915_vm_bind.h | 252 +++ 1 file changed, 252 insertions(+) create mode 100644 Documentation/gpu/rfc/i915_vm_bind.h diff --git a/Documentation/gpu/rfc/i915_vm_bind.h b/Documentation/gpu/rfc/i915_vm_bind.h new file mode 100644 index ..7248791a4513 --- /dev/null +++ b/Documentation/gpu/rfc/i915_vm_bind.h @@ -0,0 +1,252 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2022 Intel Corporation + */ + +/** + * DOC: I915_PARAM_HAS_VM_BIND + * + * VM_BIND feature availability. + * See typedef drm_i915_getparam_t param. + */ +#define I915_PARAM_HAS_VM_BIND 57 + +/** + * DOC: I915_VM_CREATE_FLAGS_USE_VM_BIND + * + * Flag to opt-in for VM_BIND mode of binding during VM creation. + * See struct drm_i915_gem_vm_control flags. + * + * The older execbuf2 ioctl will not support VM_BIND mode of operation. + * For VM_BIND mode, we have new execbuf3 ioctl which will not accept any + * execlist (See struct drm_i915_gem_execbuffer3 for more details). + * + */ +#define I915_VM_CREATE_FLAGS_USE_VM_BIND (1 << 0) + +/* VM_BIND related ioctls */ +#define DRM_I915_GEM_VM_BIND 0x3d +#define DRM_I915_GEM_VM_UNBIND 0x3e +#define DRM_I915_GEM_EXECBUFFER3 0x3f + +#define DRM_IOCTL_I915_GEM_VM_BIND DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_VM_BIND, struct drm_i915_gem_vm_bind) +#define DRM_IOCTL_I915_GEM_VM_UNBIND DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_VM_UNBIND, struct drm_i915_gem_vm_bind) +#define DRM_IOCTL_I915_GEM_EXECBUFFER3 DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER3, struct drm_i915_gem_execbuffer3) + +/** + * struct drm_i915_gem_vm_bind_fence - Bind/unbind completion notification. + * + * A timeline out fence for vm_bind/unbind completion notification. + */ +struct drm_i915_gem_vm_bind_fence { + /** @handle: User's handle for a drm_syncobj to signal. */ + __u32 handle; + + /** @rsvd: Reserved, MBZ */ + __u32 rsvd; + + /** +* @value: A point in the timeline. +* Value must be 0 for a binary drm_syncobj. A Value of 0 for a +* timeline drm_syncobj is invalid as it turns a drm_syncobj into a +* binary one. +*/ + __u64 value; +}; + +/** + * struct drm_i915_gem_vm_bind - VA to object mapping to bind. + * + * This structure is passed to VM_BIND ioctl and specifies the mapping of GPU + * virtual address (VA) range to the section of an object that should be bound + * in the device page table of the specified address space (VM). + * The VA range specified must be unique (ie., not currently bound) and can + * be mapped to whole object or a section of the object (partial binding). + * Multiple VA mappings can be created to the same section of the object + * (aliasing). + * + * The @start, @offset and @length should be 4K page aligned. However the DG2 + * and XEHPSDV has 64K page size for device local-memory and has compact page + * table. On those platforms, for binding device local-memory objects, the + * @start should be 2M aligned, @offset and @length should be 64K aligned. + * Also, on those platforms, error -ENOSPC will be returned if user tries to + * bind a device local-memory object and a system memory object in a single 2M + * section of VA range. + * + * Error code -EINVAL will be returned if @start, @offset and @length are not + * properly aligned. Error code of -ENOSPC will be returned if the VA range + * specified can't be reserved. + * + * The bind operation can get completed asynchronously and out of submission + * order. When I915_GEM_VM_BIND_FENCE_VALID flag is set, the @fence will be + * signaled upon completion of bind operation. + */ +struct drm_i915_gem_vm_bind { + /** @vm_id: VM (address space) id to bind */ + __u32 vm_id; + + /** @handle: Object handle */ + __u32 handle; + + /** @start: Virtual Address start to bind */ + __u64 start; + + /** @offset: Offset in object to bind */ + __u64 offset; + + /** @length: Length of mapping to bind */ + __u64 length; + + /** +* @flags: Supported flags are: +* +* I915_GEM_VM_BIND_FENCE_VALID: +* @fence is valid, needs bind completion notification. +* +* I915_GEM_VM_BIND_READONLY: +* Mapping is read-only. +* +* I915_GEM_VM_BIND_CAPTURE: +* Capture this mapping in the dump upon GPU error. +*/ + __u64 flags; +#define I915_GEM_VM_BIND_FENCE_VALID (1 << 0) +#define I915_GEM_VM_BIND_READONLY (1 << 1) +#define I915_GEM_VM_BIND_CAPTURE (1 << 2) + +
[PATCH v3 2/3] drm/i915: Update i915 uapi documentation
Add some missing i915 upai documentation which the new i915 VM_BIND feature documentation will be refer to. Signed-off-by: Niranjana Vishwanathapura Reviewed-by: Matthew Auld --- include/uapi/drm/i915_drm.h | 205 1 file changed, 160 insertions(+), 45 deletions(-) diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h index de49b68b4fc8..f5ce34d447b1 100644 --- a/include/uapi/drm/i915_drm.h +++ b/include/uapi/drm/i915_drm.h @@ -751,14 +751,27 @@ typedef struct drm_i915_irq_wait { /* Must be kept compact -- no holes and well documented */ -typedef struct drm_i915_getparam { +/** + * struct drm_i915_getparam - Driver parameter query structure. + */ +struct drm_i915_getparam { + /** @param: Driver parameter to query. */ __s32 param; - /* + + /** +* @value: Address of memory where queried value should be put. +* * WARNING: Using pointers instead of fixed-size u64 means we need to write * compat32 code. Don't repeat this mistake. */ int __user *value; -} drm_i915_getparam_t; +}; + +/** + * typedef drm_i915_getparam_t - Driver parameter query structure. + * See struct drm_i915_getparam. + */ +typedef struct drm_i915_getparam drm_i915_getparam_t; /* Ioctl to set kernel params: */ @@ -1239,76 +1252,119 @@ struct drm_i915_gem_exec_object2 { __u64 rsvd2; }; +/** + * struct drm_i915_gem_exec_fence - An input or output fence for the execbuf + * ioctl. + * + * The request will wait for input fence to signal before submission. + * + * The returned output fence will be signaled after the completion of the + * request. + */ struct drm_i915_gem_exec_fence { - /** -* User's handle for a drm_syncobj to wait on or signal. -*/ + /** @handle: User's handle for a drm_syncobj to wait on or signal. */ __u32 handle; + /** +* @flags: Supported flags are: +* +* I915_EXEC_FENCE_WAIT: +* Wait for the input fence before request submission. +* +* I915_EXEC_FENCE_SIGNAL: +* Return request completion fence as output +*/ + __u32 flags; #define I915_EXEC_FENCE_WAIT(1<<0) #define I915_EXEC_FENCE_SIGNAL (1<<1) #define __I915_EXEC_FENCE_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_SIGNAL << 1)) - __u32 flags; }; -/* - * See drm_i915_gem_execbuffer_ext_timeline_fences. - */ -#define DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES 0 - -/* +/** + * struct drm_i915_gem_execbuffer_ext_timeline_fences - Timeline fences + * for execbuf ioctl. + * * This structure describes an array of drm_syncobj and associated points for * timeline variants of drm_syncobj. It is invalid to append this structure to * the execbuf if I915_EXEC_FENCE_ARRAY is set. */ struct drm_i915_gem_execbuffer_ext_timeline_fences { +#define DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES 0 + /** @base: Extension link. See struct i915_user_extension. */ struct i915_user_extension base; /** -* Number of element in the handles_ptr & value_ptr arrays. +* @fence_count: Number of elements in the @handles_ptr & @value_ptr +* arrays. */ __u64 fence_count; /** -* Pointer to an array of struct drm_i915_gem_exec_fence of length -* fence_count. +* @handles_ptr: Pointer to an array of struct drm_i915_gem_exec_fence +* of length @fence_count. */ __u64 handles_ptr; /** -* Pointer to an array of u64 values of length fence_count. Values -* must be 0 for a binary drm_syncobj. A Value of 0 for a timeline -* drm_syncobj is invalid as it turns a drm_syncobj into a binary one. +* @values_ptr: Pointer to an array of u64 values of length +* @fence_count. +* Values must be 0 for a binary drm_syncobj. A Value of 0 for a +* timeline drm_syncobj is invalid as it turns a drm_syncobj into a +* binary one. */ __u64 values_ptr; }; +/** + * struct drm_i915_gem_execbuffer2 - Structure for DRM_I915_GEM_EXECBUFFER2 + * ioctl. + */ struct drm_i915_gem_execbuffer2 { - /** -* List of gem_exec_object2 structs -*/ + /** @buffers_ptr: Pointer to a list of gem_exec_object2 structs */ __u64 buffers_ptr; + + /** @buffer_count: Number of elements in @buffers_ptr array */ __u32 buffer_count; - /** Offset in the batchbuffer to start execution from. */ + /** +* @batch_start_offset: Offset in the batchbuffer to start execution +* from. +*/ __u32 batch_start_offset; - /** Bytes used in batchbuffer from batch_start_offset */ + + /** +* @batch_len: Length in bytes of the batch buffer, starting from the +* @batch_start_offset. If 0, length is assumed to be the batch buffer +* object size. +*/
[PATCH v4 0/3] drm/doc/rfc: i915 VM_BIND feature design + uapi
This is the i915 driver VM_BIND feature design RFC patch series along with the required uapi definition and description of intended use cases. v2: Reduce the scope to simple Mesa use case. Remove all compute related uapi, vm_bind/unbind queue support and only support a timeline out fence instead of an in/out timeline fence array. v3: Expand documentation on dma-resv usage, TLB flushing, execbuf3 and VM_UNBIND. Add FENCE_VALID and TLB_FLUSH flags. v4: Remove I915_GEM_VM_BIND_TLB_FLUSH flag and add additional uapi documentation for vm_bind/unbind. Signed-off-by: Niranjana Vishwanathapura Niranjana Vishwanathapura (3): drm/doc/rfc: VM_BIND feature design document drm/i915: Update i915 uapi documentation drm/doc/rfc: VM_BIND uapi definition Documentation/gpu/rfc/i915_vm_bind.h | 252 + Documentation/gpu/rfc/i915_vm_bind.rst | 245 Documentation/gpu/rfc/index.rst| 4 + include/uapi/drm/i915_drm.h| 205 +++- 4 files changed, 661 insertions(+), 45 deletions(-) create mode 100644 Documentation/gpu/rfc/i915_vm_bind.h create mode 100644 Documentation/gpu/rfc/i915_vm_bind.rst -- 2.21.0.rc0.32.g243a4c7e27
[PATCH v3 1/3] drm/doc/rfc: VM_BIND feature design document
VM_BIND design document with description of intended use cases. v2: Reduce the scope to simple Mesa use case. v3: Expand documentation on dma-resv usage, TLB flushing and execbuf3. v4: Remove vm_bind tlb flush request support. Signed-off-by: Niranjana Vishwanathapura --- Documentation/gpu/rfc/i915_vm_bind.rst | 245 + Documentation/gpu/rfc/index.rst| 4 + 2 files changed, 249 insertions(+) create mode 100644 Documentation/gpu/rfc/i915_vm_bind.rst diff --git a/Documentation/gpu/rfc/i915_vm_bind.rst b/Documentation/gpu/rfc/i915_vm_bind.rst new file mode 100644 index ..9b6bd1e8f660 --- /dev/null +++ b/Documentation/gpu/rfc/i915_vm_bind.rst @@ -0,0 +1,245 @@ +== +I915 VM_BIND feature design and use cases +== + +VM_BIND feature + +DRM_I915_GEM_VM_BIND/UNBIND ioctls allows UMD to bind/unbind GEM buffer +objects (BOs) or sections of a BOs at specified GPU virtual addresses on a +specified address space (VM). These mappings (also referred to as persistent +mappings) will be persistent across multiple GPU submissions (execbuf calls) +issued by the UMD, without user having to provide a list of all required +mappings during each submission (as required by older execbuf mode). + +The VM_BIND/UNBIND calls allow UMDs to request a timeline fence for signaling +the completion of bind/unbind operation. + +VM_BIND feature is advertised to user via I915_PARAM_HAS_VM_BIND. +User has to opt-in for VM_BIND mode of binding for an address space (VM) +during VM creation time via I915_VM_CREATE_FLAGS_USE_VM_BIND extension. + +The bind/unbind operation can get completed asynchronously and out of +submission order. The out fence when specified will be signaled upon +completion of bind/unbind operation. + +VM_BIND features include: + +* Multiple Virtual Address (VA) mappings can map to the same physical pages + of an object (aliasing). +* VA mapping can map to a partial section of the BO (partial binding). +* Support capture of persistent mappings in the dump upon GPU error. +* TLB is flushed upon unbind completion. +* Support for userptr gem objects (no special uapi is required for this). + +TLB flushing +- +TLB is flushed upon unbind completion. If platforms support selective TLB +invalidation, only the required range is flushed. Otherwise, whole TLB is +flushed and batching the flushes might be useful here. + +Execbuf ioctl in VM_BIND mode +--- +A VM in VM_BIND mode will not support older execbuf mode of binding. +The execbuf ioctl handling in VM_BIND mode differs significantly from the +older execbuf2 ioctl (See struct drm_i915_gem_execbuffer2). +Hence, a new execbuf3 ioctl has been added to support VM_BIND mode. (See +struct drm_i915_gem_execbuffer3). The execbuf3 ioctl will not accept any +execlist. Hence, no support for implicit sync. It is expected that the below +work will be able to support requirements of object dependency setting in all +use cases: + +"dma-buf: Add an API for exporting sync files" +(https://lwn.net/Articles/859290/) + +The new execbuf3 ioctl only works in VM_BIND mode and the VM_BIND mode only +works with execbuf3 ioctl for submission. All BOs mapped on that VM (through +VM_BIND call) at the time of execbuf3 call are deemed required for that +submission. + +The execbuf3 ioctl directly specifies the batch addresses instead of as +object handles as in execbuf2 ioctl. The execbuf3 ioctl will also not +support many of the older features like in/out/submit fences, fence array, +default gem context and many more (See struct drm_i915_gem_execbuffer3). + +In VM_BIND mode, VA allocation is completely managed by the user instead of +the i915 driver. Hence all VA assignment, eviction are not applicable in +VM_BIND mode. Also, for determining object activeness, VM_BIND mode will not +be using the i915_vma active reference tracking. It will instead use dma-resv +object for that (See `VM_BIND dma_resv usage`_). + +So, a lot of existing code supporting execbuf2 ioctl, like relocations, VA +evictions, vma lookup table, implicit sync, vma active reference tracking etc., +are not applicable for execbuf3 ioctl. Hence, all execbuf3 specific handling +should be in a separate file and only functionalities common to these ioctls +can be the shared code where possible. + +VM_PRIVATE objects +--- +By default, BOs can be mapped on multiple VMs and can also be dma-buf +exported. Hence these BOs are referred to as Shared BOs. +During each execbuf submission, the request fence must be added to the +dma-resv fence list of all shared BOs mapped on the VM. + +VM_BIND feature introduces an optimization where user can create BO which +is private to a specified VM via I915_GEM_CREATE_EXT_VM_PRIVATE flag during +BO creation. Unlike Shared BOs, these VM private BOs can only be mapped on +the VM they are private to and can't be dma-buf
Re: [PATCH] drm/fourcc: fix integer type usage in uapi header
Applied. Thanks! Alex On Wed, Jun 22, 2022 at 3:02 AM Simon Ser wrote: > > On Tuesday, June 21st, 2022 at 22:39, Carlos Llamas > wrote: > > > Kernel uapi headers are supposed to use __[us]{8,16,32,64} types defined > > by as opposed to 'uint32_t' and similar. See [1] for the > > relevant discussion about this topic. In this particular case, the usage > > of 'uint64_t' escaped headers_check as these macros are not being called > > here. However, the following program triggers a compilation error: > > > > #include > > > > int main() > > { > > unsigned long x = AMD_FMT_MOD_CLEAR(RB); > > return 0; > > } > > > > gcc error: > > drm.c:5:27: error: ‘uint64_t’ undeclared (first use in this function) > > 5 | unsigned long x = AMD_FMT_MOD_CLEAR(RB); > > | ^ > > > > This patch changes AMD_FMT_MOD_{SET,CLEAR} macros to use the correct > > integer types, which fixes the above issue. > > > > [1] https://lkml.org/lkml/2019/6/5/18 > > > > Fixes: 8ba16d599374 ("drm/fourcc: Add AMD DRM modifiers.") > > Signed-off-by: Carlos Llamas > > Reviewed-by: Simon Ser > > Cc'ing Bas as well > > > --- > > include/uapi/drm/drm_fourcc.h | 4 ++-- > > 1 file changed, 2 insertions(+), 2 deletions(-) > > > > diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h > > index f1972154a594..0980678d502d 100644 > > --- a/include/uapi/drm/drm_fourcc.h > > +++ b/include/uapi/drm/drm_fourcc.h > > @@ -1444,11 +1444,11 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 > > modifier) > > #define AMD_FMT_MOD_PIPE_MASK 0x7 > > > > #define AMD_FMT_MOD_SET(field, value) \ > > - ((uint64_t)(value) << AMD_FMT_MOD_##field##_SHIFT) > > + ((__u64)(value) << AMD_FMT_MOD_##field##_SHIFT) > > #define AMD_FMT_MOD_GET(field, value) \ > > (((value) >> AMD_FMT_MOD_##field##_SHIFT) & > > AMD_FMT_MOD_##field##_MASK) > > #define AMD_FMT_MOD_CLEAR(field) \ > > - (~((uint64_t)AMD_FMT_MOD_##field##_MASK << > > AMD_FMT_MOD_##field##_SHIFT)) > > + (~((__u64)AMD_FMT_MOD_##field##_MASK << AMD_FMT_MOD_##field##_SHIFT)) > > > > #if defined(__cplusplus) > > } > > -- > > 2.37.0.rc0.104.g0611611a94-goog
Re: [PATCH v2 02/68] drm/crtc: Introduce drmm_crtc_init_with_planes
Hi Maxime, I love your patch! Perhaps something to improve: [auto build test WARNING on next-20220622] [also build test WARNING on v5.19-rc3] [cannot apply to drm-misc/drm-misc-next drm-intel/for-linux-next drm-tip/drm-tip linus/master anholt/for-next v5.19-rc3 v5.19-rc2 v5.19-rc1] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/intel-lab-lkp/linux/commits/Maxime-Ripard/drm-vc4-Fix-hotplug-for-vc4/20220622-223842 base:ac0ba5454ca85162c08dc429fef1999e077ca976 config: riscv-rv32_defconfig (https://download.01.org/0day-ci/archive/20220623/202206230238.d3tmklmq-...@intel.com/config) compiler: riscv32-linux-gcc (GCC) 11.3.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/intel-lab-lkp/linux/commit/46edccc8b6046ecee2de71b23c941dc23514f522 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Maxime-Ripard/drm-vc4-Fix-hotplug-for-vc4/20220622-223842 git checkout 46edccc8b6046ecee2de71b23c941dc23514f522 # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.3.0 make.cross W=1 O=build_dir ARCH=riscv SHELL=/bin/bash drivers/gpu/drm/ If you fix the issue, kindly add following tag where applicable Reported-by: kernel test robot All warnings (new ones prefixed by >>): drivers/gpu/drm/drm_crtc.c: In function 'drmm_crtc_init_with_planes': >> drivers/gpu/drm/drm_crtc.c:421:43: warning: function >> 'drmm_crtc_init_with_planes' might be a candidate for 'gnu_printf' format >> attribute [-Wsuggest-attribute=format] 421 | name, ap); | ^~~~ vim +421 drivers/gpu/drm/drm_crtc.c 379 380 /** 381 * drmm_crtc_init_with_planes - Initialise a new CRTC object with 382 *specified primary and cursor planes. 383 * @dev: DRM device 384 * @crtc: CRTC object to init 385 * @primary: Primary plane for CRTC 386 * @cursor: Cursor plane for CRTC 387 * @funcs: callbacks for the new CRTC 388 * @name: printf style format string for the CRTC name, or NULL for default name 389 * 390 * Inits a new object created as base part of a driver crtc object. Drivers 391 * should use this function instead of drm_crtc_init(), which is only provided 392 * for backwards compatibility with drivers which do not yet support universal 393 * planes). For really simple hardware which has only 1 plane look at 394 * drm_simple_display_pipe_init() instead. 395 * 396 * Cleanup is automatically handled through registering 397 * drmm_crtc_cleanup() with drmm_add_action(). The crtc structure should 398 * be allocated with drmm_kzalloc(). 399 * 400 * The @drm_crtc_funcs.destroy hook must be NULL. 401 * 402 * The @primary and @cursor planes are only relevant for legacy uAPI, see 403 * _crtc.primary and _crtc.cursor. 404 * 405 * Returns: 406 * Zero on success, error code on failure. 407 */ 408 int drmm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc, 409 struct drm_plane *primary, 410 struct drm_plane *cursor, 411 const struct drm_crtc_funcs *funcs, 412 const char *name, ...) 413 { 414 va_list ap; 415 int ret; 416 417 WARN_ON(funcs && funcs->destroy); 418 419 va_start(ap, name); 420 ret = __drm_crtc_init_with_planes(dev, crtc, primary, cursor, funcs, > 421name, ap); 422 va_end(ap); 423 if (ret) 424 return ret; 425 426 ret = drmm_add_action_or_reset(dev, drmm_crtc_init_with_planes_cleanup, 427 crtc); 428 if (ret) 429 return ret; 430 431 return 0; 432 } 433 EXPORT_SYMBOL(drmm_crtc_init_with_planes); 434 -- 0-DAY CI Kernel Test Service https://01.org/lkp
Re: [PATCH] drm/ast: Fix black screen when getting out of suspend
Some small nitpicks: On Wed, 2022-06-22 at 14:48 +0200, Jocelyn Falempe wrote: > With an AST2600, the screen is garbage when going out of suspend. > This is because color settings are lost, and not restored on resume. > Force the color settings on DPMS_ON, to make sure the settings are correct. > > I didn't write this code, it comes from the out-of-tree aspeed driver v1.13 > https://www.aspeedtech.com/support_driver/ > > Signed-off-by: Jocelyn Falempe > Tested-by: Venkat Tadikonda Should have a Cc: to stable imho, `dim` can do this for you: https://drm.pages.freedesktop.org/maintainer-tools/dim.html > --- > drivers/gpu/drm/ast/ast_mode.c | 13 + > 1 file changed, 13 insertions(+) > > diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c > index 3eb9afecd9d4..cdddcb5c4439 100644 > --- a/drivers/gpu/drm/ast/ast_mode.c > +++ b/drivers/gpu/drm/ast/ast_mode.c > @@ -990,6 +990,9 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int > mode) > { > struct ast_private *ast = to_ast_private(crtc->dev); > u8 ch = AST_DPMS_VSYNC_OFF | AST_DPMS_HSYNC_OFF; > + struct ast_crtc_state *ast_state; > + const struct drm_format_info *format; > + struct ast_vbios_mode_info *vbios_mode_info; > > /* TODO: Maybe control display signal generation with > * Sync Enable (bit CR17.7). > @@ -1007,6 +1010,16 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int > mode) > ast_dp_set_on_off(crtc->dev, 1); > } > > + ast_state = to_ast_crtc_state(crtc->state); > + format = ast_state->format; > + > + if (format){ Should be a space between ')' and '{'. With that fixed, this is: Reviewed-by: Lyude Paul > + vbios_mode_info = _state->vbios_mode_info; > + > + ast_set_color_reg(ast, format); > + ast_set_vbios_color_reg(ast, format, > vbios_mode_info); > + } > + > ast_crtc_load_lut(ast, crtc); > break; > case DRM_MODE_DPMS_STANDBY: -- Cheers, Lyude Paul (she/her) Software Engineer at Red Hat
Re: [PATCH] drm/msm/dp: reset drm_dev to NULL at dp_display_unbind()
On 22/06/2022 19:54, Kuogee Hsieh wrote: During msm initialize phase, dp_display_unbind() will be called to undo initializations had been done by dp_display_bind() previously if there is error happen at msm_drm_bind. Under this kind of circumstance, drm_device may not be populated completed which causes system crash at drm_dev_dbg(). This patch reset drm_dev to NULL so that following drm_dev_dbg() will not refer to any internal fields of drm_device to prevent system from crashing. Below are panic stack trace, [ 53.584904] Unable to handle kernel paging request at virtual address 70018001 . [ 53.702212] Hardware name: Qualcomm Technologies, Inc. sc7280 CRD platform (rev5+) (DT) [ 53.710445] pstate: 2049 (nzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 53.717596] pc : string_nocheck+0x1c/0x64 [ 53.721738] lr : string+0x54/0x60 [ 53.725162] sp : ffc013d6b650 [ 53.728590] pmr_save: 00e0 [ 53.731743] x29: ffc013d6b650 x28: 0002 x27: 00ff [ 53.739083] x26: ffc013d6b710 x25: ffd07a066ae0 x24: ffd07a419f97 [ 53.746420] x23: ffd07a419f99 x22: ff81fef360d4 x21: ff81fef364d4 [ 53.753760] x20: ffc013d6b6f8 x19: ffd07a06683c x18: [ 53.761093] x17: 4020386678302f30 x16: 00b0 x15: ffd0797523c8 [ 53.768429] x14: 0004 x13: ff00 x12: ffd07a066b2c [ 53.775780] x11: x10: 013c x9 : [ 53.783117] x8 : ff81fef364d4 x7 : x6 : [ 53.790445] x5 : x4 : 0a00ff04 x3 : 0a00ff04 [ 53.797783] x2 : 70018001 x1 : x0 : ff81fef360d4 [ 53.805136] Call trace: [ 53.807667] string_nocheck+0x1c/0x64 [ 53.811439] string+0x54/0x60 [ 53.814498] vsnprintf+0x374/0x53c [ 53.818009] pointer+0x3dc/0x40c [ 53.821340] vsnprintf+0x398/0x53c [ 53.824854] vscnprintf+0x3c/0x88 [ 53.828274] __trace_array_vprintk+0xcc/0x2d4 [ 53.832768] trace_array_printk+0x8c/0xb4 [ 53.836900] drm_trace_printf+0x74/0x9c [ 53.840875] drm_dev_dbg+0xfc/0x1b8 [ 53.844480] dp_pm_suspend+0x70/0xf8 [ 53.848164] dpm_run_callback+0x60/0x1a0 [ 53.85] __device_suspend+0x304/0x3f4 [ 53.856363] dpm_suspend+0xf8/0x3a8 [ 53.859959] dpm_suspend_start+0x8c/0xc0 Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dp/dp_display.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 2b72639..02fff70 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -316,6 +316,8 @@ static void dp_display_unbind(struct device *dev, struct device *master, dp_power_client_deinit(dp->power); dp_aux_unregister(dp->aux); + dp->drm_dev = NULL; + dp->aux->drm_dev = NULL; priv->dp[dp->id] = NULL; } -- With best wishes Dmitry
Re: How do I gather up new code to be converted as patches?
Hi Kevin, On Wed, Jun 22, 2022 at 07:18:58PM +0200, Kevin Brace wrote: > Hi, > > How to I use git to gather up new code to be converted to patches? > Specifically, I have 20+ new files in one location (drivers/gpu/drm/via) > and a small change to DRM main make file (drivers/gpu/drm/Makefile). One simple way to do this is to start with a clean tree, and then add files step by step. 20+ files in one patch is too much to review, so decide for a reasonable split between the files. Maybe something like (as inspiration find your own split): 0) Documentation - or add this in you cover letter. Enough info to give the reader a rough understanding of the HW and the driver structure. 1) Driver files 2) Util files 3) Files for the memory handling 4) Files for irq handling 5) HW specific files 6) A the final patch - the Kconfig, and Makefile adjustments. It is important that the final patch is final as you would otherwise break the build. I look forward to see the patches! Sam
Re: [PATCH v15 0/3] eDP/DP Phy vdda realted function
On 21/06/2022 20:01, Kuogee Hsieh wrote: 0) rebase on https://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy.git tree 1) add regulator_set_load() to eDP phy 2) add regulator_set_load() to DP phy 3) remove vdda related function out of eDP/DP controller Kuogee Hsieh (3): phy: qcom-edp: add regulator_set_load to edp phy phy: qcom-qmp: add regulator_set_load to dp phy drm/msm/dp: delete vdda regulator related functions from eDP/DP controller Kishon, Vinod, how do we proceed with merging these patches? drivers/gpu/drm/msm/dp/dp_parser.c| 14 - drivers/gpu/drm/msm/dp/dp_parser.h| 8 --- drivers/gpu/drm/msm/dp/dp_power.c | 95 +-- drivers/phy/qualcomm/phy-qcom-edp.c | 12 drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 43 ++ 5 files changed, 47 insertions(+), 125 deletions(-) -- With best wishes Dmitry
Re: [PATCH 2/3] drm/msm/dp: Remove pixel_rate from struct dp_ctrl
On 22/06/2022 18:22, Kuogee Hsieh wrote: On 6/22/2022 12:24 AM, Dmitry Baryshkov wrote: On 22/06/2022 05:59, Stephen Boyd wrote: Quoting Dmitry Baryshkov (2022-06-17 16:07:58) On 17/06/2022 23:47, Stephen Boyd wrote: This struct member is stored to in the function that calls the function which uses it. That's possible with a function argument instead of storing to a struct member. Pass the pixel_rate as an argument instead to simplify the code. Note that dp_ctrl_link_maintenance() was storing the pixel_rate but never using it so we just remove the assignment from there. Cc: Kuogee Hsieh Signed-off-by: Stephen Boyd --- drivers/gpu/drm/msm/dp/dp_ctrl.c | 57 drivers/gpu/drm/msm/dp/dp_ctrl.h | 1 - 2 files changed, 28 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c index bd445e683cfc..e114521af2e9 100644 --- a/drivers/gpu/drm/msm/dp/dp_ctrl.c +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c @@ -1336,7 +1336,7 @@ static void dp_ctrl_set_clock_rate(struct dp_ctrl_private *ctrl, name, rate); } -static int dp_ctrl_enable_mainlink_clocks(struct dp_ctrl_private *ctrl) +static int dp_ctrl_enable_mainlink_clocks(struct dp_ctrl_private *ctrl, unsigned long pixel_rate) I think we can read pixel_rate here rather than getting it as an argument. We'd need to move handling (DP_TEST_LINK_PHY_TEST_PATTERN && !ctrl->panel->dp_mode.drm_mode.clock) case here from dp_ctrl_on_link(). This is also called from dp_ctrl_on_stream() and dp_ctrl_reinitialize_mainlink(). In the dp_ctrl_on_stream() case we may divide the pixel_rate by 2 with widebus. We could move the dp_ctrl_on_link() code here, but then we also need to move widebus, and then I'm not sure which pixel rate to use. It looks like the test code doesn't care about widebus? And similarly, we may run the pixel clk faster until we get a modeset and then divide it for widebus. Good question. I'll let Kuogee or somebody else from Qualcomm to comment on test code vs widebus vs pixel rate, as I don't know these details. I'm not sure if we should halve the pixel clock in dp_ctrl_on_stream_phy_test_report() or not if the widebus is supported. From the current code I'd assume that we have to do this. Let's raise this question in the corresponding patch discussion. yes, phy test does not care pixel clock rate. So, is it 'does not care' or 'set to mode clock'? In other words, can we unify both functions by always accounting for the wide_bus_en value? -- With best wishes Dmitry
Re: [PATCH v4 0/7] usb: typec: Introduce typec-switch binding
On Wed, Jun 22, 2022 at 8:11 AM Greg Kroah-Hartman wrote: > > On Wed, Jun 22, 2022 at 04:53:40PM +0200, Krzysztof Kozlowski wrote: > > On 21/06/2022 15:17, Greg Kroah-Hartman wrote: > > > On Wed, Jun 15, 2022 at 11:13:33AM -0700, Prashant Malani wrote: > > >> I should add: > > >> > > >> Series submission suggestions (of course, open to better suggestions > > >> too): > > >> - Patches 1-3 can go through the USB repo. > > > > > > I will take patches 1 and 2 now. > > > > > > seems the others need reworks or acks from the DT people. > > > > I just gave for patch 3 and before for 4, so you can grab these as well. > > They are gone from my queue, a resend with that ack would be good so > that I can pick it up easier. Thanks Greg. I've sent out v5 [1] which has the Reviewed-by tags from Krzysztof. [1] https://lore.kernel.org/linux-usb/20220622173605.1168416-1-pmal...@chromium.org/ Best regards, -Prashant
Re: [PATCH v4 4/4] drm/msm/dpu: Add interface support for CRC debugfs
On 22/06/2022 20:18, Jessica Zhang wrote: Add support for writing CRC values for the interface block to the debugfs by calling the necessary MISR setup/collect methods. Changes since V1: - Set values_cnt to only include phys with backing hw_intf - Loop over all drm_encs connected to crtc Changes since V2: - Remove vblank.h inclusion - Change `pos + i` to `pos + entries` - Initialize values_cnt to 0 for encoder - Change DPU_CRTC_CRC_SOURCE_INTF to DPU_CRTC_CRC_SOURCE_ENCODER (and "intf" to "enc") - Change dpu_encoder_get_num_phys to dpu_encoder_get_num_hw_intfs - Add checks for setup_misr and collect_misr in dpu_encoder_get_num_hw_intfs Changes since V3: - Remove extra whitespace - Change "enc" to "encoder" - Move crcs array to dpu_crtc_get_encoder_crc - Rename dpu_encoder_get_num_hw_intfs to dpu_encoder_get_crc_values_cnt Signed-off-by: Jessica Zhang Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c| 46 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h| 3 + drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 64 + drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 22 +++ 4 files changed, 134 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index b57140c3671a..4dd0ce09ca74 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -79,6 +79,8 @@ static enum dpu_crtc_crc_source dpu_crtc_parse_crc_source(const char *src_name) if (!strcmp(src_name, "auto") || !strcmp(src_name, "lm")) return DPU_CRTC_CRC_SOURCE_LAYER_MIXER; + if (!strcmp(src_name, "encoder")) + return DPU_CRTC_CRC_SOURCE_ENCODER; return DPU_CRTC_CRC_SOURCE_INVALID; } @@ -94,8 +96,16 @@ static int dpu_crtc_verify_crc_source(struct drm_crtc *crtc, return -EINVAL; } - if (source == DPU_CRTC_CRC_SOURCE_LAYER_MIXER) + if (source == DPU_CRTC_CRC_SOURCE_LAYER_MIXER) { *values_cnt = crtc_state->num_mixers; + } else if (source == DPU_CRTC_CRC_SOURCE_ENCODER) { + struct drm_encoder *drm_enc; + + *values_cnt = 0; + + drm_for_each_encoder_mask(drm_enc, crtc->dev, crtc->state->encoder_mask) + *values_cnt += dpu_encoder_get_crc_values_cnt(drm_enc); + } return 0; } @@ -116,6 +126,14 @@ static void dpu_crtc_setup_lm_misr(struct dpu_crtc_state *crtc_state) } } +static void dpu_crtc_setup_encoder_misr(struct drm_crtc *crtc) +{ + struct drm_encoder *drm_enc; + + drm_for_each_encoder_mask(drm_enc, crtc->dev, crtc->state->encoder_mask) + dpu_encoder_setup_misr(drm_enc); +} + static int dpu_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name) { enum dpu_crtc_crc_source source = dpu_crtc_parse_crc_source(src_name); @@ -164,6 +182,8 @@ static int dpu_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name) if (source == DPU_CRTC_CRC_SOURCE_LAYER_MIXER) dpu_crtc_setup_lm_misr(crtc_state); + else if (source == DPU_CRTC_CRC_SOURCE_ENCODER) + dpu_crtc_setup_encoder_misr(crtc); else ret = -EINVAL; @@ -215,6 +235,28 @@ static int dpu_crtc_get_lm_crc(struct drm_crtc *crtc, drm_crtc_accurate_vblank_count(crtc), crcs); } +static int dpu_crtc_get_encoder_crc(struct drm_crtc *crtc) +{ + struct drm_encoder *drm_enc; + int rc, pos = 0; + u32 crcs[INTF_MAX]; + + drm_for_each_encoder_mask(drm_enc, crtc->dev, crtc->state->encoder_mask) { + rc = dpu_encoder_get_crc(drm_enc, crcs, pos); + if (rc < 0) { + if (rc != -ENODATA) + DRM_DEBUG_DRIVER("MISR read failed\n"); + + return rc; + } + + pos += rc; + } + + return drm_crtc_add_crc_entry(crtc, true, + drm_crtc_accurate_vblank_count(crtc), crcs); +} + static int dpu_crtc_get_crc(struct drm_crtc *crtc) { struct dpu_crtc_state *crtc_state = to_dpu_crtc_state(crtc->state); @@ -227,6 +269,8 @@ static int dpu_crtc_get_crc(struct drm_crtc *crtc) if (crtc_state->crc_source == DPU_CRTC_CRC_SOURCE_LAYER_MIXER) return dpu_crtc_get_lm_crc(crtc, crtc_state); + else if (crtc_state->crc_source == DPU_CRTC_CRC_SOURCE_ENCODER) + return dpu_crtc_get_encoder_crc(crtc); return -EINVAL; } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h index 20df23fe74ed..af03277a3e5a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc.
[PATCH v5 9/9] drm/bridge: it6505: Add typec_mux_set callback function
From: Pin-Yen Lin Add the callback function when the driver receives state changes of the Type-C ports. The callback function configures the lane_swap state and ends up updating the lane swap registers of it6505 bridge chip. Signed-off-by: Pin-Yen Lin Signed-off-by: Prashant Malani --- v5 is the first version for this patch. drivers/gpu/drm/bridge/ite-it6505.c | 58 + 1 file changed, 58 insertions(+) diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c index cb1dd4cbd33b..87b9bd742b52 100644 --- a/drivers/gpu/drm/bridge/ite-it6505.c +++ b/drivers/gpu/drm/bridge/ite-it6505.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -404,6 +405,7 @@ struct debugfs_entries { }; struct it6505_port_data { + bool dp_connected; struct typec_mux_dev *typec_mux; struct it6505 *it6505; }; @@ -3237,9 +3239,65 @@ static void it6505_shutdown(struct i2c_client *client) it6505_lane_off(it6505); } +static void it6505_typec_ports_update(struct it6505 *it6505) +{ + usleep_range(3000, 4000); + + if (it6505->typec_ports[0].dp_connected && it6505->typec_ports[1].dp_connected) + /* Both ports available, do nothing to retain the current one. */ + return; + else if (it6505->typec_ports[0].dp_connected) + it6505->lane_swap = false; + else if (it6505->typec_ports[1].dp_connected) + it6505->lane_swap = true; + + usleep_range(3000, 4000); +} + static int it6505_typec_mux_set(struct typec_mux_dev *mux, struct typec_mux_state *state) { + struct it6505_port_data *data = typec_mux_get_drvdata(mux); + struct it6505 *it6505 = data->it6505; + struct device *dev = >client->dev; + bool old_dp_connected, new_dp_connected; + + if (it6505->num_typec_switches == 1) + return 0; + + mutex_lock(>extcon_lock); + + old_dp_connected = it6505->typec_ports[0].dp_connected || + it6505->typec_ports[1].dp_connected; + + dev_dbg(dev, "mux_set dp_connected: c0=%d, c1=%d\n", + it6505->typec_ports[0].dp_connected, it6505->typec_ports[1].dp_connected); + + data->dp_connected = (state->alt && state->alt->svid == USB_TYPEC_DP_SID && + state->alt->mode == USB_TYPEC_DP_MODE); + + new_dp_connected = it6505->typec_ports[0].dp_connected || + it6505->typec_ports[1].dp_connected; + + if (it6505->enable_drv_hold) { + dev_dbg(dev, "enable driver hold"); + goto unlock; + } + + it6505_typec_ports_update(it6505); + + if (!old_dp_connected && new_dp_connected) + pm_runtime_get_sync(dev); + + if (old_dp_connected && !new_dp_connected) { + pm_runtime_put_sync(dev); + if (it6505->bridge.dev) + drm_helper_hpd_irq_event(it6505->bridge.dev); + memset(it6505->dpcd, 0, sizeof(it6505->dpcd)); + } + +unlock: + mutex_unlock(>extcon_lock); return 0; } -- 2.37.0.rc0.104.g0611611a94-goog
Re: [PATCH v4 1/4] drm/msm/dpu: Move LM CRC code into separate method
On 22/06/2022 20:18, Jessica Zhang wrote: Move layer mixer-specific section of dpu_crtc_get_crc() into a separate helper method. This way, we can make it easier to get CRCs from other HW blocks by adding other get_crc helper methods. Changes since V1: - Move common bitmasks to dpu_hw_util.h - Move common CRC methods to dpu_hw_util.c - Update copyrights - Change crcs array to a dynamically allocated array and added it as a member of crtc_state Changes since V2: - Put changes for hw_util into a separate commit - Revert crcs array to a static array - Add else case for set_crc_source to return EINVAL if no valid source is selected - Add DPU_CRTC_MAX_CRC_ENTRIES macro Changes since V3: - Move crcs array into dpu_crtc_get_lm_crc - Remove comment about crcs array in dpu_crtc_state struct - Revert `lm` rename - Remove DPU_CRTC_MAX_CRC_ENTRIES macro - Return EINVAL in dpu_crtc_get_crc if no valid CRC source is set Signed-off-by: Jessica Zhang Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 65 +++- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 2 + 2 files changed, 43 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index b56f777dbd0e..b57140c3671a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark @@ -99,17 +100,32 @@ static int dpu_crtc_verify_crc_source(struct drm_crtc *crtc, return 0; } +static void dpu_crtc_setup_lm_misr(struct dpu_crtc_state *crtc_state) +{ + struct dpu_crtc_mixer *m; + int i; + + for (i = 0; i < crtc_state->num_mixers; ++i) { + m = _state->mixers[i]; + + if (!m->hw_lm || !m->hw_lm->ops.setup_misr) + continue; + + /* Calculate MISR over 1 frame */ + m->hw_lm->ops.setup_misr(m->hw_lm, true, 1); + } +} + static int dpu_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name) { enum dpu_crtc_crc_source source = dpu_crtc_parse_crc_source(src_name); enum dpu_crtc_crc_source current_source; struct dpu_crtc_state *crtc_state; struct drm_device *drm_dev = crtc->dev; - struct dpu_crtc_mixer *m; bool was_enabled; bool enable = false; - int i, ret = 0; + int ret = 0; if (source < 0) { DRM_DEBUG_DRIVER("Invalid CRC source %s for CRTC%d\n", src_name, crtc->index); @@ -146,16 +162,10 @@ static int dpu_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name) crtc_state->crc_frame_skip_count = 0; - for (i = 0; i < crtc_state->num_mixers; ++i) { - m = _state->mixers[i]; - - if (!m->hw_lm || !m->hw_lm->ops.setup_misr) - continue; - - /* Calculate MISR over 1 frame */ - m->hw_lm->ops.setup_misr(m->hw_lm, true, 1); - } - + if (source == DPU_CRTC_CRC_SOURCE_LAYER_MIXER) + dpu_crtc_setup_lm_misr(crtc_state); + else + ret = -EINVAL; cleanup: drm_modeset_unlock(>mutex); @@ -174,26 +184,17 @@ static u32 dpu_crtc_get_vblank_counter(struct drm_crtc *crtc) return dpu_encoder_get_vsync_count(encoder); } - -static int dpu_crtc_get_crc(struct drm_crtc *crtc) +static int dpu_crtc_get_lm_crc(struct drm_crtc *crtc, + struct dpu_crtc_state *crtc_state) { - struct dpu_crtc_state *crtc_state; struct dpu_crtc_mixer *m; u32 crcs[CRTC_DUAL_MIXERS]; - int i = 0; int rc = 0; - - crtc_state = to_dpu_crtc_state(crtc->state); + int i; BUILD_BUG_ON(ARRAY_SIZE(crcs) != ARRAY_SIZE(crtc_state->mixers)); - /* Skip first 2 frames in case of "uncooked" CRCs */ - if (crtc_state->crc_frame_skip_count < 2) { - crtc_state->crc_frame_skip_count++; - return 0; - } - for (i = 0; i < crtc_state->num_mixers; ++i) { m = _state->mixers[i]; @@ -214,6 +215,22 @@ static int dpu_crtc_get_crc(struct drm_crtc *crtc) drm_crtc_accurate_vblank_count(crtc), crcs); } +static int dpu_crtc_get_crc(struct drm_crtc *crtc) +{ + struct dpu_crtc_state *crtc_state = to_dpu_crtc_state(crtc->state); + + /* Skip first 2 frames in case of "uncooked" CRCs */ + if (crtc_state->crc_frame_skip_count < 2) { + crtc_state->crc_frame_skip_count++; + return 0; + } + + if (crtc_state->crc_source == DPU_CRTC_CRC_SOURCE_LAYER_MIXER) + return dpu_crtc_get_lm_crc(crtc, crtc_state); + + return -EINVAL; +} + static
[PATCH v5 8/9] drm/bridge: it6505: Register Type-C mode switches
From: Pin-Yen Lin When the DT node has "switches" available, register a Type-C mode-switch for each listed "switch". This allows the driver to receive state information about what operating mode a Type-C port and its connected peripherals are in, as well as status information (like VDOs) related to that state. The callback function is currently a stub, but subsequent patches will implement the required functionality. Signed-off-by: Pin-Yen Lin Signed-off-by: Prashant Malani --- v5 is the first version for this patch. drivers/gpu/drm/bridge/ite-it6505.c | 85 - 1 file changed, 82 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c index b259f9f367f6..cb1dd4cbd33b 100644 --- a/drivers/gpu/drm/bridge/ite-it6505.c +++ b/drivers/gpu/drm/bridge/ite-it6505.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -402,6 +403,11 @@ struct debugfs_entries { const struct file_operations *fops; }; +struct it6505_port_data { + struct typec_mux_dev *typec_mux; + struct it6505 *it6505; +}; + struct it6505 { struct drm_dp_aux aux; struct drm_bridge bridge; @@ -453,6 +459,7 @@ struct it6505 { struct it6505_audio_data audio; struct dentry *debugfs; int num_typec_switches; + struct it6505_port_data *typec_ports; /* it6505 driver hold option */ bool enable_drv_hold; @@ -3230,9 +3237,59 @@ static void it6505_shutdown(struct i2c_client *client) it6505_lane_off(it6505); } +static int it6505_typec_mux_set(struct typec_mux_dev *mux, + struct typec_mux_state *state) +{ + return 0; +} + +static int it6505_register_mode_switch(struct device *dev, struct device_node *node, + struct it6505 *it6505) +{ + struct it6505_port_data *port_data; + struct typec_mux_desc mux_desc = {}; + char name[32]; + u32 port_num; + int ret; + + ret = of_property_read_u32(node, "reg", _num); + if (ret) + return ret; + + if (port_num >= it6505->num_typec_switches) { + dev_err(dev, "Invalid port number specified: %d\n", port_num); + return -EINVAL; + } + + port_data = >typec_ports[port_num]; + port_data->it6505 = it6505; + mux_desc.fwnode = >fwnode; + mux_desc.drvdata = port_data; + snprintf(name, sizeof(name), "%s-%u", node->name, port_num); + mux_desc.name = name; + mux_desc.set = it6505_typec_mux_set; + + port_data->typec_mux = typec_mux_register(dev, _desc); + if (IS_ERR(port_data->typec_mux)) { + ret = PTR_ERR(port_data->typec_mux); + dev_err(dev, "Mode switch register for port %d failed: %d", port_num, ret); + } + + return ret; +} + +static void it6505_unregister_typec_switches(struct it6505 *it6505) +{ + int i; + + for (i = 0; i < it6505->num_typec_switches; i++) + typec_mux_unregister(it6505->typec_ports[i].typec_mux); +} + static int it6505_register_typec_switches(struct device *device, struct it6505 *it6505) { - struct device_node *of; + struct device_node *of, *sw; + int ret = 0; of = of_get_child_by_name(device->of_node, "switches"); if (!of) @@ -3241,8 +3298,28 @@ static int it6505_register_typec_switches(struct device *device, struct it6505 * it6505->num_typec_switches = of_get_child_count(of); if (it6505->num_typec_switches <= 0) return -ENODEV; + it6505->typec_ports = devm_kzalloc(device, + it6505->num_typec_switches * + sizeof(struct it6505_port_data), + GFP_KERNEL); + if (!it6505->typec_ports) + return -ENOMEM; - return 0; + /* Register switches for each connector. */ + for_each_available_child_of_node(of, sw) { + if (!of_property_read_bool(sw, "mode-switch")) + continue; + ret = it6505_register_mode_switch(device, sw, it6505); + if (ret) { + dev_err(device, "Failed to register mode switch: %d\n", ret); + break; + } + } + + if (ret) + it6505_unregister_typec_switches(it6505); + + return ret; } static int it6505_i2c_probe(struct i2c_client *client, @@ -3280,7 +3357,8 @@ static int it6505_i2c_probe(struct i2c_client *client, ret = it6505_register_typec_switches(dev, it6505); if (ret) { - dev_dbg(dev, "Didn't register Type C switches, err: %d", ret); + if (ret != -ENODEV) + dev_warn(dev, "Didn't register Type C switches, err: %d", ret); if
[PATCH v5 7/9] drm/bridge: it6505: Register number of Type C switches
From: Pin-Yen Lin Parse the "switches" node, if available, and count and store the number of Type-C switches within it. The extcon registration is still supported, but we don't expect both extcon and typec-switch be registered at the same time. This patch sets a foundation for the actual registering of Type-C switches with the Type-C connector class framework. Signed-off-by: Pin-Yen Lin Signed-off-by: Prashant Malani --- v5 is the first version for this patch. drivers/gpu/drm/bridge/ite-it6505.c | 34 + 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c index 4b673c4792d7..b259f9f367f6 100644 --- a/drivers/gpu/drm/bridge/ite-it6505.c +++ b/drivers/gpu/drm/bridge/ite-it6505.c @@ -452,6 +452,7 @@ struct it6505 { struct delayed_work delayed_audio; struct it6505_audio_data audio; struct dentry *debugfs; + int num_typec_switches; /* it6505 driver hold option */ bool enable_drv_hold; @@ -3229,13 +3230,28 @@ static void it6505_shutdown(struct i2c_client *client) it6505_lane_off(it6505); } +static int it6505_register_typec_switches(struct device *device, struct it6505 *it6505) +{ + struct device_node *of; + + of = of_get_child_by_name(device->of_node, "switches"); + if (!of) + return -ENODEV; + + it6505->num_typec_switches = of_get_child_count(of); + if (it6505->num_typec_switches <= 0) + return -ENODEV; + + return 0; +} + static int it6505_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct it6505 *it6505; struct device *dev = >dev; struct extcon_dev *extcon; - int err, intp_irq; + int err, intp_irq, ret; it6505 = devm_kzalloc(>dev, sizeof(*it6505), GFP_KERNEL); if (!it6505) @@ -3255,11 +3271,21 @@ static int it6505_i2c_probe(struct i2c_client *client, if (PTR_ERR(extcon) == -EPROBE_DEFER) return -EPROBE_DEFER; if (IS_ERR(extcon)) { - dev_err(dev, "can not get extcon device!"); - return PTR_ERR(extcon); + if (PTR_ERR(extcon) != -ENODEV) + dev_warn(dev, "Cannot get extcon device: %ld", PTR_ERR(extcon)); + it6505->extcon = NULL; + } else { + it6505->extcon = extcon; } - it6505->extcon = extcon; + ret = it6505_register_typec_switches(dev, it6505); + if (ret) { + dev_dbg(dev, "Didn't register Type C switches, err: %d", ret); + if (!it6505->extcon) { + dev_err(dev, "Both extcon and typec-switch are not registered."); + return -EINVAL; + } + } it6505->regmap = devm_regmap_init_i2c(client, _regmap_config); if (IS_ERR(it6505->regmap)) { -- 2.37.0.rc0.104.g0611611a94-goog
[PATCH v5 6/9] dt/bindings: drm/bridge: it6505: Add mode-switch support
From: Pin-Yen Lin ITE IT6505 can be used in systems to switch USB Type-C DisplayPort alternate mode lane traffic between 2 Type-C ports. Update the binding to accommodate this usage by introducing a switch property. Signed-off-by: Pin-Yen Lin Signed-off-by: Prashant Malani --- v5 is the first version for this patch. .../bindings/display/bridge/ite,it6505.yaml | 97 ++- 1 file changed, 96 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/display/bridge/ite,it6505.yaml b/Documentation/devicetree/bindings/display/bridge/ite,it6505.yaml index 833d11b2303a..86bb6dc5ae6f 100644 --- a/Documentation/devicetree/bindings/display/bridge/ite,it6505.yaml +++ b/Documentation/devicetree/bindings/display/bridge/ite,it6505.yaml @@ -56,13 +56,46 @@ properties: $ref: /schemas/graph.yaml#/properties/port description: A port node pointing to DPI host port node + switches: +type: object +description: Set of switches controlling DisplayPort traffic on + outgoing RX/TX lanes to Type C ports. +additionalProperties: false + +properties: + '#address-cells': +const: 1 + + '#size-cells': +const: 0 + +patternProperties: + '^switch@[01]$': +$ref: /schemas/usb/typec-switch.yaml# +unevaluatedProperties: false + +properties: + reg: +maxItems: 1 + +required: + - reg + +required: + - switch@0 + required: - compatible - ovdd-supply - pwr18-supply - interrupts - reset-gpios - - extcon + +oneOf: + - required: + - extcon + - required: + - switches additionalProperties: false @@ -92,3 +125,65 @@ examples: }; }; }; + - | +#include + +i2c3 { +#address-cells = <1>; +#size-cells = <0>; + +it6505dptx: it6505dptx@5c { +compatible = "ite,it6505"; +interrupts = <8 IRQ_TYPE_LEVEL_LOW 8 0>; +reg = <0x5c>; +pinctrl-names = "default"; +pinctrl-0 = <_pins>; +ovdd-supply = <_vsim2_reg>; +pwr18-supply = <_dpbrdg_dx>; +reset-gpios = < 177 0>; + +port { +it6505_dp_in: endpoint { +remote-endpoint = <_out>; +}; +}; + +switches { +#address-cells = <1>; +#size-cells = <0>; +switch@0 { +compatible = "typec-switch"; +reg = <0>; +mode-switch; + +ports { +#address-cells = <1>; +#size-cells = <0>; +port@0 { +reg = <0>; +ite_typec0: endpoint { +remote-endpoint = <_port0>; +}; +}; +}; +}; + +switch@1 { +compatible = "typec-switch"; +reg = <1>; +mode-switch; + +ports { +#address-cells = <1>; +#size-cells = <0>; +port@0 { +reg = <0>; +ite_typec1: endpoint { +remote-endpoint = <_port1>; +}; +}; +}; +}; +}; +}; +}; -- 2.37.0.rc0.104.g0611611a94-goog
Re: [Freedreno] [PATCH] drm/msm/dpu: Increment vsync_cnt before waking up userspace
On 6/21/2022 7:38 PM, Stephen Boyd wrote: The 'vsync_cnt' is used to count the number of frames for a crtc. Unfortunately, we increment the count after waking up userspace via dpu_crtc_vblank_callback() calling drm_crtc_handle_vblank(). drm_crtc_handle_vblank() wakes up userspace processes that have called drm_wait_vblank_ioctl(), and if that ioctl is expecting the count to increase it won't. Increment the count before calling into the drm APIs so that we don't have to worry about ordering the increment with anything else in drm. This fixes a software video decode test that fails to see frame counts increase on Trogdor boards. Cc: Mark Yacoub Cc: Jessica Zhang Fixes: 885455d6bf82 ("drm/msm: Change dpu_crtc_get_vblank_counter to use vsync count.") Signed-off-by: Stephen Boyd Tested-by: Jessica Zhang # Trogdor (sc7180) --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 3a462e327e0e..a1b8c4592943 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1251,12 +1251,13 @@ static void dpu_encoder_vblank_callback(struct drm_encoder *drm_enc, DPU_ATRACE_BEGIN("encoder_vblank_callback"); dpu_enc = to_dpu_encoder_virt(drm_enc); + atomic_inc(_enc->vsync_cnt); + spin_lock_irqsave(_enc->enc_spinlock, lock_flags); if (dpu_enc->crtc) dpu_crtc_vblank_callback(dpu_enc->crtc); spin_unlock_irqrestore(_enc->enc_spinlock, lock_flags); - atomic_inc(_enc->vsync_cnt); DPU_ATRACE_END("encoder_vblank_callback"); } base-commit: f2906aa863381afb0015a9eb7fefad885d4e5a56 -- https://chromeos.dev
[PATCH v5 5/9] drm/bridge: anx7625: Add typec_mux_set callback function
From: Pin-Yen Lin Add the callback function when the driver receives state changes of the Type-C port. The callback function configures the crosspoint switch of the anx7625 bridge chip, which can change the output pins of the signals according to the port state. Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Nícolas F. R. A. Prado Tested-by: Nícolas F. R. A. Prado Signed-off-by: Pin-Yen Lin Signed-off-by: Prashant Malani --- Changes since v4: - Patch moved to 5/9 position (since Patch v4 1/7 and 2/7 were applied to usb-next). Changes since v3: - Added Reviewed-by tag from Angelo. Changes since v2: - Moved num_typec_switches check to beginning of function - Made dp_connected assignments fit on one line (and removed unnecessary parentheses) - Added Reviewed-by and Tested-by tags. Changes since v1: - No changes. drivers/gpu/drm/bridge/analogix/anx7625.c | 56 +++ drivers/gpu/drm/bridge/analogix/anx7625.h | 13 ++ 2 files changed, 69 insertions(+) diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index bd21f159b973..5992fc8beeeb 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -2582,9 +2583,64 @@ static void anx7625_runtime_disable(void *data) pm_runtime_disable(data); } +static void anx7625_set_crosspoint_switch(struct anx7625_data *ctx, + enum typec_orientation orientation) +{ + if (orientation == TYPEC_ORIENTATION_NORMAL) { + anx7625_reg_write(ctx, ctx->i2c.tcpc_client, TCPC_SWITCH_0, + SW_SEL1_SSRX_RX1 | SW_SEL1_DPTX0_RX2); + anx7625_reg_write(ctx, ctx->i2c.tcpc_client, TCPC_SWITCH_1, + SW_SEL2_SSTX_TX1 | SW_SEL2_DPTX1_TX2); + } else if (orientation == TYPEC_ORIENTATION_REVERSE) { + anx7625_reg_write(ctx, ctx->i2c.tcpc_client, TCPC_SWITCH_0, + SW_SEL1_SSRX_RX2 | SW_SEL1_DPTX0_RX1); + anx7625_reg_write(ctx, ctx->i2c.tcpc_client, TCPC_SWITCH_1, + SW_SEL2_SSTX_TX2 | SW_SEL2_DPTX1_TX1); + } +} + +static void anx7625_typec_two_ports_update(struct anx7625_data *ctx) +{ + if (ctx->typec_ports[0].dp_connected && ctx->typec_ports[1].dp_connected) + /* Both ports available, do nothing to retain the current one. */ + return; + else if (ctx->typec_ports[0].dp_connected) + anx7625_set_crosspoint_switch(ctx, TYPEC_ORIENTATION_NORMAL); + else if (ctx->typec_ports[1].dp_connected) + anx7625_set_crosspoint_switch(ctx, TYPEC_ORIENTATION_REVERSE); +} + static int anx7625_typec_mux_set(struct typec_mux_dev *mux, struct typec_mux_state *state) { + struct anx7625_port_data *data = typec_mux_get_drvdata(mux); + struct anx7625_data *ctx = data->ctx; + struct device *dev = >client->dev; + bool new_dp_connected, old_dp_connected; + + if (ctx->num_typec_switches == 1) + return 0; + + old_dp_connected = ctx->typec_ports[0].dp_connected || ctx->typec_ports[1].dp_connected; + + dev_dbg(dev, "mux_set dp_connected: c0=%d, c1=%d\n", + ctx->typec_ports[0].dp_connected, ctx->typec_ports[1].dp_connected); + + data->dp_connected = (state->alt && state->alt->svid == USB_TYPEC_DP_SID && + state->alt->mode == USB_TYPEC_DP_MODE); + + new_dp_connected = ctx->typec_ports[0].dp_connected || ctx->typec_ports[1].dp_connected; + + /* dp on, power on first */ + if (!old_dp_connected && new_dp_connected) + pm_runtime_get_sync(dev); + + anx7625_typec_two_ports_update(ctx); + + /* dp off, power off last */ + if (old_dp_connected && !new_dp_connected) + pm_runtime_put_sync(dev); + return 0; } diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.h b/drivers/gpu/drm/bridge/analogix/anx7625.h index 76cfc64f7574..7d6c6fdf9a3a 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.h +++ b/drivers/gpu/drm/bridge/analogix/anx7625.h @@ -55,6 +55,18 @@ #define HPD_STATUS_CHANGE 0x80 #define HPD_STATUS 0x80 +#define TCPC_SWITCH_0 0xB4 +#define SW_SEL1_DPTX0_RX2 BIT(0) +#define SW_SEL1_DPTX0_RX1 BIT(1) +#define SW_SEL1_SSRX_RX2 BIT(4) +#define SW_SEL1_SSRX_RX1 BIT(5) + +#define TCPC_SWITCH_1 0xB5 +#define SW_SEL2_DPTX1_TX2 BIT(0) +#define SW_SEL2_DPTX1_TX1 BIT(1) +#define SW_SEL2_SSTX_TX2 BIT(4) +#define SW_SEL2_SSTX_TX1 BIT(5) + / END of I2C Address 0x58 / /***/ @@ -444,6 +456,7 @@ struct anx7625_i2c_client { }; struct anx7625_port_data { + bool dp_connected; struct typec_mux_dev *typec_mux;
Re: [PATCH] drm/msm/dpu: Increment vsync_cnt before waking up userspace
On 22/06/2022 20:33, Rob Clark wrote: On Wed, Jun 22, 2022 at 10:24 AM Abhinav Kumar wrote: On 6/21/2022 7:38 PM, Stephen Boyd wrote: The 'vsync_cnt' is used to count the number of frames for a crtc. Unfortunately, we increment the count after waking up userspace via dpu_crtc_vblank_callback() calling drm_crtc_handle_vblank(). drm_crtc_handle_vblank() wakes up userspace processes that have called drm_wait_vblank_ioctl(), and if that ioctl is expecting the count to increase it won't. Increment the count before calling into the drm APIs so that we don't have to worry about ordering the increment with anything else in drm. This fixes a software video decode test that fails to see frame counts increase on Trogdor boards. Cc: Mark Yacoub Cc: Jessica Zhang Fixes: 885455d6bf82 ("drm/msm: Change dpu_crtc_get_vblank_counter to use vsync count.") Signed-off-by: Stephen Boyd This is right, we should increment before drm_crtc_handle_vblank() as that will query the vblank counter. This also matches what we do downstream, hence Reviewed-by: Abhinav Kumar One small nit though, shouldnt the fixes tag be 25fdd5933e4c ("drm/msm: Add SDM845 DPU support") *Kinda*.. but the sw vblank counter wasn't used for reporting frame nr to userspace until 885455d6bf82. You could possibly list both, perhaps, but 885455d6bf82 is the important one for folks backporting to stable kernels to be aware of I'd agree, the original Fixes tag seems good to me. Reviewed-by: Dmitry Baryshkov -- With best wishes Dmitry
[PATCH v5 4/9] drm/bridge: anx7625: Register Type-C mode switches
When the DT node has "switches" available, register a Type-C mode-switch for each listed "switch". This allows the driver to receive state information about what operating mode a Type-C port and its connected peripherals are in, as well as status information (like VDOs) related to that state. The callback function is currently a stub, but subsequent patches will implement the required functionality. Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Nícolas F. R. A. Prado Tested-by: Nícolas F. R. A. Prado Signed-off-by: Prashant Malani --- Changes since v4: - Added Reviewed-by tags. - Patch moved to 4/9 position (since Patch v4 1/7 and 2/7 were applied to usb-next). Changes since v3: - No changes. Changes since v2: - Updated dev_info() to dev_warn() print, but added a check to ensure it only triggers on non -ENODEV errors. - Made conflict resolutions resulting from changes introduced in Patch v3 5/7 (add ret variable here instead of in Patch v3 5/7). - Added Reviewed-by and Tested-by tags. Changes since v1: - No changes. drivers/gpu/drm/bridge/analogix/anx7625.c | 82 +-- drivers/gpu/drm/bridge/analogix/anx7625.h | 6 ++ 2 files changed, 84 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index e3d4c2738b8c..bd21f159b973 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -2581,10 +2582,61 @@ static void anx7625_runtime_disable(void *data) pm_runtime_disable(data); } +static int anx7625_typec_mux_set(struct typec_mux_dev *mux, +struct typec_mux_state *state) +{ + return 0; +} + +static int anx7625_register_mode_switch(struct device *dev, struct device_node *node, + struct anx7625_data *ctx) +{ + struct anx7625_port_data *port_data; + struct typec_mux_desc mux_desc = {}; + char name[32]; + u32 port_num; + int ret; + + ret = of_property_read_u32(node, "reg", _num); + if (ret) + return ret; + + if (port_num >= ctx->num_typec_switches) { + dev_err(dev, "Invalid port number specified: %d\n", port_num); + return -EINVAL; + } + + port_data = >typec_ports[port_num]; + port_data->ctx = ctx; + mux_desc.fwnode = >fwnode; + mux_desc.drvdata = port_data; + snprintf(name, sizeof(name), "%s-%u", node->name, port_num); + mux_desc.name = name; + mux_desc.set = anx7625_typec_mux_set; + + port_data->typec_mux = typec_mux_register(dev, _desc); + if (IS_ERR(port_data->typec_mux)) { + ret = PTR_ERR(port_data->typec_mux); + dev_err(dev, "Mode switch register for port %d failed: %d", port_num, ret); + } + + return ret; +} + +static void anx7625_unregister_typec_switches(struct anx7625_data *ctx) +{ + int i; + + for (i = 0; i < ctx->num_typec_switches; i++) + typec_mux_unregister(ctx->typec_ports[i].typec_mux); +} + static int anx7625_register_typec_switches(struct device *device, struct anx7625_data *ctx) { - struct device_node *of = of_get_child_by_name(device->of_node, "switches"); + struct device_node *of, *sw; + int ret = 0; + of = of_get_child_by_name(device->of_node, "switches"); if (!of) return -ENODEV; @@ -2592,7 +2644,27 @@ static int anx7625_register_typec_switches(struct device *device, struct anx7625 if (ctx->num_typec_switches <= 0) return -ENODEV; - return 0; + ctx->typec_ports = devm_kzalloc(device, + ctx->num_typec_switches * sizeof(struct anx7625_port_data), + GFP_KERNEL); + if (!ctx->typec_ports) + return -ENOMEM; + + /* Register switches for each connector. */ + for_each_available_child_of_node(of, sw) { + if (!of_property_read_bool(sw, "mode-switch")) + continue; + ret = anx7625_register_mode_switch(device, sw, ctx); + if (ret) { + dev_err(device, "Failed to register mode switch: %d\n", ret); + break; + } + } + + if (ret) + anx7625_unregister_typec_switches(ctx); + + return ret; } static int anx7625_i2c_probe(struct i2c_client *client, @@ -2701,8 +2773,8 @@ static int anx7625_i2c_probe(struct i2c_client *client, queue_work(platform->workqueue, >work); ret = anx7625_register_typec_switches(dev, platform); - if (ret) - dev_dbg(dev, "Didn't register Type C switches, err: %d\n", ret); + if (ret && ret != -ENODEV) + dev_warn(dev,
[PATCH v5 3/9] drm/bridge: anx7625: Register number of Type C switches
Parse the "switches" node, if available, and count and store the number of Type-C switches within it. Since we currently don't do anything with this info, no functional changes are expected from this change. This patch sets a foundation for the actual registering of Type-C switches with the Type-C connector class framework. Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Nícolas F. R. A. Prado Tested-by: Nícolas F. R. A. Prado Signed-off-by: Prashant Malani --- Changes since v4: - Added Reviewed-by tags. - Patch moved to 3/9 position (since Patch v4 1/7 and 2/7 were applied to usb-next). Changes since v3: - No changes. Changes since v2: - Move ret variable to Patch v3 6/7. - Make error print a dev_dbg, since it is noisy. - Added Reviewed-by and Tested-by tags. Changes since v1: - No changes. drivers/gpu/drm/bridge/analogix/anx7625.c | 18 ++ drivers/gpu/drm/bridge/analogix/anx7625.h | 1 + 2 files changed, 19 insertions(+) diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index 53a5da6c49dd..e3d4c2738b8c 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -2581,6 +2581,20 @@ static void anx7625_runtime_disable(void *data) pm_runtime_disable(data); } +static int anx7625_register_typec_switches(struct device *device, struct anx7625_data *ctx) +{ + struct device_node *of = of_get_child_by_name(device->of_node, "switches"); + + if (!of) + return -ENODEV; + + ctx->num_typec_switches = of_get_child_count(of); + if (ctx->num_typec_switches <= 0) + return -ENODEV; + + return 0; +} + static int anx7625_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -2686,6 +2700,10 @@ static int anx7625_i2c_probe(struct i2c_client *client, if (platform->pdata.intp_irq) queue_work(platform->workqueue, >work); + ret = anx7625_register_typec_switches(dev, platform); + if (ret) + dev_dbg(dev, "Didn't register Type C switches, err: %d\n", ret); + platform->bridge.funcs = _bridge_funcs; platform->bridge.of_node = client->dev.of_node; if (!anx7625_of_panel_on_aux_bus(>dev)) diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.h b/drivers/gpu/drm/bridge/analogix/anx7625.h index e257a84db962..d5cbca708842 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.h +++ b/drivers/gpu/drm/bridge/analogix/anx7625.h @@ -473,6 +473,7 @@ struct anx7625_data { struct drm_connector *connector; struct mipi_dsi_device *dsi; struct drm_dp_aux aux; + int num_typec_switches; }; #endif /* __ANX7625_H__ */ -- 2.37.0.rc0.104.g0611611a94-goog
[PATCH v5 2/9] dt-bindings: drm/bridge: anx7625: Add mode-switch support
Analogix 7625 can be used in systems to switch USB Type-C DisplayPort alternate mode lane traffic between 2 Type-C ports. Update the binding to accommodate this usage by introducing a switch property. Reviewed-by: Krzysztof Kozlowski Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Nícolas F. R. A. Prado Tested-by: Nícolas F. R. A. Prado Signed-off-by: Prashant Malani --- Changes since v4: - Added Reviewed-by tags. - Patch moved to 2/9 position (since Patch v4 1/7 and 2/7 were applied to usb-next). Changes since v3: - Fix unevaluatedProperties usage. - Add additionalProperties to top level "switches" nodes. - Make quotes consistent. - Add '^..$' to regex. (All suggested by Krzysztof Kozlowski) Changes since v2: - Added Reviewed-by and Tested-by tags. Changes since v1: - Introduced patternProperties for "switch" children (suggested by Krzysztof Kozlowski). - Added unevaluatedProperties descriptor (suggested by Krzysztof Kozlowski). - Added "address-cells" and "size-cells" properties to "switches". .../display/bridge/analogix,anx7625.yaml | 64 +++ 1 file changed, 64 insertions(+) diff --git a/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml b/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml index 35a48515836e..bc6f7644db31 100644 --- a/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml +++ b/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml @@ -105,6 +105,34 @@ properties: - port@0 - port@1 + switches: +type: object +description: Set of switches controlling DisplayPort traffic on + outgoing RX/TX lanes to Type C ports. +additionalProperties: false + +properties: + '#address-cells': +const: 1 + + '#size-cells': +const: 0 + +patternProperties: + '^switch@[01]$': +$ref: /schemas/usb/typec-switch.yaml# +unevaluatedProperties: false + +properties: + reg: +maxItems: 1 + +required: + - reg + +required: + - switch@0 + required: - compatible - reg @@ -167,5 +195,41 @@ examples: }; }; }; +switches { +#address-cells = <1>; +#size-cells = <0>; +switch@0 { +compatible = "typec-switch"; +reg = <0>; +mode-switch; + +ports { +#address-cells = <1>; +#size-cells = <0>; +port@0 { +reg = <0>; +anx_typec0: endpoint { +remote-endpoint = <_port0>; +}; +}; +}; +}; +switch@1 { +compatible = "typec-switch"; +reg = <1>; +mode-switch; + +ports { +#address-cells = <1>; +#size-cells = <0>; +port@0 { +reg = <0>; +anx_typec1: endpoint { +remote-endpoint = <_port1>; +}; +}; +}; +}; +}; }; }; -- 2.37.0.rc0.104.g0611611a94-goog
[PATCH v5 1/9] dt-bindings: usb: Add Type-C switch binding
Introduce a binding which represents a component that can control the routing of USB Type-C data lines as well as address data line orientation (based on CC lines' orientation). Reviewed-by: Krzysztof Kozlowski Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Nícolas F. R. A. Prado Tested-by: Nícolas F. R. A. Prado Signed-off-by: Prashant Malani --- Changes since v4: - Added Reviewed-by tags. - Patch moved to 1/9 position (since Patch v4 1/7 and 2/7 were applied to usb-next) Changes since v3: - No changes. Changes since v2: - Added Reviewed-by and Tested-by tags. Changes since v1: - Removed "items" from compatible. - Fixed indentation in example. .../devicetree/bindings/usb/typec-switch.yaml | 74 +++ 1 file changed, 74 insertions(+) create mode 100644 Documentation/devicetree/bindings/usb/typec-switch.yaml diff --git a/Documentation/devicetree/bindings/usb/typec-switch.yaml b/Documentation/devicetree/bindings/usb/typec-switch.yaml new file mode 100644 index ..78b0190c8543 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/typec-switch.yaml @@ -0,0 +1,74 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/usb/typec-switch.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: USB Type-C Switch + +maintainers: + - Prashant Malani + +description: + A USB Type-C switch represents a component which routes USB Type-C data + lines to various protocol host controllers (e.g USB, VESA DisplayPort, + Thunderbolt etc.) depending on which mode the Type-C port, port partner + and cable are operating in. It can also modify lane routing based on + the orientation of a connected Type-C peripheral. + +properties: + compatible: +const: typec-switch + + mode-switch: +type: boolean +description: Specify that this switch can handle alternate mode switching. + + orientation-switch: +type: boolean +description: Specify that this switch can handle orientation switching. + + ports: +$ref: /schemas/graph.yaml#/properties/ports +description: OF graph binding modelling data lines to the Type-C switch. + +properties: + port@0: +$ref: /schemas/graph.yaml#/properties/port +description: Link between the switch and a Type-C connector. + +required: + - port@0 + +required: + - compatible + - ports + +anyOf: + - required: + - mode-switch + - required: + - orientation-switch + +additionalProperties: true + +examples: + - | +drm-bridge { +usb-switch { +compatible = "typec-switch"; +mode-switch; +orientation-switch; +ports { +#address-cells = <1>; +#size-cells = <0>; + +port@0 { +reg = <0>; +anx_ep: endpoint { +remote-endpoint = <_controller>; +}; +}; +}; +}; +}; -- 2.37.0.rc0.104.g0611611a94-goog
[PATCH v5 0/9] usb: typec: Introduce typec-switch binding
This series introduces a binding for Type-C data lane switches. These control the routing and operating modes of USB Type-C data lanes based on the PD messaging from the Type-C port driver regarding connected peripherals. The first 2 patches introduce the new "typec-switch" binding as well as one user of it (the ANX7625 drm bridge). Patches 3-5 add functionality to the anx7625 driver to register the mode-switches, as well as program its crosspoint switch depending on which Type-C port has a DisplayPort (DP) peripheral connected to it. Patch 6-9 add similar bindings update and Type-C switch support to the it6505 driver. v4: https://lore.kernel.org/linux-usb/20220615172129.1314056-8-pmal...@chromium.org/ Changes in v5: - Rebased on usb-next, so removed Patch v4 1/7 and Patch v4 2/7 from this version (v5) since they are already in usb-next. - Added newer Reviewed-by tags. - Added new patches (6-9) in this version for a 2nd example (it6505) of a binding of the user. Patch submission suggestions: Option 1: - Bindings patches 1/9 and 2/9 can go through the USB repo (since they are already reviewed from v4 [1]). - Bindings patch 6/9 can go through the USB repo, and the remaining patches (3-5,7-9) can go through the DRM repo. - Patches 3-9 can all go through the DRM repo. Option 2: - All patches (1-9) go through the USB repo. (My apologies if I've made this confusing, and I appreciate any suggestions for better submission strategy). [1]: https://lore.kernel.org/linux-usb/yrmxfemc0tk%2fk...@kroah.com/ Pin-Yen Lin (5): drm/bridge: anx7625: Add typec_mux_set callback function dt/bindings: drm/bridge: it6505: Add mode-switch support drm/bridge: it6505: Register number of Type C switches drm/bridge: it6505: Register Type-C mode switches drm/bridge: it6505: Add typec_mux_set callback function Prashant Malani (4): dt-bindings: usb: Add Type-C switch binding dt-bindings: drm/bridge: anx7625: Add mode-switch support drm/bridge: anx7625: Register number of Type C switches drm/bridge: anx7625: Register Type-C mode switches .../display/bridge/analogix,anx7625.yaml | 64 +++ .../bindings/display/bridge/ite,it6505.yaml | 97 +- .../devicetree/bindings/usb/typec-switch.yaml | 74 drivers/gpu/drm/bridge/analogix/anx7625.c | 148 +++ drivers/gpu/drm/bridge/analogix/anx7625.h | 20 ++ drivers/gpu/drm/bridge/ite-it6505.c | 171 +- 6 files changed, 569 insertions(+), 5 deletions(-) create mode 100644 Documentation/devicetree/bindings/usb/typec-switch.yaml -- 2.37.0.rc0.104.g0611611a94-goog
Re: [PATCH] drm/msm/dpu: Increment vsync_cnt before waking up userspace
On Wed, Jun 22, 2022 at 10:24 AM Abhinav Kumar wrote: > > > > On 6/21/2022 7:38 PM, Stephen Boyd wrote: > > The 'vsync_cnt' is used to count the number of frames for a crtc. > > Unfortunately, we increment the count after waking up userspace via > > dpu_crtc_vblank_callback() calling drm_crtc_handle_vblank(). > > drm_crtc_handle_vblank() wakes up userspace processes that have called > > drm_wait_vblank_ioctl(), and if that ioctl is expecting the count to > > increase it won't. > > > > Increment the count before calling into the drm APIs so that we don't > > have to worry about ordering the increment with anything else in drm. > > This fixes a software video decode test that fails to see frame counts > > increase on Trogdor boards. > > > > Cc: Mark Yacoub > > Cc: Jessica Zhang > > Fixes: 885455d6bf82 ("drm/msm: Change dpu_crtc_get_vblank_counter to use > > vsync count.") > > Signed-off-by: Stephen Boyd > > This is right, we should increment before drm_crtc_handle_vblank() as > that will query the vblank counter. This also matches what we do > downstream, hence > > Reviewed-by: Abhinav Kumar > > One small nit though, shouldnt the fixes tag be > > 25fdd5933e4c ("drm/msm: Add SDM845 DPU support") *Kinda*.. but the sw vblank counter wasn't used for reporting frame nr to userspace until 885455d6bf82. You could possibly list both, perhaps, but 885455d6bf82 is the important one for folks backporting to stable kernels to be aware of BR, -R > > This code has been this way since that commit itself. > > > --- > > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 3 ++- > > 1 file changed, 2 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > > b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > > index 3a462e327e0e..a1b8c4592943 100644 > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > > @@ -1251,12 +1251,13 @@ static void dpu_encoder_vblank_callback(struct > > drm_encoder *drm_enc, > > DPU_ATRACE_BEGIN("encoder_vblank_callback"); > > dpu_enc = to_dpu_encoder_virt(drm_enc); > > > > + atomic_inc(_enc->vsync_cnt); > > + > > spin_lock_irqsave(_enc->enc_spinlock, lock_flags); > > if (dpu_enc->crtc) > > dpu_crtc_vblank_callback(dpu_enc->crtc); > > spin_unlock_irqrestore(_enc->enc_spinlock, lock_flags); > > > > - atomic_inc(_enc->vsync_cnt); > > DPU_ATRACE_END("encoder_vblank_callback"); > > } > > > > > > base-commit: f2906aa863381afb0015a9eb7fefad885d4e5a56
Re: How do I gather up new code to be converted as patches?
Generating a patch is "git format-patch". This command operates on commits in your local tree. So you need to commit your changes to your local tree. The command for that is "git commit", and it works on staged changes. To stage changes, you need to "git add" them. "git status" can help you visualize unstaged and staged changes. So, if I had a change in foo.txt, I would likely use "git status" to view that unstaged change. Then I can stage it using "git add foo.txt". "git status" will then show that it is staged. Finally, I will do "git commit", which will ask for a commit text, and commit the change to the tree. I can then verify that the change is committed using "git log". Does that help you out, or did I misunderstand your situation? -Jeff On Wed, Jun 22, 2022 at 11:19 AM Kevin Brace wrote: > > Hi, > > I spent about 2 days trying to figure this out, but I guess not a lot of > people do this, so I was not able to find a good example somewhere on the > Internet. > How to I use git to gather up new code to be converted to patches? > Specifically, I have 20+ new files in one location (drivers/gpu/drm/via) and > a small change to DRM main make file (drivers/gpu/drm/Makefile). > If someone can tell me how to do this, I will post the work on dri-devel. > > Regards, > > Kevin Brace > Brace Computer Laboratory blog > https://bracecomputerlab.com
Re: [PATCH 3/5] drm/amdgpu: Prevent race between late signaled fences and GPU reset.
Just a ping Andrey On 2022-06-21 15:45, Andrey Grodzovsky wrote: On 2022-06-21 03:25, Christian König wrote: Am 21.06.22 um 00:03 schrieb Andrey Grodzovsky: Problem: After we start handling timed out jobs we assume there fences won't be signaled but we cannot be sure and sometimes they fire late. We need to prevent concurrent accesses to fence array from amdgpu_fence_driver_clear_job_fences during GPU reset and amdgpu_fence_process from a late EOP interrupt. Fix: Before accessing fence array in GPU disable EOP interrupt and flush all pending interrupt handlers for amdgpu device's interrupt line. Signed-off-by: Andrey Grodzovsky --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 4 drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 26 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | 1 + 3 files changed, 31 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 2b92281dd0c1..c99541685804 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -4605,6 +4605,8 @@ int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev, amdgpu_virt_fini_data_exchange(adev); } + amdgpu_fence_driver_isr_toggle(adev, true); + /* block all schedulers and reset given job's ring */ for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { struct amdgpu_ring *ring = adev->rings[i]; @@ -4620,6 +4622,8 @@ int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev, amdgpu_fence_driver_force_completion(ring); } + amdgpu_fence_driver_isr_toggle(adev, false); + if (job && job->vm) drm_sched_increase_karma(>base); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c index a9ae3beaa1d3..d6d54ba4c185 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c @@ -532,6 +532,32 @@ void amdgpu_fence_driver_hw_fini(struct amdgpu_device *adev) } } +void amdgpu_fence_driver_isr_toggle(struct amdgpu_device *adev, bool stop) +{ + int i; + + for (i = 0; i < AMDGPU_MAX_RINGS; i++) { + struct amdgpu_ring *ring = adev->rings[i]; + + if (!ring || !ring->fence_drv.initialized || !ring->fence_drv.irq_src) + continue; + + if (stop) + amdgpu_irq_put(adev, ring->fence_drv.irq_src, + ring->fence_drv.irq_type); + else + amdgpu_irq_get(adev, ring->fence_drv.irq_src, + ring->fence_drv.irq_type); That won't work like this. This increments/decrements the reference count for the IRQ, but doesn't guarantee in any way that they are stopped/started. I understand that, i just assumed that the fence driver is the only holder of this interrupt source (e.g. regCP_INT_CNTL_RING0) ? I can disable amdgpu interrupt line totally using disable_irq - would this be better ? + } + + /* TODO Only waits for irq handlers on other CPUs, maybe local_irq_save + * local_irq_local_irq_restore are needed here for local interrupts ? + * + */ Well that comment made me smile. Think for a moment what the local CPU would be doing if an interrupt would run :) No, I understand this of course, I am ok to be interrupted by interrupt handler at this point, what i am trying to do is to prevent amdgpu_fence_process to run concurrently with amdgpu_fence_driver_clear_job_fences - that is what this function is trying to prevent - i disable and flush pending EOP ISR handlers before the call to clear fences and re-enable after. I guess we can also introduce a spinlock to serialize them ? Yiqing reported seeing a race between them so we have to do something. Andrey Cheers, Christian. + if (stop) + synchronize_irq(adev->irq.irq); +} + void amdgpu_fence_driver_sw_fini(struct amdgpu_device *adev) { unsigned int i, j; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h index 7d89a52091c0..82c178a9033a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h @@ -143,6 +143,7 @@ signed long amdgpu_fence_wait_polling(struct amdgpu_ring *ring, uint32_t wait_seq, signed long timeout); unsigned amdgpu_fence_count_emitted(struct amdgpu_ring *ring); +void amdgpu_fence_driver_isr_toggle(struct amdgpu_device *adev, bool stop); /* * Rings.
Re: [PATCH] drm/msm/dpu: Increment vsync_cnt before waking up userspace
On 6/21/2022 7:38 PM, Stephen Boyd wrote: The 'vsync_cnt' is used to count the number of frames for a crtc. Unfortunately, we increment the count after waking up userspace via dpu_crtc_vblank_callback() calling drm_crtc_handle_vblank(). drm_crtc_handle_vblank() wakes up userspace processes that have called drm_wait_vblank_ioctl(), and if that ioctl is expecting the count to increase it won't. Increment the count before calling into the drm APIs so that we don't have to worry about ordering the increment with anything else in drm. This fixes a software video decode test that fails to see frame counts increase on Trogdor boards. Cc: Mark Yacoub Cc: Jessica Zhang Fixes: 885455d6bf82 ("drm/msm: Change dpu_crtc_get_vblank_counter to use vsync count.") Signed-off-by: Stephen Boyd This is right, we should increment before drm_crtc_handle_vblank() as that will query the vblank counter. This also matches what we do downstream, hence Reviewed-by: Abhinav Kumar One small nit though, shouldnt the fixes tag be 25fdd5933e4c ("drm/msm: Add SDM845 DPU support") This code has been this way since that commit itself. --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 3a462e327e0e..a1b8c4592943 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1251,12 +1251,13 @@ static void dpu_encoder_vblank_callback(struct drm_encoder *drm_enc, DPU_ATRACE_BEGIN("encoder_vblank_callback"); dpu_enc = to_dpu_encoder_virt(drm_enc); + atomic_inc(_enc->vsync_cnt); + spin_lock_irqsave(_enc->enc_spinlock, lock_flags); if (dpu_enc->crtc) dpu_crtc_vblank_callback(dpu_enc->crtc); spin_unlock_irqrestore(_enc->enc_spinlock, lock_flags); - atomic_inc(_enc->vsync_cnt); DPU_ATRACE_END("encoder_vblank_callback"); } base-commit: f2906aa863381afb0015a9eb7fefad885d4e5a56
Re: [PATCH 5/5] drm/amdgpu: Follow up change to previous drm scheduler change.
On 2022-06-22 03:17, Christian König wrote: Am 21.06.22 um 22:00 schrieb Andrey Grodzovsky: On 2022-06-21 03:28, Christian König wrote: Am 21.06.22 um 00:03 schrieb Andrey Grodzovsky: Align refcount behaviour for amdgpu_job embedded HW fence with classic pointer style HW fences by increasing refcount each time emit is called so amdgpu code doesn't need to make workarounds using amdgpu_job.job_run_counter to keep the HW fence refcount balanced. Could we now also remove job_run_counter? Christian. I am afraid not, job counter is needed since at all times the refcount on the embedded fence cannot drop to zero because this will free the job itself before the end of it's life cycle. We have to be able to differentiate in amdgpu_fence_emit between first ever call where we init the embedded fence's refcount from scratch using kref_init to repeating calls when refcount already > 0 and we just fake increase the refcount to align behavior with pointer style fences in other drivers. Well what we should probably rather do is move the init out of emit instead. The only down side I can see is that the sequence number isn't know on initial init and so needs to be zero or something like that. Regards, Christian. Not sure how this help, the problem is not there but in amdgpu_job_run, for embedded fence and resubmit job in pending list amdgpu_job_run will be called twice or even 3 times with recheck guilty job sequence. I am supposed to do dma_fence_init to embeded HW fence only on first call while on second and third only update sequence_num and increase refcount. How can i differentiate between first and non first calls without job_run_counter ? Andrey I guess we could assume that embedded fence is all zeroes before first dma_fence_init if assuming the job itself was allocated using kzalloc and so u can look at dma_fence_ops == NULL or maybe seqno == 0 as a hint if that the fist call or not but it's a risky assumption in my opinion. Andrey Also since in the previous patch we resumed setting s_fence->parent to NULL in drm_sched_stop switch to directly checking if job->hw_fence is signaled to short circuit reset if already signed. Signed-off-by: Andrey Grodzovsky Tested-by: Yiqing Yao --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c | 2 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 23 -- drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 7 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 4 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c index 513c57f839d8..447bd92c4856 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c @@ -684,6 +684,8 @@ int amdgpu_amdkfd_submit_ib(struct amdgpu_device *adev, goto err_ib_sched; } + /* Drop the initial kref_init count (see drm_sched_main as example) */ + dma_fence_put(f); ret = dma_fence_wait(f, false); err_ib_sched: diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index c99541685804..f9718119834f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -5009,16 +5009,28 @@ static void amdgpu_device_recheck_guilty_jobs( /* clear job's guilty and depend the folowing step to decide the real one */ drm_sched_reset_karma(s_job); - /* for the real bad job, it will be resubmitted twice, adding a dma_fence_get - * to make sure fence is balanced */ - dma_fence_get(s_job->s_fence->parent); drm_sched_resubmit_jobs_ext(>sched, 1); + if (!s_job->s_fence->parent) { + DRM_WARN("Failed to get a HW fence for job!"); + continue; + } + ret = dma_fence_wait_timeout(s_job->s_fence->parent, false, ring->sched.timeout); if (ret == 0) { /* timeout */ DRM_ERROR("Found the real bad job! ring:%s, job_id:%llx\n", ring->sched.name, s_job->id); + + /* Clear this failed job from fence array */ + amdgpu_fence_driver_clear_job_fences(ring); + + /* Since the job won't signal and we go for + * another resubmit drop this parent pointer + */ + dma_fence_put(s_job->s_fence->parent); + s_job->s_fence->parent = NULL; + /* set guilty */ drm_sched_increase_karma(s_job); retry: @@ -5047,7 +5059,6 @@ static void amdgpu_device_recheck_guilty_jobs( /* got the hw fence, signal finished fence */ atomic_dec(ring->sched.score); - dma_fence_put(s_job->s_fence->parent); dma_fence_get(_job->s_fence->finished); dma_fence_signal(_job->s_fence->finished); dma_fence_put(_job->s_fence->finished); @@ -5220,8 +5231,8 @@ int amdgpu_device_gpu_recover(struct
How do I gather up new code to be converted as patches?
Hi, I spent about 2 days trying to figure this out, but I guess not a lot of people do this, so I was not able to find a good example somewhere on the Internet. How to I use git to gather up new code to be converted to patches? Specifically, I have 20+ new files in one location (drivers/gpu/drm/via) and a small change to DRM main make file (drivers/gpu/drm/Makefile). If someone can tell me how to do this, I will post the work on dri-devel. Regards, Kevin Brace Brace Computer Laboratory blog https://bracecomputerlab.com
[PATCH v4 4/4] drm/msm/dpu: Add interface support for CRC debugfs
Add support for writing CRC values for the interface block to the debugfs by calling the necessary MISR setup/collect methods. Changes since V1: - Set values_cnt to only include phys with backing hw_intf - Loop over all drm_encs connected to crtc Changes since V2: - Remove vblank.h inclusion - Change `pos + i` to `pos + entries` - Initialize values_cnt to 0 for encoder - Change DPU_CRTC_CRC_SOURCE_INTF to DPU_CRTC_CRC_SOURCE_ENCODER (and "intf" to "enc") - Change dpu_encoder_get_num_phys to dpu_encoder_get_num_hw_intfs - Add checks for setup_misr and collect_misr in dpu_encoder_get_num_hw_intfs Changes since V3: - Remove extra whitespace - Change "enc" to "encoder" - Move crcs array to dpu_crtc_get_encoder_crc - Rename dpu_encoder_get_num_hw_intfs to dpu_encoder_get_crc_values_cnt Signed-off-by: Jessica Zhang --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c| 46 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h| 3 + drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 64 + drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 22 +++ 4 files changed, 134 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index b57140c3671a..4dd0ce09ca74 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -79,6 +79,8 @@ static enum dpu_crtc_crc_source dpu_crtc_parse_crc_source(const char *src_name) if (!strcmp(src_name, "auto") || !strcmp(src_name, "lm")) return DPU_CRTC_CRC_SOURCE_LAYER_MIXER; + if (!strcmp(src_name, "encoder")) + return DPU_CRTC_CRC_SOURCE_ENCODER; return DPU_CRTC_CRC_SOURCE_INVALID; } @@ -94,8 +96,16 @@ static int dpu_crtc_verify_crc_source(struct drm_crtc *crtc, return -EINVAL; } - if (source == DPU_CRTC_CRC_SOURCE_LAYER_MIXER) + if (source == DPU_CRTC_CRC_SOURCE_LAYER_MIXER) { *values_cnt = crtc_state->num_mixers; + } else if (source == DPU_CRTC_CRC_SOURCE_ENCODER) { + struct drm_encoder *drm_enc; + + *values_cnt = 0; + + drm_for_each_encoder_mask(drm_enc, crtc->dev, crtc->state->encoder_mask) + *values_cnt += dpu_encoder_get_crc_values_cnt(drm_enc); + } return 0; } @@ -116,6 +126,14 @@ static void dpu_crtc_setup_lm_misr(struct dpu_crtc_state *crtc_state) } } +static void dpu_crtc_setup_encoder_misr(struct drm_crtc *crtc) +{ + struct drm_encoder *drm_enc; + + drm_for_each_encoder_mask(drm_enc, crtc->dev, crtc->state->encoder_mask) + dpu_encoder_setup_misr(drm_enc); +} + static int dpu_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name) { enum dpu_crtc_crc_source source = dpu_crtc_parse_crc_source(src_name); @@ -164,6 +182,8 @@ static int dpu_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name) if (source == DPU_CRTC_CRC_SOURCE_LAYER_MIXER) dpu_crtc_setup_lm_misr(crtc_state); + else if (source == DPU_CRTC_CRC_SOURCE_ENCODER) + dpu_crtc_setup_encoder_misr(crtc); else ret = -EINVAL; @@ -215,6 +235,28 @@ static int dpu_crtc_get_lm_crc(struct drm_crtc *crtc, drm_crtc_accurate_vblank_count(crtc), crcs); } +static int dpu_crtc_get_encoder_crc(struct drm_crtc *crtc) +{ + struct drm_encoder *drm_enc; + int rc, pos = 0; + u32 crcs[INTF_MAX]; + + drm_for_each_encoder_mask(drm_enc, crtc->dev, crtc->state->encoder_mask) { + rc = dpu_encoder_get_crc(drm_enc, crcs, pos); + if (rc < 0) { + if (rc != -ENODATA) + DRM_DEBUG_DRIVER("MISR read failed\n"); + + return rc; + } + + pos += rc; + } + + return drm_crtc_add_crc_entry(crtc, true, + drm_crtc_accurate_vblank_count(crtc), crcs); +} + static int dpu_crtc_get_crc(struct drm_crtc *crtc) { struct dpu_crtc_state *crtc_state = to_dpu_crtc_state(crtc->state); @@ -227,6 +269,8 @@ static int dpu_crtc_get_crc(struct drm_crtc *crtc) if (crtc_state->crc_source == DPU_CRTC_CRC_SOURCE_LAYER_MIXER) return dpu_crtc_get_lm_crc(crtc, crtc_state); + else if (crtc_state->crc_source == DPU_CRTC_CRC_SOURCE_ENCODER) + return dpu_crtc_get_encoder_crc(crtc); return -EINVAL; } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h index 20df23fe74ed..af03277a3e5a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2021 The Linux Foundation. All rights
[PATCH v4 3/4] drm/msm/dpu: Add MISR register support for interface
Add support for setting MISR registers within the interface Changes since V1: - Replaced dpu_hw_intf collect_misr and setup_misr implementations with calls to dpu_hw_utils helper methods Signed-off-by: Jessica Zhang Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 19 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h | 8 +++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c index 3f4d2c6e1b45..b37eeea36532 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c @@ -1,5 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. +/* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ #include "dpu_hwio.h" @@ -67,6 +69,9 @@ #define INTF_CFG2_DATABUS_WIDENBIT(0) #define INTF_CFG2_DATA_HCTL_EN BIT(4) +#define INTF_MISR_CTRL 0x180 +#define INTF_MISR_SIGNATURE0x184 + static const struct dpu_intf_cfg *_intf_offset(enum dpu_intf intf, const struct dpu_mdss_cfg *m, void __iomem *addr, @@ -319,6 +324,16 @@ static u32 dpu_hw_intf_get_line_count(struct dpu_hw_intf *intf) return DPU_REG_READ(c, INTF_LINE_COUNT); } +static void dpu_hw_intf_setup_misr(struct dpu_hw_intf *intf, bool enable, u32 frame_count) +{ + dpu_hw_setup_misr(>hw, INTF_MISR_CTRL, enable, frame_count); +} + +static int dpu_hw_intf_collect_misr(struct dpu_hw_intf *intf, u32 *misr_value) +{ + return dpu_hw_collect_misr(>hw, INTF_MISR_CTRL, INTF_MISR_SIGNATURE, misr_value); +} + static void _setup_intf_ops(struct dpu_hw_intf_ops *ops, unsigned long cap) { @@ -329,6 +344,8 @@ static void _setup_intf_ops(struct dpu_hw_intf_ops *ops, ops->get_line_count = dpu_hw_intf_get_line_count; if (cap & BIT(DPU_INTF_INPUT_CTRL)) ops->bind_pingpong_blk = dpu_hw_intf_bind_pingpong_blk; + ops->setup_misr = dpu_hw_intf_setup_misr; + ops->collect_misr = dpu_hw_intf_collect_misr; } struct dpu_hw_intf *dpu_hw_intf_init(enum dpu_intf idx, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h index 7b2d96ac61e8..8d0e7b509260 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. +/* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ #ifndef _DPU_HW_INTF_H @@ -57,6 +59,8 @@ struct intf_status { * @ get_line_count: reads current vertical line counter * @bind_pingpong_blk: enable/disable the connection with pingpong which will * feed pixels to this interface + * @setup_misr: enable/disable MISR + * @collect_misr: read MISR signature */ struct dpu_hw_intf_ops { void (*setup_timing_gen)(struct dpu_hw_intf *intf, @@ -77,6 +81,8 @@ struct dpu_hw_intf_ops { void (*bind_pingpong_blk)(struct dpu_hw_intf *intf, bool enable, const enum dpu_pingpong pp); + void (*setup_misr)(struct dpu_hw_intf *intf, bool enable, u32 frame_count); + int (*collect_misr)(struct dpu_hw_intf *intf, u32 *misr_value); }; struct dpu_hw_intf { -- 2.35.1
[PATCH v4 2/4] drm/msm/dpu: Move MISR methods to dpu_hw_util
Move layer mixer specific MISR methods to generalized helper methods. This will make it easier to add CRC support for other blocks in the future. Changes since V2: - Reordered parameters so that offsets are after hw_blk_reg_map - Fixed mismatched whitespace in bitmask definitions Signed-off-by: Jessica Zhang Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c | 42 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c | 49 - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h | 16 +++ 3 files changed, 67 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c index 462f5082099e..e370dcd76e17 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. */ @@ -27,11 +28,6 @@ #define LM_MISR_CTRL 0x310 #define LM_MISR_SIGNATURE0x314 -#define LM_MISR_FRAME_COUNT_MASK 0xFF -#define LM_MISR_CTRL_ENABLE BIT(8) -#define LM_MISR_CTRL_STATUS BIT(9) -#define LM_MISR_CTRL_STATUS_CLEARBIT(10) -#define LM_MISR_CTRL_FREE_RUN_MASK BIT(31) static const struct dpu_lm_cfg *_lm_offset(enum dpu_lm mixer, @@ -108,44 +104,12 @@ static void dpu_hw_lm_setup_border_color(struct dpu_hw_mixer *ctx, static void dpu_hw_lm_setup_misr(struct dpu_hw_mixer *ctx, bool enable, u32 frame_count) { - struct dpu_hw_blk_reg_map *c = >hw; - u32 config = 0; - - DPU_REG_WRITE(c, LM_MISR_CTRL, LM_MISR_CTRL_STATUS_CLEAR); - - /* Clear old MISR value (in case it's read before a new value is calculated)*/ - wmb(); - - if (enable) { - config = (frame_count & LM_MISR_FRAME_COUNT_MASK) | - LM_MISR_CTRL_ENABLE | LM_MISR_CTRL_FREE_RUN_MASK; - - DPU_REG_WRITE(c, LM_MISR_CTRL, config); - } else { - DPU_REG_WRITE(c, LM_MISR_CTRL, 0); - } - + dpu_hw_setup_misr(>hw, LM_MISR_CTRL, enable, frame_count); } static int dpu_hw_lm_collect_misr(struct dpu_hw_mixer *ctx, u32 *misr_value) { - struct dpu_hw_blk_reg_map *c = >hw; - u32 ctrl = 0; - - if (!misr_value) - return -EINVAL; - - ctrl = DPU_REG_READ(c, LM_MISR_CTRL); - - if (!(ctrl & LM_MISR_CTRL_ENABLE)) - return -ENODATA; - - if (!(ctrl & LM_MISR_CTRL_STATUS)) - return -EINVAL; - - *misr_value = DPU_REG_READ(c, LM_MISR_SIGNATURE); - - return 0; + return dpu_hw_collect_misr(>hw, LM_MISR_CTRL, LM_MISR_SIGNATURE, misr_value); } static void dpu_hw_lm_setup_blend_config_sdm845(struct dpu_hw_mixer *ctx, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c index 512316f25a51..a679757159e9 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c @@ -1,5 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. +/* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ #define pr_fmt(fmt)"[drm:%s:%d] " fmt, __func__, __LINE__ @@ -447,3 +449,48 @@ u64 _dpu_hw_get_qos_lut(const struct dpu_qos_lut_tbl *tbl, return 0; } + +void dpu_hw_setup_misr(struct dpu_hw_blk_reg_map *c, + u32 misr_ctrl_offset, + bool enable, u32 frame_count) +{ + u32 config = 0; + + DPU_REG_WRITE(c, misr_ctrl_offset, MISR_CTRL_STATUS_CLEAR); + + /* Clear old MISR value (in case it's read before a new value is calculated)*/ + wmb(); + + if (enable) { + config = (frame_count & MISR_FRAME_COUNT_MASK) | + MISR_CTRL_ENABLE | MISR_CTRL_FREE_RUN_MASK; + + DPU_REG_WRITE(c, misr_ctrl_offset, config); + } else { + DPU_REG_WRITE(c, misr_ctrl_offset, 0); + } + +} + +int dpu_hw_collect_misr(struct dpu_hw_blk_reg_map *c, + u32 misr_ctrl_offset, + u32 misr_signature_offset, + u32 *misr_value) +{ + u32 ctrl = 0; + + if (!misr_value) + return -EINVAL; + + ctrl = DPU_REG_READ(c, misr_ctrl_offset); + + if (!(ctrl & MISR_CTRL_ENABLE)) + return -ENODATA; + + if (!(ctrl & MISR_CTRL_STATUS)) + return -EINVAL; + + *misr_value = DPU_REG_READ(c, misr_signature_offset); + + return 0; +} diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h index e4a65eb4f769..98f1be0d2559 100644 ---
[PATCH v4 1/4] drm/msm/dpu: Move LM CRC code into separate method
Move layer mixer-specific section of dpu_crtc_get_crc() into a separate helper method. This way, we can make it easier to get CRCs from other HW blocks by adding other get_crc helper methods. Changes since V1: - Move common bitmasks to dpu_hw_util.h - Move common CRC methods to dpu_hw_util.c - Update copyrights - Change crcs array to a dynamically allocated array and added it as a member of crtc_state Changes since V2: - Put changes for hw_util into a separate commit - Revert crcs array to a static array - Add else case for set_crc_source to return EINVAL if no valid source is selected - Add DPU_CRTC_MAX_CRC_ENTRIES macro Changes since V3: - Move crcs array into dpu_crtc_get_lm_crc - Remove comment about crcs array in dpu_crtc_state struct - Revert `lm` rename - Remove DPU_CRTC_MAX_CRC_ENTRIES macro - Return EINVAL in dpu_crtc_get_crc if no valid CRC source is set Signed-off-by: Jessica Zhang --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 65 +++- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 2 + 2 files changed, 43 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index b56f777dbd0e..b57140c3671a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark @@ -99,17 +100,32 @@ static int dpu_crtc_verify_crc_source(struct drm_crtc *crtc, return 0; } +static void dpu_crtc_setup_lm_misr(struct dpu_crtc_state *crtc_state) +{ + struct dpu_crtc_mixer *m; + int i; + + for (i = 0; i < crtc_state->num_mixers; ++i) { + m = _state->mixers[i]; + + if (!m->hw_lm || !m->hw_lm->ops.setup_misr) + continue; + + /* Calculate MISR over 1 frame */ + m->hw_lm->ops.setup_misr(m->hw_lm, true, 1); + } +} + static int dpu_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name) { enum dpu_crtc_crc_source source = dpu_crtc_parse_crc_source(src_name); enum dpu_crtc_crc_source current_source; struct dpu_crtc_state *crtc_state; struct drm_device *drm_dev = crtc->dev; - struct dpu_crtc_mixer *m; bool was_enabled; bool enable = false; - int i, ret = 0; + int ret = 0; if (source < 0) { DRM_DEBUG_DRIVER("Invalid CRC source %s for CRTC%d\n", src_name, crtc->index); @@ -146,16 +162,10 @@ static int dpu_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name) crtc_state->crc_frame_skip_count = 0; - for (i = 0; i < crtc_state->num_mixers; ++i) { - m = _state->mixers[i]; - - if (!m->hw_lm || !m->hw_lm->ops.setup_misr) - continue; - - /* Calculate MISR over 1 frame */ - m->hw_lm->ops.setup_misr(m->hw_lm, true, 1); - } - + if (source == DPU_CRTC_CRC_SOURCE_LAYER_MIXER) + dpu_crtc_setup_lm_misr(crtc_state); + else + ret = -EINVAL; cleanup: drm_modeset_unlock(>mutex); @@ -174,26 +184,17 @@ static u32 dpu_crtc_get_vblank_counter(struct drm_crtc *crtc) return dpu_encoder_get_vsync_count(encoder); } - -static int dpu_crtc_get_crc(struct drm_crtc *crtc) +static int dpu_crtc_get_lm_crc(struct drm_crtc *crtc, + struct dpu_crtc_state *crtc_state) { - struct dpu_crtc_state *crtc_state; struct dpu_crtc_mixer *m; u32 crcs[CRTC_DUAL_MIXERS]; - int i = 0; int rc = 0; - - crtc_state = to_dpu_crtc_state(crtc->state); + int i; BUILD_BUG_ON(ARRAY_SIZE(crcs) != ARRAY_SIZE(crtc_state->mixers)); - /* Skip first 2 frames in case of "uncooked" CRCs */ - if (crtc_state->crc_frame_skip_count < 2) { - crtc_state->crc_frame_skip_count++; - return 0; - } - for (i = 0; i < crtc_state->num_mixers; ++i) { m = _state->mixers[i]; @@ -214,6 +215,22 @@ static int dpu_crtc_get_crc(struct drm_crtc *crtc) drm_crtc_accurate_vblank_count(crtc), crcs); } +static int dpu_crtc_get_crc(struct drm_crtc *crtc) +{ + struct dpu_crtc_state *crtc_state = to_dpu_crtc_state(crtc->state); + + /* Skip first 2 frames in case of "uncooked" CRCs */ + if (crtc_state->crc_frame_skip_count < 2) { + crtc_state->crc_frame_skip_count++; + return 0; + } + + if (crtc_state->crc_source == DPU_CRTC_CRC_SOURCE_LAYER_MIXER) + return dpu_crtc_get_lm_crc(crtc, crtc_state); + + return -EINVAL; +} + static bool dpu_crtc_get_scanout_position(struct drm_crtc *crtc,
[PATCH v4 0/4] Expand CRC to support interface blocks
Refactor existing CRC code for layer mixer and add CRC support for interface blocks Changes since V1: - Create helper methods for collect_misr and setup_misr in dpu_hw_util.c - Move common bitmasks into dpu_hw_util.h - Update copyrights - Create a dynamically allocated crcs array in dpu_crtc_state - Collect CRCs for all drm_encoders connected to the crtc Changes since V2: - Separate dpu_hw_util changes into a separate patch - Revert back to using a static array and define a macro for MAX_CRC_ENTRIES Changes since V3: - Move crcs array into block-specific get_crc helper methods - Rename "enc" source string to "encoder" Jessica Zhang (4): drm/msm/dpu: Move LM CRC code into separate method drm/msm/dpu: Move MISR methods to dpu_hw_util drm/msm/dpu: Add MISR register support for interface drm/msm/dpu: Add interface support for CRC debugfs drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c| 111 +++- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h| 5 + drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 64 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 22 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 19 +++- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h | 8 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c | 42 +--- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c | 49 - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h | 16 +++ 9 files changed, 269 insertions(+), 67 deletions(-) -- 2.35.1
[PATCH] drm/msm/dp: reset drm_dev to NULL at dp_display_unbind()
During msm initialize phase, dp_display_unbind() will be called to undo initializations had been done by dp_display_bind() previously if there is error happen at msm_drm_bind. Under this kind of circumstance, drm_device may not be populated completed which causes system crash at drm_dev_dbg(). This patch reset drm_dev to NULL so that following drm_dev_dbg() will not refer to any internal fields of drm_device to prevent system from crashing. Below are panic stack trace, [ 53.584904] Unable to handle kernel paging request at virtual address 70018001 . [ 53.702212] Hardware name: Qualcomm Technologies, Inc. sc7280 CRD platform (rev5+) (DT) [ 53.710445] pstate: 2049 (nzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 53.717596] pc : string_nocheck+0x1c/0x64 [ 53.721738] lr : string+0x54/0x60 [ 53.725162] sp : ffc013d6b650 [ 53.728590] pmr_save: 00e0 [ 53.731743] x29: ffc013d6b650 x28: 0002 x27: 00ff [ 53.739083] x26: ffc013d6b710 x25: ffd07a066ae0 x24: ffd07a419f97 [ 53.746420] x23: ffd07a419f99 x22: ff81fef360d4 x21: ff81fef364d4 [ 53.753760] x20: ffc013d6b6f8 x19: ffd07a06683c x18: [ 53.761093] x17: 4020386678302f30 x16: 00b0 x15: ffd0797523c8 [ 53.768429] x14: 0004 x13: ff00 x12: ffd07a066b2c [ 53.775780] x11: x10: 013c x9 : [ 53.783117] x8 : ff81fef364d4 x7 : x6 : [ 53.790445] x5 : x4 : 0a00ff04 x3 : 0a00ff04 [ 53.797783] x2 : 70018001 x1 : x0 : ff81fef360d4 [ 53.805136] Call trace: [ 53.807667] string_nocheck+0x1c/0x64 [ 53.811439] string+0x54/0x60 [ 53.814498] vsnprintf+0x374/0x53c [ 53.818009] pointer+0x3dc/0x40c [ 53.821340] vsnprintf+0x398/0x53c [ 53.824854] vscnprintf+0x3c/0x88 [ 53.828274] __trace_array_vprintk+0xcc/0x2d4 [ 53.832768] trace_array_printk+0x8c/0xb4 [ 53.836900] drm_trace_printf+0x74/0x9c [ 53.840875] drm_dev_dbg+0xfc/0x1b8 [ 53.844480] dp_pm_suspend+0x70/0xf8 [ 53.848164] dpm_run_callback+0x60/0x1a0 [ 53.85] __device_suspend+0x304/0x3f4 [ 53.856363] dpm_suspend+0xf8/0x3a8 [ 53.859959] dpm_suspend_start+0x8c/0xc0 Signed-off-by: Kuogee Hsieh --- drivers/gpu/drm/msm/dp/dp_display.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 2b72639..02fff70 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -316,6 +316,8 @@ static void dp_display_unbind(struct device *dev, struct device *master, dp_power_client_deinit(dp->power); dp_aux_unregister(dp->aux); + dp->drm_dev = NULL; + dp->aux->drm_dev = NULL; priv->dp[dp->id] = NULL; } -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
Re: [PATCH v1 0/9] drm/bridge: ps8640 and ti-sn65dsi86 updates
Hi Kieran, On Wed, Jun 22, 2022 at 11:07:26AM +0100, Kieran Bingham wrote: > Hi Sam, > > Quoting Sam Ravnborg (2022-02-06 19:09:11) > > > > > > The code builds - but needs testing. > > > > Hrmff, no it does not build. The fixes was by accident not included. > > Will wait a bit for feedback before posting a v2. > > > > Sam > > Do you have any plan to send a v2 on this series? > > I have built up a series to extend the ti-sn65dsi86 which is now based > on this. (which means I'll have an implied Tested-by: tag for these as > well). That is too good not to do something about it. I will give it a spin this weekend - I do not have time until then. Sam
Re: [Intel-gfx] [PATCH v3 3/3] drm/doc/rfc: VM_BIND uapi definition
On Wed, Jun 22, 2022 at 04:57:17PM +0100, Tvrtko Ursulin wrote: On 22/06/2022 16:12, Niranjana Vishwanathapura wrote: On Wed, Jun 22, 2022 at 09:10:07AM +0100, Tvrtko Ursulin wrote: On 22/06/2022 04:56, Niranjana Vishwanathapura wrote: VM_BIND and related uapi definitions v2: Reduce the scope to simple Mesa use case. v3: Expand VM_UNBIND documentation and add I915_GEM_VM_BIND/UNBIND_FENCE_VALID and I915_GEM_VM_BIND_TLB_FLUSH flags. Signed-off-by: Niranjana Vishwanathapura --- Documentation/gpu/rfc/i915_vm_bind.h | 243 +++ 1 file changed, 243 insertions(+) create mode 100644 Documentation/gpu/rfc/i915_vm_bind.h diff --git a/Documentation/gpu/rfc/i915_vm_bind.h b/Documentation/gpu/rfc/i915_vm_bind.h new file mode 100644 index ..fa23b2d7ec6f --- /dev/null +++ b/Documentation/gpu/rfc/i915_vm_bind.h @@ -0,0 +1,243 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2022 Intel Corporation + */ + +/** + * DOC: I915_PARAM_HAS_VM_BIND + * + * VM_BIND feature availability. + * See typedef drm_i915_getparam_t param. + */ +#define I915_PARAM_HAS_VM_BIND 57 + +/** + * DOC: I915_VM_CREATE_FLAGS_USE_VM_BIND + * + * Flag to opt-in for VM_BIND mode of binding during VM creation. + * See struct drm_i915_gem_vm_control flags. + * + * The older execbuf2 ioctl will not support VM_BIND mode of operation. + * For VM_BIND mode, we have new execbuf3 ioctl which will not accept any + * execlist (See struct drm_i915_gem_execbuffer3 for more details). + * + */ +#define I915_VM_CREATE_FLAGS_USE_VM_BIND (1 << 0) + +/* VM_BIND related ioctls */ +#define DRM_I915_GEM_VM_BIND 0x3d +#define DRM_I915_GEM_VM_UNBIND 0x3e +#define DRM_I915_GEM_EXECBUFFER3 0x3f + +#define DRM_IOCTL_I915_GEM_VM_BIND DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_VM_BIND, struct drm_i915_gem_vm_bind) +#define DRM_IOCTL_I915_GEM_VM_UNBIND DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_VM_UNBIND, struct drm_i915_gem_vm_bind) +#define DRM_IOCTL_I915_GEM_EXECBUFFER3 DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER3, struct drm_i915_gem_execbuffer3) + +/** + * struct drm_i915_gem_vm_bind_fence - Bind/unbind completion notification. + * + * A timeline out fence for vm_bind/unbind completion notification. + */ +struct drm_i915_gem_vm_bind_fence { + /** @handle: User's handle for a drm_syncobj to signal. */ + __u32 handle; + + /** @rsvd: Reserved, MBZ */ + __u32 rsvd; + + /** + * @value: A point in the timeline. + * Value must be 0 for a binary drm_syncobj. A Value of 0 for a + * timeline drm_syncobj is invalid as it turns a drm_syncobj into a + * binary one. + */ + __u64 value; +}; + +/** + * struct drm_i915_gem_vm_bind - VA to object mapping to bind. + * + * This structure is passed to VM_BIND ioctl and specifies the mapping of GPU + * virtual address (VA) range to the section of an object that should be bound + * in the device page table of the specified address space (VM). + * The VA range specified must be unique (ie., not currently bound) and can + * be mapped to whole object or a section of the object (partial binding). + * Multiple VA mappings can be created to the same section of the object + * (aliasing). + * + * The @start, @offset and @length should be 4K page aligned. However the DG2 + * and XEHPSDV has 64K page size for device local-memory and has compact page + * table. On those platforms, for binding device local-memory objects, the + * @start should be 2M aligned, @offset and @length should be 64K aligned. Should some error codes be documented and has the ability to programmatically probe the alignment restrictions been considered? Currently what we have internally is that -EINVAL is returned if the sart, offset and length are not aligned. If the specified mapping already exits, we return -EEXIST. If there are conflicts in the VA range and VA range can't be reserved, then -ENOSPC is returned. I can add this documentation here. But I am worried that there will be more suggestions/feedback about error codes while reviewing the code patch series, and we have to revisit it again. I'd still suggest documenting those three. It makes sense to explain to userspace what behaviour they will see if they get it wrong. Ok. + * Also, on those platforms, it is not allowed to bind an device local-memory + * object and a system memory object in a single 2M section of VA range. Text should be clear whether "not allowed" means there will be an error returned, or it will appear to work but bad things will happen. Yah, error returned, will fix. + */ +struct drm_i915_gem_vm_bind { + /** @vm_id: VM (address space) id to bind */ + __u32 vm_id; + + /** @handle: Object handle */ + __u32 handle; + + /** @start: Virtual Address start to bind */ + __u64 start; + + /** @offset: Offset in object to bind */ + __u64 offset; + + /** @length: Length of mapping to
[PATCH] drm/i915: tweak the ordering in cpu_write_needs_clflush
For imported dma-buf objects we leave the object as cache_coherent = 0 across all platforms, which is reasonable given that have no clue what the memory underneath is, and its not like the driver can ever manually clflush the pages anyway (like with i915_gem_clflush_object) for such objects. However on discrete we choose to treat cache_dirty = true as a programmer error, leading to a warning. The simplest fix looks to be to just change the ordering in cpu_write_needs_clflush to prevent ever setting cache_dirty for dma-buf objects on discrete. Fixes: d028a7690d87 ("drm/i915/dmabuf: Fix prime_mmap to work when using LMEM") Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/5266 Signed-off-by: Matthew Auld Cc: Thomas Hellström Cc: Gwan-gyeong Mun --- drivers/gpu/drm/i915/gem/i915_gem_domain.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_domain.c b/drivers/gpu/drm/i915/gem/i915_gem_domain.c index 3e5d6057b3ef..1674b0c5802b 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_domain.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_domain.c @@ -35,12 +35,12 @@ bool i915_gem_cpu_write_needs_clflush(struct drm_i915_gem_object *obj) if (obj->cache_dirty) return false; - if (!(obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_WRITE)) - return true; - if (IS_DGFX(i915)) return false; + if (!(obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_WRITE)) + return true; + /* Currently in use by HW (display engine)? Keep flushed. */ return i915_gem_object_is_framebuffer(obj); } -- 2.36.1
Re: [Intel-gfx] [PATCH v3 3/3] drm/doc/rfc: VM_BIND uapi definition
On 22/06/2022 16:12, Niranjana Vishwanathapura wrote: On Wed, Jun 22, 2022 at 09:10:07AM +0100, Tvrtko Ursulin wrote: On 22/06/2022 04:56, Niranjana Vishwanathapura wrote: VM_BIND and related uapi definitions v2: Reduce the scope to simple Mesa use case. v3: Expand VM_UNBIND documentation and add I915_GEM_VM_BIND/UNBIND_FENCE_VALID and I915_GEM_VM_BIND_TLB_FLUSH flags. Signed-off-by: Niranjana Vishwanathapura --- Documentation/gpu/rfc/i915_vm_bind.h | 243 +++ 1 file changed, 243 insertions(+) create mode 100644 Documentation/gpu/rfc/i915_vm_bind.h diff --git a/Documentation/gpu/rfc/i915_vm_bind.h b/Documentation/gpu/rfc/i915_vm_bind.h new file mode 100644 index ..fa23b2d7ec6f --- /dev/null +++ b/Documentation/gpu/rfc/i915_vm_bind.h @@ -0,0 +1,243 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2022 Intel Corporation + */ + +/** + * DOC: I915_PARAM_HAS_VM_BIND + * + * VM_BIND feature availability. + * See typedef drm_i915_getparam_t param. + */ +#define I915_PARAM_HAS_VM_BIND 57 + +/** + * DOC: I915_VM_CREATE_FLAGS_USE_VM_BIND + * + * Flag to opt-in for VM_BIND mode of binding during VM creation. + * See struct drm_i915_gem_vm_control flags. + * + * The older execbuf2 ioctl will not support VM_BIND mode of operation. + * For VM_BIND mode, we have new execbuf3 ioctl which will not accept any + * execlist (See struct drm_i915_gem_execbuffer3 for more details). + * + */ +#define I915_VM_CREATE_FLAGS_USE_VM_BIND (1 << 0) + +/* VM_BIND related ioctls */ +#define DRM_I915_GEM_VM_BIND 0x3d +#define DRM_I915_GEM_VM_UNBIND 0x3e +#define DRM_I915_GEM_EXECBUFFER3 0x3f + +#define DRM_IOCTL_I915_GEM_VM_BIND DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_VM_BIND, struct drm_i915_gem_vm_bind) +#define DRM_IOCTL_I915_GEM_VM_UNBIND DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_VM_UNBIND, struct drm_i915_gem_vm_bind) +#define DRM_IOCTL_I915_GEM_EXECBUFFER3 DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER3, struct drm_i915_gem_execbuffer3) + +/** + * struct drm_i915_gem_vm_bind_fence - Bind/unbind completion notification. + * + * A timeline out fence for vm_bind/unbind completion notification. + */ +struct drm_i915_gem_vm_bind_fence { + /** @handle: User's handle for a drm_syncobj to signal. */ + __u32 handle; + + /** @rsvd: Reserved, MBZ */ + __u32 rsvd; + + /** + * @value: A point in the timeline. + * Value must be 0 for a binary drm_syncobj. A Value of 0 for a + * timeline drm_syncobj is invalid as it turns a drm_syncobj into a + * binary one. + */ + __u64 value; +}; + +/** + * struct drm_i915_gem_vm_bind - VA to object mapping to bind. + * + * This structure is passed to VM_BIND ioctl and specifies the mapping of GPU + * virtual address (VA) range to the section of an object that should be bound + * in the device page table of the specified address space (VM). + * The VA range specified must be unique (ie., not currently bound) and can + * be mapped to whole object or a section of the object (partial binding). + * Multiple VA mappings can be created to the same section of the object + * (aliasing). + * + * The @start, @offset and @length should be 4K page aligned. However the DG2 + * and XEHPSDV has 64K page size for device local-memory and has compact page + * table. On those platforms, for binding device local-memory objects, the + * @start should be 2M aligned, @offset and @length should be 64K aligned. Should some error codes be documented and has the ability to programmatically probe the alignment restrictions been considered? Currently what we have internally is that -EINVAL is returned if the sart, offset and length are not aligned. If the specified mapping already exits, we return -EEXIST. If there are conflicts in the VA range and VA range can't be reserved, then -ENOSPC is returned. I can add this documentation here. But I am worried that there will be more suggestions/feedback about error codes while reviewing the code patch series, and we have to revisit it again. I'd still suggest documenting those three. It makes sense to explain to userspace what behaviour they will see if they get it wrong. + * Also, on those platforms, it is not allowed to bind an device local-memory + * object and a system memory object in a single 2M section of VA range. Text should be clear whether "not allowed" means there will be an error returned, or it will appear to work but bad things will happen. Yah, error returned, will fix. + */ +struct drm_i915_gem_vm_bind { + /** @vm_id: VM (address space) id to bind */ + __u32 vm_id; + + /** @handle: Object handle */ + __u32 handle; + + /** @start: Virtual Address start to bind */ + __u64 start; + + /** @offset: Offset in object to bind */ + __u64 offset; + + /** @length: Length of mapping to bind */ + __u64 length; + + /** + * @flags: Supported flags
Re: [PATCH v8 01/16] clk: generalize devm_clk_get() a bit
On 21/06/2022 21:49, Uwe Kleine-König wrote: On Tue, Jun 21, 2022 at 08:57:00PM +0100, Jon Hunter wrote: Some of our Tegra boards are not booting with the current -next and bisect is pointing to this commit. Looking at the boot log I am seeing the following panic ... [2.097048] 8<--- cut here --- [2.097053] Unable to handle kernel paging request at virtual address c216c810 [2.097060] [c216c810] *pgd=0201141e(bad) [2.097079] Internal error: Oops: 800d [#1] SMP ARM [2.097088] Modules linked in: [2.097097] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 5.19.0-rc3-next-20220621-g34d1d36073ea #1 [2.097107] Hardware name: NVIDIA Tegra SoC (Flattened Device Tree) [2.097113] PC is at 0xc216c810 [2.097123] LR is at devm_clk_release+0x18/0x24 [2.097150] pc : []lr : []psr: a013 [2.097155] sp : f080dde8 ip : 06cf fp : c18d4854 [2.097161] r10: c1501850 r9 : c1a04d10 r8 : c1c4efa0 [2.097166] r7 : c216c810 r6 : f080de1c r5 : c2737680 r4 : c26a9680 [2.097172] r3 : c216c810 r2 : r1 : c2737840 r0 : c2082840 [2.097179] Flags: NzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none [2.097187] Control: 10c5387d Table: 0020404a DAC: 0051 [2.097191] Register r0 information: slab kmalloc-192 start c2082840 pointer offset 0 size 192 [2.097216] Register r1 information: slab kmalloc-128 start c2737800 pointer offset 64 size 128 [2.097236] Register r2 information: NULL pointer [2.097244] Register r3 information: slab kmalloc-1k start c216c800 pointer offset 16 size 1024 [2.097263] Register r4 information: slab kmalloc-64 start c26a9680 pointer offset 0 size 64 [2.097282] Register r5 information: slab kmalloc-128 start c2737680 pointer offset 0 size 128 [2.097301] Register r6 information: 2-page vmalloc region starting at 0xf080c000 allocated at kernel_clone+0xb4/0x3e8 [2.097321] Register r7 information: slab kmalloc-1k start c216c800 pointer offset 16 size 1024 [2.097341] Register r8 information: non-slab/vmalloc memory [2.097348] Register r9 information: non-slab/vmalloc memory [2.097355] Register r10 information: non-slab/vmalloc memory [2.097362] Register r11 information: non-slab/vmalloc memory [2.097369] Register r12 information: non-paged memory [2.097375] Process swapper/0 (pid: 1, stack limit = 0x(ptrval)) [2.097384] Stack: (0xf080dde8 to 0xf080e000) [2.097394] dde0: c2737800 c0a72d38 c18d4854 c0530490 c216c810 f080de1c [2.097404] de00: c212 0005 c216c9c0 8013 017e c0a73d68 0008 c2629e00 [2.097413] de20: c2737880 5640e141 c216c810 c216c810 0205 c1c09dd4 c27375b8 [2.097422] de40: c2091700 c0a6e9a0 c216c810 c0a6f288 c216c810 c1c09dd4 c216c810 [2.097430] de60: c27375b8 c0a6f3c0 c1caa8e0 c216c810 c216c810 c0a6f450 c216c810 [2.097439] de80: c1c09dd4 c212 c27375b8 c0a6f850 c1c09dd4 c0a6f7c4 c0a6d4c0 [2.097447] dea0: c2091458 c2286434 5640e141 c1be7f08 c1c09dd4 c2737580 c1be7f08 [2.097455] dec0: c0a6e484 c1615714 c1be7c50 c1c09dd4 c212 c189a99c [2.097464] dee0: c212 c0a701a0 c1c494e0 c212 c189a99c c0302144 017d c0364438 [2.097472] df00: c16da8bc c1626700 0006 0006 c16554c8 c212 [2.097480] df20: c15105bc c14f9778 c2091700 c20917d9 5640e141 c1a88930 c16da8bc [2.097488] df40: c1c59000 5640e141 c16da8bc c1c59000 c1953b4c c18d4834 0007 c1801340 [2.097497] df60: 0006 0006 c18004dc c212 c18004dc f080df74 c1a04cc0 [2.097505] df80: c106bbf0 c106bc08 [2.097513] dfa0: c106bbf0 c03001a8 [2.097520] dfc0: [2.097528] dfe0: 0013 [2.097542] devm_clk_release from release_nodes+0x58/0xc0 [2.097575] release_nodes from devres_release_all+0x7c/0xc0 [2.097596] devres_release_all from device_unbind_cleanup+0xc/0x60 [2.097626] device_unbind_cleanup from really_probe+0x1f4/0x2a8 [2.097650] really_probe from __driver_probe_device+0x84/0xe4 [2.097673] __driver_probe_device from driver_probe_device+0x30/0xd0 [2.097696] driver_probe_device from __driver_attach+0x8c/0xf0 [2.097713] __driver_attach from bus_for_each_dev+0x70/0xb0 [2.097729] bus_for_each_dev from bus_add_driver+0x168/0x1f4 [2.097749] bus_add_driver from driver_register+0x7c/0x118 [2.097766] driver_register from do_one_initcall+0x44/0x1ec [2.097784] do_one_initcall from kernel_init_freeable+0x1d4/0x224 [2.097803] kernel_init_freeable from kernel_init+0x18/0x12c [2.097820] kernel_init from ret_from_fork+0x14/0x2c [2.097831] Exception
Re: [PATCH 2/3] drm/msm/dp: Remove pixel_rate from struct dp_ctrl
On 6/22/2022 12:24 AM, Dmitry Baryshkov wrote: On 22/06/2022 05:59, Stephen Boyd wrote: Quoting Dmitry Baryshkov (2022-06-17 16:07:58) On 17/06/2022 23:47, Stephen Boyd wrote: This struct member is stored to in the function that calls the function which uses it. That's possible with a function argument instead of storing to a struct member. Pass the pixel_rate as an argument instead to simplify the code. Note that dp_ctrl_link_maintenance() was storing the pixel_rate but never using it so we just remove the assignment from there. Cc: Kuogee Hsieh Signed-off-by: Stephen Boyd --- drivers/gpu/drm/msm/dp/dp_ctrl.c | 57 drivers/gpu/drm/msm/dp/dp_ctrl.h | 1 - 2 files changed, 28 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c index bd445e683cfc..e114521af2e9 100644 --- a/drivers/gpu/drm/msm/dp/dp_ctrl.c +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c @@ -1336,7 +1336,7 @@ static void dp_ctrl_set_clock_rate(struct dp_ctrl_private *ctrl, name, rate); } -static int dp_ctrl_enable_mainlink_clocks(struct dp_ctrl_private *ctrl) +static int dp_ctrl_enable_mainlink_clocks(struct dp_ctrl_private *ctrl, unsigned long pixel_rate) I think we can read pixel_rate here rather than getting it as an argument. We'd need to move handling (DP_TEST_LINK_PHY_TEST_PATTERN && !ctrl->panel->dp_mode.drm_mode.clock) case here from dp_ctrl_on_link(). This is also called from dp_ctrl_on_stream() and dp_ctrl_reinitialize_mainlink(). In the dp_ctrl_on_stream() case we may divide the pixel_rate by 2 with widebus. We could move the dp_ctrl_on_link() code here, but then we also need to move widebus, and then I'm not sure which pixel rate to use. It looks like the test code doesn't care about widebus? And similarly, we may run the pixel clk faster until we get a modeset and then divide it for widebus. Good question. I'll let Kuogee or somebody else from Qualcomm to comment on test code vs widebus vs pixel rate, as I don't know these details. I'm not sure if we should halve the pixel clock in dp_ctrl_on_stream_phy_test_report() or not if the widebus is supported. From the current code I'd assume that we have to do this. Let's raise this question in the corresponding patch discussion. yes, phy test does not care pixel clock rate. Is that why you're suggesting to check !ctrl->panel->dp_mode.drm_mode.clock? I hesitate because it isn't a direct conversion, instead it checks some other stashed struct member. I'll also note that dp_ctrl_enable_mainlink_clocks() doesn't really use this argument except to print the value in drm_dbg_dp(). Maybe we should simply remove it from here instead? Yes, do it please. @@ -1588,12 +1586,12 @@ static int dp_ctrl_on_stream_phy_test_report(struct dp_ctrl *dp_ctrl) { int ret; struct dp_ctrl_private *ctrl; + unsigned long pixel_rate; ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl); - ctrl->dp_ctrl.pixel_rate = ctrl->panel->dp_mode.drm_mode.clock; - - ret = dp_ctrl_enable_stream_clocks(ctrl); + pixel_rate = ctrl->panel->dp_mode.drm_mode.clock; + ret = dp_ctrl_enable_stream_clocks(ctrl, pixel_rate); I think we can take another step forward here. Read the ctrl->panel->dp_mode.drm_mode.clock from within the dp_ctrl_enable_stream_clocks() function. This removes the need to pass pixel_rate as an argument here. This is also affected by widebus and if the function is called from dp_ctrl_on_stream() or dp_ctrl_on_stream_phy_test_report(). Maybe it would be better to inline dp_ctrl_enable_stream_clocks() to the callsites? That would probably simplify things because the function is mostly a wrapper around a couple functions. Yes, this sounds good. Then we can drop the drm_dbg_dp from it (as it nearly duplicates the data that was just printed.
Re: [PATCH v8 1/2] drm/msm/dp: force link training for display resolution change
On 6/22/2022 12:26 AM, Dmitry Baryshkov wrote: On 16/06/2022 20:09, Kuogee Hsieh wrote: Display resolution change is implemented through drm modeset. Older modeset (resolution) has to be disabled first before newer modeset (resolution) can be enabled. Display disable will turn off both pixel clock and main link clock so that main link have to be re-trained during display enable to have new video stream flow again. At current implementation, display enable function manually kicks up irq_hpd_handle which will read panel link status and start link training if link status is not in sync state. However, there is rare case that a particular panel links status keep staying in sync for some period of time after main link had been shut down previously at display disabled. In this case, main link retraining will not be executed by irq_hdp_handle(). Hence video stream of newer display resolution will fail to be transmitted to panel due to main link is not in sync between host and panel. This patch will bypass irq_hpd_handle() in favor of directly call dp_ctrl_on_stream() to always perform link training in regardless of main link status. So that no unexpected exception resolution change failure cases will happen. Also this implementation are more efficient than manual kicking off irq_hpd_handle function. Changes in v2: -- set force_link_train flag on DP only (is_edp == false) Changes in v3: -- revise commit text -- add Fixes tag Changes in v4: -- revise commit text Changes in v5: -- fix spelling at commit text Changes in v6: -- split dp_ctrl_on_stream() for phy test case -- revise commit text for modeset Changes in v7: -- drop 0 assignment at local variable (ret = 0) Changes in v8: -- add patch to remove pixel_rate from dp_ctrl Fixes: 62671d2ef24b ("drm/msm/dp: fixes wrong connection state caused by failure of link train") Signed-off-by: Kuogee Hsieh --- drivers/gpu/drm/msm/dp/dp_ctrl.c | 31 +++ drivers/gpu/drm/msm/dp/dp_ctrl.h | 3 ++- drivers/gpu/drm/msm/dp/dp_display.c | 13 ++--- 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c index af7a80c..01028b5 100644 --- a/drivers/gpu/drm/msm/dp/dp_ctrl.c +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c @@ -1551,7 +1551,7 @@ static int dp_ctrl_process_phy_test_request(struct dp_ctrl_private *ctrl) ret = dp_ctrl_on_link(>dp_ctrl); if (!ret) - ret = dp_ctrl_on_stream(>dp_ctrl); + ret = dp_ctrl_on_stream_phy_test_report(>dp_ctrl); else DRM_ERROR("failed to enable DP link controller\n"); @@ -1807,7 +1807,27 @@ static int dp_ctrl_link_retrain(struct dp_ctrl_private *ctrl) return dp_ctrl_setup_main_link(ctrl, _step); } -int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl) +int dp_ctrl_on_stream_phy_test_report(struct dp_ctrl *dp_ctrl) +{ + int ret; + struct dp_ctrl_private *ctrl; + + ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl); + + ctrl->dp_ctrl.pixel_rate = ctrl->panel->dp_mode.drm_mode.clock; Stephen has raised an interesting question. Comparing this to the dp_ctrl_on_stream(), he noticed that we do not halve the pixel clock here (if the wide bus is supported). So, the question is if this is correct or not. pixel is for video stream which has nothing to do phy test. Therefore no half pixel clock rate required for phy test. + + ret = dp_ctrl_enable_stream_clocks(ctrl); + if (ret) { + DRM_ERROR("Failed to start pixel clocks. ret=%d\n", ret); + return ret; + } + + dp_ctrl_send_phy_test_pattern(ctrl); + + return 0; +} + +int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl, bool force_link_train) { int ret = 0; bool mainlink_ready = false; @@ -1843,12 +1863,7 @@ int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl) goto end; } - if (ctrl->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN) { - dp_ctrl_send_phy_test_pattern(ctrl); - return 0; - } - - if (!dp_ctrl_channel_eq_ok(ctrl)) + if (force_link_train || !dp_ctrl_channel_eq_ok(ctrl)) dp_ctrl_link_retrain(ctrl); /* stop txing train pattern to end link training */
Re: [PATCH v3 05/13] drm/edid: add drm_edid_connector_update()
On Wed, Jun 22, 2022 at 01:59:19PM +0300, Jani Nikula wrote: > Add a new function drm_edid_connector_update() to replace the > combination of calls drm_connector_update_edid_property() and > drm_add_edid_modes(). Usually they are called in the drivers in this > order, however the former needs information from the latter. > > Since the new drm_edid_read*() functions no longer call the connector > updates directly, and the read and update are separated, we'll need this > new function for the connector update. > > This is all in drm_edid.c simply to keep struct drm_edid opaque. > > v2: > - Share code with drm_connector_update_edid_property() (Ville) > - Add comment about override EDID handling > > Signed-off-by: Jani Nikula Had to take notes to figure who did/does what. But it does look like non-static stuff should end up doing the same thing before and after this patch, apart from the new function that is. Reviewed-by: Ville Syrjälä > --- > drivers/gpu/drm/drm_edid.c | 103 - > include/drm/drm_edid.h | 2 + > 2 files changed, 81 insertions(+), 24 deletions(-) > > diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c > index c3f0f0a5a8a9..41b3de52b8f1 100644 > --- a/drivers/gpu/drm/drm_edid.c > +++ b/drivers/gpu/drm/drm_edid.c > @@ -6160,8 +6160,8 @@ static int add_displayid_detailed_modes(struct > drm_connector *connector, > return num_modes; > } > > -static int drm_edid_connector_update(struct drm_connector *connector, > - const struct drm_edid *drm_edid) > +static int _drm_edid_connector_update(struct drm_connector *connector, > + const struct drm_edid *drm_edid) > { > int num_modes = 0; > u32 quirks; > @@ -6227,31 +6227,12 @@ static int drm_edid_connector_update(struct > drm_connector *connector, > static void _drm_update_tile_info(struct drm_connector *connector, > const struct drm_edid *drm_edid); > > -static int _drm_connector_update_edid_property(struct drm_connector > *connector, > +static int _drm_edid_connector_property_update(struct drm_connector > *connector, > const struct drm_edid *drm_edid) > { > struct drm_device *dev = connector->dev; > int ret; > > - /* ignore requests to set edid when overridden */ > - if (connector->override_edid) > - return 0; > - > - /* > - * Set the display info, using edid if available, otherwise resetting > - * the values to defaults. This duplicates the work done in > - * drm_add_edid_modes, but that function is not consistently called > - * before this one in all drivers and the computation is cheap enough > - * that it seems better to duplicate it rather than attempt to ensure > - * some arbitrary ordering of calls. > - */ > - if (drm_edid) > - update_display_info(connector, drm_edid); > - else > - drm_reset_display_info(connector); > - > - _drm_update_tile_info(connector, drm_edid); > - > if (connector->edid_blob_ptr) { > const struct edid *old_edid = connector->edid_blob_ptr->data; > > @@ -6297,6 +6278,76 @@ static int _drm_connector_update_edid_property(struct > drm_connector *connector, > return ret; > } > > +/** > + * drm_edid_connector_update - Update connector information from EDID > + * @connector: Connector > + * @drm_edid: EDID > + * > + * Update the connector mode list, display info, ELD, HDR metadata, relevant > + * properties, etc. from the passed in EDID. > + * > + * If EDID is NULL, reset the information. > + * > + * Return: The number of modes added or 0 if we couldn't find any. > + */ > +int drm_edid_connector_update(struct drm_connector *connector, > + const struct drm_edid *drm_edid) > +{ > + int count; > + > + /* > + * FIXME: Reconcile the differences in override_edid handling between > + * this and drm_connector_update_edid_property(). > + * > + * If override_edid is set, and the EDID passed in here originates from > + * drm_edid_read() and friends, it will be the override EDID, and there > + * are no issues. drm_connector_update_edid_property() ignoring requests > + * to set the EDID dates back to a time when override EDID was not > + * handled at the low level EDID read. > + * > + * The only way the EDID passed in here can be different from the > + * override EDID is when a driver passes in an EDID that does *not* > + * originate from drm_edid_read() and friends, or passes in a stale > + * cached version. This, in turn, is a question of when an override EDID > + * set via debugfs should take effect. > + */ > + > + count = _drm_edid_connector_update(connector, drm_edid); > + > + _drm_update_tile_info(connector, drm_edid); > + > + /* Note: Ignore
Re: [Intel-gfx] [PATCH v3 3/3] drm/doc/rfc: VM_BIND uapi definition
On Wed, Jun 22, 2022 at 09:10:07AM +0100, Tvrtko Ursulin wrote: On 22/06/2022 04:56, Niranjana Vishwanathapura wrote: VM_BIND and related uapi definitions v2: Reduce the scope to simple Mesa use case. v3: Expand VM_UNBIND documentation and add I915_GEM_VM_BIND/UNBIND_FENCE_VALID and I915_GEM_VM_BIND_TLB_FLUSH flags. Signed-off-by: Niranjana Vishwanathapura --- Documentation/gpu/rfc/i915_vm_bind.h | 243 +++ 1 file changed, 243 insertions(+) create mode 100644 Documentation/gpu/rfc/i915_vm_bind.h diff --git a/Documentation/gpu/rfc/i915_vm_bind.h b/Documentation/gpu/rfc/i915_vm_bind.h new file mode 100644 index ..fa23b2d7ec6f --- /dev/null +++ b/Documentation/gpu/rfc/i915_vm_bind.h @@ -0,0 +1,243 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2022 Intel Corporation + */ + +/** + * DOC: I915_PARAM_HAS_VM_BIND + * + * VM_BIND feature availability. + * See typedef drm_i915_getparam_t param. + */ +#define I915_PARAM_HAS_VM_BIND 57 + +/** + * DOC: I915_VM_CREATE_FLAGS_USE_VM_BIND + * + * Flag to opt-in for VM_BIND mode of binding during VM creation. + * See struct drm_i915_gem_vm_control flags. + * + * The older execbuf2 ioctl will not support VM_BIND mode of operation. + * For VM_BIND mode, we have new execbuf3 ioctl which will not accept any + * execlist (See struct drm_i915_gem_execbuffer3 for more details). + * + */ +#define I915_VM_CREATE_FLAGS_USE_VM_BIND (1 << 0) + +/* VM_BIND related ioctls */ +#define DRM_I915_GEM_VM_BIND 0x3d +#define DRM_I915_GEM_VM_UNBIND 0x3e +#define DRM_I915_GEM_EXECBUFFER3 0x3f + +#define DRM_IOCTL_I915_GEM_VM_BIND DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_VM_BIND, struct drm_i915_gem_vm_bind) +#define DRM_IOCTL_I915_GEM_VM_UNBIND DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_VM_UNBIND, struct drm_i915_gem_vm_bind) +#define DRM_IOCTL_I915_GEM_EXECBUFFER3 DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER3, struct drm_i915_gem_execbuffer3) + +/** + * struct drm_i915_gem_vm_bind_fence - Bind/unbind completion notification. + * + * A timeline out fence for vm_bind/unbind completion notification. + */ +struct drm_i915_gem_vm_bind_fence { + /** @handle: User's handle for a drm_syncobj to signal. */ + __u32 handle; + + /** @rsvd: Reserved, MBZ */ + __u32 rsvd; + + /** +* @value: A point in the timeline. +* Value must be 0 for a binary drm_syncobj. A Value of 0 for a +* timeline drm_syncobj is invalid as it turns a drm_syncobj into a +* binary one. +*/ + __u64 value; +}; + +/** + * struct drm_i915_gem_vm_bind - VA to object mapping to bind. + * + * This structure is passed to VM_BIND ioctl and specifies the mapping of GPU + * virtual address (VA) range to the section of an object that should be bound + * in the device page table of the specified address space (VM). + * The VA range specified must be unique (ie., not currently bound) and can + * be mapped to whole object or a section of the object (partial binding). + * Multiple VA mappings can be created to the same section of the object + * (aliasing). + * + * The @start, @offset and @length should be 4K page aligned. However the DG2 + * and XEHPSDV has 64K page size for device local-memory and has compact page + * table. On those platforms, for binding device local-memory objects, the + * @start should be 2M aligned, @offset and @length should be 64K aligned. Should some error codes be documented and has the ability to programmatically probe the alignment restrictions been considered? Currently what we have internally is that -EINVAL is returned if the sart, offset and length are not aligned. If the specified mapping already exits, we return -EEXIST. If there are conflicts in the VA range and VA range can't be reserved, then -ENOSPC is returned. I can add this documentation here. But I am worried that there will be more suggestions/feedback about error codes while reviewing the code patch series, and we have to revisit it again. + * Also, on those platforms, it is not allowed to bind an device local-memory + * object and a system memory object in a single 2M section of VA range. Text should be clear whether "not allowed" means there will be an error returned, or it will appear to work but bad things will happen. Yah, error returned, will fix. + */ +struct drm_i915_gem_vm_bind { + /** @vm_id: VM (address space) id to bind */ + __u32 vm_id; + + /** @handle: Object handle */ + __u32 handle; + + /** @start: Virtual Address start to bind */ + __u64 start; + + /** @offset: Offset in object to bind */ + __u64 offset; + + /** @length: Length of mapping to bind */ + __u64 length; + + /** +* @flags: Supported flags are: +* +* I915_GEM_VM_BIND_FENCE_VALID: +* @fence is valid, needs bind completion notification. +* +
Re: [PATCH v4 0/7] usb: typec: Introduce typec-switch binding
On Wed, Jun 22, 2022 at 04:53:40PM +0200, Krzysztof Kozlowski wrote: > On 21/06/2022 15:17, Greg Kroah-Hartman wrote: > > On Wed, Jun 15, 2022 at 11:13:33AM -0700, Prashant Malani wrote: > >> I should add: > >> > >> Series submission suggestions (of course, open to better suggestions too): > >> - Patches 1-3 can go through the USB repo. > > > > I will take patches 1 and 2 now. > > > > seems the others need reworks or acks from the DT people. > > I just gave for patch 3 and before for 4, so you can grab these as well. They are gone from my queue, a resend with that ack would be good so that I can pick it up easier. thanks, gre gk-h
Re: [PATCH v4 1/2] drm/panfrost: Add specific register offset macros for JS and MMU AS
Reviewed-by: Alyssa Rosenzweig On Wed, Jun 22, 2022 at 03:36:15PM +0100, Adri??n Larumbe wrote: > Each Panfrost job has its own job slot and MMU address space set of > registers, which are selected with a job-specific index. > > Turn the shift and stride used for selection of the right register set base > into a define rather than using magic numbers. > > Signed-off-by: Adri??n Larumbe > --- > drivers/gpu/drm/panfrost/panfrost_regs.h | 39 +--- > 1 file changed, 21 insertions(+), 18 deletions(-) > > diff --git a/drivers/gpu/drm/panfrost/panfrost_regs.h > b/drivers/gpu/drm/panfrost/panfrost_regs.h > index accb4fa3adb8..1ddc6c4c5e1c 100644 > --- a/drivers/gpu/drm/panfrost/panfrost_regs.h > +++ b/drivers/gpu/drm/panfrost/panfrost_regs.h > @@ -225,24 +225,26 @@ > #define JOB_INT_MASK_ERR(j) BIT((j) + 16) > #define JOB_INT_MASK_DONE(j) BIT(j) > > +#define JS_SLOT_STRIDE 0x80 > + > #define JS_BASE 0x1800 > -#define JS_HEAD_LO(n)(JS_BASE + ((n) * 0x80) + 0x00) > -#define JS_HEAD_HI(n)(JS_BASE + ((n) * 0x80) + 0x04) > -#define JS_TAIL_LO(n)(JS_BASE + ((n) * 0x80) + 0x08) > -#define JS_TAIL_HI(n)(JS_BASE + ((n) * 0x80) + 0x0c) > -#define JS_AFFINITY_LO(n)(JS_BASE + ((n) * 0x80) + 0x10) > -#define JS_AFFINITY_HI(n)(JS_BASE + ((n) * 0x80) + 0x14) > -#define JS_CONFIG(n) (JS_BASE + ((n) * 0x80) + 0x18) > -#define JS_XAFFINITY(n) (JS_BASE + ((n) * 0x80) + 0x1c) > -#define JS_COMMAND(n)(JS_BASE + ((n) * 0x80) + 0x20) > -#define JS_STATUS(n) (JS_BASE + ((n) * 0x80) + 0x24) > -#define JS_HEAD_NEXT_LO(n) (JS_BASE + ((n) * 0x80) + 0x40) > -#define JS_HEAD_NEXT_HI(n) (JS_BASE + ((n) * 0x80) + 0x44) > -#define JS_AFFINITY_NEXT_LO(n) (JS_BASE + ((n) * 0x80) + 0x50) > -#define JS_AFFINITY_NEXT_HI(n) (JS_BASE + ((n) * 0x80) + 0x54) > -#define JS_CONFIG_NEXT(n)(JS_BASE + ((n) * 0x80) + 0x58) > -#define JS_COMMAND_NEXT(n) (JS_BASE + ((n) * 0x80) + 0x60) > -#define JS_FLUSH_ID_NEXT(n) (JS_BASE + ((n) * 0x80) + 0x70) > +#define JS_HEAD_LO(n)(JS_BASE + ((n) * > JS_SLOT_STRIDE) + 0x00) > +#define JS_HEAD_HI(n)(JS_BASE + ((n) * > JS_SLOT_STRIDE) + 0x04) > +#define JS_TAIL_LO(n)(JS_BASE + ((n) * > JS_SLOT_STRIDE) + 0x08) > +#define JS_TAIL_HI(n)(JS_BASE + ((n) * > JS_SLOT_STRIDE) + 0x0c) > +#define JS_AFFINITY_LO(n)(JS_BASE + ((n) * JS_SLOT_STRIDE) + > 0x10) > +#define JS_AFFINITY_HI(n)(JS_BASE + ((n) * JS_SLOT_STRIDE) + > 0x14) > +#define JS_CONFIG(n) (JS_BASE + ((n) * JS_SLOT_STRIDE) + > 0x18) > +#define JS_XAFFINITY(n) (JS_BASE + ((n) * > JS_SLOT_STRIDE) + 0x1c) > +#define JS_COMMAND(n)(JS_BASE + ((n) * > JS_SLOT_STRIDE) + 0x20) > +#define JS_STATUS(n) (JS_BASE + ((n) * JS_SLOT_STRIDE) + > 0x24) > +#define JS_HEAD_NEXT_LO(n) (JS_BASE + ((n) * JS_SLOT_STRIDE) + > 0x40) > +#define JS_HEAD_NEXT_HI(n) (JS_BASE + ((n) * JS_SLOT_STRIDE) + > 0x44) > +#define JS_AFFINITY_NEXT_LO(n) (JS_BASE + ((n) * > JS_SLOT_STRIDE) + 0x50) > +#define JS_AFFINITY_NEXT_HI(n) (JS_BASE + ((n) * > JS_SLOT_STRIDE) + 0x54) > +#define JS_CONFIG_NEXT(n)(JS_BASE + ((n) * JS_SLOT_STRIDE) + > 0x58) > +#define JS_COMMAND_NEXT(n) (JS_BASE + ((n) * JS_SLOT_STRIDE) + > 0x60) > +#define JS_FLUSH_ID_NEXT(n) (JS_BASE + ((n) * JS_SLOT_STRIDE) + > 0x70) > > /* Possible values of JS_CONFIG and JS_CONFIG_NEXT registers */ > #define JS_CONFIG_START_FLUSH_CLEAN BIT(8) > @@ -281,7 +283,8 @@ > #define AS_COMMAND_FLUSH_MEM 0x05/* Wait for memory accesses to > complete, flush all the L1s cache then > flush all L2 caches then > issue a flush region command to all MMUs */ > > -#define MMU_AS(as) (0x2400 + ((as) << 6)) > +#define MMU_AS_SHIFT 0x06 > +#define MMU_AS(as) (0x2400 + ((as) << MMU_AS_SHIFT)) > > #define AS_TRANSTAB_LO(as) (MMU_AS(as) + 0x00) /* (RW) Translation > Table Base Address for address space n, low word */ > #define AS_TRANSTAB_HI(as) (MMU_AS(as) + 0x04) /* (RW) Translation > Table Base Address for address space n, high word */ > -- > 2.36.1 >
Re: [PATCH v3 08/13] drm/i915/edid: convert DP, HDMI and LVDS to drm_edid
On Wed, Jun 22, 2022 at 01:59:22PM +0300, Jani Nikula wrote: > @@ -948,27 +948,30 @@ void intel_lvds_init(struct drm_i915_private *dev_priv) >* preferred mode is the right one. >*/ > mutex_lock(>mode_config.mutex); > - if (vga_switcheroo_handler_flags() & VGA_SWITCHEROO_CAN_SWITCH_DDC) > + if (vga_switcheroo_handler_flags() & VGA_SWITCHEROO_CAN_SWITCH_DDC) { > + const struct edid *edid; > + > + /* FIXME: Make drm_get_edid_switcheroo() return drm_edid */ > edid = drm_get_edid_switcheroo(connector, > - intel_gmbus_get_adapter(dev_priv, pin)); > - else > - edid = drm_get_edid(connector, > - intel_gmbus_get_adapter(dev_priv, pin)); > - if (edid) { > - if (drm_add_edid_modes(connector, edid)) { > - drm_connector_update_edid_property(connector, > - edid); > - } else { > - kfree(edid); > - edid = ERR_PTR(-EINVAL); > + > intel_gmbus_get_adapter(dev_priv, pin)); > + if (edid) > + drm_edid = drm_edid_alloc(edid, (edid->extensions + 1) > * EDID_LENGTH); This one still seems to leak. > + } else { > + drm_edid = drm_edid_read_ddc(connector, > + intel_gmbus_get_adapter(dev_priv, > pin)); > + } > + if (drm_edid) { > + if (!drm_edid_connector_update(connector, drm_edid)) { > + drm_edid_free(drm_edid); > + drm_edid = ERR_PTR(-EINVAL); > } > } else { > - edid = ERR_PTR(-ENOENT); > + drm_edid = ERR_PTR(-ENOENT); > } > - intel_connector->edid = edid; > + intel_connector->edid = drm_edid; > > intel_bios_init_panel(dev_priv, _connector->panel, NULL, > - IS_ERR(edid) ? NULL : edid); > + IS_ERR_OR_NULL(drm_edid) ? NULL : > drm_edid_raw(drm_edid)); > > /* Try EDID first */ > intel_panel_add_edid_fixed_modes(intel_connector, > -- > 2.30.2 -- Ville Syrjälä Intel
Re: [PATCH 1/5] drm/amdgpu: Fix possible refcount leak for release of external_hw_fence
Am 22.06.22 um 17:01 schrieb Andrey Grodzovsky: On 2022-06-22 05:00, Christian König wrote: Am 21.06.22 um 21:34 schrieb Andrey Grodzovsky: On 2022-06-21 03:19, Christian König wrote: Am 21.06.22 um 00:02 schrieb Andrey Grodzovsky: Problem: In amdgpu_job_submit_direct - The refcount should drop by 2 but it drops only by 1. amdgpu_ib_sched->emit -> refcount 1 from first fence init dma_fence_get -> refcount 2 dme_fence_put -> refcount 1 Fix: Add put for external_hw_fence in amdgpu_job_free/free_cb Well what is the external_hw_fence good for in this construct? As far as I understand for direct submissions you don't want to pass a job pointer to ib_schedule and so u can't use the embedded fence for this case. Can you please look a bit deeper into this, we now have a couple of fields in the job structure which have no obvious use. I think we could pass a job structure to ib_schedule even for direct submit now. Are you sure ? I see a lot of activities in amdgpu_ib_schedule depend on presence of vm and fence_ctx which are set if the job pointer argument != NULL, might this have a negative impact on direct submit ? Not 100% sure, but we did tons of workarounds because we didn't had a job pointer for direct submit. But this was before we embedded the IBs at the end of the job. It's quite likely that this should be possible now, it's just that somebody needs to double check. Christian. Andrey Regards, Christian. Andrey Signed-off-by: Andrey Grodzovsky --- drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c index 10aa073600d4..58568fdde2d0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c @@ -152,8 +152,10 @@ static void amdgpu_job_free_cb(struct drm_sched_job *s_job) /* only put the hw fence if has embedded fence */ if (job->hw_fence.ops != NULL) dma_fence_put(>hw_fence); - else + else { When one side of the if uses {} the other side should use {} as well, e.g. use } else { here. Christian. + dma_fence_put(job->external_hw_fence); kfree(job); + } } void amdgpu_job_free(struct amdgpu_job *job) @@ -165,8 +167,10 @@ void amdgpu_job_free(struct amdgpu_job *job) /* only put the hw fence if has embedded fence */ if (job->hw_fence.ops != NULL) dma_fence_put(>hw_fence); - else + else { + dma_fence_put(job->external_hw_fence); kfree(job); + } } int amdgpu_job_submit(struct amdgpu_job *job, struct drm_sched_entity *entity,
Re: [PATCH 1/5] drm/amdgpu: Fix possible refcount leak for release of external_hw_fence
On 2022-06-22 05:00, Christian König wrote: Am 21.06.22 um 21:34 schrieb Andrey Grodzovsky: On 2022-06-21 03:19, Christian König wrote: Am 21.06.22 um 00:02 schrieb Andrey Grodzovsky: Problem: In amdgpu_job_submit_direct - The refcount should drop by 2 but it drops only by 1. amdgpu_ib_sched->emit -> refcount 1 from first fence init dma_fence_get -> refcount 2 dme_fence_put -> refcount 1 Fix: Add put for external_hw_fence in amdgpu_job_free/free_cb Well what is the external_hw_fence good for in this construct? As far as I understand for direct submissions you don't want to pass a job pointer to ib_schedule and so u can't use the embedded fence for this case. Can you please look a bit deeper into this, we now have a couple of fields in the job structure which have no obvious use. I think we could pass a job structure to ib_schedule even for direct submit now. Are you sure ? I see a lot of activities in amdgpu_ib_schedule depend on presence of vm and fence_ctx which are set if the job pointer argument != NULL, might this have a negative impact on direct submit ? Andrey Regards, Christian. Andrey Signed-off-by: Andrey Grodzovsky --- drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c index 10aa073600d4..58568fdde2d0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c @@ -152,8 +152,10 @@ static void amdgpu_job_free_cb(struct drm_sched_job *s_job) /* only put the hw fence if has embedded fence */ if (job->hw_fence.ops != NULL) dma_fence_put(>hw_fence); - else + else { When one side of the if uses {} the other side should use {} as well, e.g. use } else { here. Christian. + dma_fence_put(job->external_hw_fence); kfree(job); + } } void amdgpu_job_free(struct amdgpu_job *job) @@ -165,8 +167,10 @@ void amdgpu_job_free(struct amdgpu_job *job) /* only put the hw fence if has embedded fence */ if (job->hw_fence.ops != NULL) dma_fence_put(>hw_fence); - else + else { + dma_fence_put(job->external_hw_fence); kfree(job); + } } int amdgpu_job_submit(struct amdgpu_job *job, struct drm_sched_entity *entity,
Re: [PATCH] video: fbdev: omap: Remove duplicate 'the' in two places.
On 6/21/22 20:54, Jiang Jian wrote: > file: drivers/video/fbdev/omap/sossi.c > line: 362 > * We set explicitly the the bus_pick_count as well, although > changed to > * We set explicitly the bus_pick_count as well, although > > Signed-off-by: Jiang Jian Both patches applied. Thanks! Helge > --- > drivers/video/fbdev/omap/sossi.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/video/fbdev/omap/sossi.c > b/drivers/video/fbdev/omap/sossi.c > index c90eb8ca58af..66aff6cd1df0 100644 > --- a/drivers/video/fbdev/omap/sossi.c > +++ b/drivers/video/fbdev/omap/sossi.c > @@ -359,7 +359,7 @@ static void sossi_set_bits_per_cycle(int bpc) > int bus_pick_count, bus_pick_width; > > /* > - * We set explicitly the the bus_pick_count as well, although > + * We set explicitly the bus_pick_count as well, although >* with remapping/reordering disabled it will be calculated by HW >* as (32 / bus_pick_width). >*/
[drm-misc:drm-misc-next 1/4] drivers/gpu/drm/hyperv/hyperv_drm_modeset.c:58:17: error: implicit declaration of function 'drm_add_modes_noedid'
tree: git://anongit.freedesktop.org/drm/drm-misc drm-misc-next head: 62a4ddcb79e073465f21c5cf84d80a2f22820c39 commit: 255490f9150da7c6dabe468f3a877b92fd0f02c1 [1/4] drm: Drop drm_edid.h from drm_crtc.h config: x86_64-allyesconfig (https://download.01.org/0day-ci/archive/20220622/20220609.btdat1bp-...@intel.com/config) compiler: gcc-11 (Debian 11.3.0-3) 11.3.0 reproduce (this is a W=1 build): git remote add drm-misc git://anongit.freedesktop.org/drm/drm-misc git fetch --no-tags drm-misc drm-misc-next git checkout 255490f9150da7c6dabe468f3a877b92fd0f02c1 # save the config file mkdir build_dir && cp config build_dir/.config make W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash If you fix the issue, kindly add following tag where applicable Reported-by: kernel test robot All errors (new ones prefixed by >>): drivers/gpu/drm/hyperv/hyperv_drm_modeset.c: In function 'hyperv_connector_get_modes': >> drivers/gpu/drm/hyperv/hyperv_drm_modeset.c:58:17: error: implicit >> declaration of function 'drm_add_modes_noedid' >> [-Werror=implicit-function-declaration] 58 | count = drm_add_modes_noedid(connector, | ^~~~ >> drivers/gpu/drm/hyperv/hyperv_drm_modeset.c:61:9: error: implicit >> declaration of function 'drm_set_preferred_mode'; did you mean >> 'drm_mm_reserve_node'? [-Werror=implicit-function-declaration] 61 | drm_set_preferred_mode(connector, hv->preferred_width, | ^~ | drm_mm_reserve_node cc1: some warnings being treated as errors vim +/drm_add_modes_noedid +58 drivers/gpu/drm/hyperv/hyperv_drm_modeset.c 76c56a5affeba1 Deepak Rawat 2021-05-27 52 76c56a5affeba1 Deepak Rawat 2021-05-27 53 static int hyperv_connector_get_modes(struct drm_connector *connector) 76c56a5affeba1 Deepak Rawat 2021-05-27 54 { 76c56a5affeba1 Deepak Rawat 2021-05-27 55 struct hyperv_drm_device *hv = to_hv(connector->dev); 76c56a5affeba1 Deepak Rawat 2021-05-27 56 int count; 76c56a5affeba1 Deepak Rawat 2021-05-27 57 76c56a5affeba1 Deepak Rawat 2021-05-27 @58 count = drm_add_modes_noedid(connector, 76c56a5affeba1 Deepak Rawat 2021-05-27 59 connector->dev->mode_config.max_width, 76c56a5affeba1 Deepak Rawat 2021-05-27 60 connector->dev->mode_config.max_height); 76c56a5affeba1 Deepak Rawat 2021-05-27 @61 drm_set_preferred_mode(connector, hv->preferred_width, 76c56a5affeba1 Deepak Rawat 2021-05-27 62 hv->preferred_height); 76c56a5affeba1 Deepak Rawat 2021-05-27 63 76c56a5affeba1 Deepak Rawat 2021-05-27 64 return count; 76c56a5affeba1 Deepak Rawat 2021-05-27 65 } 76c56a5affeba1 Deepak Rawat 2021-05-27 66 :: The code at line 58 was first introduced by commit :: 76c56a5affeba1e163b66b9d8cc192e6154466f0 drm/hyperv: Add DRM driver for hyperv synthetic video device :: TO: Deepak Rawat :: CC: Deepak Rawat -- 0-DAY CI Kernel Test Service https://01.org/lkp
Re: [PATCH v4 0/7] usb: typec: Introduce typec-switch binding
On 21/06/2022 15:17, Greg Kroah-Hartman wrote: > On Wed, Jun 15, 2022 at 11:13:33AM -0700, Prashant Malani wrote: >> I should add: >> >> Series submission suggestions (of course, open to better suggestions too): >> - Patches 1-3 can go through the USB repo. > > I will take patches 1 and 2 now. > > seems the others need reworks or acks from the DT people. I just gave for patch 3 and before for 4, so you can grab these as well. Thanks! Best regards, Krzysztof
Re: [PATCH v4 3/7] dt-bindings: usb: Add Type-C switch binding
On 15/06/2022 19:20, Prashant Malani wrote: > Introduce a binding which represents a component that can control the > routing of USB Type-C data lines as well as address data line > orientation (based on CC lines' orientation). > > Reviewed-by: Nícolas F. R. A. Prado > Tested-by: Nícolas F. R. A. Prado > Signed-off-by: Prashant Malani Reviewed-by: Krzysztof Kozlowski Best regards, Krzysztof
Re: (subset) [PATCH] drm/vc4: fix error code in vc4_check_tex_size()
On Wed, 22 Jun 2022 15:25:15 +0300, Dan Carpenter wrote: > The vc4_check_tex_size() function is supposed to return false on error > but this error path accidentally returns -ENODEV (which means true). > > Applied to drm/drm-misc (drm-misc-fixes). Thanks! Maxime
Re: [PATCH v3 04/13] drm/edid: abstract debugfs override EDID set/reset
On Wed, Jun 22, 2022 at 01:59:18PM +0300, Jani Nikula wrote: > Add functions drm_edid_override_set() and drm_edid_override_reset() to > support "edid_override" connector debugfs, and to hide the details about > it in drm_edid.c. No functional changes at this time. > > Also note in the connector.override_edid flag kernel-doc that this is > only supposed to be modified by the code doing debugfs EDID override > handling. Currently, it is still being modified by amdgpu in > create_eml_sink() and handle_edid_mgmt() for reasons unknown. This was > added in commit 4562236b3bc0 ("drm/amd/dc: Add dc display driver (v2)") > and later moved to amdgpu_dm.c in commit e7b07ceef2a6 ("drm/amd/display: > Merge amdgpu_dm_types and amdgpu_dm"). > > Signed-off-by: Jani Nikula Reviewed-by: Ville Syrjälä > --- > drivers/gpu/drm/drm_crtc_internal.h | 2 ++ > drivers/gpu/drm/drm_debugfs.c | 21 + > drivers/gpu/drm/drm_edid.c | 26 ++ > include/drm/drm_connector.h | 6 +- > 4 files changed, 38 insertions(+), 17 deletions(-) > > diff --git a/drivers/gpu/drm/drm_crtc_internal.h > b/drivers/gpu/drm/drm_crtc_internal.h > index aecab5308bae..56041b604881 100644 > --- a/drivers/gpu/drm/drm_crtc_internal.h > +++ b/drivers/gpu/drm/drm_crtc_internal.h > @@ -286,3 +286,5 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, > > /* drm_edid.c */ > void drm_mode_fixup_1366x768(struct drm_display_mode *mode); > +int drm_edid_override_set(struct drm_connector *connector, const void *edid, > size_t size); > +int drm_edid_override_reset(struct drm_connector *connector); > diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c > index fb04b7a984de..493922069c90 100644 > --- a/drivers/gpu/drm/drm_debugfs.c > +++ b/drivers/gpu/drm/drm_debugfs.c > @@ -350,31 +350,20 @@ static ssize_t edid_write(struct file *file, const char > __user *ubuf, > struct seq_file *m = file->private_data; > struct drm_connector *connector = m->private; > char *buf; > - struct edid *edid; > int ret; > > buf = memdup_user(ubuf, len); > if (IS_ERR(buf)) > return PTR_ERR(buf); > > - edid = (struct edid *) buf; > - > - if (len == 5 && !strncmp(buf, "reset", 5)) { > - connector->override_edid = false; > - ret = drm_connector_update_edid_property(connector, NULL); > - } else if (len < EDID_LENGTH || > -EDID_LENGTH * (1 + edid->extensions) > len) > - ret = -EINVAL; > - else { > - connector->override_edid = false; > - ret = drm_connector_update_edid_property(connector, edid); > - if (!ret) > - connector->override_edid = true; > - } > + if (len == 5 && !strncmp(buf, "reset", 5)) > + ret = drm_edid_override_reset(connector); > + else > + ret = drm_edid_override_set(connector, buf, len); > > kfree(buf); > > - return (ret) ? ret : len; > + return ret ? ret : len; > } > > /* > diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c > index e360e1a269f4..c3f0f0a5a8a9 100644 > --- a/drivers/gpu/drm/drm_edid.c > +++ b/drivers/gpu/drm/drm_edid.c > @@ -2161,6 +2161,32 @@ static struct edid *drm_get_override_edid(struct > drm_connector *connector, > return IS_ERR(override) ? NULL : override; > } > > +/* For debugfs edid_override implementation */ > +int drm_edid_override_set(struct drm_connector *connector, const void *edid, > + size_t size) > +{ > + int ret; > + > + if (size < EDID_LENGTH || edid_size(edid) > size) > + return -EINVAL; > + > + connector->override_edid = false; > + > + ret = drm_connector_update_edid_property(connector, edid); > + if (!ret) > + connector->override_edid = true; > + > + return ret; > +} > + > +/* For debugfs edid_override implementation */ > +int drm_edid_override_reset(struct drm_connector *connector) > +{ > + connector->override_edid = false; > + > + return drm_connector_update_edid_property(connector, NULL); > +} > + > /** > * drm_add_override_edid_modes - add modes from override/firmware EDID > * @connector: connector we're probing > diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h > index 94b422b55cc1..a1705d6b3fba 100644 > --- a/include/drm/drm_connector.h > +++ b/include/drm/drm_connector.h > @@ -1527,7 +1527,11 @@ struct drm_connector { > struct drm_cmdline_mode cmdline_mode; > /** @force: a DRM_FORCE_ state for forced mode sets */ > enum drm_connector_force force; > - /** @override_edid: has the EDID been overwritten through debugfs for > testing? */ > + /** > + * @override_edid: has the EDID been overwritten through debugfs for > + * testing? Do not modify outside of drm_edid_override_set() and > + * drm_edid_override_reset(). > + */ >
Re: [PATCH v3 03/13] drm/edid: clean up connector update error handling and debug logging
On Wed, Jun 22, 2022 at 01:59:17PM +0300, Jani Nikula wrote: > Bail out on all errors, debug log all errors, and convert to drm device > based debug logging. > > Signed-off-by: Jani Nikula > --- > drivers/gpu/drm/drm_edid.c | 41 ++ > 1 file changed, 28 insertions(+), 13 deletions(-) > > diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c > index 62967db78139..e360e1a269f4 100644 > --- a/drivers/gpu/drm/drm_edid.c > +++ b/drivers/gpu/drm/drm_edid.c > @@ -6231,29 +6231,44 @@ static int _drm_connector_update_edid_property(struct > drm_connector *connector, > > if (old_edid) { > if (!drm_edid_are_equal(drm_edid ? drm_edid->edid : > NULL, old_edid)) { > - DRM_DEBUG_KMS("[CONNECTOR:%d:%s] Edid was > changed.\n", > - connector->base.id, > connector->name); > - > - connector->epoch_counter += 1; > - DRM_DEBUG_KMS("Updating change counter to > %llu\n", > - connector->epoch_counter); > + connector->epoch_counter++; > + drm_dbg_kms(dev, "[CONNECTOR:%d:%s] EDID > changed, epoch counter %llu\n", > + connector->base.id, connector->name, > + connector->epoch_counter); > } > } > } > > - drm_object_property_set_value(>base, > - dev->mode_config.non_desktop_property, > - connector->display_info.non_desktop); > - > ret = drm_property_replace_global_blob(dev, > >edid_blob_ptr, > drm_edid ? drm_edid->size : 0, > drm_edid ? drm_edid->edid : NULL, > >base, > dev->mode_config.edid_property); > - if (ret) > - return ret; > - return drm_connector_set_tile_property(connector); > + if (ret) { > + drm_dbg_kms(dev, "[CONNECTOR:%d:%s] EDID property update failed > (%d)\n", > + connector->base.id, connector->name, ret); > + goto out; > + } > + > + ret = drm_object_property_set_value(>base, > + > dev->mode_config.non_desktop_property, > + > connector->display_info.non_desktop); > + if (ret) { > + drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Non-desktop property update > failed (%d)\n", > + connector->base.id, connector->name, ret); > + goto out; > + } > + > + ret = drm_connector_set_tile_property(connector); > + if (ret) { > + drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Tile property update failed > (%d)\n", > + connector->base.id, connector->name, ret); > + goto out; > + } > + > +out: Could just return directly w/o the goto detour. Or maybe this becomes useful later? Reviewed-by: Ville Syrjälä > + return ret; > } > > /** > -- > 2.30.2 -- Ville Syrjälä Intel
Re: [PATCH v3 02/13] drm/edid: convert drm_connector_update_edid_property() to struct drm_edid
On Wed, Jun 22, 2022 at 01:59:16PM +0300, Jani Nikula wrote: > Make drm_connector_update_edid_property() a thin wrapper around a struct > drm_edid based version of the same. > > This lets us remove the legacy drm_update_tile_info() and > drm_add_display_info() functions altogether. > > Signed-off-by: Jani Nikula Reviewed-by: Ville Syrjälä > --- > drivers/gpu/drm/drm_edid.c | 81 -- > 1 file changed, 35 insertions(+), 46 deletions(-) > > diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c > index 36bf7b0fe8d9..62967db78139 100644 > --- a/drivers/gpu/drm/drm_edid.c > +++ b/drivers/gpu/drm/drm_edid.c > @@ -6042,14 +6042,6 @@ static u32 update_display_info(struct drm_connector > *connector, > return quirks; > } > > -static u32 drm_add_display_info(struct drm_connector *connector, const > struct edid *edid) > -{ > - struct drm_edid drm_edid; > - > - return update_display_info(connector, > -drm_edid_legacy_init(_edid, edid)); > -} > - > static struct drm_display_mode *drm_mode_displayid_detailed(struct > drm_device *dev, > struct > displayid_detailed_timings_1 *timings, > bool type_7) > @@ -6206,38 +6198,19 @@ static int drm_edid_connector_update(struct > drm_connector *connector, > return num_modes; > } > > -static void drm_update_tile_info(struct drm_connector *connector, > - const struct edid *edid); > +static void _drm_update_tile_info(struct drm_connector *connector, > + const struct drm_edid *drm_edid); > > -/** > - * drm_connector_update_edid_property - update the edid property of a > connector > - * @connector: drm connector > - * @edid: new value of the edid property > - * > - * This function creates a new blob modeset object and assigns its id to the > - * connector's edid property. > - * Since we also parse tile information from EDID's displayID block, we also > - * set the connector's tile property here. See > drm_connector_set_tile_property() > - * for more details. > - * > - * Returns: > - * Zero on success, negative errno on failure. > - */ > -int drm_connector_update_edid_property(struct drm_connector *connector, > -const struct edid *edid) > +static int _drm_connector_update_edid_property(struct drm_connector > *connector, > +const struct drm_edid *drm_edid) > { > struct drm_device *dev = connector->dev; > - size_t size = 0; > int ret; > - const struct edid *old_edid; > > /* ignore requests to set edid when overridden */ > if (connector->override_edid) > return 0; > > - if (edid) > - size = EDID_LENGTH * (1 + edid->extensions); > - > /* >* Set the display info, using edid if available, otherwise resetting >* the values to defaults. This duplicates the work done in > @@ -6246,17 +6219,18 @@ int drm_connector_update_edid_property(struct > drm_connector *connector, >* that it seems better to duplicate it rather than attempt to ensure >* some arbitrary ordering of calls. >*/ > - if (edid) > - drm_add_display_info(connector, edid); > + if (drm_edid) > + update_display_info(connector, drm_edid); > else > drm_reset_display_info(connector); > > - drm_update_tile_info(connector, edid); > + _drm_update_tile_info(connector, drm_edid); > > if (connector->edid_blob_ptr) { > - old_edid = (const struct edid *)connector->edid_blob_ptr->data; > + const struct edid *old_edid = connector->edid_blob_ptr->data; > + > if (old_edid) { > - if (!drm_edid_are_equal(edid, old_edid)) { > + if (!drm_edid_are_equal(drm_edid ? drm_edid->edid : > NULL, old_edid)) { > DRM_DEBUG_KMS("[CONNECTOR:%d:%s] Edid was > changed.\n", > connector->base.id, > connector->name); > > @@ -6273,14 +6247,37 @@ int drm_connector_update_edid_property(struct > drm_connector *connector, > > ret = drm_property_replace_global_blob(dev, > >edid_blob_ptr, > -size, > -edid, > +drm_edid ? drm_edid->size : 0, > +drm_edid ? drm_edid->edid : NULL, > >base, > dev->mode_config.edid_property); > if (ret) > return ret; > return drm_connector_set_tile_property(connector); > } > + > +/** > + *
Re: [PATCH v3 01/13] drm/edid: move drm_connector_update_edid_property() to drm_edid.c
On Wed, Jun 22, 2022 at 01:59:15PM +0300, Jani Nikula wrote: > The function needs access to drm_edid.c internals more than > drm_connector.c. We can make drm_reset_display_info(), > drm_add_display_info() and drm_update_tile_info() static. There will be > more benefits with follow-up struct drm_edid refactoring. > > Signed-off-by: Jani Nikula Reviewed-by: Ville Syrjälä > --- > drivers/gpu/drm/drm_connector.c | 74 - > drivers/gpu/drm/drm_crtc_internal.h | 3 - > drivers/gpu/drm/drm_edid.c | 86 +++-- > 3 files changed, 81 insertions(+), 82 deletions(-) > > diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c > index 28ea0f8196b9..2b9a8972eff1 100644 > --- a/drivers/gpu/drm/drm_connector.c > +++ b/drivers/gpu/drm/drm_connector.c > @@ -2078,80 +2078,6 @@ int drm_connector_set_tile_property(struct > drm_connector *connector) > } > EXPORT_SYMBOL(drm_connector_set_tile_property); > > -/** > - * drm_connector_update_edid_property - update the edid property of a > connector > - * @connector: drm connector > - * @edid: new value of the edid property > - * > - * This function creates a new blob modeset object and assigns its id to the > - * connector's edid property. > - * Since we also parse tile information from EDID's displayID block, we also > - * set the connector's tile property here. See > drm_connector_set_tile_property() > - * for more details. > - * > - * Returns: > - * Zero on success, negative errno on failure. > - */ > -int drm_connector_update_edid_property(struct drm_connector *connector, > -const struct edid *edid) > -{ > - struct drm_device *dev = connector->dev; > - size_t size = 0; > - int ret; > - const struct edid *old_edid; > - > - /* ignore requests to set edid when overridden */ > - if (connector->override_edid) > - return 0; > - > - if (edid) > - size = EDID_LENGTH * (1 + edid->extensions); > - > - /* Set the display info, using edid if available, otherwise > - * resetting the values to defaults. This duplicates the work > - * done in drm_add_edid_modes, but that function is not > - * consistently called before this one in all drivers and the > - * computation is cheap enough that it seems better to > - * duplicate it rather than attempt to ensure some arbitrary > - * ordering of calls. > - */ > - if (edid) > - drm_add_display_info(connector, edid); > - else > - drm_reset_display_info(connector); > - > - drm_update_tile_info(connector, edid); > - > - if (connector->edid_blob_ptr) { > - old_edid = (const struct edid *)connector->edid_blob_ptr->data; > - if (old_edid) { > - if (!drm_edid_are_equal(edid, old_edid)) { > - DRM_DEBUG_KMS("[CONNECTOR:%d:%s] Edid was > changed.\n", > - connector->base.id, > connector->name); > - > - connector->epoch_counter += 1; > - DRM_DEBUG_KMS("Updating change counter to > %llu\n", > - connector->epoch_counter); > - } > - } > - } > - > - drm_object_property_set_value(>base, > - dev->mode_config.non_desktop_property, > - connector->display_info.non_desktop); > - > - ret = drm_property_replace_global_blob(dev, > ->edid_blob_ptr, > -size, > -edid, > ->base, > -dev->mode_config.edid_property); > - if (ret) > - return ret; > - return drm_connector_set_tile_property(connector); > -} > -EXPORT_SYMBOL(drm_connector_update_edid_property); > - > /** > * drm_connector_set_link_status_property - Set link status property of a > connector > * @connector: drm connector > diff --git a/drivers/gpu/drm/drm_crtc_internal.h > b/drivers/gpu/drm/drm_crtc_internal.h > index 63279e984342..aecab5308bae 100644 > --- a/drivers/gpu/drm/drm_crtc_internal.h > +++ b/drivers/gpu/drm/drm_crtc_internal.h > @@ -286,6 +286,3 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, > > /* drm_edid.c */ > void drm_mode_fixup_1366x768(struct drm_display_mode *mode); > -void drm_reset_display_info(struct drm_connector *connector); > -u32 drm_add_display_info(struct drm_connector *connector, const struct edid > *edid); > -void drm_update_tile_info(struct drm_connector *connector, const struct edid > *edid); > diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c > index 2bdaf1e34a9d..36bf7b0fe8d9 100644 > --- a/drivers/gpu/drm/drm_edid.c > +++
[PATCH v4 2/2] drm/panfrost: Add support for devcoredump
In the event of a job timeout, debug dump information will be written into /sys/class/devcoredump. Inspired by etnaviv's similar feature. Signed-off-by: Adrián Larumbe --- drivers/gpu/drm/panfrost/Kconfig | 1 + drivers/gpu/drm/panfrost/Makefile| 3 +- drivers/gpu/drm/panfrost/panfrost_dump.c | 249 +++ drivers/gpu/drm/panfrost/panfrost_dump.h | 12 ++ drivers/gpu/drm/panfrost/panfrost_job.c | 3 + include/uapi/drm/panfrost_drm.h | 47 + 6 files changed, 314 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/panfrost/panfrost_dump.c create mode 100644 drivers/gpu/drm/panfrost/panfrost_dump.h diff --git a/drivers/gpu/drm/panfrost/Kconfig b/drivers/gpu/drm/panfrost/Kconfig index 86cdc0ce79e6..079600328be1 100644 --- a/drivers/gpu/drm/panfrost/Kconfig +++ b/drivers/gpu/drm/panfrost/Kconfig @@ -11,6 +11,7 @@ config DRM_PANFROST select DRM_GEM_SHMEM_HELPER select PM_DEVFREQ select DEVFREQ_GOV_SIMPLE_ONDEMAND + select WANT_DEV_COREDUMP help DRM driver for ARM Mali Midgard (T6xx, T7xx, T8xx) and Bifrost (G3x, G5x, G7x) GPUs. diff --git a/drivers/gpu/drm/panfrost/Makefile b/drivers/gpu/drm/panfrost/Makefile index b71935862417..7da2b3f02ed9 100644 --- a/drivers/gpu/drm/panfrost/Makefile +++ b/drivers/gpu/drm/panfrost/Makefile @@ -9,6 +9,7 @@ panfrost-y := \ panfrost_gpu.o \ panfrost_job.o \ panfrost_mmu.o \ - panfrost_perfcnt.o + panfrost_perfcnt.o \ + panfrost_dump.o obj-$(CONFIG_DRM_PANFROST) += panfrost.o diff --git a/drivers/gpu/drm/panfrost/panfrost_dump.c b/drivers/gpu/drm/panfrost/panfrost_dump.c new file mode 100644 index ..a710ed7bcefa --- /dev/null +++ b/drivers/gpu/drm/panfrost/panfrost_dump.c @@ -0,0 +1,249 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright 2021 Collabora ltd. */ + +#include +#include +#include +#include +#include +#include +#include + +#include "panfrost_job.h" +#include "panfrost_gem.h" +#include "panfrost_regs.h" +#include "panfrost_dump.h" +#include "panfrost_device.h" + +static bool panfrost_dump_core = true; +module_param_named(dump_core, panfrost_dump_core, bool, 0600); + +struct panfrost_dump_iterator { + void *start; + struct panfrost_dump_object_header *hdr; + void *data; +}; + +static const unsigned short panfrost_dump_registers[] = { + SHADER_READY_LO, + SHADER_READY_HI, + TILER_READY_LO, + TILER_READY_HI, + L2_READY_LO, + L2_READY_HI, + JOB_INT_MASK, + JOB_INT_STAT, + JS_HEAD_LO(0), + JS_HEAD_HI(0), + JS_TAIL_LO(0), + JS_TAIL_HI(0), + JS_AFFINITY_LO(0), + JS_AFFINITY_HI(0), + JS_CONFIG(0), + JS_STATUS(0), + JS_HEAD_NEXT_LO(0), + JS_HEAD_NEXT_HI(0), + JS_AFFINITY_NEXT_LO(0), + JS_AFFINITY_NEXT_HI(0), + JS_CONFIG_NEXT(0), + MMU_INT_MASK, + MMU_INT_STAT, + AS_TRANSTAB_LO(0), + AS_TRANSTAB_HI(0), + AS_MEMATTR_LO(0), + AS_MEMATTR_HI(0), + AS_FAULTSTATUS(0), + AS_FAULTADDRESS_LO(0), + AS_FAULTADDRESS_HI(0), + AS_STATUS(0), +}; + +static void panfrost_core_dump_header(struct panfrost_dump_iterator *iter, + u32 type, void *data_end) +{ + struct panfrost_dump_object_header *hdr = iter->hdr; + + hdr->magic = cpu_to_le32(PANFROSTDUMP_MAGIC); + hdr->type = cpu_to_le32(type); + hdr->file_offset = cpu_to_le32(iter->data - iter->start); + hdr->file_size = cpu_to_le32(data_end - iter->data); + + iter->hdr++; + iter->data += le32_to_cpu(hdr->file_size); +} + +static void +panfrost_core_dump_registers(struct panfrost_dump_iterator *iter, +struct panfrost_device *pfdev, +u32 as_nr, int slot) +{ + struct panfrost_dump_registers *dumpreg = iter->data; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(panfrost_dump_registers); i++, dumpreg++) { + unsigned int js_as_offset = 0; + unsigned int reg; + + if (panfrost_dump_registers[i] >= JS_HEAD_LO(0) && + panfrost_dump_registers[i] <= JS_CONFIG_NEXT(0)) + js_as_offset = slot * JS_SLOT_STRIDE; + else if (panfrost_dump_registers[i] >= AS_TRANSTAB_LO(0) && +panfrost_dump_registers[i] <= AS_STATUS(0)) + js_as_offset = (as_nr << MMU_AS_SHIFT); + + reg = panfrost_dump_registers[i] + js_as_offset; + + dumpreg->reg = cpu_to_le32(reg); + dumpreg->value = cpu_to_le32(gpu_read(pfdev, reg)); + } + + panfrost_core_dump_header(iter, PANFROSTDUMP_BUF_REG, dumpreg); +} + +void panfrost_core_dump(struct panfrost_job *job) +{ + struct panfrost_device *pfdev = job->pfdev; + struct panfrost_dump_iterator iter; + struct drm_gem_object
[PATCH v4 1/2] drm/panfrost: Add specific register offset macros for JS and MMU AS
Each Panfrost job has its own job slot and MMU address space set of registers, which are selected with a job-specific index. Turn the shift and stride used for selection of the right register set base into a define rather than using magic numbers. Signed-off-by: Adrián Larumbe --- drivers/gpu/drm/panfrost/panfrost_regs.h | 39 +--- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/panfrost/panfrost_regs.h b/drivers/gpu/drm/panfrost/panfrost_regs.h index accb4fa3adb8..1ddc6c4c5e1c 100644 --- a/drivers/gpu/drm/panfrost/panfrost_regs.h +++ b/drivers/gpu/drm/panfrost/panfrost_regs.h @@ -225,24 +225,26 @@ #define JOB_INT_MASK_ERR(j)BIT((j) + 16) #define JOB_INT_MASK_DONE(j) BIT(j) +#define JS_SLOT_STRIDE 0x80 + #define JS_BASE0x1800 -#define JS_HEAD_LO(n) (JS_BASE + ((n) * 0x80) + 0x00) -#define JS_HEAD_HI(n) (JS_BASE + ((n) * 0x80) + 0x04) -#define JS_TAIL_LO(n) (JS_BASE + ((n) * 0x80) + 0x08) -#define JS_TAIL_HI(n) (JS_BASE + ((n) * 0x80) + 0x0c) -#define JS_AFFINITY_LO(n) (JS_BASE + ((n) * 0x80) + 0x10) -#define JS_AFFINITY_HI(n) (JS_BASE + ((n) * 0x80) + 0x14) -#define JS_CONFIG(n) (JS_BASE + ((n) * 0x80) + 0x18) -#define JS_XAFFINITY(n)(JS_BASE + ((n) * 0x80) + 0x1c) -#define JS_COMMAND(n) (JS_BASE + ((n) * 0x80) + 0x20) -#define JS_STATUS(n) (JS_BASE + ((n) * 0x80) + 0x24) -#define JS_HEAD_NEXT_LO(n) (JS_BASE + ((n) * 0x80) + 0x40) -#define JS_HEAD_NEXT_HI(n) (JS_BASE + ((n) * 0x80) + 0x44) -#define JS_AFFINITY_NEXT_LO(n) (JS_BASE + ((n) * 0x80) + 0x50) -#define JS_AFFINITY_NEXT_HI(n) (JS_BASE + ((n) * 0x80) + 0x54) -#define JS_CONFIG_NEXT(n) (JS_BASE + ((n) * 0x80) + 0x58) -#define JS_COMMAND_NEXT(n) (JS_BASE + ((n) * 0x80) + 0x60) -#define JS_FLUSH_ID_NEXT(n)(JS_BASE + ((n) * 0x80) + 0x70) +#define JS_HEAD_LO(n) (JS_BASE + ((n) * JS_SLOT_STRIDE) + 0x00) +#define JS_HEAD_HI(n) (JS_BASE + ((n) * JS_SLOT_STRIDE) + 0x04) +#define JS_TAIL_LO(n) (JS_BASE + ((n) * JS_SLOT_STRIDE) + 0x08) +#define JS_TAIL_HI(n) (JS_BASE + ((n) * JS_SLOT_STRIDE) + 0x0c) +#define JS_AFFINITY_LO(n) (JS_BASE + ((n) * JS_SLOT_STRIDE) + 0x10) +#define JS_AFFINITY_HI(n) (JS_BASE + ((n) * JS_SLOT_STRIDE) + 0x14) +#define JS_CONFIG(n) (JS_BASE + ((n) * JS_SLOT_STRIDE) + 0x18) +#define JS_XAFFINITY(n)(JS_BASE + ((n) * JS_SLOT_STRIDE) + 0x1c) +#define JS_COMMAND(n) (JS_BASE + ((n) * JS_SLOT_STRIDE) + 0x20) +#define JS_STATUS(n) (JS_BASE + ((n) * JS_SLOT_STRIDE) + 0x24) +#define JS_HEAD_NEXT_LO(n) (JS_BASE + ((n) * JS_SLOT_STRIDE) + 0x40) +#define JS_HEAD_NEXT_HI(n) (JS_BASE + ((n) * JS_SLOT_STRIDE) + 0x44) +#define JS_AFFINITY_NEXT_LO(n) (JS_BASE + ((n) * JS_SLOT_STRIDE) + 0x50) +#define JS_AFFINITY_NEXT_HI(n) (JS_BASE + ((n) * JS_SLOT_STRIDE) + 0x54) +#define JS_CONFIG_NEXT(n) (JS_BASE + ((n) * JS_SLOT_STRIDE) + 0x58) +#define JS_COMMAND_NEXT(n) (JS_BASE + ((n) * JS_SLOT_STRIDE) + 0x60) +#define JS_FLUSH_ID_NEXT(n)(JS_BASE + ((n) * JS_SLOT_STRIDE) + 0x70) /* Possible values of JS_CONFIG and JS_CONFIG_NEXT registers */ #define JS_CONFIG_START_FLUSH_CLEANBIT(8) @@ -281,7 +283,8 @@ #define AS_COMMAND_FLUSH_MEM 0x05/* Wait for memory accesses to complete, flush all the L1s cache then flush all L2 caches then issue a flush region command to all MMUs */ -#define MMU_AS(as) (0x2400 + ((as) << 6)) +#define MMU_AS_SHIFT 0x06 +#define MMU_AS(as) (0x2400 + ((as) << MMU_AS_SHIFT)) #define AS_TRANSTAB_LO(as) (MMU_AS(as) + 0x00) /* (RW) Translation Table Base Address for address space n, low word */ #define AS_TRANSTAB_HI(as) (MMU_AS(as) + 0x04) /* (RW) Translation Table Base Address for address space n, high word */ -- 2.36.1