RE: [PATCH] drm/radeon: ERROR: "foo* bar" should be "foo *bar"
[Public] Reviewed-by: Srinivasan Shanmugam -Original Message- From: amd-gfx On Behalf Of shijie...@208suo.com Sent: Friday, July 14, 2023 1:36 PM To: Deucher, Alexander ; Pan, Xinhui ; airl...@gmail.com; dan...@ffwll.ch Cc: dri-devel@lists.freedesktop.org; amd-...@lists.freedesktop.org; linux-ker...@vger.kernel.org Subject: [PATCH] drm/radeon: ERROR: "foo* bar" should be "foo *bar" Fix five occurrences of the checkpatch.pl error: ERROR: "foo* bar" should be "foo *bar" ERROR: that open brace { should be on the previous line Signed-off-by: Jie Shi --- drivers/gpu/drm/radeon/radeon_audio.c | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c index d6ccaf24ee0c..a010bc2c155c 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.c +++ b/drivers/gpu/drm/radeon/radeon_audio.c @@ -35,15 +35,14 @@ void dce6_audio_enable(struct radeon_device *rdev, struct r600_audio_pin *pin, u8 enable_mask); -struct r600_audio_pin* r600_audio_get_pin(struct radeon_device *rdev); -struct r600_audio_pin* dce6_audio_get_pin(struct radeon_device *rdev); +struct r600_audio_pin *r600_audio_get_pin(struct radeon_device *rdev); +struct r600_audio_pin *dce6_audio_get_pin(struct radeon_device *rdev); static void radeon_audio_hdmi_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode); static void radeon_audio_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode); -static const u32 pin_offsets[7] = -{ +static const u32 pin_offsets[7] = { (0x5e00 - 0x5e00), (0x5e18 - 0x5e00), (0x5e30 - 0x5e00), @@ -359,7 +358,7 @@ static void radeon_audio_write_latency_fields(struct drm_encoder *encoder, radeon_encoder->audio->write_latency_fields(encoder, connector, mode); } -struct r600_audio_pin* radeon_audio_get_pin(struct drm_encoder *encoder) +struct r600_audio_pin *radeon_audio_get_pin(struct drm_encoder *encoder) { struct radeon_device *rdev = encoder->dev->dev_private; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); @@ -526,7 +525,7 @@ static void radeon_audio_calc_cts(unsigned int clock, int *CTS, int *N, int freq *N, *CTS, freq); } -static const struct radeon_hdmi_acr* radeon_audio_acr(unsigned int clock) +static const struct radeon_hdmi_acr *radeon_audio_acr(unsigned int clock) { static struct radeon_hdmi_acr res; u8 i;
Re: [PATCH 2/3] drm/scheduler: Fix UAF in drm_sched_fence_get_timeline_name
On 2023-07-14 05:57, Christian König wrote: > Am 14.07.23 um 11:49 schrieb Asahi Lina: >> On 14/07/2023 17.43, Christian König wrote: >>> Am 14.07.23 um 10:21 schrieb Asahi Lina: A signaled scheduler fence can outlive its scheduler, since fences are independencly reference counted. Therefore, we can't reference the scheduler in the get_timeline_name() implementation. Fixes oopses on `cat /sys/kernel/debug/dma_buf/bufinfo` when shared dma-bufs reference fences from GPU schedulers that no longer exist. Signed-off-by: Asahi Lina --- drivers/gpu/drm/scheduler/sched_entity.c | 7 ++- drivers/gpu/drm/scheduler/sched_fence.c | 4 +++- include/drm/gpu_scheduler.h | 5 + 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c index b2bbc8a68b30..17f35b0b005a 100644 --- a/drivers/gpu/drm/scheduler/sched_entity.c +++ b/drivers/gpu/drm/scheduler/sched_entity.c @@ -389,7 +389,12 @@ static bool drm_sched_entity_add_dependency_cb(struct drm_sched_entity *entity) /* * Fence is from the same scheduler, only need to wait for - * it to be scheduled + * it to be scheduled. + * + * Note: s_fence->sched could have been freed and reallocated + * as another scheduler. This false positive case is okay, as if + * the old scheduler was freed all of its jobs must have + * signaled their completion fences. >>> >>> This is outright nonsense. As long as an entity for a scheduler exists >>> it is not allowed to free up this scheduler. >>> >>> So this function can't be called like this. >> >> As I already explained, the fences can outlive their scheduler. That >> means *this* entity certainly exists for *this* scheduler, but the >> *dependency* fence might have come from a past scheduler that was >> already destroyed along with all of its entities, and its address reused. > > Well this is function is not about fences, this function is a callback > for the entity. > >> >> Christian, I'm really getting tired of your tone. I don't appreciate >> being told my comments are "outright nonsense" when you don't even >> take the time to understand what the issue is and what I'm trying to >> do/document. If you aren't interested in working with me, I'm just >> going to give up on drm_sched, wait until Rust gets workqueue support, >> and reimplement it in Rust. You can keep your broken fence lifetime >> semantics and I'll do my own thing. > > I'm certainly trying to help here, but you seem to have unrealistic > expectations. > > I perfectly understand what you are trying to do, but you don't seem to > understand that this functionality here isn't made for your use case. > > We can adjust the functionality to better match your requirements, but > you can't say it is broken because it doesn't work when you use it not > in the way it is intended to be used. I believe "adjusting" functionality to fit some external requirements, may have unintended consequences, requiring yet more and more "adjustments". (Or may allow (new) drivers to do wild things which may lead to wild results. :-) ) We need to be extra careful and wary of this. -- Regards, Luben
Re: [PATCH v2] drm/msm/dsi: Enable DATABUS_WIDEN for DSI command mode
On 15/07/2023 03:59, Jessica Zhang wrote: On 7/14/2023 3:30 PM, Dmitry Baryshkov wrote: On Fri, 14 Jul 2023 at 22:03, Jessica Zhang wrote: On 7/13/2023 6:23 PM, Dmitry Baryshkov wrote: On 14/07/2023 03:21, Jessica Zhang wrote: DSI 6G v2.5.x+ and DPU 7.x+ support a data-bus widen mode that allows DSI to send 48 bits of compressed data per pclk instead of 24. For all chipsets that support this mode, enable it whenever DSC is enabled as recommended by the hardware programming guide. Only enable this for command mode as we are currently unable to validate it for video mode. Signed-off-by: Jessica Zhang --- Note: The dsi.xml.h changes were generated using the headergen2 script in envytools [2], but the changes to the copyright and rules-ng-ng source file paths were dropped. Separate commit please, so that it can be replaced by headers sync with Mesa3d. Hi Dmitry, Acked. [1] https://patchwork.freedesktop.org/series/120580/ [2] https://github.com/freedreno/envytools/ -- Changes in v2: - Rebased on top of "drm/msm/dpu: Re-introduce dpu core revision" - Squashed all commits to avoid breaking feature if the series is only partially applied No. Please unsquash it. Please design the series so that the patches work even if it is only partially applied. Acked. - Moved DATABUS_WIDEN bit setting to dsi_ctr_enable() (Marijn) - Have DPU check if wide bus is requested by output driver (Dmitry) - Introduced bytes_per_pclk variable for dsi_timing_setup() hdisplay adjustment (Marijn) - Link to v1: https://lore.kernel.org/r/20230525-add-widebus-support-v1-0-c7069f2ef...@quicinc.com --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 10 ++ .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 4 +++- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 3 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h | 1 + drivers/gpu/drm/msm/dsi/dsi.c | 5 + drivers/gpu/drm/msm/dsi/dsi.h | 1 + drivers/gpu/drm/msm/dsi/dsi.xml.h | 1 + drivers/gpu/drm/msm/dsi/dsi_host.c | 23 +- drivers/gpu/drm/msm/msm_drv.h | 6 ++ 9 files changed, 48 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index f0a2a1dca741..6aed63c06c1d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -2411,6 +2411,7 @@ struct drm_encoder *dpu_encoder_init(struct drm_device *dev, struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms); struct drm_encoder *drm_enc = NULL; struct dpu_encoder_virt *dpu_enc = NULL; + int index = disp_info->h_tile_instance[0]; int ret = 0; dpu_enc = devm_kzalloc(dev->dev, sizeof(*dpu_enc), GFP_KERNEL); @@ -2439,13 +2440,14 @@ struct drm_encoder *dpu_encoder_init(struct drm_device *dev, timer_setup(_enc->frame_done_timer, dpu_encoder_frame_done_timeout, 0); - if (disp_info->intf_type == INTF_DSI) + if (disp_info->intf_type == INTF_DSI) { timer_setup(_enc->vsync_event_timer, dpu_encoder_vsync_event_handler, While you are touching this part, could you please drop dpu_encoder_vsync_event_handler() and dpu_encoder_vsync_event_work_handler(), they are useless? Since these calls aren't related to widebus, I don't think I'll include it in this series. However, I can post this cleanup as a separate patch and add that as a dependency if that's ok. Sure, that will work for me. Thank you! 0); - else if (disp_info->intf_type == INTF_DP) - dpu_enc->wide_bus_en = msm_dp_wide_bus_available( - priv->dp[disp_info->h_tile_instance[0]]); + dpu_enc->wide_bus_en = msm_dsi_is_widebus_enabled(priv->dsi[index]); + } else if (disp_info->intf_type == INTF_DP) { + dpu_enc->wide_bus_en = msm_dp_wide_bus_available(priv->dp[index]); + } INIT_DELAYED_WORK(_enc->delayed_off_work, dpu_encoder_off_work); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c index df88358e7037..dace6168be2d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c @@ -69,8 +69,10 @@ static void _dpu_encoder_phys_cmd_update_intf_cfg( phys_enc->hw_intf, phys_enc->hw_pp->idx); - if (intf_cfg.dsc != 0) + if (intf_cfg.dsc != 0) { cmd_mode_cfg.data_compress = true; + cmd_mode_cfg.wide_bus_en = dpu_encoder_is_widebus_enabled(phys_enc->parent); + } if (phys_enc->hw_intf->ops.program_intf_cmd_cfg) phys_enc->hw_intf->ops.program_intf_cmd_cfg(phys_enc->hw_intf, _mode_cfg); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
Re: [PATCH v2] drm/msm/dsi: Enable DATABUS_WIDEN for DSI command mode
On 7/14/2023 3:30 PM, Dmitry Baryshkov wrote: On Fri, 14 Jul 2023 at 22:03, Jessica Zhang wrote: On 7/13/2023 6:23 PM, Dmitry Baryshkov wrote: On 14/07/2023 03:21, Jessica Zhang wrote: DSI 6G v2.5.x+ and DPU 7.x+ support a data-bus widen mode that allows DSI to send 48 bits of compressed data per pclk instead of 24. For all chipsets that support this mode, enable it whenever DSC is enabled as recommended by the hardware programming guide. Only enable this for command mode as we are currently unable to validate it for video mode. Signed-off-by: Jessica Zhang --- Note: The dsi.xml.h changes were generated using the headergen2 script in envytools [2], but the changes to the copyright and rules-ng-ng source file paths were dropped. Separate commit please, so that it can be replaced by headers sync with Mesa3d. Hi Dmitry, Acked. [1] https://patchwork.freedesktop.org/series/120580/ [2] https://github.com/freedreno/envytools/ -- Changes in v2: - Rebased on top of "drm/msm/dpu: Re-introduce dpu core revision" - Squashed all commits to avoid breaking feature if the series is only partially applied No. Please unsquash it. Please design the series so that the patches work even if it is only partially applied. Acked. - Moved DATABUS_WIDEN bit setting to dsi_ctr_enable() (Marijn) - Have DPU check if wide bus is requested by output driver (Dmitry) - Introduced bytes_per_pclk variable for dsi_timing_setup() hdisplay adjustment (Marijn) - Link to v1: https://lore.kernel.org/r/20230525-add-widebus-support-v1-0-c7069f2ef...@quicinc.com --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c| 10 ++ .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 4 +++- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c| 3 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h| 1 + drivers/gpu/drm/msm/dsi/dsi.c | 5 + drivers/gpu/drm/msm/dsi/dsi.h | 1 + drivers/gpu/drm/msm/dsi/dsi.xml.h | 1 + drivers/gpu/drm/msm/dsi/dsi_host.c | 23 +- drivers/gpu/drm/msm/msm_drv.h | 6 ++ 9 files changed, 48 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index f0a2a1dca741..6aed63c06c1d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -2411,6 +2411,7 @@ struct drm_encoder *dpu_encoder_init(struct drm_device *dev, struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms); struct drm_encoder *drm_enc = NULL; struct dpu_encoder_virt *dpu_enc = NULL; +int index = disp_info->h_tile_instance[0]; int ret = 0; dpu_enc = devm_kzalloc(dev->dev, sizeof(*dpu_enc), GFP_KERNEL); @@ -2439,13 +2440,14 @@ struct drm_encoder *dpu_encoder_init(struct drm_device *dev, timer_setup(_enc->frame_done_timer, dpu_encoder_frame_done_timeout, 0); -if (disp_info->intf_type == INTF_DSI) +if (disp_info->intf_type == INTF_DSI) { timer_setup(_enc->vsync_event_timer, dpu_encoder_vsync_event_handler, While you are touching this part, could you please drop dpu_encoder_vsync_event_handler() and dpu_encoder_vsync_event_work_handler(), they are useless? Since these calls aren't related to widebus, I don't think I'll include it in this series. However, I can post this cleanup as a separate patch and add that as a dependency if that's ok. Sure, that will work for me. Thank you! 0); -else if (disp_info->intf_type == INTF_DP) -dpu_enc->wide_bus_en = msm_dp_wide_bus_available( -priv->dp[disp_info->h_tile_instance[0]]); +dpu_enc->wide_bus_en = msm_dsi_is_widebus_enabled(priv->dsi[index]); +} else if (disp_info->intf_type == INTF_DP) { +dpu_enc->wide_bus_en = msm_dp_wide_bus_available(priv->dp[index]); +} INIT_DELAYED_WORK(_enc->delayed_off_work, dpu_encoder_off_work); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c index df88358e7037..dace6168be2d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c @@ -69,8 +69,10 @@ static void _dpu_encoder_phys_cmd_update_intf_cfg( phys_enc->hw_intf, phys_enc->hw_pp->idx); -if (intf_cfg.dsc != 0) +if (intf_cfg.dsc != 0) { cmd_mode_cfg.data_compress = true; +cmd_mode_cfg.wide_bus_en = dpu_encoder_is_widebus_enabled(phys_enc->parent); +} if (phys_enc->hw_intf->ops.program_intf_cmd_cfg) phys_enc->hw_intf->ops.program_intf_cmd_cfg(phys_enc->hw_intf, _mode_cfg); 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 8ec6505d9e78..dc6f3febb574 100644 ---
Re: [PATCH v2 05/13] drm/msm/dpu: use devres-managed allocation for MDP TOP
On 7/7/2023 4:12 PM, Dmitry Baryshkov wrote: Use devm_kzalloc to create MDP TOP structure. This allows us to remove corresponding kfree and drop dpu_hw_mdp_destroy() function. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c | 17 +++-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h | 8 +--- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c| 5 ++--- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c index cff48763ce25..481b373d9ccb 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c @@ -2,6 +2,8 @@ /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ +#include + #include "dpu_hwio.h" #include "dpu_hw_catalog.h" #include "dpu_hw_top.h" @@ -268,16 +270,17 @@ static void _setup_mdp_ops(struct dpu_hw_mdp_ops *ops, ops->intf_audio_select = dpu_hw_intf_audio_select; } -struct dpu_hw_mdp *dpu_hw_mdptop_init(const struct dpu_mdp_cfg *cfg, - void __iomem *addr, - const struct dpu_mdss_cfg *m) +struct dpu_hw_mdp *dpu_hw_mdptop_init(struct drm_device *dev, + const struct dpu_mdp_cfg *cfg, + void __iomem *addr, + const struct dpu_mdss_cfg *m) { struct dpu_hw_mdp *mdp; if (!addr) return ERR_PTR(-EINVAL); - mdp = kzalloc(sizeof(*mdp), GFP_KERNEL); + mdp = drmm_kzalloc(dev, sizeof(*mdp), GFP_KERNEL); if (!mdp) return ERR_PTR(-ENOMEM); @@ -292,9 +295,3 @@ struct dpu_hw_mdp *dpu_hw_mdptop_init(const struct dpu_mdp_cfg *cfg, return mdp; } - -void dpu_hw_mdp_destroy(struct dpu_hw_mdp *mdp) -{ - kfree(mdp); -} - diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h index 8b1463d2b2f0..6f3dc98087df 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h @@ -145,13 +145,15 @@ struct dpu_hw_mdp { /** * dpu_hw_mdptop_init - initializes the top driver for the passed config + * @dev: Corresponding device for devres management * @cfg: MDP TOP configuration from catalog * @addr: Mapped register io address of MDP * @m:Pointer to mdss catalog data */ -struct dpu_hw_mdp *dpu_hw_mdptop_init(const struct dpu_mdp_cfg *cfg, - void __iomem *addr, - const struct dpu_mdss_cfg *m); +struct dpu_hw_mdp *dpu_hw_mdptop_init(struct drm_device *dev, + const struct dpu_mdp_cfg *cfg, + void __iomem *addr, + const struct dpu_mdss_cfg *m); void dpu_hw_mdp_destroy(struct dpu_hw_mdp *mdp); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index f7723f89cbbc..48c3f8b6b88f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -822,8 +822,6 @@ static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms) dpu_kms->catalog = NULL; - if (dpu_kms->hw_mdp) - dpu_hw_mdp_destroy(dpu_kms->hw_mdp); Hi Dmitry, This section is causing a merge conflict for me. Seems that your working branch is missing a section of code [1]: ``` ... if (dpu_kms->vbif[VBIF_NRT]) devm_iounmap(_kms->pdev->dev, dpu_kms->vbif[VBIF_NRT]); dpu_kms->vbif[VBIF_NRT] = NULL; if (dpu_kms->vbif[VBIF_RT]) devm_iounmap(_kms->pdev->dev, dpu_kms->vbif[VBIF_RT]); dpu_kms->vbif[VBIF_RT] = NULL; ... ``` Unfortunately, I'm unable to find which series removed it. Can you list the relevant series as a dependency? Thanks, Jessica Zhang [1] https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c#L812 dpu_kms->hw_mdp = NULL; } @@ -1051,7 +1049,8 @@ static int dpu_kms_hw_init(struct msm_kms *kms) dpu_kms->rm_init = true; - dpu_kms->hw_mdp = dpu_hw_mdptop_init(dpu_kms->catalog->mdp, + dpu_kms->hw_mdp = dpu_hw_mdptop_init(dev, +dpu_kms->catalog->mdp, dpu_kms->mmio, dpu_kms->catalog); if (IS_ERR(dpu_kms->hw_mdp)) { -- 2.39.2
Re: [RFC 2/2] drm/i915: Remove PAT hack from i915_gem_object_can_bypass_llc
On Fri, Jul 14, 2023 at 11:11:30AM +0100, Tvrtko Ursulin wrote: > > On 14/07/2023 06:43, Yang, Fei wrote: > > > From: Tvrtko Ursulin > > > > > > According to the comment in i915_gem_object_can_bypass_llc the > > > purpose of the function is to return false if the platform/object > > > has a caching mode where GPU can bypass the LLC. > > > > > > So far the only platforms which allegedly can do this are Jasperlake > > > and Elkhartlake, and that via MOCS (not PAT). > > > > > > Instead of blindly assuming that objects where userspace has set the > > > PAT index can (bypass the LLC), question is is there a such PAT index > > > on a platform. Probably starting with Meteorlake since that one is the > > > only one where set PAT extension can be currently used. Or if there is > > > a MOCS entry which can achieve the same thing on Meteorlake. > > > > > > If there is such PAT, now that i915 can be made to understand them > > > better, we can make the check more fine grained. Or if there is a MOCS > > > entry then we probably should apply the blanket IS_METEORLAKE condition. > > > > > > Signed-off-by: Tvrtko Ursulin > > > Fixes: 9275277d5324 ("drm/i915: use pat_index instead of cache_level") > > > Cc: Chris Wilson > > > Cc: Fei Yang > > > Cc: Andi Shyti > > > Cc: Matt Roper > > > --- > > > drivers/gpu/drm/i915/gem/i915_gem_object.c | 6 -- > > > 1 file changed, 6 deletions(-) > > > > > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c > > > b/drivers/gpu/drm/i915/gem/i915_gem_object.c > > > index 33a1e97d18b3..1e34171c4162 100644 > > > --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c > > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c > > > @@ -229,12 +229,6 @@ bool i915_gem_object_can_bypass_llc(struct > > > drm_i915_gem_object *obj) > > >if (!(obj->flags & I915_BO_ALLOC_USER)) > > >return false; > > > > > > - /* > > > - * Always flush cache for UMD objects at creation time. > > > - */ > > > - if (obj->pat_set_by_user) > > > > I'm afraid this is going to break MESA. Can we run MESA tests with this > > patch? > > I can't, but question is why it would break Mesa which would need a nice > comment here? > > For instance should the check be IS_METEORLAKE? > > Or should it be "is wb" && "not has 1-way coherent"? > > Or both? > > Or, given how Meteorlake does not have LLC, how can anything bypass it > there? Or is it about snooping on Meteorlake and how? I think the "LLC" in the function name is a bit misleading since this is really all just about the ability to avoid coherency (which might come from an LLC on some platforms or from snooping on others). The concern is that the CPU writes to the buffer and those writes sit in a CPU cache without making it to RAM immediately. If the GPU then reads the object with any of the non-coherent PAT settings that were introduced in Xe_LPG, it will not snoop the CPU cache and will read old, stale data from RAM. So I think we'd want a condition like ("Xe_LPG or later" && "any non coherent PAT"). The WB/WT/UC status of the GPU behavior shouldn't matter here, just the coherency setting. Matt > > Regards, > > Tvrtko > > > > > >/* > > > * EHL and JSL add the 'Bypass LLC' MOCS entry, which should make > > > it > > > * possible for userspace to bypass the GTT caching bits set by the > > > -- > > > 2.39.2 -- Matt Roper Graphics Software Engineer Linux GPU Platform Enablement Intel Corporation
Re: [PATCH] drm/nouveau/fifo:Fix Nineteen occurrences of the gk104.c error: ERROR: : trailing statements should be on next line
NAK - checkpatch.pl is a (strongish) guideline, but not a rule. In the cases corrected in the patch series here, we format the switch cases on single lines as it dramatically improves the readability of what is otherwise just a /long/ list of slightly different static mappings. I don't believe we're the only part of the kernel to do this either. On Fri, 2023-07-14 at 14:58 +0800, huzhi...@208suo.com wrote: > Signed-off-by: ZhiHu > --- > .../gpu/drm/nouveau/nvkm/engine/fifo/gk104.c | 40 ++- > 1 file changed, 29 insertions(+), 11 deletions(-) > > diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c > b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c > index d8a4d773a58c..b99e0a7c96bb 100644 > --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c > +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c > @@ -137,15 +137,29 @@ gk104_ectx_bind(struct nvkm_engn *engn, struct > nvkm_cctx *cctx, struct nvkm_chan > u64 addr = 0ULL; > > switch (engn->engine->subdev.type) { > -case NVKM_ENGINE_SW: return; > -case NVKM_ENGINE_GR: ptr0 = 0x0210; break; > -case NVKM_ENGINE_SEC : ptr0 = 0x0220; break; > -case NVKM_ENGINE_MSPDEC: ptr0 = 0x0250; break; > -case NVKM_ENGINE_MSPPP : ptr0 = 0x0260; break; > -case NVKM_ENGINE_MSVLD : ptr0 = 0x0270; break; > -case NVKM_ENGINE_VIC : ptr0 = 0x0280; break; > -case NVKM_ENGINE_MSENC : ptr0 = 0x0290; break; > -case NVKM_ENGINE_NVDEC : > +case NVKM_ENGINE_SW: > +return; > +case NVKM_ENGINE_GR: > +ptr0 = 0x0210; > +break; > +case NVKM_ENGINE_SEC: > +ptr0 = 0x0220; > +break; > +case NVKM_ENGINE_MSPDEC: > +ptr0 = 0x0250; > +break; > +case NVKM_ENGINE_MSPPP: > +ptr0 = 0x0260; > +break; > +case NVKM_ENGINE_MSVLD: > +ptr0 = 0x0270; > +break; > +case NVKM_ENGINE_VIC: > +ptr0 = 0x0280; break; > +case NVKM_ENGINE_MSENC: > +ptr0 = 0x0290; > +break; > +case NVKM_ENGINE_NVDEC: > ptr1 = 0x0270; > ptr0 = 0x0210; > break; > @@ -435,8 +449,12 @@ gk104_runl_commit(struct nvkm_runl *runl, struct > nvkm_memory *memory, u32 start, > int target; > > switch (nvkm_memory_target(memory)) { > -case NVKM_MEM_TARGET_VRAM: target = 0; break; > -case NVKM_MEM_TARGET_NCOH: target = 3; break; > +case NVKM_MEM_TARGET_VRAM: > +target = 0; > +break; > +case NVKM_MEM_TARGET_NCOH: > +target = 3; > +break; This one isn't very long, but I'd still say it's definitely a lot easier to read in the compact form. If anything, the only change I would make here is formatting the default: case to be on a single line as well > default: > WARN_ON(1); > return; -- Cheers, Lyude Paul (she/her) Software Engineer at Red Hat
Re: [PATCH v2] drm/msm/dsi: Enable DATABUS_WIDEN for DSI command mode
On Fri, 14 Jul 2023 at 22:03, Jessica Zhang wrote: > > > > On 7/13/2023 6:23 PM, Dmitry Baryshkov wrote: > > On 14/07/2023 03:21, Jessica Zhang wrote: > >> DSI 6G v2.5.x+ and DPU 7.x+ support a data-bus widen mode that allows DSI > >> to send 48 bits of compressed data per pclk instead of 24. > >> > >> For all chipsets that support this mode, enable it whenever DSC is > >> enabled as recommended by the hardware programming guide. > >> > >> Only enable this for command mode as we are currently unable to validate > >> it for video mode. > >> > >> Signed-off-by: Jessica Zhang > >> --- > >> Note: The dsi.xml.h changes were generated using the headergen2 script in > >> envytools [2], but the changes to the copyright and rules-ng-ng source > >> file > >> paths were dropped. > > > > Separate commit please, so that it can be replaced by headers sync with > > Mesa3d. > > Hi Dmitry, > > Acked. > > > > >> > >> [1] https://patchwork.freedesktop.org/series/120580/ > >> [2] https://github.com/freedreno/envytools/ > >> > >> -- > >> Changes in v2: > >> - Rebased on top of "drm/msm/dpu: Re-introduce dpu core revision" > >> - Squashed all commits to avoid breaking feature if the series is only > >> partially applied > > > > No. Please unsquash it. Please design the series so that the patches > > work even if it is only partially applied. > > Acked. > > > > >> - Moved DATABUS_WIDEN bit setting to dsi_ctr_enable() (Marijn) > >> - Have DPU check if wide bus is requested by output driver (Dmitry) > >> - Introduced bytes_per_pclk variable for dsi_timing_setup() hdisplay > >> adjustment (Marijn) > >> - Link to v1: > >> https://lore.kernel.org/r/20230525-add-widebus-support-v1-0-c7069f2ef...@quicinc.com > >> --- > >> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c| 10 ++ > >> .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 4 +++- > >> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c| 3 +++ > >> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h| 1 + > >> drivers/gpu/drm/msm/dsi/dsi.c | 5 + > >> drivers/gpu/drm/msm/dsi/dsi.h | 1 + > >> drivers/gpu/drm/msm/dsi/dsi.xml.h | 1 + > >> drivers/gpu/drm/msm/dsi/dsi_host.c | 23 > >> +- > >> drivers/gpu/drm/msm/msm_drv.h | 6 ++ > >> 9 files changed, 48 insertions(+), 6 deletions(-) > >> > >> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > >> b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > >> index f0a2a1dca741..6aed63c06c1d 100644 > >> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > >> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > >> @@ -2411,6 +2411,7 @@ struct drm_encoder *dpu_encoder_init(struct > >> drm_device *dev, > >> struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms); > >> struct drm_encoder *drm_enc = NULL; > >> struct dpu_encoder_virt *dpu_enc = NULL; > >> +int index = disp_info->h_tile_instance[0]; > >> int ret = 0; > >> dpu_enc = devm_kzalloc(dev->dev, sizeof(*dpu_enc), GFP_KERNEL); > >> @@ -2439,13 +2440,14 @@ struct drm_encoder *dpu_encoder_init(struct > >> drm_device *dev, > >> timer_setup(_enc->frame_done_timer, > >> dpu_encoder_frame_done_timeout, 0); > >> -if (disp_info->intf_type == INTF_DSI) > >> +if (disp_info->intf_type == INTF_DSI) { > >> timer_setup(_enc->vsync_event_timer, > >> dpu_encoder_vsync_event_handler, > > > > While you are touching this part, could you please drop > > dpu_encoder_vsync_event_handler() and > > dpu_encoder_vsync_event_work_handler(), they are useless? > > Since these calls aren't related to widebus, I don't think I'll include > it in this series. However, I can post this cleanup as a separate patch > and add that as a dependency if that's ok. Sure, that will work for me. Thank you! > > > > >> 0); > >> -else if (disp_info->intf_type == INTF_DP) > >> -dpu_enc->wide_bus_en = msm_dp_wide_bus_available( > >> -priv->dp[disp_info->h_tile_instance[0]]); > >> +dpu_enc->wide_bus_en = > >> msm_dsi_is_widebus_enabled(priv->dsi[index]); > >> +} else if (disp_info->intf_type == INTF_DP) { > >> +dpu_enc->wide_bus_en = > >> msm_dp_wide_bus_available(priv->dp[index]); > >> +} > >> INIT_DELAYED_WORK(_enc->delayed_off_work, > >> dpu_encoder_off_work); > >> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > >> b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > >> index df88358e7037..dace6168be2d 100644 > >> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > >> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > >> @@ -69,8 +69,10 @@ static void _dpu_encoder_phys_cmd_update_intf_cfg( > >> phys_enc->hw_intf, > >> phys_enc->hw_pp->idx); > >> -if (intf_cfg.dsc != 0) > >> +if (intf_cfg.dsc != 0) { > >>
Re: [PATCH v2] drm/msm/dsi: Enable DATABUS_WIDEN for DSI command mode
On Fri, 14 Jul 2023 at 23:09, Jessica Zhang wrote: > > > > On 7/14/2023 12:41 AM, Dmitry Baryshkov wrote: > > On 14/07/2023 03:21, Jessica Zhang wrote: > >> DSI 6G v2.5.x+ and DPU 7.x+ support a data-bus widen mode that allows DSI > > > > sm8250 has widebus support in DP and thus in DPU, according to the > > published DT. Thus the 'DPU 7.x+' is not fully correct. > > Hi Dmitry, > > Acked -- Will change this to say "DSI 6G v2.5+ supports a data-bus widen > mode for DPU 7.x+ that ... " instead. I'd suggest skipping DPU version at all. > > Thanks, > > Jessica Zhang > > > > >> to send 48 bits of compressed data per pclk instead of 24. > >> > >> For all chipsets that support this mode, enable it whenever DSC is > >> enabled as recommended by the hardware programming guide. > >> > >> Only enable this for command mode as we are currently unable to validate > >> it for video mode. > >> > >> Signed-off-by: Jessica Zhang > >> --- > >> Note: The dsi.xml.h changes were generated using the headergen2 script in > >> envytools [2], but the changes to the copyright and rules-ng-ng source > >> file > >> paths were dropped. > >> > >> [1] https://patchwork.freedesktop.org/series/120580/ > >> [2] https://github.com/freedreno/envytools/ > >> > >> -- > >> Changes in v2: > >> - Rebased on top of "drm/msm/dpu: Re-introduce dpu core revision" > >> - Squashed all commits to avoid breaking feature if the series is only > >> partially applied > >> - Moved DATABUS_WIDEN bit setting to dsi_ctr_enable() (Marijn) > >> - Have DPU check if wide bus is requested by output driver (Dmitry) > >> - Introduced bytes_per_pclk variable for dsi_timing_setup() hdisplay > >> adjustment (Marijn) > >> - Link to v1: > >> https://lore.kernel.org/r/20230525-add-widebus-support-v1-0-c7069f2ef...@quicinc.com > >> --- > >> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c| 10 ++ > >> .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 4 +++- > >> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c| 3 +++ > >> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h| 1 + > >> drivers/gpu/drm/msm/dsi/dsi.c | 5 + > >> drivers/gpu/drm/msm/dsi/dsi.h | 1 + > >> drivers/gpu/drm/msm/dsi/dsi.xml.h | 1 + > >> drivers/gpu/drm/msm/dsi/dsi_host.c | 23 > >> +- > >> drivers/gpu/drm/msm/msm_drv.h | 6 ++ > >> 9 files changed, 48 insertions(+), 6 deletions(-) > >> > >> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > >> b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > >> index f0a2a1dca741..6aed63c06c1d 100644 > >> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > >> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > >> @@ -2411,6 +2411,7 @@ struct drm_encoder *dpu_encoder_init(struct > >> drm_device *dev, > >> struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms); > >> struct drm_encoder *drm_enc = NULL; > >> struct dpu_encoder_virt *dpu_enc = NULL; > >> +int index = disp_info->h_tile_instance[0]; > >> int ret = 0; > >> dpu_enc = devm_kzalloc(dev->dev, sizeof(*dpu_enc), GFP_KERNEL); > >> @@ -2439,13 +2440,14 @@ struct drm_encoder *dpu_encoder_init(struct > >> drm_device *dev, > >> timer_setup(_enc->frame_done_timer, > >> dpu_encoder_frame_done_timeout, 0); > >> -if (disp_info->intf_type == INTF_DSI) > >> +if (disp_info->intf_type == INTF_DSI) { > >> timer_setup(_enc->vsync_event_timer, > >> dpu_encoder_vsync_event_handler, > >> 0); > >> -else if (disp_info->intf_type == INTF_DP) > >> -dpu_enc->wide_bus_en = msm_dp_wide_bus_available( > >> -priv->dp[disp_info->h_tile_instance[0]]); > >> +dpu_enc->wide_bus_en = > >> msm_dsi_is_widebus_enabled(priv->dsi[index]); > >> +} else if (disp_info->intf_type == INTF_DP) { > >> +dpu_enc->wide_bus_en = > >> msm_dp_wide_bus_available(priv->dp[index]); > >> +} > >> INIT_DELAYED_WORK(_enc->delayed_off_work, > >> dpu_encoder_off_work); > >> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > >> b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > >> index df88358e7037..dace6168be2d 100644 > >> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > >> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > >> @@ -69,8 +69,10 @@ static void _dpu_encoder_phys_cmd_update_intf_cfg( > >> phys_enc->hw_intf, > >> phys_enc->hw_pp->idx); > >> -if (intf_cfg.dsc != 0) > >> +if (intf_cfg.dsc != 0) { > >> cmd_mode_cfg.data_compress = true; > >> +cmd_mode_cfg.wide_bus_en = > >> dpu_encoder_is_widebus_enabled(phys_enc->parent); > >> +} > >> if (phys_enc->hw_intf->ops.program_intf_cmd_cfg) > >> > >> phys_enc->hw_intf->ops.program_intf_cmd_cfg(phys_enc->hw_intf, > >> _mode_cfg); > >> diff --git
Re: [Freedreno] [PATCH 1/2] drm/msm/adreno: Fix warn splat for devices without revn
On 7/4/2023 9:36 AM, Rob Clark wrote: From: Rob Clark Recently, a WARN_ON() was introduced to ensure that revn is filled before adreno_is_aXYZ is called. This however doesn't work very well when revn is 0 by design (such as for A635). Cc: Konrad Dybcio Fixes: cc943f43ece7 ("drm/msm/adreno: warn if chip revn is verified before being set") Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/adreno_gpu.h | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) Tested-by: Abhinav Kumar # sc7280
Re: [PATCH v2 01/13] drm/msm/dpu: cleanup dpu_kms_hw_init error path
On 7/7/2023 4:12 PM, Dmitry Baryshkov wrote: It was noticed that dpu_kms_hw_init()'s error path contains several labels which point to the same code path. Replace all of them with a single label. Suggested-by: Konrad Dybcio Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 21 + 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index c11b3ab572ab..e7ac02e92f42 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -1037,7 +1037,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) if (!dpu_kms->catalog) { DPU_ERROR("device config not known!\n"); rc = -EINVAL; - goto power_error; + goto err_pm_put; } /* @@ -1047,13 +1047,13 @@ static int dpu_kms_hw_init(struct msm_kms *kms) rc = _dpu_kms_mmu_init(dpu_kms); if (rc) { DPU_ERROR("dpu_kms_mmu_init failed: %d\n", rc); - goto power_error; + goto err_pm_put; } rc = dpu_rm_init(_kms->rm, dpu_kms->catalog, dpu_kms->mmio); if (rc) { DPU_ERROR("rm init failed: %d\n", rc); - goto power_error; + goto err_pm_put; } dpu_kms->rm_init = true; @@ -1065,7 +1065,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) rc = PTR_ERR(dpu_kms->hw_mdp); DPU_ERROR("failed to get hw_mdp: %d\n", rc); dpu_kms->hw_mdp = NULL; - goto power_error; + goto err_pm_put; } for (i = 0; i < dpu_kms->catalog->vbif_count; i++) { @@ -1076,7 +1076,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) if (IS_ERR(hw)) { rc = PTR_ERR(hw); DPU_ERROR("failed to init vbif %d: %d\n", vbif->id, rc); - goto power_error; + goto err_pm_put; } dpu_kms->hw_vbif[vbif->id] = hw; @@ -1092,7 +1092,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) rc = dpu_core_perf_init(_kms->perf, dpu_kms->catalog->perf, max_core_clk_rate); if (rc) { DPU_ERROR("failed to init perf %d\n", rc); - goto perf_err; + goto err_pm_put; } dpu_kms->hw_intr = dpu_hw_intr_init(dpu_kms->mmio, dpu_kms->catalog); @@ -1100,7 +1100,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) rc = PTR_ERR(dpu_kms->hw_intr); DPU_ERROR("hw_intr init failed: %d\n", rc); dpu_kms->hw_intr = NULL; - goto hw_intr_init_err; + goto err_pm_put; } dev->mode_config.min_width = 0; @@ -1125,7 +1125,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) rc = _dpu_kms_drm_obj_init(dpu_kms); if (rc) { DPU_ERROR("modeset init failed: %d\n", rc); - goto drm_obj_init_err; + goto err_pm_put; } dpu_vbif_init_memtypes(dpu_kms); @@ -1134,10 +1134,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) return 0; -drm_obj_init_err: Hey Dmitry, The change itself LGTM -- however, it seems that there's a dependency on the core perf cleanup series that wasn't listed in the cover letter. Thanks, Jessica Zhang -hw_intr_init_err: -perf_err: -power_error: +err_pm_put: pm_runtime_put_sync(_kms->pdev->dev); error: _dpu_kms_hw_destroy(dpu_kms); -- 2.39.2
[Bug 199979] amdgpu: changing pwm1_enable from 1 to 2 does not resume automatic fan control
https://bugzilla.kernel.org/show_bug.cgi?id=199979 Artem S. Tashkinov (a...@gmx.com) changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |ANSWERED --- Comment #2 from Artem S. Tashkinov (a...@gmx.com) --- Please report here if that's still an issue in 6.4.3. https://gitlab.freedesktop.org/drm/amd/-/issues -- 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] drm/msm/dsi: Enable DATABUS_WIDEN for DSI command mode
On 7/14/2023 12:41 AM, Dmitry Baryshkov wrote: On 14/07/2023 03:21, Jessica Zhang wrote: DSI 6G v2.5.x+ and DPU 7.x+ support a data-bus widen mode that allows DSI sm8250 has widebus support in DP and thus in DPU, according to the published DT. Thus the 'DPU 7.x+' is not fully correct. Hi Dmitry, Acked -- Will change this to say "DSI 6G v2.5+ supports a data-bus widen mode for DPU 7.x+ that ... " instead. Thanks, Jessica Zhang to send 48 bits of compressed data per pclk instead of 24. For all chipsets that support this mode, enable it whenever DSC is enabled as recommended by the hardware programming guide. Only enable this for command mode as we are currently unable to validate it for video mode. Signed-off-by: Jessica Zhang --- Note: The dsi.xml.h changes were generated using the headergen2 script in envytools [2], but the changes to the copyright and rules-ng-ng source file paths were dropped. [1] https://patchwork.freedesktop.org/series/120580/ [2] https://github.com/freedreno/envytools/ -- Changes in v2: - Rebased on top of "drm/msm/dpu: Re-introduce dpu core revision" - Squashed all commits to avoid breaking feature if the series is only partially applied - Moved DATABUS_WIDEN bit setting to dsi_ctr_enable() (Marijn) - Have DPU check if wide bus is requested by output driver (Dmitry) - Introduced bytes_per_pclk variable for dsi_timing_setup() hdisplay adjustment (Marijn) - Link to v1: https://lore.kernel.org/r/20230525-add-widebus-support-v1-0-c7069f2ef...@quicinc.com --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 10 ++ .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 4 +++- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 3 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h | 1 + drivers/gpu/drm/msm/dsi/dsi.c | 5 + drivers/gpu/drm/msm/dsi/dsi.h | 1 + drivers/gpu/drm/msm/dsi/dsi.xml.h | 1 + drivers/gpu/drm/msm/dsi/dsi_host.c | 23 +- drivers/gpu/drm/msm/msm_drv.h | 6 ++ 9 files changed, 48 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index f0a2a1dca741..6aed63c06c1d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -2411,6 +2411,7 @@ struct drm_encoder *dpu_encoder_init(struct drm_device *dev, struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms); struct drm_encoder *drm_enc = NULL; struct dpu_encoder_virt *dpu_enc = NULL; + int index = disp_info->h_tile_instance[0]; int ret = 0; dpu_enc = devm_kzalloc(dev->dev, sizeof(*dpu_enc), GFP_KERNEL); @@ -2439,13 +2440,14 @@ struct drm_encoder *dpu_encoder_init(struct drm_device *dev, timer_setup(_enc->frame_done_timer, dpu_encoder_frame_done_timeout, 0); - if (disp_info->intf_type == INTF_DSI) + if (disp_info->intf_type == INTF_DSI) { timer_setup(_enc->vsync_event_timer, dpu_encoder_vsync_event_handler, 0); - else if (disp_info->intf_type == INTF_DP) - dpu_enc->wide_bus_en = msm_dp_wide_bus_available( - priv->dp[disp_info->h_tile_instance[0]]); + dpu_enc->wide_bus_en = msm_dsi_is_widebus_enabled(priv->dsi[index]); + } else if (disp_info->intf_type == INTF_DP) { + dpu_enc->wide_bus_en = msm_dp_wide_bus_available(priv->dp[index]); + } INIT_DELAYED_WORK(_enc->delayed_off_work, dpu_encoder_off_work); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c index df88358e7037..dace6168be2d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c @@ -69,8 +69,10 @@ static void _dpu_encoder_phys_cmd_update_intf_cfg( phys_enc->hw_intf, phys_enc->hw_pp->idx); - if (intf_cfg.dsc != 0) + if (intf_cfg.dsc != 0) { cmd_mode_cfg.data_compress = true; + cmd_mode_cfg.wide_bus_en = dpu_encoder_is_widebus_enabled(phys_enc->parent); + } if (phys_enc->hw_intf->ops.program_intf_cmd_cfg) phys_enc->hw_intf->ops.program_intf_cmd_cfg(phys_enc->hw_intf, _mode_cfg); 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 8ec6505d9e78..dc6f3febb574 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c @@ -521,6 +521,9 @@ static void dpu_hw_intf_program_intf_cmd_cfg(struct dpu_hw_intf *ctx, if (cmd_mode_cfg->data_compress) intf_cfg2 |= INTF_CFG2_DCE_DATA_COMPRESS; + if (cmd_mode_cfg->wide_bus_en) + intf_cfg2 |= INTF_CFG2_DATABUS_WIDEN; + DPU_REG_WRITE(>hw, INTF_CONFIG2, intf_cfg2); } diff --git
Re: [PATCH v3 1/3] drm/panel: Fix IS_ERR() vs NULL check in nt35950_probe()
Hi Gaosheng, On Fri, Jul 14, 2023 at 09:48:18AM +0800, Gaosheng Cui wrote: > The mipi_dsi_device_register_full() returns an ERR_PTR() on failure, > we should use IS_ERR() to check the return value. Correct - so the code is indeed wrong. Can you update it so we print the error code as this can be very helpful. And then please use dev_probe_err() too. Sam > > Fixes: 623a3531e9cf ("drm/panel: Add driver for Novatek NT35950 DSI DriverIC > panels") > Signed-off-by: Gaosheng Cui > --- > drivers/gpu/drm/panel/panel-novatek-nt35950.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/panel/panel-novatek-nt35950.c > b/drivers/gpu/drm/panel/panel-novatek-nt35950.c > index 8b108ac80b55..4903bbf1df55 100644 > --- a/drivers/gpu/drm/panel/panel-novatek-nt35950.c > +++ b/drivers/gpu/drm/panel/panel-novatek-nt35950.c > @@ -571,7 +571,7 @@ static int nt35950_probe(struct mipi_dsi_device *dsi) > } > > nt->dsi[1] = mipi_dsi_device_register_full(dsi_r_host, info); > - if (!nt->dsi[1]) { > + if (IS_ERR(nt->dsi[1])) { > dev_err(dev, "Cannot get secondary DSI node\n"); > return -ENODEV; > } > -- > 2.25.1
Re: [Freedreno] [PATCH v3 2/3] drm/msm: Fix IS_ERR() vs NULL check in a5xx_submit_in_rb()
On 7/14/2023 12:10 PM, Abhinav Kumar wrote: On 7/13/2023 6:48 PM, Gaosheng Cui wrote: The msm_gem_get_vaddr() returns an ERR_PTR() on failure, we should use IS_ERR() to check the return value. use IS_ERR_OR_NULL() I can even fix this while applying Actually even subject line needs correction, so better you push another rev. Fixes: 6a8bd08d0465 ("drm/msm: add sudo flag to submit ioctl") Signed-off-by: Gaosheng Cui Reviewed-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar Reviewed-by: Akhil P Oommen --- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index a99310b68793..bbb1bf33f98e 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -89,7 +89,7 @@ static void a5xx_submit_in_rb(struct msm_gpu *gpu, struct msm_gem_submit *submit * since we've already mapped it once in * submit_reloc() */ - if (WARN_ON(!ptr)) + if (WARN_ON(IS_ERR_OR_NULL(ptr))) return; for (i = 0; i < dwords; i++) {
Re: [PATCH v5 2/2] arm64: dts: qcom: sdm845-db845c: Mark cont splash memory region as reserved
On 13/07/2023 17:52, Amit Pundir wrote: > Adding a reserved memory region for the framebuffer memory > (the splash memory region set up by the bootloader). > > Signed-off-by: Amit Pundir Reviewed-by: Caleb Connolly > --- > v5: Re-sending with updated dt-bindings patch in mdss-common > schema. > > v4: Re-sending this along with a new dt-bindings patch to > document memory-region property in qcom,sdm845-mdss > schema and keep dtbs_check happy. > > v3: Point this reserved region to MDSS. > > v2: Updated commit message. > > There was some dicussion on v1 but it didn't go anywhere, > https://lore.kernel.org/linux-kernel/20230124182857.1524912-1-amit.pun...@linaro.org/T/#u. > The general consensus is that this memory should be freed and be > made resuable but that (releasing this piece of memory) has been > tried before and it is not trivial to return the reserved memory > node to the system RAM pool in this case. > > arch/arm64/boot/dts/qcom/sdm845-db845c.dts | 9 + > 1 file changed, 9 insertions(+) > > diff --git a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts > b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts > index d6b464cb61d6..f546f6f57c1e 100644 > --- a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts > +++ b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts > @@ -101,6 +101,14 @@ hdmi_con: endpoint { > }; > }; > > + reserved-memory { > + /* Cont splash region set up by the bootloader */ > + cont_splash_mem: framebuffer@9d40 { > + reg = <0x0 0x9d40 0x0 0x240>; > + no-map; > + }; > + }; > + > lt9611_1v8: lt9611-vdd18-regulator { > compatible = "regulator-fixed"; > regulator-name = "LT9611_1V8"; > @@ -506,6 +514,7 @@ { > }; > > { > + memory-region = <_splash_mem>; > status = "okay"; > }; > -- // Caleb (they/them)
Re: [PATCH v3 2/3] drm/msm: Fix IS_ERR() vs NULL check in a5xx_submit_in_rb()
On 7/13/2023 6:48 PM, Gaosheng Cui wrote: The msm_gem_get_vaddr() returns an ERR_PTR() on failure, we should use IS_ERR() to check the return value. use IS_ERR_OR_NULL() I can even fix this while applying Fixes: 6a8bd08d0465 ("drm/msm: add sudo flag to submit ioctl") Signed-off-by: Gaosheng Cui Reviewed-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar Reviewed-by: Akhil P Oommen --- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index a99310b68793..bbb1bf33f98e 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -89,7 +89,7 @@ static void a5xx_submit_in_rb(struct msm_gpu *gpu, struct msm_gem_submit *submit * since we've already mapped it once in * submit_reloc() */ - if (WARN_ON(!ptr)) + if (WARN_ON(IS_ERR_OR_NULL(ptr))) return; for (i = 0; i < dwords; i++) {
Re: [PATCH v2] drm/msm/dsi: Enable DATABUS_WIDEN for DSI command mode
On 7/13/2023 6:23 PM, Dmitry Baryshkov wrote: On 14/07/2023 03:21, Jessica Zhang wrote: DSI 6G v2.5.x+ and DPU 7.x+ support a data-bus widen mode that allows DSI to send 48 bits of compressed data per pclk instead of 24. For all chipsets that support this mode, enable it whenever DSC is enabled as recommended by the hardware programming guide. Only enable this for command mode as we are currently unable to validate it for video mode. Signed-off-by: Jessica Zhang --- Note: The dsi.xml.h changes were generated using the headergen2 script in envytools [2], but the changes to the copyright and rules-ng-ng source file paths were dropped. Separate commit please, so that it can be replaced by headers sync with Mesa3d. Hi Dmitry, Acked. [1] https://patchwork.freedesktop.org/series/120580/ [2] https://github.com/freedreno/envytools/ -- Changes in v2: - Rebased on top of "drm/msm/dpu: Re-introduce dpu core revision" - Squashed all commits to avoid breaking feature if the series is only partially applied No. Please unsquash it. Please design the series so that the patches work even if it is only partially applied. Acked. - Moved DATABUS_WIDEN bit setting to dsi_ctr_enable() (Marijn) - Have DPU check if wide bus is requested by output driver (Dmitry) - Introduced bytes_per_pclk variable for dsi_timing_setup() hdisplay adjustment (Marijn) - Link to v1: https://lore.kernel.org/r/20230525-add-widebus-support-v1-0-c7069f2ef...@quicinc.com --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 10 ++ .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 4 +++- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 3 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h | 1 + drivers/gpu/drm/msm/dsi/dsi.c | 5 + drivers/gpu/drm/msm/dsi/dsi.h | 1 + drivers/gpu/drm/msm/dsi/dsi.xml.h | 1 + drivers/gpu/drm/msm/dsi/dsi_host.c | 23 +- drivers/gpu/drm/msm/msm_drv.h | 6 ++ 9 files changed, 48 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index f0a2a1dca741..6aed63c06c1d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -2411,6 +2411,7 @@ struct drm_encoder *dpu_encoder_init(struct drm_device *dev, struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms); struct drm_encoder *drm_enc = NULL; struct dpu_encoder_virt *dpu_enc = NULL; + int index = disp_info->h_tile_instance[0]; int ret = 0; dpu_enc = devm_kzalloc(dev->dev, sizeof(*dpu_enc), GFP_KERNEL); @@ -2439,13 +2440,14 @@ struct drm_encoder *dpu_encoder_init(struct drm_device *dev, timer_setup(_enc->frame_done_timer, dpu_encoder_frame_done_timeout, 0); - if (disp_info->intf_type == INTF_DSI) + if (disp_info->intf_type == INTF_DSI) { timer_setup(_enc->vsync_event_timer, dpu_encoder_vsync_event_handler, While you are touching this part, could you please drop dpu_encoder_vsync_event_handler() and dpu_encoder_vsync_event_work_handler(), they are useless? Since these calls aren't related to widebus, I don't think I'll include it in this series. However, I can post this cleanup as a separate patch and add that as a dependency if that's ok. 0); - else if (disp_info->intf_type == INTF_DP) - dpu_enc->wide_bus_en = msm_dp_wide_bus_available( - priv->dp[disp_info->h_tile_instance[0]]); + dpu_enc->wide_bus_en = msm_dsi_is_widebus_enabled(priv->dsi[index]); + } else if (disp_info->intf_type == INTF_DP) { + dpu_enc->wide_bus_en = msm_dp_wide_bus_available(priv->dp[index]); + } INIT_DELAYED_WORK(_enc->delayed_off_work, dpu_encoder_off_work); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c index df88358e7037..dace6168be2d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c @@ -69,8 +69,10 @@ static void _dpu_encoder_phys_cmd_update_intf_cfg( phys_enc->hw_intf, phys_enc->hw_pp->idx); - if (intf_cfg.dsc != 0) + if (intf_cfg.dsc != 0) { cmd_mode_cfg.data_compress = true; + cmd_mode_cfg.wide_bus_en = dpu_encoder_is_widebus_enabled(phys_enc->parent); + } if (phys_enc->hw_intf->ops.program_intf_cmd_cfg) phys_enc->hw_intf->ops.program_intf_cmd_cfg(phys_enc->hw_intf, _mode_cfg); 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 8ec6505d9e78..dc6f3febb574 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c @@ -521,6 +521,9 @@ static void
Re: [PATCH] dma-buf/dma-resv: Stop leaking on krealloc() failure
On Fri, Jul 14, 2023 at 08:56:15AM +0200, Christian König wrote: > Am 13.07.23 um 21:47 schrieb Ville Syrjala: > > From: Ville Syrjälä > > > > Currently dma_resv_get_fences() will leak the previously > > allocated array if the fence iteration got restarted and > > the krealloc_array() fails. > > > > Free the old array by hand, and make sure we still clear > > the returned *fences so the caller won't end up accessing > > freed memory. Some (but not all) of the callers of > > dma_resv_get_fences() seem to still trawl through the > > array even when dma_resv_get_fences() failed. And let's > > zero out *num_fences as well for good measure. > > > > Cc: Sumit Semwal > > Cc: Christian König > > Cc: linux-me...@vger.kernel.org > > Cc: dri-devel@lists.freedesktop.org > > Cc: linaro-mm-...@lists.linaro.org > > Fixes: d3c80698c9f5 ("dma-buf: use new iterator in dma_resv_get_fences v3") > > Signed-off-by: Ville Syrjälä > > Good catch, Reviewed-by: Christian König > > Should I add a CC: stable and push to drm-misc-fixes? Sure, if you don't mind. Thanks. > > Thanks, > Christian. > > > --- > > drivers/dma-buf/dma-resv.c | 13 + > > 1 file changed, 9 insertions(+), 4 deletions(-) > > > > diff --git a/drivers/dma-buf/dma-resv.c b/drivers/dma-buf/dma-resv.c > > index b6f71eb00866..38b4110378de 100644 > > --- a/drivers/dma-buf/dma-resv.c > > +++ b/drivers/dma-buf/dma-resv.c > > @@ -571,6 +571,7 @@ int dma_resv_get_fences(struct dma_resv *obj, enum > > dma_resv_usage usage, > > dma_resv_for_each_fence_unlocked(, fence) { > > > > if (dma_resv_iter_is_restarted()) { > > + struct dma_fence **new_fences; > > unsigned int count; > > > > while (*num_fences) > > @@ -579,13 +580,17 @@ int dma_resv_get_fences(struct dma_resv *obj, enum > > dma_resv_usage usage, > > count = cursor.num_fences + 1; > > > > /* Eventually re-allocate the array */ > > - *fences = krealloc_array(*fences, count, > > -sizeof(void *), > > -GFP_KERNEL); > > - if (count && !*fences) { > > + new_fences = krealloc_array(*fences, count, > > + sizeof(void *), > > + GFP_KERNEL); > > + if (count && !new_fences) { > > + kfree(*fences); > > + *fences = NULL; > > + *num_fences = 0; > > dma_resv_iter_end(); > > return -ENOMEM; > > } > > + *fences = new_fences; > > } > > > > (*fences)[(*num_fences)++] = dma_fence_get(fence); -- Ville Syrjälä Intel
Re: [git pull] drm fixes for 6.5-rc2
The pull request you sent on Fri, 14 Jul 2023 14:39:37 +1000: > git://anongit.freedesktop.org/drm/drm tags/drm-fixes-2023-07-14-1 has been merged into torvalds/linux.git: https://git.kernel.org/torvalds/c/3a97a2993e7e7392292323fefc46d79bf9633e44 Thank you! -- Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/prtracker.html
[PATCH 4/4] drm/tests: Add test case for drm_internal_framebuffer_create()
Introduce a test to cover the creation of a framebuffer with a setted modifier and a driver that don't support modifiers. Signed-off-by: Carlos Eduardo Gallo Filho --- drivers/gpu/drm/tests/drm_framebuffer_test.c | 21 1 file changed, 21 insertions(+) diff --git a/drivers/gpu/drm/tests/drm_framebuffer_test.c b/drivers/gpu/drm/tests/drm_framebuffer_test.c index 1fbb534b2e22..7ee595321462 100644 --- a/drivers/gpu/drm/tests/drm_framebuffer_test.c +++ b/drivers/gpu/drm/tests/drm_framebuffer_test.c @@ -388,6 +388,26 @@ static void drm_framebuffer_test_to_desc(const struct drm_framebuffer_test *t, c KUNIT_ARRAY_PARAM(drm_framebuffer_create, drm_framebuffer_create_cases, drm_framebuffer_test_to_desc); +static void drm_test_framebuffer_modifiers_not_supported(struct kunit *test) +{ + struct drm_mode_fb_cmd2 cmd = { + .width = MAX_WIDTH, .height = MAX_HEIGHT, + .pixel_format = DRM_FORMAT_ABGR, .handles = { 1, 0, 0 }, + .offsets = { UINT_MAX / 2, 0, 0 }, .pitches = { 4 * MAX_WIDTH, 0, 0 }, + .flags = DRM_MODE_FB_MODIFIERS, + }; + struct drm_device *mock = test->priv; + int buffer_created = 0; + + mock->dev_private = _created; + mock->mode_config.fb_modifiers_not_supported = 1; + + drm_internal_framebuffer_create(mock, , NULL); + KUNIT_EXPECT_EQ(test, 0, buffer_created); + + mock->mode_config.fb_modifiers_not_supported = 0; +} + struct check_src_coords_case { const int expect; const uint32_t src_x; @@ -494,6 +514,7 @@ KUNIT_ARRAY_PARAM(check_src_coords, check_src_coords_cases, check_src_coords_test_to_desc); static struct kunit_case drm_framebuffer_tests[] = { + KUNIT_CASE(drm_test_framebuffer_modifiers_not_supported), KUNIT_CASE_PARAM(drm_test_framebuffer_create, drm_framebuffer_create_gen_params), KUNIT_CASE_PARAM(drm_test_framebuffer_check_src_coords, check_src_coords_gen_params), { } -- 2.41.0
[PATCH 3/4] drm/tests: Add parameters to the drm_test_framebuffer_create test
Extend the existing test case to cover: 1. Invalid flag atribute in the struct drm_mode_fb_cmd2. 2. Pixel format which requires non-linear modifier with DRM_FORMAT_MOD_LINEAR set. 3. Non-zero buffer offset for an unused plane Signed-off-by: Carlos Eduardo Gallo Filho --- drivers/gpu/drm/tests/drm_framebuffer_test.c | 21 1 file changed, 21 insertions(+) diff --git a/drivers/gpu/drm/tests/drm_framebuffer_test.c b/drivers/gpu/drm/tests/drm_framebuffer_test.c index 175146f7ac9e..1fbb534b2e22 100644 --- a/drivers/gpu/drm/tests/drm_framebuffer_test.c +++ b/drivers/gpu/drm/tests/drm_framebuffer_test.c @@ -20,6 +20,8 @@ #define MIN_HEIGHT 4 #define MAX_HEIGHT 4096 +#define DRM_MODE_FB_INVALID BIT(2) + struct drm_framebuffer_test { int buffer_created; struct drm_mode_fb_cmd2 cmd; @@ -84,6 +86,18 @@ static const struct drm_framebuffer_test drm_framebuffer_create_cases[] = { .pitches = { 4 * MAX_WIDTH, 0, 0 }, } }, +{ .buffer_created = 0, .name = "ABGR Non-zero buffer offset for unused plane", + .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR, +.handles = { 1, 0, 0 }, .offsets = { UINT_MAX / 2, UINT_MAX / 2, 0 }, +.pitches = { 4 * MAX_WIDTH, 0, 0 }, .flags = DRM_MODE_FB_MODIFIERS, + } +}, +{ .buffer_created = 0, .name = "ABGR Invalid flag", + .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR, +.handles = { 1, 0, 0 }, .offsets = { UINT_MAX / 2, 0, 0 }, +.pitches = { 4 * MAX_WIDTH, 0, 0 }, .flags = DRM_MODE_FB_INVALID, + } +}, { .buffer_created = 1, .name = "ABGR Set DRM_MODE_FB_MODIFIERS without modifiers", .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR, .handles = { 1, 0, 0 }, .offsets = { UINT_MAX / 2, 0, 0 }, @@ -263,6 +277,13 @@ static const struct drm_framebuffer_test drm_framebuffer_create_cases[] = { .pitches = { MAX_WIDTH, DIV_ROUND_UP(MAX_WIDTH, 2), DIV_ROUND_UP(MAX_WIDTH, 2) }, } }, +{ .buffer_created = 0, .name = "YUV420_10BIT Invalid modifier(DRM_FORMAT_MOD_LINEAR)", + .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_YUV420_10BIT, +.handles = { 1, 0, 0 }, .flags = DRM_MODE_FB_MODIFIERS, +.modifier = { DRM_FORMAT_MOD_LINEAR, 0, 0 }, +.pitches = { MAX_WIDTH, 0, 0 }, + } +}, { .buffer_created = 1, .name = "X0L2 Normal sizes", .cmd = { .width = 600, .height = 600, .pixel_format = DRM_FORMAT_X0L2, .handles = { 1, 0, 0 }, .pitches = { 1200, 0, 0 } -- 2.41.0
[PATCH 2/4] drm/tests: Add test for drm_framebuffer_check_src_coords()
Add a parametrized test for the drm_framebuffer_check_src_coords function. Signed-off-by: Carlos Eduardo Gallo Filho --- drivers/gpu/drm/tests/drm_framebuffer_test.c | 107 +++ 1 file changed, 107 insertions(+) diff --git a/drivers/gpu/drm/tests/drm_framebuffer_test.c b/drivers/gpu/drm/tests/drm_framebuffer_test.c index f759d9f3b76e..175146f7ac9e 100644 --- a/drivers/gpu/drm/tests/drm_framebuffer_test.c +++ b/drivers/gpu/drm/tests/drm_framebuffer_test.c @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -366,8 +367,114 @@ static void drm_framebuffer_test_to_desc(const struct drm_framebuffer_test *t, c KUNIT_ARRAY_PARAM(drm_framebuffer_create, drm_framebuffer_create_cases, drm_framebuffer_test_to_desc); +struct check_src_coords_case { + const int expect; + const uint32_t src_x; + const uint32_t src_y; + const uint32_t src_w; + const uint32_t src_h; + const struct drm_framebuffer fb; + const char *name; +}; + +static const struct check_src_coords_case check_src_coords_cases[] = { + { .name = "source inside framebuffer", + .expect = 0, + .src_x = 500 << 16, .src_y = 700 << 16, + .src_w = 100 << 16, .src_h = 100 << 16, + .fb = { .width = 600, .height = 800 } + }, + { .name = "out of bound with normal sizes and coordinates", + .expect = -ENOSPC, + .src_x = (500 << 16) + 1, .src_y = (700 << 16) + 1, + .src_w = 100 << 16, .src_h = 100 << 16, + .fb = { .width = 600, .height = 800 } + }, + { .name = "source width higher than framebuffer width", + .expect = -ENOSPC, + .src_x = 0, .src_y = 700 << 16, + .src_w = (600 << 16) + 1, .src_h = 100 << 16, + .fb = { .width = 600, .height = 800 } + }, + { .name = "source width equal framebuffer width with x coordinates 0", + .expect = 0, + .src_x = 0, .src_y = 700 << 16, + .src_w = 600 << 16, .src_h = 100 << 16, + .fb = { .width = 600, .height = 800 } + }, + { .name = "source width equal framebuffer width with non-zero x coordinate", + .expect = -ENOSPC, + .src_x = 1, .src_y = 700 << 16, + .src_w = 600 << 16, .src_h = 100 << 16, + .fb = { .width = 600, .height = 800 } + }, + { .name = "out of bound with normal width and x", + .expect = -ENOSPC, + .src_x = (500 << 16) + 1, .src_y = 700 << 16, + .src_w = 100 << 16, .src_h = 100 << 16, + .fb = { .width = 600, .height = 800 } + }, + { .name = "x coordinate higher than framebuffer width", + .expect = -ENOSPC, + .src_x = (600 << 16) + 1, .src_y = 700 << 16, + .src_w = 0, .src_h = 100 << 16, + .fb = { .width = 600, .height = 800 } + }, + { .name = "source height higher than framebuffer height", + .expect = -ENOSPC, + .src_x = 700 << 16, .src_y = 0, + .src_w = 100 << 16, .src_h = (600 << 16) + 1, + .fb = { .width = 800, .height = 600 } + }, + { .name = "source height equal framebuffer height with y coordinates 0", + .expect = 0, + .src_x = 700 << 16, .src_y = 0, + .src_w = 100 << 16, .src_h = 600 << 16, + .fb = { .width = 800, .height = 600 } + }, + { .name = "source height equal framebuffer height with non-zero y coordinate", + .expect = -ENOSPC, + .src_x = 700 << 16, .src_y = 1, + .src_w = 100 << 16, .src_h = 600 << 16, + .fb = { .width = 800, .height = 600 } + }, + { .name = "out of bound with normal height and y", + .expect = -ENOSPC, + .src_x = 700 << 16, .src_y = (500 << 16) + 1, + .src_w = 100 << 16, .src_h = 100 << 16, + .fb = { .width = 800, .height = 600 } + }, + { .name = "y coordinate higher than framebuffer height", + .expect = -ENOSPC, + .src_x = 700 << 16, .src_y = (600 << 16) + 1, + .src_w = 100 << 16, .src_h = 0, + .fb = { .width = 800, .height = 600 } + }, +}; + +static void drm_test_framebuffer_check_src_coords(struct kunit *test) +{ + const struct check_src_coords_case *params = test->param_value; + int r; + + r = drm_framebuffer_check_src_coords(params->src_x, params->src_y, +params->src_w, params->src_h, +>fb); + KUNIT_EXPECT_EQ(test, r, params->expect); +} + +static void check_src_coords_test_to_desc(const struct check_src_coords_case *t, + char *desc) +{ + strcpy(desc, t->name); +} + +KUNIT_ARRAY_PARAM(check_src_coords, check_src_coords_cases, + check_src_coords_test_to_desc); + static struct kunit_case drm_framebuffer_tests[] = { KUNIT_CASE_PARAM(drm_test_framebuffer_create,
[PATCH 1/4] drm: Add kernel-doc for drm_framebuffer_check_src_coords()
Signed-off-by: Carlos Eduardo Gallo Filho --- drivers/gpu/drm/drm_framebuffer.c | 16 +++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c index aff3746dedfb..49df3ca3b3ee 100644 --- a/drivers/gpu/drm/drm_framebuffer.c +++ b/drivers/gpu/drm/drm_framebuffer.c @@ -73,6 +73,21 @@ * drm_framebuffer. */ +/** + * drm_framebuffer_check_src_coords - check if the source with given + * coordinates and sizes is inside the framebuffer + * @src_x: source x coordinate + * @src_y: source y coordinate + * @src_w: source width + * @src_h: source height + * @fb: pointer to the framebuffer to check + * + * This function checks if an object with the given set of coordinates and + * sizes fits inside the framebuffer by looking at its size. + * + * Returns: + * Zero on success, negative errno on failure. + */ int drm_framebuffer_check_src_coords(uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h, const struct drm_framebuffer *fb) @@ -82,7 +97,6 @@ int drm_framebuffer_check_src_coords(uint32_t src_x, uint32_t src_y, fb_width = fb->width << 16; fb_height = fb->height << 16; - /* Make sure source coordinates are inside the fb. */ if (src_w > fb_width || src_x > fb_width - src_w || src_h > fb_height || -- 2.41.0
[PATCH 0/4] Add documentation and KUnit tests for functions on drm_framebuffer.c
This series adds documentation and unit tests for drm_framebuffer_check_src_coords() and drm_internal_framebuffer_create() functions on drm_framebuffer.c, including new parameters to the, until then, only existent test. Many thanks, Carlos Carlos Eduardo Gallo Filho (4): drm: Add kernel-doc for drm_framebuffer_check_src_coords() drm/tests: Add test for drm_framebuffer_check_src_coords() drm/tests: Add parameters to the drm_test_framebuffer_create test drm/tests: Add test case for drm_internal_framebuffer_create() drivers/gpu/drm/drm_framebuffer.c| 16 +- drivers/gpu/drm/tests/drm_framebuffer_test.c | 149 +++ 2 files changed, 164 insertions(+), 1 deletion(-) -- 2.41.0
[PATCH] fb: Explicitly include correct DT includes
The DT of_device.h and of_platform.h date back to the separate of_platform_bus_type before it as merged into the regular platform bus. As part of that merge prepping Arm DT support 13 years ago, they "temporarily" include each other. They also include platform_device.h and of.h. As a result, there's a pretty much random mix of those include files used throughout the tree. In order to detangle these headers and replace the implicit includes with struct declarations, users need to explicitly include the correct includes. Signed-off-by: Rob Herring --- drivers/video/fbdev/bw2.c| 3 ++- drivers/video/fbdev/cg14.c | 3 ++- drivers/video/fbdev/cg3.c| 3 ++- drivers/video/fbdev/cg6.c| 3 ++- drivers/video/fbdev/ffb.c| 3 ++- drivers/video/fbdev/grvga.c | 3 +-- drivers/video/fbdev/leo.c| 3 ++- drivers/video/fbdev/mb862xx/mb862xxfb_accel.c| 4 +--- drivers/video/fbdev/mb862xx/mb862xxfbdrv.c | 6 +++--- drivers/video/fbdev/omap2/omapfb/displays/panel-dsi-cm.c | 2 +- drivers/video/fbdev/p9100.c | 3 ++- drivers/video/fbdev/platinumfb.c | 4 ++-- drivers/video/fbdev/sbuslib.c| 6 +++--- drivers/video/fbdev/sunxvr1000.c | 3 ++- drivers/video/fbdev/sunxvr2500.c | 2 +- drivers/video/fbdev/sunxvr500.c | 2 +- drivers/video/fbdev/tcx.c| 3 ++- drivers/video/fbdev/xilinxfb.c | 5 ++--- 18 files changed, 33 insertions(+), 28 deletions(-) diff --git a/drivers/video/fbdev/bw2.c b/drivers/video/fbdev/bw2.c index 025d663dc6fd..39f438de0d6b 100644 --- a/drivers/video/fbdev/bw2.c +++ b/drivers/video/fbdev/bw2.c @@ -17,7 +17,8 @@ #include #include #include -#include +#include +#include #include #include diff --git a/drivers/video/fbdev/cg14.c b/drivers/video/fbdev/cg14.c index 832a82f45c80..90fdc9d9bf5a 100644 --- a/drivers/video/fbdev/cg14.c +++ b/drivers/video/fbdev/cg14.c @@ -17,7 +17,8 @@ #include #include #include -#include +#include +#include #include #include diff --git a/drivers/video/fbdev/cg3.c b/drivers/video/fbdev/cg3.c index 6335cd364c74..98c60f72046a 100644 --- a/drivers/video/fbdev/cg3.c +++ b/drivers/video/fbdev/cg3.c @@ -17,7 +17,8 @@ #include #include #include -#include +#include +#include #include #include diff --git a/drivers/video/fbdev/cg6.c b/drivers/video/fbdev/cg6.c index 6884572efea1..6427b85f1a94 100644 --- a/drivers/video/fbdev/cg6.c +++ b/drivers/video/fbdev/cg6.c @@ -17,7 +17,8 @@ #include #include #include -#include +#include +#include #include #include diff --git a/drivers/video/fbdev/ffb.c b/drivers/video/fbdev/ffb.c index c6d3111dcbb0..c473841eb6ff 100644 --- a/drivers/video/fbdev/ffb.c +++ b/drivers/video/fbdev/ffb.c @@ -16,7 +16,8 @@ #include #include #include -#include +#include +#include #include #include diff --git a/drivers/video/fbdev/grvga.c b/drivers/video/fbdev/grvga.c index 9aa15be29ea9..d4a9a58b3691 100644 --- a/drivers/video/fbdev/grvga.c +++ b/drivers/video/fbdev/grvga.c @@ -12,8 +12,7 @@ #include #include -#include -#include +#include #include #include #include diff --git a/drivers/video/fbdev/leo.c b/drivers/video/fbdev/leo.c index 3ffc0a725f89..89ca48235dbe 100644 --- a/drivers/video/fbdev/leo.c +++ b/drivers/video/fbdev/leo.c @@ -16,8 +16,9 @@ #include #include #include -#include #include +#include +#include #include diff --git a/drivers/video/fbdev/mb862xx/mb862xxfb_accel.c b/drivers/video/fbdev/mb862xx/mb862xxfb_accel.c index 61aed7fc0b8d..c35a7479fbf2 100644 --- a/drivers/video/fbdev/mb862xx/mb862xxfb_accel.c +++ b/drivers/video/fbdev/mb862xx/mb862xxfb_accel.c @@ -15,9 +15,7 @@ #include #include #include -#if defined(CONFIG_OF) -#include -#endif + #include "mb862xxfb.h" #include "mb862xx_reg.h" #include "mb862xxfb_accel.h" diff --git a/drivers/video/fbdev/mb862xx/mb862xxfbdrv.c b/drivers/video/fbdev/mb862xx/mb862xxfbdrv.c index b5c8fcab9940..9dc347d163cf 100644 --- a/drivers/video/fbdev/mb862xx/mb862xxfbdrv.c +++ b/drivers/video/fbdev/mb862xx/mb862xxfbdrv.c @@ -18,11 +18,11 @@ #include #include #include -#if defined(CONFIG_OF) +#include #include #include -#include -#endif +#include + #include "mb862xxfb.h" #include "mb862xx_reg.h" diff --git a/drivers/video/fbdev/omap2/omapfb/displays/panel-dsi-cm.c b/drivers/video/fbdev/omap2/omapfb/displays/panel-dsi-cm.c index ba94a0a7bd4f..77fce1223a64 100644 --- a/drivers/video/fbdev/omap2/omapfb/displays/panel-dsi-cm.c +++ b/drivers/video/fbdev/omap2/omapfb/displays/panel-dsi-cm.c @@ -15,12 +15,12 @@ #include #include #include +#include
[PATCH] backlight: qcom-wled: Explicitly include correct DT includes
The DT of_device.h and of_platform.h date back to the separate of_platform_bus_type before it as merged into the regular platform bus. As part of that merge prepping Arm DT support 13 years ago, they "temporarily" include each other. They also include platform_device.h and of.h. As a result, there's a pretty much random mix of those include files used throughout the tree. In order to detangle these headers and replace the implicit includes with struct declarations, users need to explicitly include the correct includes. Signed-off-by: Rob Herring --- drivers/video/backlight/qcom-wled.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/backlight/qcom-wled.c b/drivers/video/backlight/qcom-wled.c index c6996aa288e6..10129095a4c1 100644 --- a/drivers/video/backlight/qcom-wled.c +++ b/drivers/video/backlight/qcom-wled.c @@ -9,8 +9,8 @@ #include #include #include -#include #include +#include #include /* From DT binding */ -- 2.40.1
[PATCH] phy: Explicitly include correct DT includes
The DT of_device.h and of_platform.h date back to the separate of_platform_bus_type before it as merged into the regular platform bus. As part of that merge prepping Arm DT support 13 years ago, they "temporarily" include each other. They also include platform_device.h and of.h. As a result, there's a pretty much random mix of those include files used throughout the tree. In order to detangle these headers and replace the implicit includes with struct declarations, users need to explicitly include the correct includes. Signed-off-by: Rob Herring --- drivers/phy/allwinner/phy-sun4i-usb.c | 2 -- drivers/phy/allwinner/phy-sun50i-usb3.c | 1 + drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c | 2 +- drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c | 1 + drivers/phy/amlogic/phy-meson-axg-pcie.c | 1 + drivers/phy/amlogic/phy-meson-g12a-mipi-dphy-analog.c | 1 + drivers/phy/amlogic/phy-meson-g12a-usb2.c | 2 +- drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c| 2 +- drivers/phy/amlogic/phy-meson-gxl-usb2.c | 2 +- drivers/phy/amlogic/phy-meson8-hdmi-tx.c | 2 +- drivers/phy/amlogic/phy-meson8b-usb2.c| 2 +- drivers/phy/broadcom/phy-bcm63xx-usbh.c | 1 + drivers/phy/broadcom/phy-brcm-usb.c | 1 - drivers/phy/cadence/cdns-dphy-rx.c| 1 + drivers/phy/cadence/cdns-dphy.c | 3 +-- drivers/phy/cadence/phy-cadence-torrent.c | 2 -- drivers/phy/freescale/phy-fsl-imx8m-pcie.c| 2 +- drivers/phy/freescale/phy-fsl-imx8mq-usb.c| 2 +- drivers/phy/freescale/phy-fsl-lynx-28g.c | 1 + drivers/phy/hisilicon/phy-hi3660-usb3.c | 1 + drivers/phy/hisilicon/phy-hi3670-usb3.c | 1 + drivers/phy/hisilicon/phy-hi6220-usb.c| 1 + drivers/phy/hisilicon/phy-hisi-inno-usb2.c| 3 ++- drivers/phy/hisilicon/phy-histb-combphy.c | 3 ++- drivers/phy/hisilicon/phy-hix5hd2-sata.c | 1 + drivers/phy/ingenic/phy-ingenic-usb.c | 1 + drivers/phy/lantiq/phy-lantiq-rcu-usb2.c | 1 - drivers/phy/marvell/phy-armada38x-comphy.c| 1 + drivers/phy/marvell/phy-berlin-sata.c | 1 + drivers/phy/marvell/phy-mmp3-hsic.c | 1 + drivers/phy/marvell/phy-mmp3-usb.c| 1 + drivers/phy/marvell/phy-mvebu-a3700-comphy.c | 1 + drivers/phy/marvell/phy-mvebu-a3700-utmi.c| 2 +- drivers/phy/marvell/phy-mvebu-cp110-comphy.c | 1 + drivers/phy/marvell/phy-mvebu-cp110-utmi.c| 2 +- drivers/phy/marvell/phy-mvebu-sata.c | 1 + drivers/phy/marvell/phy-pxa-28nm-usb2.c | 1 - drivers/phy/mediatek/phy-mtk-hdmi.h | 1 - drivers/phy/mediatek/phy-mtk-mipi-dsi.h | 1 - drivers/phy/mediatek/phy-mtk-pcie.c | 2 +- drivers/phy/mediatek/phy-mtk-tphy.c | 2 +- drivers/phy/mediatek/phy-mtk-ufs.c| 1 + drivers/phy/phy-can-transceiver.c | 1 + drivers/phy/phy-xgene.c | 1 + drivers/phy/qualcomm/phy-ath79-usb.c | 1 + drivers/phy/qualcomm/phy-qcom-edp.c | 2 -- drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c| 1 - drivers/phy/qualcomm/phy-qcom-ipq4019-usb.c | 3 +-- drivers/phy/qualcomm/phy-qcom-ipq806x-usb.c | 2 +- drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 1 - drivers/phy/qualcomm/phy-qcom-qmp-pcie-msm8996.c | 1 - drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 1 - drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 1 - drivers/phy/qualcomm/phy-qcom-qmp-usb.c | 1 - drivers/phy/qualcomm/phy-qcom-qusb2.c | 1 - drivers/phy/qualcomm/phy-qcom-snps-eusb2.c| 1 + drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c | 1 - drivers/phy/qualcomm/phy-qcom-usb-hs.c| 2 +- drivers/phy/ralink/phy-mt7621-pci.c | 3 +-- drivers/phy/renesas/phy-rcar-gen2.c | 1 - drivers/phy/renesas/phy-rcar-gen3-pcie.c | 1 - drivers/phy/renesas/phy-rcar-gen3-usb2.c | 2 -- drivers/phy/renesas/r8a779f0-ether-serdes.c | 1 + drivers/phy/rockchip/phy-rockchip-dphy-rx0.c | 1 - drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c | 2 +- drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 1 - drivers/phy/rockchip/phy-rockchip-naneng-combphy.c| 3 ++- drivers/phy/rockchip/phy-rockchip-snps-pcie3.c| 3 ++- drivers/phy/samsung/phy-exynos-dp-video.c | 2 -- drivers/phy/samsung/phy-exynos-mipi-video.c | 3 +-- drivers/phy/samsung/phy-exynos5-usbdrd.c | 2 -- drivers/phy/samsung/phy-samsung-usb2.c| 2 --
[PATCH] gpu/host1x: Explicitly include correct DT includes
The DT of_device.h and of_platform.h date back to the separate of_platform_bus_type before it as merged into the regular platform bus. As part of that merge prepping Arm DT support 13 years ago, they "temporarily" include each other. They also include platform_device.h and of.h. As a result, there's a pretty much random mix of those include files used throughout the tree. In order to detangle these headers and replace the implicit includes with struct declarations, users need to explicitly include the correct includes. Signed-off-by: Rob Herring --- drivers/gpu/host1x/context.c | 2 +- drivers/gpu/host1x/dev.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/host1x/context.c b/drivers/gpu/host1x/context.c index 9ad89d22c0ca..c000d4e0c2c6 100644 --- a/drivers/gpu/host1x/context.c +++ b/drivers/gpu/host1x/context.c @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c index aae2efeef503..7c6699aed7d2 100644 --- a/drivers/gpu/host1x/dev.c +++ b/drivers/gpu/host1x/dev.c @@ -11,8 +11,9 @@ #include #include #include -#include #include +#include +#include #include #include -- 2.40.1
[PATCH] char: Explicitly include correct DT includes
The DT of_device.h and of_platform.h date back to the separate of_platform_bus_type before it as merged into the regular platform bus. As part of that merge prepping Arm DT support 13 years ago, they "temporarily" include each other. They also include platform_device.h and of.h. As a result, there's a pretty much random mix of those include files used throughout the tree. In order to detangle these headers and replace the implicit includes with struct declarations, users need to explicitly include the correct includes. Signed-off-by: Rob Herring --- drivers/char/agp/uninorth-agp.c| 1 + drivers/char/bsr.c | 3 +-- drivers/char/hw_random/atmel-rng.c | 2 +- drivers/char/hw_random/bcm2835-rng.c | 3 +-- drivers/char/hw_random/ingenic-trng.c | 2 +- drivers/char/hw_random/iproc-rng200.c | 3 +-- drivers/char/hw_random/npcm-rng.c | 3 +-- drivers/char/hw_random/omap-rng.c | 2 -- drivers/char/hw_random/omap3-rom-rng.c | 1 - drivers/char/hw_random/pasemi-rng.c| 3 +-- drivers/char/hw_random/pic32-rng.c | 3 +-- drivers/char/hw_random/stm32-rng.c | 3 ++- drivers/char/hw_random/xgene-rng.c | 5 ++--- drivers/char/hw_random/xiphera-trng.c | 1 - drivers/char/ipmi/kcs_bmc_aspeed.c | 1 - drivers/char/tpm/tpm_ftpm_tee.c| 1 - drivers/char/tpm/tpm_tis.c | 1 - drivers/char/tpm/tpm_tis_spi_main.c| 2 +- drivers/char/tpm/tpm_tis_synquacer.c | 1 - 19 files changed, 14 insertions(+), 27 deletions(-) diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c index 62de7f4ba864..84411b13c49f 100644 --- a/drivers/char/agp/uninorth-agp.c +++ b/drivers/char/agp/uninorth-agp.c @@ -3,6 +3,7 @@ * UniNorth AGPGART routines. */ #include +#include #include #include #include diff --git a/drivers/char/bsr.c b/drivers/char/bsr.c index 12143854aeac..70d31aed9011 100644 --- a/drivers/char/bsr.c +++ b/drivers/char/bsr.c @@ -6,11 +6,10 @@ * Author: Sonny Rao */ +#include #include #include #include -#include -#include #include #include #include diff --git a/drivers/char/hw_random/atmel-rng.c b/drivers/char/hw_random/atmel-rng.c index b8effe77d80f..a37367ebcbac 100644 --- a/drivers/char/hw_random/atmel-rng.c +++ b/drivers/char/hw_random/atmel-rng.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/char/hw_random/bcm2835-rng.c b/drivers/char/hw_random/bcm2835-rng.c index e98fcac578d6..e19b0f9f48b9 100644 --- a/drivers/char/hw_random/bcm2835-rng.c +++ b/drivers/char/hw_random/bcm2835-rng.c @@ -8,8 +8,7 @@ #include #include #include -#include -#include +#include #include #include #include diff --git a/drivers/char/hw_random/ingenic-trng.c b/drivers/char/hw_random/ingenic-trng.c index 0eb80f786f4d..759445d4f65a 100644 --- a/drivers/char/hw_random/ingenic-trng.c +++ b/drivers/char/hw_random/ingenic-trng.c @@ -11,8 +11,8 @@ #include #include #include +#include #include -#include #include #include diff --git a/drivers/char/hw_random/iproc-rng200.c b/drivers/char/hw_random/iproc-rng200.c index 06bc060534d8..34df3f0d3e45 100644 --- a/drivers/char/hw_random/iproc-rng200.c +++ b/drivers/char/hw_random/iproc-rng200.c @@ -12,8 +12,7 @@ #include #include #include -#include -#include +#include #include #include diff --git a/drivers/char/hw_random/npcm-rng.c b/drivers/char/hw_random/npcm-rng.c index 9903d0357e06..8a304b754217 100644 --- a/drivers/char/hw_random/npcm-rng.c +++ b/drivers/char/hw_random/npcm-rng.c @@ -8,12 +8,11 @@ #include #include #include +#include #include #include #include -#include #include -#include #define NPCM_RNGCS_REG 0x00/* Control and status register */ #define NPCM_RNGD_REG 0x04/* Data register */ diff --git a/drivers/char/hw_random/omap-rng.c b/drivers/char/hw_random/omap-rng.c index 00ff96703dd2..be03f76a2a80 100644 --- a/drivers/char/hw_random/omap-rng.c +++ b/drivers/char/hw_random/omap-rng.c @@ -26,8 +26,6 @@ #include #include #include -#include -#include #include #include #include diff --git a/drivers/char/hw_random/omap3-rom-rng.c b/drivers/char/hw_random/omap3-rom-rng.c index f06e4f95114f..18dc46b1b58e 100644 --- a/drivers/char/hw_random/omap3-rom-rng.c +++ b/drivers/char/hw_random/omap3-rom-rng.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include diff --git a/drivers/char/hw_random/pasemi-rng.c b/drivers/char/hw_random/pasemi-rng.c index 2498d4ef9fe2..6959d6edd44c 100644 --- a/drivers/char/hw_random/pasemi-rng.c +++ b/drivers/char/hw_random/pasemi-rng.c @@ -9,11 +9,10 @@ #include #include +#include #include #include #include -#include -#include #include #define SDCRNG_CTL_REG 0x00 diff --git a/drivers/char/hw_random/pic32-rng.c b/drivers/char/hw_random/pic32-rng.c index 99c8bd0859a1..728b68b1a496 100644 ---
RE: [RFC 2/2] drm/i915: Remove PAT hack from i915_gem_object_can_bypass_llc
> On 14/07/2023 06:43, Yang, Fei wrote: >>> From: Tvrtko Ursulin >>> >>> According to the comment in i915_gem_object_can_bypass_llc the >>> purpose of the function is to return false if the platform/object has >>> a caching mode where GPU can bypass the LLC. >>> >>> So far the only platforms which allegedly can do this are Jasperlake >>> and Elkhartlake, and that via MOCS (not PAT). >>> >>> Instead of blindly assuming that objects where userspace has set the >>> PAT index can (bypass the LLC), question is is there a such PAT index >>> on a platform. Probably starting with Meteorlake since that one is >>> the only one where set PAT extension can be currently used. Or if >>> there is a MOCS entry which can achieve the same thing on Meteorlake. >>> >>> If there is such PAT, now that i915 can be made to understand them >>> better, we can make the check more fine grained. Or if there is a >>> MOCS entry then we probably should apply the blanket IS_METEORLAKE >>> condition. >>> >>> Signed-off-by: Tvrtko Ursulin >>> Fixes: 9275277d5324 ("drm/i915: use pat_index instead of >>> cache_level") >>> Cc: Chris Wilson >>> Cc: Fei Yang >>> Cc: Andi Shyti >>> Cc: Matt Roper >>> --- >>> drivers/gpu/drm/i915/gem/i915_gem_object.c | 6 -- >>> 1 file changed, 6 deletions(-) >>> >>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c >>> b/drivers/gpu/drm/i915/gem/i915_gem_object.c >>> index 33a1e97d18b3..1e34171c4162 100644 >>> --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c >>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c >>> @@ -229,12 +229,6 @@ bool i915_gem_object_can_bypass_llc(struct >>> drm_i915_gem_object *obj) >>>if (!(obj->flags & I915_BO_ALLOC_USER)) >>>return false; >>> >>> - /* >>> - * Always flush cache for UMD objects at creation time. >>> - */ >>> - if (obj->pat_set_by_user) >> >> I'm afraid this is going to break MESA. Can we run MESA tests with this >> patch? > > I can't, but question is why it would break Mesa which would need a > nice comment here? For objects with PAT index set by user, the KMD doesn't know whether the user space would map it as cacheable or not for CPU access. So we want to enforce a cache flush at BO creation time before handing the BO over to user space. I remember the issue we had before is that MESA sees garbage data in a BO that is supposed to be initialized with zero. I understand your point, checking for obj->pat_set_by_user is not something to be done in this function. I'm fine with the removal of these lines, but the checking needs to be done somewhere, maybe just one level up? diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c index 1df74f7aa3dc..39cd903ba223 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c @@ -258,6 +258,7 @@ static int i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj) * the driver. */ if (i915_gem_object_can_bypass_llc(obj) || + obj->pat_set_by_user || (!HAS_LLC(i915) && !IS_DG1(i915))) wbinvd_on_all_cpus(); diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c index 8f1633c3fb93..770e02a851f6 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c @@ -254,7 +254,8 @@ static int shmem_get_pages(struct drm_i915_gem_object *obj) if (i915_gem_object_needs_bit17_swizzle(obj)) i915_gem_object_do_bit_17_swizzle(obj, st); - if (i915_gem_object_can_bypass_llc(obj)) + if (i915_gem_object_can_bypass_llc(obj) || + obj->pat_set_by_user) obj->cache_dirty = true; __i915_gem_object_set_pages(obj, st); diff --git a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c index 1d3ebdf4069b..9e65e3324422 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c @@ -170,7 +170,8 @@ static int i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj) } WARN_ON_ONCE(!(obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_WRITE)); - if (i915_gem_object_can_bypass_llc(obj)) + if (i915_gem_object_can_bypass_llc(obj) || + obj->pat_set_by_user) obj->cache_dirty = true; __i915_gem_object_set_pages(obj, st); -Fei > For instance should the check be IS_METEORLAKE? > > Or should it be "is wb" && "not has 1-way coherent"? > > Or both? > > Or, given how Meteorlake does not have LLC, how can anything bypass it > there? Or is it about snooping on Meteorlake and how? > > Regards, > > Tvrtko > >> >>>/* >>> * EHL and JSL add the 'Bypass LLC' MOCS entry, which should make it >>> * possible for userspace to bypass the GTT caching bits set >>> by the >>> -- >>> 2.39.2
Re: [PATCH v4 21/21] dyndbg-doc: add classmap info to howto
On Thu, Jul 13, 2023 at 1:13 PM Randy Dunlap wrote: > > > > On 7/13/23 09:36, Jim Cromie wrote: > > Add some basic info on classmap usage and api > > > > Signed-off-by: Jim Cromie > > --- > > .../admin-guide/dynamic-debug-howto.rst | 64 ++- > > 1 file changed, 63 insertions(+), 1 deletion(-) > > > > diff --git a/Documentation/admin-guide/dynamic-debug-howto.rst > > b/Documentation/admin-guide/dynamic-debug-howto.rst > > index 8dc668cc1216..878750ce8c1d 100644 > > --- a/Documentation/admin-guide/dynamic-debug-howto.rst > > +++ b/Documentation/admin-guide/dynamic-debug-howto.rst > > > @@ -374,3 +373,66 @@ just a shortcut for ``print_hex_dump(KERN_DEBUG)``. > > For ``print_hex_dump_debug()``/``print_hex_dump_bytes()``, format string is > > its ``prefix_str`` argument, if it is constant string; or ``hexdump`` > > in case ``prefix_str`` is built dynamically. > > + > > +Dynamic Debug classmaps > > +=== > > + > > +Dyndbg generally selects *prdbg* callsites using structural info: > > +module, file, function, line. Using classmaps, user modules can > > +organize/select pr_debug()s as they like. > > + > > +- classes coordinates/spans multiple modules > > +- complements the mod,file,func attrs > > +- keeps pr_debug's 0-off-cost JUMP_LABEL goodness > > +- isolates from other class'd and un-class'd pr_debugs() > > + (one doesnt mix 2 clients bank accounts) > > doesn't > thanks Randy, got this, and the rest.
Re: [PATCH v4 20/21] config TEST_DYNAMIC_DEBUG default m
On Thu, Jul 13, 2023 at 1:04 PM Randy Dunlap wrote: > > Hi Jim, > > On 7/13/23 09:36, Jim Cromie wrote: > > Signed-off-by: Jim Cromie > > --- > > lib/Kconfig.debug | 3 ++- > > 1 file changed, 2 insertions(+), 1 deletion(-) > > > > diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug > > index d4fbbcc395d2..82d11ac63758 100644 > > --- a/lib/Kconfig.debug > > +++ b/lib/Kconfig.debug > > @@ -2696,13 +2696,14 @@ config TEST_STATIC_KEYS > > > > config TEST_DYNAMIC_DEBUG > > tristate "Build test-dynamic-debug module" > > + default m > > You need to justify such a change, and since it's not required > for running the system, I don't think it should be 'm'. > meh, now I cant "justify" the bored/curious comment. ;-) I'll drop this patch. > > depends on DYNAMIC_DEBUG || DYNAMIC_DEBUG_CORE > > help > > This module works/demo's the dyndbg's classmap API, by > > creating 2 classes: a DISJOINT classmap (like DRM.debug) > > and a LEVELS/VERBOSE classmap (where 2>1). > > > > - If unsure, say N. > > + If unsure, say N. If bored/curious, say M > > > > config TEST_KMOD > > tristate "kmod stress tester" > > -- > ~Randy
Re: [PATCH 1/1] drm/bridge: Fix handling of bridges with pre_enable_prev_first flag
Hi Frieder On Mon, 10 Jul 2023 at 08:46, Frieder Schrempf wrote: > > On 07.07.23 21:00, Vladimir Lypak wrote: > > [Sie erhalten nicht häufig E-Mails von vladimir.ly...@gmail.com. Weitere > > Informationen, warum dies wichtig ist, finden Sie unter > > https://aka.ms/LearnAboutSenderIdentification ] > > > > In function drm_atomic_bridge_chain_post_disable handling of > > pre_enable_prev_first flag is broken because "next" variable will always > > end up set to value of "bridge". This breaks loop which should disable > > bridges in reverse: > > > > next = list_next_entry(bridge, chain_node); > > > > if (next->pre_enable_prev_first) { > > /* next bridge had requested that prev > > * was enabled first, so disabled last > > */ > > limit = next; > > > > /* Find the next bridge that has NOT requested > > * prev to be enabled first / disabled last > > */ > > list_for_each_entry_from(next, >bridge_chain, > > chain_node) { > > // Next condition is always true. It is likely meant to be inversed > > // according to comment above. But doing this uncovers another problem: > > // it won't work if there are few bridges with this flag set at the end. > > if (next->pre_enable_prev_first) { > > next = list_prev_entry(next, chain_node); > > limit = next; > > // Here we always set next = limit = branch at first iteration. > > break; > > } > > } > > > > /* Call these bridges in reverse order */ > > list_for_each_entry_from_reverse(next, >bridge_chain, > > chain_node) { > > // This loop never executes past this branch. > > if (next == bridge) > > break; > > > > drm_atomic_bridge_call_post_disable(next, old_state); > > > > In this patch logic for handling the flag is simplified. Temporary > > "iter" variable is introduced instead of "next" which is used only > > inside inner loops. > > > > Fixes: 4fb912e5e190 ("drm/bridge: Introduce pre_enable_prev_first to alter > > bridge init order") > > Signed-off-by: Vladimir Lypak > > I haven't had a chance to look at this, but I still want to reference > another patch by Jagan that intends to fix some bug in this area: > > https://patchwork.kernel.org/project/dri-devel/patch/20230328170752.1102347-1-ja...@amarulasolutions.com/ > > +Cc: Jagan > > Dave, as you introduced this feature, did you have a chance to look at > Jagan's and Vladimir's patches? Sorry, they'd fallen off my radar. I'm having a look at the moment, but will probably need to carry it over to Monday. Dave
[PATCH v5 3/4] fbdev: Split frame buffer support in FB and FB_CORE symbols
Currently the CONFIG_FB option has to be enabled even if no legacy fbdev drivers are needed (e.g: only to have support for framebuffer consoles). The DRM subsystem has a fbdev emulation layer, but depends on CONFIG_FB and so it can only be enabled if that dependency is enabled as well. That means fbdev drivers have to be explicitly disabled if users want to enable CONFIG_FB, only to use fbcon and/or the DRM fbdev emulation layer. This patch introduces a non-visible CONFIG_FB_CORE symbol that could be enabled just to have core support needed for CONFIG_DRM_FBDEV_EMULATION, allowing CONFIG_FB to be disabled (and automatically disabling all the fbdev drivers). Nothing from fb_backlight.o and fbmon.o is used by the DRM fbdev emulation layer so these two objects can be compiled out when CONFIG_FB is disabled. Signed-off-by: Javier Martinez Canillas --- Changes in v5: - Fix ifdef guard check in drivers/video/backlight/backlight.c (Arnd Bergmann). Changes in v4: - Fix menuconfig hierarchy that was broken in v3 (Arnd Bergmann). Changes in v3: - Really make a hidden symbol by removing the prompt (Arnd Bergmann). - Change FB_CORE to config instead of menuconfig (Arnd Bergmann). - Keep "depends on FB" for FIRMWARE_EDID (Arnd Bergmann). - Compile out fb_backlight.o and fbmon.o that are only needed for FB (Arnd Bergmann). - Make FB_DEVICE to depend on FB_CORE instead of selecting it. Changes in v2: - Keep "depends on FB" for FB_DDC, FB_HECUBA, FB_SVGALIB, FB_MACMODES, FB_BACKLIGHT, FB_MODE_HELPERS and FB_TILEBLITTING (Arnd Bergmann). - Don't change the fb.o object name (Arnd Bergmann). - Make FB_CORE a non-visible Kconfig symbol instead (Thomas Zimmermann). arch/x86/Makefile | 2 +- arch/x86/video/Makefile | 2 +- drivers/video/backlight/backlight.c | 6 +++--- drivers/video/console/Kconfig | 2 +- drivers/video/fbdev/Kconfig | 10 -- drivers/video/fbdev/core/Kconfig| 30 - drivers/video/fbdev/core/Makefile | 8 7 files changed, 35 insertions(+), 25 deletions(-) diff --git a/arch/x86/Makefile b/arch/x86/Makefile index b39975977c03..89a02e69be5f 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -259,7 +259,7 @@ drivers-$(CONFIG_PCI)+= arch/x86/pci/ # suspend and hibernation support drivers-$(CONFIG_PM) += arch/x86/power/ -drivers-$(CONFIG_FB) += arch/x86/video/ +drivers-$(CONFIG_FB_CORE) += arch/x86/video/ # boot loader support. Several targets are kept for legacy purposes diff --git a/arch/x86/video/Makefile b/arch/x86/video/Makefile index 11640c116115..5ebe48752ffc 100644 --- a/arch/x86/video/Makefile +++ b/arch/x86/video/Makefile @@ -1,2 +1,2 @@ # SPDX-License-Identifier: GPL-2.0-only -obj-$(CONFIG_FB) += fbdev.o +obj-$(CONFIG_FB_CORE) += fbdev.o diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index 9a885d398c22..86e1cdc8e369 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c @@ -79,8 +79,8 @@ static const char *const backlight_scale_types[] = { [BACKLIGHT_SCALE_NON_LINEAR]= "non-linear", }; -#if defined(CONFIG_FB) || (defined(CONFIG_FB_MODULE) && \ - defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)) +#if defined(CONFIG_FB_CORE) || (defined(CONFIG_FB_CORE_MODULE) && \ + defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)) /* * fb_notifier_callback * @@ -155,7 +155,7 @@ static inline int backlight_register_fb(struct backlight_device *bd) static inline void backlight_unregister_fb(struct backlight_device *bd) { } -#endif /* CONFIG_FB */ +#endif /* CONFIG_FB_CORE */ static void backlight_generate_event(struct backlight_device *bd, enum backlight_update_reason reason) diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index a2a88d42edf0..1b5a319971ed 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -72,7 +72,7 @@ config DUMMY_CONSOLE_ROWS config FRAMEBUFFER_CONSOLE bool "Framebuffer Console support" - depends on FB && !UML + depends on FB_CORE && !UML select VT_HW_CONSOLE_BINDING select CRC32 select FONT_SUPPORT diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index ec4068abeb8e..7e65a648f71a 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -4,9 +4,9 @@ # menuconfig FB - tristate "Support for frame buffer devices" + tristate "Support for frame buffer device drivers" + select FB_CORE select FB_NOTIFY - select VIDEO_CMDLINE help The frame buffer device provides an abstraction for the graphics hardware. It represents the frame buffer of some video hardware and @@ -30,6 +30,12 @@ menuconfig FB
[PATCH v5 4/4] drm: Make FB_CORE to be selected if DRM fbdev emulation is enabled
Now that fbdev core has been split in FB_CORE and FB, make the DRM symbol to select the FB_CORE option if the DRM fbdev emulation layer is enabled. This allows to disable the CONFIG_FB option if is not needed, which will avoid the need to explicitly disable each of the legacy fbdev drivers. Signed-off-by: Javier Martinez Canillas --- (no changes since v3) Changes in v3: - Make the DRM symbol to select FB_CORE if DRM_FBDEV_EMULATION is enabled (Arnd Bergmann). - Also make DRM select FB_SYS_HELPERS_DEFERRED if DRM_FBDEV_EMULATION - Make DRM_FBDEV_EMULATION to depend on DRM instead of DRM_KMS_HELPER. Changes in v2: - Make CONFIG_DRM_FBDEV_EMULATION to select FB_CORE (Thomas Zimmermann). drivers/gpu/drm/Kconfig | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 22c1ba9ea28c..4f209e5c958c 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -9,6 +9,9 @@ menuconfig DRM tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)" depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && HAS_DMA select DRM_PANEL_ORIENTATION_QUIRKS + select DRM_KMS_HELPER if DRM_FBDEV_EMULATION + select FB_CORE if DRM_FBDEV_EMULATION + select FB_SYS_HELPERS_DEFERRED if DRM_FBDEV_EMULATION select HDMI select I2C select DMA_SHARED_BUFFER @@ -96,7 +99,6 @@ config DRM_KUNIT_TEST config DRM_KMS_HELPER tristate depends on DRM - select FB_SYS_HELPERS_DEFERRED if DRM_FBDEV_EMULATION help CRTC helpers for KMS drivers. @@ -132,8 +134,7 @@ config DRM_DEBUG_MODESET_LOCK config DRM_FBDEV_EMULATION bool "Enable legacy fbdev support for your modesetting driver" - depends on DRM_KMS_HELPER - depends on FB=y || FB=DRM_KMS_HELPER + depends on DRM select FRAMEBUFFER_CONSOLE if !EXPERT select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE default y -- 2.41.0
[PATCH v5 2/4] fbdev: Move core fbdev symbols to a separate Kconfig file
The drivers/video/fbdev/Kconfig defines both symbols for fbdev drivers and core fbdev symbols, that can be enabled independently of the fbdev drivers. Split the Kconfig in two, one that only has the symbols for fbdev drivers and another one that contains the fbdev core symbols. Suggested-by: Arnd Bergmann Signed-off-by: Javier Martinez Canillas --- (no changes since v1) drivers/video/fbdev/Kconfig | 203 +-- drivers/video/fbdev/core/Kconfig | 202 ++ 2 files changed, 204 insertions(+), 201 deletions(-) create mode 100644 drivers/video/fbdev/core/Kconfig diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index c12c166be7d1..ec4068abeb8e 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -3,9 +3,6 @@ # fbdev configuration # -config FB_NOTIFY - bool - menuconfig FB tristate "Support for frame buffer devices" select FB_NOTIFY @@ -42,204 +39,6 @@ menuconfig FB (e.g. an accelerated X server) and that are not frame buffer device-aware may cause unexpected results. If unsure, say N. -config FIRMWARE_EDID - bool "Enable firmware EDID" - depends on FB - help - This enables access to the EDID transferred from the firmware. - On the i386, this is from the Video BIOS. Enable this if DDC/I2C - transfers do not work for your driver and if you are using - nvidiafb, i810fb or savagefb. - - In general, choosing Y for this option is safe. If you - experience extremely long delays while booting before you get - something on your display, try setting this to N. Matrox cards in - combination with certain motherboards and monitors are known to - suffer from this problem. - -config FB_DEVICE - bool "Provide legacy /dev/fb* device" - depends on FB - default y - help - Say Y here if you want the legacy /dev/fb* device file and - interfaces within sysfs anc procfs. It is only required if you - have userspace programs that depend on fbdev for graphics output. - This does not affect the framebuffer console. If unsure, say N. - -config FB_DDC - tristate - depends on FB - select I2C_ALGOBIT - select I2C - -config FB_CFB_FILLRECT - tristate - depends on FB - help - Include the cfb_fillrect function for generic software rectangle - filling. This is used by drivers that don't provide their own - (accelerated) version. - -config FB_CFB_COPYAREA - tristate - depends on FB - help - Include the cfb_copyarea function for generic software area copying. - This is used by drivers that don't provide their own (accelerated) - version. - -config FB_CFB_IMAGEBLIT - tristate - depends on FB - help - Include the cfb_imageblit function for generic software image - blitting. This is used by drivers that don't provide their own - (accelerated) version. - -config FB_CFB_REV_PIXELS_IN_BYTE - bool - depends on FB - help - Allow generic frame-buffer functions to work on displays with 1, 2 - and 4 bits per pixel depths which has opposite order of pixels in - byte order to bytes in long order. - -config FB_SYS_FILLRECT - tristate - depends on FB - help - Include the sys_fillrect function for generic software rectangle - filling. This is used by drivers that don't provide their own - (accelerated) version and the framebuffer is in system RAM. - -config FB_SYS_COPYAREA - tristate - depends on FB - help - Include the sys_copyarea function for generic software area copying. - This is used by drivers that don't provide their own (accelerated) - version and the framebuffer is in system RAM. - -config FB_SYS_IMAGEBLIT - tristate - depends on FB - help - Include the sys_imageblit function for generic software image - blitting. This is used by drivers that don't provide their own - (accelerated) version and the framebuffer is in system RAM. - -config FB_PROVIDE_GET_FB_UNMAPPED_AREA - bool - depends on FB - help - Allow generic frame-buffer to provide get_fb_unmapped_area - function to provide shareable character device support on nommu. - -menuconfig FB_FOREIGN_ENDIAN - bool "Framebuffer foreign endianness support" - depends on FB - help - This menu will let you enable support for the framebuffers with - non-native endianness (e.g. Little-Endian framebuffer on a - Big-Endian machine). Most probably you don't have such hardware, - so it's safe to say "n" here. - -choice - prompt "Choice endianness support" - depends on FB_FOREIGN_ENDIAN - -config
[PATCH v5 1/4] video: Add auxiliary display drivers to Graphics support menu
The drivers in this subsystem are for character-based LCD displays, which can fall into the same category of the DRM/KMS and fbdev drivers that are located under the "Graphics support" menu. Add auxdisplay there as well. Suggested-by: Thomas Zimmermann Signed-off-by: Javier Martinez Canillas --- Changes in v5: - Take the auxdisplay/Kconfig source out of "if HAS_IOMEM" (Geert Uytterhoeven). drivers/Kconfig | 2 -- drivers/video/Kconfig | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/Kconfig b/drivers/Kconfig index 514ae6b24cb2..496ca02ee18f 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -129,8 +129,6 @@ source "drivers/dma-buf/Kconfig" source "drivers/dca/Kconfig" -source "drivers/auxdisplay/Kconfig" - source "drivers/uio/Kconfig" source "drivers/vfio/Kconfig" diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 8b2b9ac37c3d..e5b1cc54cafa 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -25,6 +25,8 @@ config VIDEO_NOMODESET bool default n +source "drivers/auxdisplay/Kconfig" + if HAS_IOMEM config HAVE_FB_ATMEL -- 2.41.0
[PATCH v5 0/4] Allow disabling all native fbdev drivers and only keeping DRM emulation
This patch series splits the fbdev core support in two different Kconfig symbols: FB and FB_CORE. The motivation for this is to allow CONFIG_FB to be disabled, while still having the the core fbdev support needed for the CONFIG_DRM_FBDEV_EMULATION to be enabled. The motivation is automatically disabling all fbdev drivers instead of having to be disabled individually. The reason for doing this is that now with simpledrm, there's no need for the legacy fbdev (e.g: efifb or vesafb) drivers anymore and many distros now disable them. But it would simplify the config a lot fo have a single Kconfig symbol to disable all fbdev drivers. I've built tested with possible combinations of CONFIG_FB, CONFIG_FB_CORE, CONFIG_DRM_FBDEV_EMULATION and CONFIG_FB_DEVICE symbols set to 'y' or 'n'. Patch #1 moves the auxdisplay drivers to "Graphics support" Kconfig menu, patch #2 moves the core fbdev Kconfig symbols to a separate Kconfig file, patch #3 does the FB symbol split and introduces the FB_CORE symbol and finally patch #4 makes the DRM symbol to select FB_CORE if the DRM fbdev emualtion support was enabled. Since this series touches three subsystems (auxdisplay, fbdev and DRM), I would like to merge it through DRM with the acks of these maintainers. This is a v5 of the patch-set that addresses issues pointed out by Arnd Bergmann, Thomas Zimmermann and Geert Uytterhoeven in the previous v4: https://lists.freedesktop.org/archives/dri-devel/2023-July/411842.html Changes in v5: - Take the auxdisplay/Kconfig source out of "if HAS_IOMEM" (Geert Uytterhoeven). - Fix ifdef guard check in drivers/video/backlight/backlight.c (Arnd Bergmann). Changes in v4: - Fix menuconfig hierarchy that was broken in v3 (Arnd Bergmann). Changes in v3: - Really make a hidden symbol by removing the prompt (Arnd Bergmann). - Change FB_CORE to config instead of menuconfig (Arnd Bergmann). - Keep "depends on FB" for FIRMWARE_EDID (Arnd Bergmann). - Compile out fb_backlight.o and fbmon.o that are only needed for FB (Arnd Bergmann). - Make FB_DEVICE to depend on FB_CORE instead of selecting it. - Make the DRM symbol to select FB_CORE if DRM_FBDEV_EMULATION is enabled (Arnd Bergmann). - Also make DRM select FB_SYS_HELPERS_DEFERRED if DRM_FBDEV_EMULATION - Make DRM_FBDEV_EMULATION to depend on DRM instead of DRM_KMS_HELPER. Changes in v2: - Keep "depends on FB" for FB_DDC, FB_HECUBA, FB_SVGALIB, FB_MACMODES, FB_BACKLIGHT, FB_MODE_HELPERS and FB_TILEBLITTING (Arnd Bergmann). - Don't change the fb.o object name (Arnd Bergmann). - Make FB_CORE a non-visible Kconfig symbol instead (Thomas Zimmermann). - Make CONFIG_DRM_FBDEV_EMULATION to select FB_CORE (Thomas Zimmermann). Javier Martinez Canillas (4): video: Add auxiliary display drivers to Graphics support menu fbdev: Move core fbdev symbols to a separate Kconfig file fbdev: Split frame buffer support in FB and FB_CORE symbols drm: Make FB_CORE to be selected if DRM fbdev emulation is enabled arch/x86/Makefile | 2 +- arch/x86/video/Makefile | 2 +- drivers/Kconfig | 2 - drivers/gpu/drm/Kconfig | 7 +- drivers/video/Kconfig | 2 + drivers/video/backlight/backlight.c | 6 +- drivers/video/console/Kconfig | 2 +- drivers/video/fbdev/Kconfig | 213 ++-- drivers/video/fbdev/core/Kconfig| 206 +++ drivers/video/fbdev/core/Makefile | 8 +- 10 files changed, 232 insertions(+), 218 deletions(-) create mode 100644 drivers/video/fbdev/core/Kconfig -- 2.41.0
Re: [PATCH 5/5 v4] accel/qaic: Fix a leak in map_user_pages()
On 7/14/2023 5:47 AM, Pranjal Ramajor Asha Kanojiya wrote: On 7/11/2023 1:51 PM, Dan Carpenter wrote: If get_user_pages_fast() allocates some pages but not as many as we wanted, then the current code leaks those pages. Call put_page() on the pages before returning. Fixes: 129776ac2e38 ("accel/qaic: Add control path") Signed-off-by: Dan Carpenter Reviewed-by: Pranjal Ramajor Asha Kanojiya Pushed to drm-misc-fixes -Jeff
Re: [PATCH 3/5 v4] accel/qaic: Add consistent integer overflow checks
On 7/14/2023 5:44 AM, Pranjal Ramajor Asha Kanojiya wrote: On 7/11/2023 1:51 PM, Dan Carpenter wrote: The encode_dma() function has integer overflow checks. The encode_passthrough(), encode_activate() and encode_status() functions did not. I added integer overflow checking everywhere. I also updated the integer overflow checking in encode_dma() to use size_add() so everything is consistent. Fixes: 129776ac2e38 ("accel/qaic: Add control path") Signed-off-by: Dan Carpenter --- v2: no change drivers/accel/qaic/qaic_control.c | 14 ++ 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/accel/qaic/qaic_control.c b/drivers/accel/qaic/qaic_control.c index 752b67aff777..23680f5f1902 100644 --- a/drivers/accel/qaic/qaic_control.c +++ b/drivers/accel/qaic/qaic_control.c @@ -367,7 +367,7 @@ static int encode_passthrough(struct qaic_device *qdev, void *trans, struct wrap if (in_trans->hdr.len % 8 != 0) return -EINVAL; - if (msg_hdr_len + in_trans->hdr.len > QAIC_MANAGE_EXT_MSG_LENGTH) + if (size_add(msg_hdr_len, in_trans->hdr.len) > QAIC_MANAGE_EXT_MSG_LENGTH) return -ENOSPC; trans_wrapper = add_wrapper(wrappers, @@ -558,12 +558,10 @@ static int encode_dma(struct qaic_device *qdev, void *trans, struct wrapper_list msg = >msg; msg_hdr_len = le32_to_cpu(msg->hdr.len); - if (msg_hdr_len > (UINT_MAX - QAIC_MANAGE_EXT_MSG_LENGTH)) - return -EINVAL; - /* There should be enough space to hold at least one ASP entry. */ - if (msg_hdr_len + sizeof(*out_trans) + sizeof(struct wire_addr_size_pair) > - QAIC_MANAGE_EXT_MSG_LENGTH) + if (size_add(msg_hdr_len, + sizeof(*out_trans) + sizeof(struct wire_addr_size_pair)) > Can we have the entire size_add() on same line? + QAIC_MANAGE_EXT_MSG_LENGTH) return -ENOMEM; if (in_trans->addr + in_trans->size < in_trans->addr || !in_trans->size) @@ -635,7 +633,7 @@ static int encode_activate(struct qaic_device *qdev, void *trans, struct wrapper msg = >msg; msg_hdr_len = le32_to_cpu(msg->hdr.len); - if (msg_hdr_len + sizeof(*out_trans) > QAIC_MANAGE_MAX_MSG_LENGTH) + if (size_add(msg_hdr_len, sizeof(*out_trans)) > QAIC_MANAGE_MAX_MSG_LENGTH) return -ENOSPC; if (!in_trans->queue_size) @@ -719,7 +717,7 @@ static int encode_status(struct qaic_device *qdev, void *trans, struct wrapper_l msg = >msg; msg_hdr_len = le32_to_cpu(msg->hdr.len); - if (msg_hdr_len + in_trans->hdr.len > QAIC_MANAGE_MAX_MSG_LENGTH) + if (size_add(msg_hdr_len, in_trans->hdr.len) > QAIC_MANAGE_MAX_MSG_LENGTH) return -ENOSPC; trans_wrapper = add_wrapper(wrappers, sizeof(*trans_wrapper)); Reviewed-by: Pranjal Ramajor Asha Kanojiya Pushed to drm-misc-fixes -Jeff
[PATCH v3 5/5] drm/amdgpu: Create version number for coredumps
Even if there's nothing currently parsing amdgpu's coredump files, if we eventually have such tools they will be glad to find a version field to properly read the file. Create a version number to be displayed on top of coredump file, to be incremented when the file format or content get changed. Signed-off-by: André Almeida --- drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h | 3 +++ 2 files changed, 4 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c index 081cdf3bc267..dab385f9dd80 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c @@ -192,6 +192,7 @@ static ssize_t amdgpu_devcoredump_read(char *buffer, loff_t offset, p = drm_coredump_printer(); drm_printf(, " AMDGPU Device Coredump \n"); + drm_printf(, "version: " AMDGPU_COREDUMP_VERSION "\n"); drm_printf(, "kernel: " UTS_RELEASE "\n"); drm_printf(, "module: " KBUILD_MODNAME "\n"); drm_printf(, "time: %lld.%09ld\n", coredump->reset_time.tv_sec, coredump->reset_time.tv_nsec); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h index 362954521721..7b6767ca8127 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h @@ -88,6 +88,9 @@ struct amdgpu_reset_domain { }; #ifdef CONFIG_DEV_COREDUMP + +#define AMDGPU_COREDUMP_VERSION "1" + struct amdgpu_coredump_info { struct amdgpu_device*adev; struct amdgpu_task_info reset_task_info; -- 2.41.0
[PATCH v3 4/5] drm/amdgpu: Move coredump code to amdgpu_reset file
Giving that we use codedump just for device resets, move it's functions and structs to a more semantic file, the amdgpu_reset.{c, h}. Signed-off-by: André Almeida --- drivers/gpu/drm/amd/amdgpu/amdgpu.h| 9 --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 80 -- drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c | 78 + drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h | 11 +++ 4 files changed, 89 insertions(+), 89 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index e1cc83a89d46..1e76cb38a554 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1080,15 +1080,6 @@ struct amdgpu_device { uint32_taid_mask; }; -#ifdef CONFIG_DEV_COREDUMP -struct amdgpu_coredump_info { - struct amdgpu_device*adev; - struct amdgpu_task_info reset_task_info; - struct timespec64 reset_time; - boolreset_vram_lost; -}; -#endif - static inline struct amdgpu_device *drm_to_adev(struct drm_device *ddev) { return container_of(ddev, struct amdgpu_device, ddev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index e80670420586..e84d499aaf4a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -32,8 +32,6 @@ #include #include #include -#include -#include #include #include @@ -4963,84 +4961,6 @@ static int amdgpu_reset_reg_dumps(struct amdgpu_device *adev) return 0; } -#ifndef CONFIG_DEV_COREDUMP -static void amdgpu_coredump(struct amdgpu_device *adev, bool vram_lost, - struct amdgpu_reset_context *reset_context) -{ -} -#else -static ssize_t amdgpu_devcoredump_read(char *buffer, loff_t offset, - size_t count, void *data, size_t datalen) -{ - struct drm_printer p; - struct amdgpu_coredump_info *coredump = data; - struct drm_print_iterator iter; - int i; - - iter.data = buffer; - iter.offset = 0; - iter.start = offset; - iter.remain = count; - - p = drm_coredump_printer(); - - drm_printf(, " AMDGPU Device Coredump \n"); - drm_printf(, "kernel: " UTS_RELEASE "\n"); - drm_printf(, "module: " KBUILD_MODNAME "\n"); - drm_printf(, "time: %lld.%09ld\n", coredump->reset_time.tv_sec, coredump->reset_time.tv_nsec); - if (coredump->reset_task_info.pid) - drm_printf(, "process_name: %s PID: %d\n", - coredump->reset_task_info.process_name, - coredump->reset_task_info.pid); - - if (coredump->reset_vram_lost) - drm_printf(, "VRAM is lost due to GPU reset!\n"); - if (coredump->adev->num_regs) { - drm_printf(, "AMDGPU register dumps:\nOffset: Value:\n"); - - for (i = 0; i < coredump->adev->num_regs; i++) - drm_printf(, "0x%08x: 0x%08x\n", - coredump->adev->reset_dump_reg_list[i], - coredump->adev->reset_dump_reg_value[i]); - } - - return count - iter.remain; -} - -static void amdgpu_devcoredump_free(void *data) -{ - kfree(data); -} - -static void amdgpu_coredump(struct amdgpu_device *adev, bool vram_lost, - struct amdgpu_reset_context *reset_context) -{ - struct amdgpu_coredump_info *coredump; - struct drm_device *dev = adev_to_drm(adev); - - coredump = kmalloc(sizeof(*coredump), GFP_NOWAIT); - - if (!coredump) { - DRM_ERROR("%s: failed to allocate memory for coredump\n", __func__); - return; - } - - memset(coredump, 0, sizeof(*coredump)); - - coredump->reset_vram_lost = vram_lost; - - if (reset_context->job && reset_context->job->vm) - coredump->reset_task_info = reset_context->job->vm->task_info; - - coredump->adev = adev; - - ktime_get_ts64(>reset_time); - - dev_coredumpm(dev->dev, THIS_MODULE, coredump, 0, GFP_NOWAIT, - amdgpu_devcoredump_read, amdgpu_devcoredump_free); -} -#endif - int amdgpu_do_asic_reset(struct list_head *device_list_handle, struct amdgpu_reset_context *reset_context) { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c index eec41ad30406..081cdf3bc267 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c @@ -21,6 +21,9 @@ * */ +#include +#include + #include "amdgpu_reset.h" #include "aldebaran.h" #include "sienna_cichlid.h" @@ -167,5 +170,80 @@ void amdgpu_device_unlock_reset_domain(struct amdgpu_reset_domain *reset_domain) up_write(_domain->sem); } +#ifndef CONFIG_DEV_COREDUMP +void
[PATCH v3 2/5] drm/amdgpu: Allocate coredump memory in a nonblocking way
During a GPU reset, a normal memory reclaim could block to reclaim memory. Giving that coredump is a best effort mechanism, it shouldn't disturb the reset path. Change its memory allocation flag to a nonblocking one. Signed-off-by: André Almeida Reviewed-by: Christian König --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index e25f085ee886..a824f844a984 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -5011,7 +5011,7 @@ static void amdgpu_reset_capture_coredumpm(struct amdgpu_device *adev) struct drm_device *dev = adev_to_drm(adev); ktime_get_ts64(>reset_time); - dev_coredumpm(dev->dev, THIS_MODULE, adev, 0, GFP_KERNEL, + dev_coredumpm(dev->dev, THIS_MODULE, adev, 0, GFP_NOWAIT, amdgpu_devcoredump_read, amdgpu_devcoredump_free); } #endif -- 2.41.0
[PATCH v3 3/5] drm/amdgpu: Rework coredump to use memory dynamically
Instead of storing coredump information inside amdgpu_device struct, move if to a proper separated struct and allocate it dynamically. This will make it easier to further expand the logged information. Signed-off-by: André Almeida --- drivers/gpu/drm/amd/amdgpu/amdgpu.h| 14 +++-- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 65 ++ 2 files changed, 51 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index dbe062a087c5..e1cc83a89d46 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1068,11 +1068,6 @@ struct amdgpu_device { uint32_t*reset_dump_reg_list; uint32_t*reset_dump_reg_value; int num_regs; -#ifdef CONFIG_DEV_COREDUMP - struct amdgpu_task_info reset_task_info; - boolreset_vram_lost; - struct timespec64 reset_time; -#endif boolscpm_enabled; uint32_tscpm_status; @@ -1085,6 +1080,15 @@ struct amdgpu_device { uint32_taid_mask; }; +#ifdef CONFIG_DEV_COREDUMP +struct amdgpu_coredump_info { + struct amdgpu_device*adev; + struct amdgpu_task_info reset_task_info; + struct timespec64 reset_time; + boolreset_vram_lost; +}; +#endif + static inline struct amdgpu_device *drm_to_adev(struct drm_device *ddev) { return container_of(ddev, struct amdgpu_device, ddev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index a824f844a984..e80670420586 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -4963,12 +4963,17 @@ static int amdgpu_reset_reg_dumps(struct amdgpu_device *adev) return 0; } -#ifdef CONFIG_DEV_COREDUMP +#ifndef CONFIG_DEV_COREDUMP +static void amdgpu_coredump(struct amdgpu_device *adev, bool vram_lost, + struct amdgpu_reset_context *reset_context) +{ +} +#else static ssize_t amdgpu_devcoredump_read(char *buffer, loff_t offset, size_t count, void *data, size_t datalen) { struct drm_printer p; - struct amdgpu_device *adev = data; + struct amdgpu_coredump_info *coredump = data; struct drm_print_iterator iter; int i; @@ -4982,21 +4987,21 @@ static ssize_t amdgpu_devcoredump_read(char *buffer, loff_t offset, drm_printf(, " AMDGPU Device Coredump \n"); drm_printf(, "kernel: " UTS_RELEASE "\n"); drm_printf(, "module: " KBUILD_MODNAME "\n"); - drm_printf(, "time: %lld.%09ld\n", adev->reset_time.tv_sec, adev->reset_time.tv_nsec); - if (adev->reset_task_info.pid) + drm_printf(, "time: %lld.%09ld\n", coredump->reset_time.tv_sec, coredump->reset_time.tv_nsec); + if (coredump->reset_task_info.pid) drm_printf(, "process_name: %s PID: %d\n", - adev->reset_task_info.process_name, - adev->reset_task_info.pid); + coredump->reset_task_info.process_name, + coredump->reset_task_info.pid); - if (adev->reset_vram_lost) + if (coredump->reset_vram_lost) drm_printf(, "VRAM is lost due to GPU reset!\n"); - if (adev->num_regs) { + if (coredump->adev->num_regs) { drm_printf(, "AMDGPU register dumps:\nOffset: Value:\n"); - for (i = 0; i < adev->num_regs; i++) + for (i = 0; i < coredump->adev->num_regs; i++) drm_printf(, "0x%08x: 0x%08x\n", - adev->reset_dump_reg_list[i], - adev->reset_dump_reg_value[i]); + coredump->adev->reset_dump_reg_list[i], + coredump->adev->reset_dump_reg_value[i]); } return count - iter.remain; @@ -5004,14 +5009,34 @@ static ssize_t amdgpu_devcoredump_read(char *buffer, loff_t offset, static void amdgpu_devcoredump_free(void *data) { + kfree(data); } -static void amdgpu_reset_capture_coredumpm(struct amdgpu_device *adev) +static void amdgpu_coredump(struct amdgpu_device *adev, bool vram_lost, + struct amdgpu_reset_context *reset_context) { + struct amdgpu_coredump_info *coredump; struct drm_device *dev = adev_to_drm(adev); - ktime_get_ts64(>reset_time); - dev_coredumpm(dev->dev, THIS_MODULE, adev, 0, GFP_NOWAIT, + coredump = kmalloc(sizeof(*coredump), GFP_NOWAIT); + + if (!coredump) { + DRM_ERROR("%s: failed to allocate memory for coredump\n", __func__); +
[PATCH v3 1/5] drm/amdgpu: Create a module param to disable soft recovery
Create a module parameter to disable soft recoveries on amdgpu, making every recovery go through the device reset path. This option makes easier to force device resets for testing and debugging purposes. Signed-off-by: André Almeida --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 9 + drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 6 +- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index a84bd4a0c421..dbe062a087c5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -189,6 +189,7 @@ extern uint amdgpu_force_long_training; extern int amdgpu_lbpw; extern int amdgpu_compute_multipipe; extern int amdgpu_gpu_recovery; +extern bool amdgpu_soft_recovery; extern int amdgpu_emu_mode; extern uint amdgpu_smu_memory_pool_size; extern int amdgpu_smu_pptable_id; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 3b711babd4e2..7c69f3169aa6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -163,6 +163,7 @@ uint amdgpu_force_long_training; int amdgpu_lbpw = -1; int amdgpu_compute_multipipe = -1; int amdgpu_gpu_recovery = -1; /* auto */ +bool amdgpu_soft_recovery = true; int amdgpu_emu_mode; uint amdgpu_smu_memory_pool_size; int amdgpu_smu_pptable_id = -1; @@ -540,6 +541,14 @@ module_param_named(compute_multipipe, amdgpu_compute_multipipe, int, 0444); MODULE_PARM_DESC(gpu_recovery, "Enable GPU recovery mechanism, (1 = enable, 0 = disable, -1 = auto)"); module_param_named(gpu_recovery, amdgpu_gpu_recovery, int, 0444); +/** + * DOC: gpu_soft_recovery (bool) + * Set true to allow the driver to try soft recoveries if a job get stuck. Set + * to false to always force a GPU reset during recovery. + */ +MODULE_PARM_DESC(gpu_soft_recovery, "Enable GPU soft recovery mechanism (default: true)"); +module_param_named(gpu_soft_recovery, amdgpu_soft_recovery, bool, 0644); + /** * DOC: emu_mode (int) * Set value 1 to enable emulation mode. This is only needed when running on an emulator. The default is 0 (disabled). diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c index 80d6e132e409..40678d9fb17e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c @@ -434,8 +434,12 @@ bool amdgpu_ring_soft_recovery(struct amdgpu_ring *ring, unsigned int vmid, struct dma_fence *fence) { unsigned long flags; + ktime_t deadline; - ktime_t deadline = ktime_add_us(ktime_get(), 1); + if (!amdgpu_soft_recovery) + return false; + + deadline = ktime_add_us(ktime_get(), 1); if (amdgpu_sriov_vf(ring->adev) || !ring->funcs->soft_recovery || !fence) return false; -- 2.41.0
[PATCH v3 0/5] drm/amdgpu: Add new reset option and rework coredump
Hi, The goal of this patchset is to improve debugging device resets on amdgpu. The first patch creates a new module parameter to disable soft recoveries, ensuring every recovery go through the full device reset, making easier to generate resets from userspace tools like [0] and [1]. This is important to validate how the stack behaves on resets, from end-to-end. The last patches are a rework to alloc devcoredump dynamically and to move it to a better source file. I have dropped the patches that add more information to devcoredump for now, until I figure out a better way to do so, like storing the IB address in the fence. Thanks, André [0] https://gitlab.freedesktop.org/andrealmeid/gpu-timeout [1] https://github.com/andrealmeid/vulkan-triangle-v1 Changelog: v2: https://lore.kernel.org/dri-devel/20230713213242.680944-1-andrealm...@igalia.com/ - Drop the IB and ring patch - Drop patch that limited information from kernel threads - Add patch to move coredump to amdgpu_reset v1: https://lore.kernel.org/dri-devel/20230711213501.526237-1-andrealm...@igalia.com/ - Drop "Mark contexts guilty for causing soft recoveries" patch - Use GFP_NOWAIT for devcoredump allocation André Almeida (5): drm/amdgpu: Create a module param to disable soft recovery drm/amdgpu: Allocate coredump memory in a nonblocking way drm/amdgpu: Rework coredump to use memory dynamically drm/amdgpu: Move coredump code to amdgpu_reset file drm/amdgpu: Create version number for coredumps drivers/gpu/drm/amd/amdgpu/amdgpu.h| 6 +- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 67 +- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c| 9 +++ drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c | 79 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h | 14 drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 6 +- 6 files changed, 111 insertions(+), 70 deletions(-) -- 2.41.0
Re: [PATCH 2/5 v4] accel/qaic: tighten bounds checking in decode_message()
On 7/14/2023 5:42 AM, Pranjal Ramajor Asha Kanojiya wrote: On 7/11/2023 1:50 PM, Dan Carpenter wrote: Copy the bounds checking from encode_message() to decode_message(). This patch addresses the following concerns. Ensure that there is enough space for at least one header so that we don't have a negative size later. if (msg_hdr_len < sizeof(*trans_hdr)) Ensure that we have enough space to read the next header from the msg->data. if (msg_len > msg_hdr_len - sizeof(*trans_hdr)) return -EINVAL; Check that the trans_hdr->len is not below the minimum size: if (hdr_len < sizeof(*trans_hdr)) This minimum check ensures that we don't corrupt memory in decode_passthrough() when we do. memcpy(out_trans->data, in_trans->data, len - sizeof(in_trans->hdr)); And finally, use size_add() to prevent an integer overflow: if (size_add(msg_len, hdr_len) > msg_hdr_len) Fixes: 129776ac2e38 ("accel/qaic: Add control path") Signed-off-by: Dan Carpenter Reviewed-by: Pranjal Ramajor Asha Kanojiya Pushed to drm-misc-fixes -Jeff
Re: [PATCH 1/5 v4] accel/qaic: tighten bounds checking in encode_message()
On 7/14/2023 5:41 AM, Pranjal Ramajor Asha Kanojiya wrote: On 7/11/2023 1:50 PM, Dan Carpenter wrote: There are several issues in this code. The check at the start of the loop: if (user_len >= user_msg->len) { This check does not ensure that we have enough space for the trans_hdr (8 bytes). Instead the check needs to be: if (user_len > user_msg->len - sizeof(*trans_hdr)) { That subtraction is done as an unsigned long we want to avoid negatives. Add a lower bound to the start of the function. if (user_msg->len < sizeof(*trans_hdr)) There is a second integer underflow which can happen if trans_hdr->len is zero inside the encode_passthrough() function. memcpy(out_trans->data, in_trans->data, in_trans->hdr.len - sizeof(in_trans->hdr)); Instead of adding a check to encode_passthrough() it's better to check in this central place. Add that check: if (trans_hdr->len < sizeof(trans_hdr) The final concern is that the "user_len + trans_hdr->len" might have an integer overflow bug. Use size_add() to prevent that. - if (user_len + trans_hdr->len > user_msg->len) { + if (size_add(user_len, trans_hdr->len) > user_msg->len) { Fixes: 129776ac2e38 ("accel/qaic: Add control path") Signed-off-by: Dan Carpenter Reviewed-by: Pranjal Ramajor Asha Kanojiya Applied to drm-misc-fixes -Jeff
Re: [PATCH 0/2] eventfd: simplify signal helpers
On Fri, Jul 14, 2023 at 09:05:21AM +0200, Christian Brauner wrote: > I have no skin in the game aside from having to drop this conversion > which I'm fine to do if there are actually users for this btu really, > that looks a lot like abusing an api that really wasn't designed for > this. Yeah, I think so too. The ACPI thing should use its own FD if it wants to feed actual data.. Jason
Re: [PATCH 3/5] drm/amdkfd: use vma_is_stack() and vma_is_heap()
Am 2023-07-14 um 10:26 schrieb Vlastimil Babka: On 7/12/23 18:24, Felix Kuehling wrote: Allocations in the heap and stack tend to be small, with several allocations sharing the same page. Sharing the same page for different allocations with different access patterns leads to thrashing when we migrate data back and forth on GPU and CPU access. To avoid this we disable HMM migrations for head and stack VMAs. Wonder how well does it really work in practice? AFAIK "heaps" (malloc()) today uses various arenas obtained by mmap() and not a single brk() managed space anymore? And programs might be multithreaded, thus have multiple stacks, while vma_is_stack() will recognize only the initial one... Thanks for these pointers. I have not heard of such problems with mmap arenas and multiple thread stacks in practice. But I'll keep it in mind in case we observe unexpected thrashing in the future. FWIW, we once had the opposite problem of a custom malloc implementation that used sbrk for very large allocations. This disabled migrations of large buffers unexpectedly. I agree that eventually we'll want a more dynamic way of detecting and suppressing thrashing that's based on observed memory access patterns. Getting this right is probably trickier than it sounds, so I'd prefer to have some more experience with real workloads to use as benchmarks. Compared to other things we're working on, this is fairly low on our priority list at the moment. Using the VMA flags is a simple and effective method for now, at least until we see it failing in real workloads. Regards, Felix Vlastimil Regards, Felix Am 2023-07-12 um 10:42 schrieb Christoph Hellwig: On Wed, Jul 12, 2023 at 10:38:29PM +0800, Kefeng Wang wrote: Use the helpers to simplify code. Nothing against your addition of a helper, but a GPU driver really should have no business even looking at this information..
Re: [RFC PATCH 3/3] drm/file: drop DRM_MINOR_CONTROL
Hi Am 14.07.23 um 16:37 schrieb Simon Ser: On Friday, July 14th, 2023 at 16:28, Thomas Zimmermann wrote: Hi Simon Am 14.07.23 um 12:46 schrieb Simon Ser: This entry should never be used by the kernel. Record the historical context in a comment. Signed-off-by: Simon Ser Cc: Christian König Cc: James Zhu Cc: Marek Olšák Cc: Daniel Vetter --- include/drm/drm_file.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/drm/drm_file.h b/include/drm/drm_file.h index 010239392adf..a23cc2f6163f 100644 --- a/include/drm/drm_file.h +++ b/include/drm/drm_file.h @@ -53,12 +53,14 @@ struct file; /* Note that the values of this enum are ABI (it determines * /dev/dri/renderD* numbers). * + * There used to be a DRM_MINOR_CONTROL = 1 entry, but such nodes were never + * exposed. Still, some user-space has logic to handle them. + * * Setting DRM_MINOR_ACCEL to 32 gives enough space for more drm minors to * be implemented before we hit any future */ enum drm_minor_type { DRM_MINOR_PRIMARY = 0, - DRM_MINOR_CONTROL = 1, Maybe rather leave this line in and comment it with "// obsolete". Otherwise someone might accidentally use 1 for something. Yeah... That's why I added the comment. But maybe better to leave the entry indeed, even if we risk someone accidentally using it. You could still out-comment the line as a whole. Simply having it there will warn potential users. Best regards Thomas In any case Reviewed-by: Thomas Zimmermann for the whole series. Thanks for the review! -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg) OpenPGP_signature Description: OpenPGP digital signature
Re: [RFC PATCH 3/3] drm/file: drop DRM_MINOR_CONTROL
On Friday, July 14th, 2023 at 16:28, Thomas Zimmermann wrote: > Hi Simon > > Am 14.07.23 um 12:46 schrieb Simon Ser: > > This entry should never be used by the kernel. Record the historical > > context in a comment. > > > > Signed-off-by: Simon Ser > > Cc: Christian König > > Cc: James Zhu > > Cc: Marek Olšák > > Cc: Daniel Vetter > > --- > > include/drm/drm_file.h | 4 +++- > > 1 file changed, 3 insertions(+), 1 deletion(-) > > > > diff --git a/include/drm/drm_file.h b/include/drm/drm_file.h > > index 010239392adf..a23cc2f6163f 100644 > > --- a/include/drm/drm_file.h > > +++ b/include/drm/drm_file.h > > @@ -53,12 +53,14 @@ struct file; > > /* Note that the values of this enum are ABI (it determines > >* /dev/dri/renderD* numbers). > >* > > + * There used to be a DRM_MINOR_CONTROL = 1 entry, but such nodes were > > never > > + * exposed. Still, some user-space has logic to handle them. > > + * > >* Setting DRM_MINOR_ACCEL to 32 gives enough space for more drm minors to > >* be implemented before we hit any future > >*/ > > enum drm_minor_type { > > DRM_MINOR_PRIMARY = 0, > > - DRM_MINOR_CONTROL = 1, > > Maybe rather leave this line in and comment it with "// obsolete". > Otherwise someone might accidentally use 1 for something. Yeah... That's why I added the comment. But maybe better to leave the entry indeed, even if we risk someone accidentally using it. > In any case > > Reviewed-by: Thomas Zimmermann > > for the whole series. Thanks for the review!
[PATCH v4 17/17] arm64: dts: ti: k3-am62-main: Add GPU device node [DO NOT MERGE]
Add the Series AXE GPU node to the AM62 device tree. Signed-off-by: Sarah Walker --- arch/arm64/boot/dts/ti/k3-am62-main.dtsi | 13 + 1 file changed, 13 insertions(+) diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi index b3e4857bbbe4..ad13414acf18 100644 --- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi @@ -892,4 +892,17 @@ mcasp2: audio-controller@2b2 { power-domains = <_pds 192 TI_SCI_PD_EXCLUSIVE>; status = "disabled"; }; + +gpu: gpu@fd0 { +compatible = "ti,am62-gpu", "img,powervr-seriesaxe"; +reg = <0 0x0fd0 0 0x2>; +power-domains = <_pds 187 TI_SCI_PD_EXCLUSIVE>; +clocks = <_clks 187 0>; +clock-names = "core"; +interrupts = ; +interrupt-names = "gpu"; +#cooling-cells = <2>; +#cooling-min-level = <0>; +#cooling-max-level = <3>; +}; }; -- 2.41.0
[PATCH v4 16/17] drm/imagination: Add driver documentation
Add documentation for the UAPI and for the virtual memory design. Signed-off-by: Sarah Walker --- Documentation/gpu/drivers.rst | 2 + Documentation/gpu/imagination/index.rst | 14 + Documentation/gpu/imagination/uapi.rst| 174 +++ .../gpu/imagination/virtual_memory.rst| 462 ++ MAINTAINERS | 1 + 5 files changed, 653 insertions(+) create mode 100644 Documentation/gpu/imagination/index.rst create mode 100644 Documentation/gpu/imagination/uapi.rst create mode 100644 Documentation/gpu/imagination/virtual_memory.rst diff --git a/Documentation/gpu/drivers.rst b/Documentation/gpu/drivers.rst index 3a52f48215a3..5487deb218a3 100644 --- a/Documentation/gpu/drivers.rst +++ b/Documentation/gpu/drivers.rst @@ -3,9 +3,11 @@ GPU Driver Documentation .. toctree:: + :maxdepth: 3 amdgpu/index i915 + imagination/index mcde meson pl111 diff --git a/Documentation/gpu/imagination/index.rst b/Documentation/gpu/imagination/index.rst new file mode 100644 index ..57f28e460a03 --- /dev/null +++ b/Documentation/gpu/imagination/index.rst @@ -0,0 +1,14 @@ +=== +drm/imagination PowerVR Graphics Driver +=== + +.. kernel-doc:: drivers/gpu/drm/imagination/pvr_drv.c + :doc: PowerVR Graphics Driver + +Contents + +.. toctree:: + :maxdepth: 2 + + uapi + virtual_memory diff --git a/Documentation/gpu/imagination/uapi.rst b/Documentation/gpu/imagination/uapi.rst new file mode 100644 index ..2227ea7e6222 --- /dev/null +++ b/Documentation/gpu/imagination/uapi.rst @@ -0,0 +1,174 @@ + +UAPI + +The sources associated with this section can be found in ``pvr_drm.h``. + +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :doc: PowerVR UAPI + +OBJECT ARRAYS += +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :identifiers: drm_pvr_obj_array + +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :identifiers: DRM_PVR_OBJ_ARRAY + +IOCTLS +== +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :doc: PowerVR IOCTL interface + +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :identifiers: PVR_IOCTL + +DEV_QUERY +- +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :doc: PowerVR IOCTL DEV_QUERY interface + +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :identifiers: drm_pvr_dev_query + +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :identifiers: drm_pvr_ioctl_dev_query_args + +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :identifiers: drm_pvr_dev_query_gpu_info + drm_pvr_dev_query_runtime_info + drm_pvr_dev_query_hwrt_info + drm_pvr_dev_query_quirks + drm_pvr_dev_query_enhancements + +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :identifiers: drm_pvr_heap_id + drm_pvr_heap + drm_pvr_dev_query_heap_info + +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :doc: Flags for DRM_PVR_DEV_QUERY_HEAP_INFO_GET. + +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :identifiers: drm_pvr_static_data_area_usage + drm_pvr_static_data_area + drm_pvr_dev_query_static_data_areas + +CREATE_BO +- +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :doc: PowerVR IOCTL CREATE_BO interface + +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :identifiers: drm_pvr_ioctl_create_bo_args + +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :doc: Flags for CREATE_BO + +GET_BO_MMAP_OFFSET +-- +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :doc: PowerVR IOCTL GET_BO_MMAP_OFFSET interface + +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :identifiers: drm_pvr_ioctl_get_bo_mmap_offset_args + +CREATE_VM_CONTEXT and DESTROY_VM_CONTEXT + +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :doc: PowerVR IOCTL CREATE_VM_CONTEXT and DESTROY_VM_CONTEXT interfaces + +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :identifiers: drm_pvr_ioctl_create_vm_context_args + drm_pvr_ioctl_destroy_vm_context_args + +VM_MAP and VM_UNMAP +--- +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :doc: PowerVR IOCTL VM_MAP and VM_UNMAP interfaces + +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :identifiers: drm_pvr_ioctl_vm_map_args + drm_pvr_ioctl_vm_unmap_args + +CREATE_CONTEXT and DESTROY_CONTEXT +-- +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :doc: PowerVR IOCTL CREATE_CONTEXT and DESTROY_CONTEXT interfaces + +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :identifiers: drm_pvr_ioctl_create_context_args + +.. kernel-doc:: include/uapi/drm/pvr_drm.h + :identifiers: drm_pvr_ctx_priority + drm_pvr_ctx_type + drm_pvr_static_render_context_state + drm_pvr_static_render_context_state_format +
[PATCH v4 15/17] drm/imagination: Add firmware trace to debugfs
Firmware trace is exposed at /sys/debug/dri//pvr_fw/trace_0. Trace is enabled via the group mask at /sys/debug/dri//pvr_params/fw_trace_mask. Changes since v3: - Use drm_dev_{enter,exit} Signed-off-by: Sarah Walker --- drivers/gpu/drm/imagination/Makefile | 4 + drivers/gpu/drm/imagination/pvr_debugfs.c | 53 +++ drivers/gpu/drm/imagination/pvr_debugfs.h | 29 ++ drivers/gpu/drm/imagination/pvr_device.c | 9 + drivers/gpu/drm/imagination/pvr_device.h | 10 + drivers/gpu/drm/imagination/pvr_drv.c | 4 + drivers/gpu/drm/imagination/pvr_fw_trace.c | 394 + drivers/gpu/drm/imagination/pvr_params.c | 147 drivers/gpu/drm/imagination/pvr_params.h | 72 9 files changed, 722 insertions(+) create mode 100644 drivers/gpu/drm/imagination/pvr_debugfs.c create mode 100644 drivers/gpu/drm/imagination/pvr_debugfs.h create mode 100644 drivers/gpu/drm/imagination/pvr_params.c create mode 100644 drivers/gpu/drm/imagination/pvr_params.h diff --git a/drivers/gpu/drm/imagination/Makefile b/drivers/gpu/drm/imagination/Makefile index 7e8be9f1b37e..b14c855c6619 100644 --- a/drivers/gpu/drm/imagination/Makefile +++ b/drivers/gpu/drm/imagination/Makefile @@ -20,6 +20,7 @@ powervr-y := \ pvr_hwrt.o \ pvr_job.o \ pvr_mmu.o \ + pvr_params.o \ pvr_power.o \ pvr_queue.o \ pvr_stream.o \ @@ -28,4 +29,7 @@ powervr-y := \ pvr_vm.o \ pvr_vm_mips.o +powervr-$(CONFIG_DEBUG_FS) += \ + pvr_debugfs.o + obj-$(CONFIG_DRM_POWERVR) += powervr.o diff --git a/drivers/gpu/drm/imagination/pvr_debugfs.c b/drivers/gpu/drm/imagination/pvr_debugfs.c new file mode 100644 index ..02e44c070861 --- /dev/null +++ b/drivers/gpu/drm/imagination/pvr_debugfs.c @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* Copyright (c) 2022 Imagination Technologies Ltd. */ + +#include "pvr_debugfs.h" + +#include "pvr_device.h" +#include "pvr_fw_trace.h" +#include "pvr_params.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +static const struct pvr_debugfs_entry pvr_debugfs_entries[] = { + {"pvr_params", pvr_params_debugfs_init}, + {"pvr_fw", pvr_fw_trace_debugfs_init}, +}; + +void +pvr_debugfs_init(struct drm_minor *minor) +{ + struct drm_device *drm_dev = minor->dev; + struct pvr_device *pvr_dev = to_pvr_device(drm_dev); + struct dentry *root = minor->debugfs_root; + size_t i; + + for (i = 0; i < ARRAY_SIZE(pvr_debugfs_entries); ++i) { + const struct pvr_debugfs_entry *entry = _debugfs_entries[i]; + struct dentry *dir; + + dir = debugfs_create_dir(entry->name, root); + if (IS_ERR(dir)) { + drm_warn(drm_dev, +"failed to create debugfs dir '%s' (err=%d)", +entry->name, (int)PTR_ERR(dir)); + continue; + } + + entry->init(pvr_dev, dir); + } +} + +/* + * Since all entries are created under _minor->debugfs_root, there's no + * need for a pvr_debugfs_fini() as DRM will clean up everything under its root + * automatically. + */ diff --git a/drivers/gpu/drm/imagination/pvr_debugfs.h b/drivers/gpu/drm/imagination/pvr_debugfs.h new file mode 100644 index ..b260a2b26ebd --- /dev/null +++ b/drivers/gpu/drm/imagination/pvr_debugfs.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0 OR MIT */ +/* Copyright (c) 2022 Imagination Technologies Ltd. */ + +#ifndef PVR_DEBUGFS_H +#define PVR_DEBUGFS_H + +/* Forward declaration from . */ +struct drm_minor; + +#if defined(CONFIG_DEBUG_FS) +/* Forward declaration from "pvr_device.h". */ +struct pvr_device; + +/* Forward declaration from . */ +struct dentry; + +struct pvr_debugfs_entry { + const char *name; + void (*init)(struct pvr_device *pvr_dev, struct dentry *dir); +}; + +void pvr_debugfs_init(struct drm_minor *minor); +#else /* defined(CONFIG_DEBUG_FS) */ +#include + +static __always_inline void pvr_debugfs_init(struct drm_minor *minor) {} +#endif /* defined(CONFIG_DEBUG_FS) */ + +#endif /* PVR_DEBUGFS_H */ diff --git a/drivers/gpu/drm/imagination/pvr_device.c b/drivers/gpu/drm/imagination/pvr_device.c index ea45757cc58e..2101693aaa7f 100644 --- a/drivers/gpu/drm/imagination/pvr_device.c +++ b/drivers/gpu/drm/imagination/pvr_device.c @@ -5,6 +5,7 @@ #include "pvr_device_info.h" #include "pvr_fw.h" +#include "pvr_params.h" #include "pvr_power.h" #include "pvr_queue.h" #include "pvr_rogue_cr_defs.h" @@ -489,6 +490,14 @@ pvr_device_init(struct pvr_device *pvr_dev) struct device *dev = drm_dev->dev; int err; + /* +* Setup device parameters. We do this first in case other steps +* depend on them. +*/ + err = pvr_device_params_init(_dev->params); + if (err) + return err; +
[PATCH v4 14/17] drm/imagination: Implement job submission and scheduling
Implement job submission ioctl. Job scheduling is implemented using drm_sched. Jobs are submitted in a stream format. This is intended to allow the UAPI data format to be independent of the actual FWIF structures in use, which vary depending on the GPU in use. The stream formats are documented at: https://gitlab.freedesktop.org/mesa/mesa/-/blob/f8d2b42ae65c2f16f36a43e0ae39d288431e4263/src/imagination/csbgen/rogue_kmd_stream.xml This patch depends on: drm/sched: Convert drm scheduler to use a work queue rather than kthread: https://lore.kernel.org/dri-devel/20230404002211.3611376-2-matthew.br...@intel.com/ drm/sched: Move schedule policy to scheduler / entity: https://lore.kernel.org/dri-devel/20230404002211.3611376-3-matthew.br...@intel.com/ drm/sched: Add DRM_SCHED_POLICY_SINGLE_ENTITY scheduling policy: https://lore.kernel.org/dri-devel/20230404002211.3611376-4-matthew.br...@intel.com/ drm/sched: Start run wq before TDR in drm_sched_start: https://lore.kernel.org/dri-devel/20230404002211.3611376-6-matthew.br...@intel.com/ drm/sched: Submit job before starting TDR: https://lore.kernel.org/dri-devel/20230404002211.3611376-7-matthew.br...@intel.com/ drm/sched: Add helper to set TDR timeout: https://lore.kernel.org/dri-devel/20230404002211.3611376-8-matthew.br...@intel.com/ drm/sched: Make sure we wait for all dependencies in kill_jobs_cb(): https://lore.kernel.org/dri-devel/20230619071921.3465992-1-boris.brezil...@collabora.com/ drm/sched: Call drm_sched_fence_set_parent() from drm_sched_fence_scheduled(): https://lore.kernel.org/dri-devel/20230623075204.382350-1-boris.brezil...@collabora.com/ Changes since v3: - Support partial render jobs - Add job timeout handler - Split sync handling out of job code - Use drm_dev_{enter,exit} Changes since v2: - Use drm_sched for job scheduling Signed-off-by: Sarah Walker --- drivers/gpu/drm/imagination/Makefile |3 + drivers/gpu/drm/imagination/pvr_context.c | 127 +- drivers/gpu/drm/imagination/pvr_context.h | 44 + drivers/gpu/drm/imagination/pvr_device.c | 31 + drivers/gpu/drm/imagination/pvr_device.h | 40 + drivers/gpu/drm/imagination/pvr_drv.c | 44 +- drivers/gpu/drm/imagination/pvr_job.c | 605 +++ drivers/gpu/drm/imagination/pvr_job.h | 161 ++ drivers/gpu/drm/imagination/pvr_power.c | 28 + drivers/gpu/drm/imagination/pvr_queue.c | 1457 + drivers/gpu/drm/imagination/pvr_queue.h | 179 ++ drivers/gpu/drm/imagination/pvr_stream_defs.c | 226 +++ drivers/gpu/drm/imagination/pvr_sync.c| 287 drivers/gpu/drm/imagination/pvr_sync.h| 84 + 14 files changed, 3311 insertions(+), 5 deletions(-) create mode 100644 drivers/gpu/drm/imagination/pvr_job.c create mode 100644 drivers/gpu/drm/imagination/pvr_job.h create mode 100644 drivers/gpu/drm/imagination/pvr_queue.c create mode 100644 drivers/gpu/drm/imagination/pvr_queue.h create mode 100644 drivers/gpu/drm/imagination/pvr_sync.c create mode 100644 drivers/gpu/drm/imagination/pvr_sync.h diff --git a/drivers/gpu/drm/imagination/Makefile b/drivers/gpu/drm/imagination/Makefile index 96679b782cf1..7e8be9f1b37e 100644 --- a/drivers/gpu/drm/imagination/Makefile +++ b/drivers/gpu/drm/imagination/Makefile @@ -18,10 +18,13 @@ powervr-y := \ pvr_fw_trace.o \ pvr_gem.o \ pvr_hwrt.o \ + pvr_job.o \ pvr_mmu.o \ pvr_power.o \ + pvr_queue.o \ pvr_stream.o \ pvr_stream_defs.o \ + pvr_sync.o \ pvr_vm.o \ pvr_vm_mips.o diff --git a/drivers/gpu/drm/imagination/pvr_context.c b/drivers/gpu/drm/imagination/pvr_context.c index 19714e0f37e5..9006fea05fcf 100644 --- a/drivers/gpu/drm/imagination/pvr_context.c +++ b/drivers/gpu/drm/imagination/pvr_context.c @@ -6,10 +6,12 @@ #include "pvr_device.h" #include "pvr_drv.h" #include "pvr_gem.h" +#include "pvr_job.h" #include "pvr_power.h" #include "pvr_rogue_fwif.h" #include "pvr_rogue_fwif_common.h" #include "pvr_rogue_fwif_resetframework.h" +#include "pvr_stream.h" #include "pvr_stream_defs.h" #include "pvr_vm.h" @@ -164,6 +166,116 @@ ctx_fw_data_init(void *cpu_ptr, void *priv) memcpy(cpu_ptr, ctx->data, ctx->data_size); } +/** + * pvr_context_destroy_queues() - Destroy all queues attached to a context. + * @ctx: Context to destroy queues on. + * + * Should be called when the last reference to a context object is dropped. + * It releases all resources attached to the queues bound to this context. + */ +static void pvr_context_destroy_queues(struct pvr_context *ctx) +{ + switch (ctx->type) { + case DRM_PVR_CTX_TYPE_RENDER: + pvr_queue_destroy(ctx->queues.fragment); + pvr_queue_destroy(ctx->queues.geometry); + break; + case DRM_PVR_CTX_TYPE_COMPUTE: + pvr_queue_destroy(ctx->queues.compute); + break; + case
[PATCH v4 13/17] drm/imagination: Implement context creation/destruction ioctls
Implement ioctls for the creation and destruction of contexts. Contexts are used for job submission and each is associated with a particular job type. Changes since v3: - Use drm_dev_{enter,exit} Signed-off-by: Sarah Walker --- drivers/gpu/drm/imagination/Makefile | 4 + drivers/gpu/drm/imagination/pvr_cccb.c| 268 ++ drivers/gpu/drm/imagination/pvr_cccb.h| 109 ++ drivers/gpu/drm/imagination/pvr_context.c | 338 ++ drivers/gpu/drm/imagination/pvr_context.h | 161 + drivers/gpu/drm/imagination/pvr_device.h | 21 ++ drivers/gpu/drm/imagination/pvr_drv.c | 29 +- drivers/gpu/drm/imagination/pvr_stream.c | 285 +++ drivers/gpu/drm/imagination/pvr_stream.h | 75 drivers/gpu/drm/imagination/pvr_stream_defs.c | 125 +++ drivers/gpu/drm/imagination/pvr_stream_defs.h | 16 + 11 files changed, 1429 insertions(+), 2 deletions(-) create mode 100644 drivers/gpu/drm/imagination/pvr_cccb.c create mode 100644 drivers/gpu/drm/imagination/pvr_cccb.h create mode 100644 drivers/gpu/drm/imagination/pvr_context.c create mode 100644 drivers/gpu/drm/imagination/pvr_context.h create mode 100644 drivers/gpu/drm/imagination/pvr_stream.c create mode 100644 drivers/gpu/drm/imagination/pvr_stream.h create mode 100644 drivers/gpu/drm/imagination/pvr_stream_defs.c create mode 100644 drivers/gpu/drm/imagination/pvr_stream_defs.h diff --git a/drivers/gpu/drm/imagination/Makefile b/drivers/gpu/drm/imagination/Makefile index df3fd372f6f6..96679b782cf1 100644 --- a/drivers/gpu/drm/imagination/Makefile +++ b/drivers/gpu/drm/imagination/Makefile @@ -5,6 +5,8 @@ subdir-ccflags-y := -I$(srctree)/$(src) powervr-y := \ pvr_ccb.o \ + pvr_cccb.o \ + pvr_context.o \ pvr_device.o \ pvr_device_info.o \ pvr_drv.o \ @@ -18,6 +20,8 @@ powervr-y := \ pvr_hwrt.o \ pvr_mmu.o \ pvr_power.o \ + pvr_stream.o \ + pvr_stream_defs.o \ pvr_vm.o \ pvr_vm_mips.o diff --git a/drivers/gpu/drm/imagination/pvr_cccb.c b/drivers/gpu/drm/imagination/pvr_cccb.c new file mode 100644 index ..d1837fb93f2c --- /dev/null +++ b/drivers/gpu/drm/imagination/pvr_cccb.c @@ -0,0 +1,268 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* Copyright (c) 2022 Imagination Technologies Ltd. */ + +#include "pvr_ccb.h" +#include "pvr_cccb.h" +#include "pvr_device.h" +#include "pvr_gem.h" +#include "pvr_hwrt.h" + +#include +#include +#include +#include +#include + +static __always_inline u32 +get_ccb_space(u32 w_off, u32 r_off, u32 ccb_size) +{ + return (((r_off) - (w_off)) + ((ccb_size) - 1)) & ((ccb_size) - 1); +} + +static void +cccb_ctrl_init(void *cpu_ptr, void *priv) +{ + struct rogue_fwif_cccb_ctl *ctrl = cpu_ptr; + struct pvr_cccb *pvr_cccb = priv; + + WRITE_ONCE(ctrl->write_offset, 0); + WRITE_ONCE(ctrl->read_offset, 0); + WRITE_ONCE(ctrl->dep_offset, 0); + WRITE_ONCE(ctrl->wrap_mask, pvr_cccb->wrap_mask); +} + +/** + * pvr_cccb_init() - Initialise a Client CCB + * @pvr_dev: Device pointer. + * @pvr_cccb: Pointer to Client CCB structure to initialise. + * @size_log2: Log2 size of Client CCB in bytes. + * @name: Name of owner of Client CCB. Used for fence context. + * + * Return: + * * Zero on success, or + * * Any error code returned by pvr_fw_object_create_and_map(). + */ +int +pvr_cccb_init(struct pvr_device *pvr_dev, struct pvr_cccb *pvr_cccb, + u32 size_log2, const char *name) +{ + size_t size = 1 << size_log2; + int err; + + pvr_cccb->size = size; + pvr_cccb->write_offset = 0; + pvr_cccb->wrap_mask = size - 1; + + /* +* Map CCCB and control structure as uncached, so we don't have to flush +* CPU cache repeatedly when polling for space. +*/ + pvr_cccb->ctrl = pvr_fw_object_create_and_map(pvr_dev, sizeof(*pvr_cccb->ctrl), + PVR_BO_FW_FLAGS_DEVICE_UNCACHED, + cccb_ctrl_init, pvr_cccb, + _cccb->ctrl_obj); + if (IS_ERR(pvr_cccb->ctrl)) + return PTR_ERR(pvr_cccb->ctrl); + + pvr_cccb->cccb = pvr_fw_object_create_and_map(pvr_dev, size, + PVR_BO_FW_FLAGS_DEVICE_UNCACHED | + DRM_PVR_BO_CREATE_ZEROED, + NULL, NULL, _cccb->cccb_obj); + if (IS_ERR(pvr_cccb->cccb)) { + err = PTR_ERR(pvr_cccb->cccb); + goto err_free_ctrl; + } + + pvr_fw_object_get_fw_addr(pvr_cccb->ctrl_obj, _cccb->ctrl_fw_addr); + pvr_fw_object_get_fw_addr(pvr_cccb->cccb_obj, _cccb->cccb_fw_addr); + + return 0; + +err_free_ctrl: +
[PATCH v4 12/17] drm/imagination: Implement free list and HWRT create and destroy ioctls
Implement ioctls to create and destroy free lists and HWRT datasets. Free lists are used for GPU-side memory allocation during geometry processing. HWRT datasets are the FW-side structures representing render targets. Changes since v3: - Support free list grow requests from FW - Use drm_dev_{enter,exit} Signed-off-by: Sarah Walker --- drivers/gpu/drm/imagination/Makefile| 2 + drivers/gpu/drm/imagination/pvr_ccb.c | 10 + drivers/gpu/drm/imagination/pvr_device.h| 24 + drivers/gpu/drm/imagination/pvr_drv.c | 112 +++- drivers/gpu/drm/imagination/pvr_free_list.c | 639 drivers/gpu/drm/imagination/pvr_free_list.h | 195 ++ drivers/gpu/drm/imagination/pvr_hwrt.c | 552 + drivers/gpu/drm/imagination/pvr_hwrt.h | 165 + 8 files changed, 1695 insertions(+), 4 deletions(-) create mode 100644 drivers/gpu/drm/imagination/pvr_free_list.c create mode 100644 drivers/gpu/drm/imagination/pvr_free_list.h create mode 100644 drivers/gpu/drm/imagination/pvr_hwrt.c create mode 100644 drivers/gpu/drm/imagination/pvr_hwrt.h diff --git a/drivers/gpu/drm/imagination/Makefile b/drivers/gpu/drm/imagination/Makefile index 3172b65783b6..df3fd372f6f6 100644 --- a/drivers/gpu/drm/imagination/Makefile +++ b/drivers/gpu/drm/imagination/Makefile @@ -8,12 +8,14 @@ powervr-y := \ pvr_device.o \ pvr_device_info.o \ pvr_drv.o \ + pvr_free_list.o \ pvr_fw.o \ pvr_fw_meta.o \ pvr_fw_mips.o \ pvr_fw_startstop.o \ pvr_fw_trace.o \ pvr_gem.o \ + pvr_hwrt.o \ pvr_mmu.o \ pvr_power.o \ pvr_vm.o \ diff --git a/drivers/gpu/drm/imagination/pvr_ccb.c b/drivers/gpu/drm/imagination/pvr_ccb.c index b36898d953db..7fa9ee88aeeb 100644 --- a/drivers/gpu/drm/imagination/pvr_ccb.c +++ b/drivers/gpu/drm/imagination/pvr_ccb.c @@ -4,6 +4,7 @@ #include "pvr_ccb.h" #include "pvr_device.h" #include "pvr_drv.h" +#include "pvr_free_list.h" #include "pvr_fw.h" #include "pvr_gem.h" #include "pvr_power.h" @@ -139,6 +140,15 @@ process_fwccb_command(struct pvr_device *pvr_dev, struct rogue_fwif_fwccb_cmd *c pvr_power_reset(pvr_dev, false); break; + case ROGUE_FWIF_FWCCB_CMD_FREELISTS_RECONSTRUCTION: + pvr_free_list_process_reconstruct_req(pvr_dev, + >cmd_data.cmd_freelists_reconstruction); + break; + + case ROGUE_FWIF_FWCCB_CMD_FREELIST_GROW: + pvr_free_list_process_grow_req(pvr_dev, >cmd_data.cmd_free_list_gs); + break; + default: drm_info(from_pvr_device(pvr_dev), "Received unknown FWCCB command %x\n", cmd->cmd_type); diff --git a/drivers/gpu/drm/imagination/pvr_device.h b/drivers/gpu/drm/imagination/pvr_device.h index 6725df65cf54..4aef66ede2bb 100644 --- a/drivers/gpu/drm/imagination/pvr_device.h +++ b/drivers/gpu/drm/imagination/pvr_device.h @@ -146,6 +146,14 @@ struct pvr_device { /** @fw_dev: Firmware related data. */ struct pvr_fw_device fw_dev; + /** +* @free_list_ids: Array of free lists belonging to this device. Array members +* are of type "struct pvr_free_list *". +* +* This array is used to allocate IDs used by the firmware. +*/ + struct xarray free_list_ids; + struct { /** @work: Work item for watchdog callback. */ struct delayed_work work; @@ -241,6 +249,22 @@ struct pvr_file { */ struct pvr_device *pvr_dev; + /** +* @free_list_handles: Array of free lists belonging to this file. Array +* members are of type "struct pvr_free_list *". +* +* This array is used to allocate handles returned to userspace. +*/ + struct xarray free_list_handles; + + /** +* @hwrt_handles: Array of HWRT datasets belonging to this file. Array +* members are of type "struct pvr_hwrt_dataset *". +* +* This array is used to allocate handles returned to userspace. +*/ + struct xarray hwrt_handles; + /** * @vm_ctx_handles: Array of VM contexts belonging to this file. Array * members are of type "struct pvr_vm_context *". diff --git a/drivers/gpu/drm/imagination/pvr_drv.c b/drivers/gpu/drm/imagination/pvr_drv.c index cf07078cca39..acd06135fbd0 100644 --- a/drivers/gpu/drm/imagination/pvr_drv.c +++ b/drivers/gpu/drm/imagination/pvr_drv.c @@ -3,7 +3,9 @@ #include "pvr_device.h" #include "pvr_drv.h" +#include "pvr_free_list.h" #include "pvr_gem.h" +#include "pvr_hwrt.h" #include "pvr_power.h" #include "pvr_rogue_defs.h" #include "pvr_rogue_fwif_client.h" @@ -725,7 +727,41 @@ static int pvr_ioctl_create_free_list(struct drm_device *drm_dev, void *raw_args, struct drm_file *file)
Re: [RFC PATCH 3/3] drm/file: drop DRM_MINOR_CONTROL
Hi Simon Am 14.07.23 um 12:46 schrieb Simon Ser: This entry should never be used by the kernel. Record the historical context in a comment. Signed-off-by: Simon Ser Cc: Christian König Cc: James Zhu Cc: Marek Olšák Cc: Daniel Vetter --- include/drm/drm_file.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/drm/drm_file.h b/include/drm/drm_file.h index 010239392adf..a23cc2f6163f 100644 --- a/include/drm/drm_file.h +++ b/include/drm/drm_file.h @@ -53,12 +53,14 @@ struct file; /* Note that the values of this enum are ABI (it determines * /dev/dri/renderD* numbers). * + * There used to be a DRM_MINOR_CONTROL = 1 entry, but such nodes were never + * exposed. Still, some user-space has logic to handle them. + * * Setting DRM_MINOR_ACCEL to 32 gives enough space for more drm minors to * be implemented before we hit any future */ enum drm_minor_type { DRM_MINOR_PRIMARY = 0, - DRM_MINOR_CONTROL = 1, Maybe rather leave this line in and comment it with "// obsolete". Otherwise someone might accidentally use 1 for something. In any case Reviewed-by: Thomas Zimmermann for the whole series. Best regards Thomas DRM_MINOR_RENDER = 2, DRM_MINOR_ACCEL = 32, }; -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg) OpenPGP_signature Description: OpenPGP digital signature
[PATCH v4 11/17] drm/imagination: Implement MIPS firmware processor and MMU support
Add support for the MIPS firmware processor, used in the Series AXE GPU. The MIPS firmware processor uses a separate MMU to the rest of the GPU, so this patch adds support for that as well. Changes since v3: - Get regs resource (removed from GPU resources commit) Signed-off-by: Sarah Walker --- drivers/gpu/drm/imagination/Makefile | 4 +- drivers/gpu/drm/imagination/pvr_device.c | 5 +- drivers/gpu/drm/imagination/pvr_device.h | 3 + drivers/gpu/drm/imagination/pvr_fw.c | 2 + drivers/gpu/drm/imagination/pvr_fw_mips.c | 261 ++ drivers/gpu/drm/imagination/pvr_fw_mips.h | 38 drivers/gpu/drm/imagination/pvr_vm_mips.c | 209 + drivers/gpu/drm/imagination/pvr_vm_mips.h | 22 ++ 8 files changed, 542 insertions(+), 2 deletions(-) create mode 100644 drivers/gpu/drm/imagination/pvr_fw_mips.c create mode 100644 drivers/gpu/drm/imagination/pvr_fw_mips.h create mode 100644 drivers/gpu/drm/imagination/pvr_vm_mips.c create mode 100644 drivers/gpu/drm/imagination/pvr_vm_mips.h diff --git a/drivers/gpu/drm/imagination/Makefile b/drivers/gpu/drm/imagination/Makefile index f4e265ab0735..3172b65783b6 100644 --- a/drivers/gpu/drm/imagination/Makefile +++ b/drivers/gpu/drm/imagination/Makefile @@ -10,11 +10,13 @@ powervr-y := \ pvr_drv.o \ pvr_fw.o \ pvr_fw_meta.o \ + pvr_fw_mips.o \ pvr_fw_startstop.o \ pvr_fw_trace.o \ pvr_gem.o \ pvr_mmu.o \ pvr_power.o \ - pvr_vm.o + pvr_vm.o \ + pvr_vm_mips.o obj-$(CONFIG_DRM_POWERVR) += powervr.o diff --git a/drivers/gpu/drm/imagination/pvr_device.c b/drivers/gpu/drm/imagination/pvr_device.c index 3736f95b86f1..16c64c7ecfff 100644 --- a/drivers/gpu/drm/imagination/pvr_device.c +++ b/drivers/gpu/drm/imagination/pvr_device.c @@ -50,16 +50,19 @@ pvr_device_reg_init(struct pvr_device *pvr_dev) { struct drm_device *drm_dev = from_pvr_device(pvr_dev); struct platform_device *plat_dev = to_platform_device(drm_dev->dev); + struct resource *regs_resource; void __iomem *regs; + pvr_dev->regs_resource = NULL; pvr_dev->regs = NULL; - regs = devm_platform_ioremap_resource(plat_dev, 0); + regs = devm_platform_get_and_ioremap_resource(plat_dev, 0, _resource); if (IS_ERR(regs)) return dev_err_probe(drm_dev->dev, PTR_ERR(regs), "failed to ioremap gpu registers\n"); pvr_dev->regs = regs; + pvr_dev->regs_resource = regs_resource; return 0; } diff --git a/drivers/gpu/drm/imagination/pvr_device.h b/drivers/gpu/drm/imagination/pvr_device.h index 5521bd6e6550..6725df65cf54 100644 --- a/drivers/gpu/drm/imagination/pvr_device.h +++ b/drivers/gpu/drm/imagination/pvr_device.h @@ -93,6 +93,9 @@ struct pvr_device { /** @fw_version: Firmware version detected at runtime. */ struct pvr_fw_version fw_version; + /** @regs_resource: Resource representing device control registers. */ + struct resource *regs_resource; + /** * @regs: Device control registers. * diff --git a/drivers/gpu/drm/imagination/pvr_fw.c b/drivers/gpu/drm/imagination/pvr_fw.c index 3d8cd72ebc03..0f470fca3040 100644 --- a/drivers/gpu/drm/imagination/pvr_fw.c +++ b/drivers/gpu/drm/imagination/pvr_fw.c @@ -883,6 +883,8 @@ pvr_fw_init(struct pvr_device *pvr_dev) if (fw_dev->processor_type == PVR_FW_PROCESSOR_TYPE_META) fw_dev->defs = _fw_defs_meta; + else if (fw_dev->processor_type == PVR_FW_PROCESSOR_TYPE_MIPS) + fw_dev->defs = _fw_defs_mips; else return -EINVAL; diff --git a/drivers/gpu/drm/imagination/pvr_fw_mips.c b/drivers/gpu/drm/imagination/pvr_fw_mips.c new file mode 100644 index ..7d26d47e493e --- /dev/null +++ b/drivers/gpu/drm/imagination/pvr_fw_mips.c @@ -0,0 +1,261 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* Copyright (c) 2022 Imagination Technologies Ltd. */ + +#include "pvr_device.h" +#include "pvr_fw.h" +#include "pvr_fw_mips.h" +#include "pvr_gem.h" +#include "pvr_rogue_mips.h" +#include "pvr_vm_mips.h" + +#include +#include +#include + +#define ROGUE_FW_HEAP_MIPS_BASE 0xC000 +#define ROGUE_FW_HEAP_MIPS_SHIFT 24 /* 16 MB */ +#define ROGUE_FW_HEAP_MIPS_RESERVED_SIZE SZ_1M + +/** + * process_elf_command_stream() - Process ELF firmware image and populate + *firmware sections + * @pvr_dev: Device pointer. + * @fw: Pointer to firmware image. + * @layout_entries: Pointer to layout table. + * @num_layout_entries: Number of entries in layout table. + * @fw_code_ptr: Pointer to FW code section. + * @fw_data_ptr: Pointer to FW data section. + * @fw_core_code_ptr: Pointer to FW coremem code section. + * @fw_core_data_ptr: Pointer to FW coremem data section. + * + * Returns : + * * 0 on success, or + * * -EINVAL on any error in ELF command stream. + */
[PATCH v4 10/17] drm/imagination: Implement firmware infrastructure and META FW support
The infrastructure includes parsing of the firmware image, initialising FW-side structures, handling the kernel and firmware command ringbuffers and starting & stopping the firmware processor. This patch also adds the necessary support code for the META firmware processor. Changes since v3: - Hard reset FW processor on watchdog timeout - Switch to threaded IRQ - Rework FW object creation/initialisation to aid hard reset - Added MODULE_FIRMWARE() - Use drm_dev_{enter,exit} Signed-off-by: Sarah Walker --- drivers/gpu/drm/imagination/Makefile |5 + drivers/gpu/drm/imagination/pvr_ccb.c | 632 +++ drivers/gpu/drm/imagination/pvr_ccb.h | 71 + drivers/gpu/drm/imagination/pvr_device.c | 97 ++ drivers/gpu/drm/imagination/pvr_device.h | 60 + drivers/gpu/drm/imagination/pvr_drv.c |1 + drivers/gpu/drm/imagination/pvr_fw.c | 1450 + drivers/gpu/drm/imagination/pvr_fw.h | 490 +- drivers/gpu/drm/imagination/pvr_fw_info.h | 115 ++ drivers/gpu/drm/imagination/pvr_fw_meta.c | 569 +++ drivers/gpu/drm/imagination/pvr_fw_meta.h | 14 + .../gpu/drm/imagination/pvr_fw_startstop.c| 302 .../gpu/drm/imagination/pvr_fw_startstop.h| 13 + drivers/gpu/drm/imagination/pvr_fw_trace.c| 123 ++ drivers/gpu/drm/imagination/pvr_fw_trace.h| 78 + drivers/gpu/drm/imagination/pvr_gem.h | 11 +- drivers/gpu/drm/imagination/pvr_mmu.c | 40 +- drivers/gpu/drm/imagination/pvr_power.c | 154 +- drivers/gpu/drm/imagination/pvr_vm.c | 27 +- 19 files changed, 4226 insertions(+), 26 deletions(-) create mode 100644 drivers/gpu/drm/imagination/pvr_ccb.c create mode 100644 drivers/gpu/drm/imagination/pvr_ccb.h create mode 100644 drivers/gpu/drm/imagination/pvr_fw.c create mode 100644 drivers/gpu/drm/imagination/pvr_fw_info.h create mode 100644 drivers/gpu/drm/imagination/pvr_fw_meta.c create mode 100644 drivers/gpu/drm/imagination/pvr_fw_meta.h create mode 100644 drivers/gpu/drm/imagination/pvr_fw_startstop.c create mode 100644 drivers/gpu/drm/imagination/pvr_fw_startstop.h create mode 100644 drivers/gpu/drm/imagination/pvr_fw_trace.c create mode 100644 drivers/gpu/drm/imagination/pvr_fw_trace.h diff --git a/drivers/gpu/drm/imagination/Makefile b/drivers/gpu/drm/imagination/Makefile index 534bffd59273..f4e265ab0735 100644 --- a/drivers/gpu/drm/imagination/Makefile +++ b/drivers/gpu/drm/imagination/Makefile @@ -4,9 +4,14 @@ subdir-ccflags-y := -I$(srctree)/$(src) powervr-y := \ + pvr_ccb.o \ pvr_device.o \ pvr_device_info.o \ pvr_drv.o \ + pvr_fw.o \ + pvr_fw_meta.o \ + pvr_fw_startstop.o \ + pvr_fw_trace.o \ pvr_gem.o \ pvr_mmu.o \ pvr_power.o \ diff --git a/drivers/gpu/drm/imagination/pvr_ccb.c b/drivers/gpu/drm/imagination/pvr_ccb.c new file mode 100644 index ..b36898d953db --- /dev/null +++ b/drivers/gpu/drm/imagination/pvr_ccb.c @@ -0,0 +1,632 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* Copyright (c) 2022 Imagination Technologies Ltd. */ + +#include "pvr_ccb.h" +#include "pvr_device.h" +#include "pvr_drv.h" +#include "pvr_fw.h" +#include "pvr_gem.h" +#include "pvr_power.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#define RESERVE_SLOT_TIMEOUT (1 * HZ) /* 1s */ + +static void +ccb_ctrl_init(void *cpu_ptr, void *priv) +{ + struct rogue_fwif_ccb_ctl *ctrl = cpu_ptr; + struct pvr_ccb *pvr_ccb = priv; + + ctrl->write_offset = 0; + ctrl->read_offset = 0; + ctrl->wrap_mask = pvr_ccb->num_cmds - 1; + ctrl->cmd_size = pvr_ccb->cmd_size; +} + +/** + * pvr_ccb_init() - Initialise a CCB + * @pvr_dev: Device pointer. + * @pvr_ccb: Pointer to CCB structure to initialise. + * @num_cmds_log2: Log2 of number of commands in this CCB. + * @cmd_size: Command size for this CCB. + * + * Return: + * * Zero on success, or + * * Any error code returned by pvr_fw_object_create_and_map(). + */ +static int +pvr_ccb_init(struct pvr_device *pvr_dev, struct pvr_ccb *pvr_ccb, +u32 num_cmds_log2, size_t cmd_size) +{ + u32 num_cmds = 1 << num_cmds_log2; + u32 ccb_size = num_cmds * cmd_size; + int err; + + pvr_ccb->num_cmds = num_cmds; + pvr_ccb->cmd_size = cmd_size; + + err = drmm_mutex_init(from_pvr_device(pvr_dev), _ccb->lock); + if (err) + return err; + + /* +* Map CCB and control structure as uncached, so we don't have to flush +* CPU cache repeatedly when polling for space. +*/ + pvr_ccb->ctrl = pvr_fw_object_create_and_map(pvr_dev, sizeof(*pvr_ccb->ctrl), + PVR_BO_FW_FLAGS_DEVICE_UNCACHED, +ccb_ctrl_init, pvr_ccb, _ccb->ctrl_obj); + if (IS_ERR(pvr_ccb->ctrl)) +
[PATCH v4 09/17] drm/imagination: Implement power management
Add power management to the driver, using runtime pm. The power off sequence depends on firmware commands which are not implemented in this patch. Changes since v3: - Don't power device when calling pvr_device_gpu_fini() - Documentation for pvr_dev->lost has been improved - pvr_power_init() renamed to pvr_watchdog_init() - Use drm_dev_{enter,exit} Changes since v2: - Use runtime PM - Implement watchdog Signed-off-by: Sarah Walker --- drivers/gpu/drm/imagination/Makefile | 1 + drivers/gpu/drm/imagination/pvr_device.c | 27 ++- drivers/gpu/drm/imagination/pvr_device.h | 22 ++ drivers/gpu/drm/imagination/pvr_drv.c| 19 +- drivers/gpu/drm/imagination/pvr_power.c | 271 +++ drivers/gpu/drm/imagination/pvr_power.h | 39 6 files changed, 376 insertions(+), 3 deletions(-) create mode 100644 drivers/gpu/drm/imagination/pvr_power.c create mode 100644 drivers/gpu/drm/imagination/pvr_power.h diff --git a/drivers/gpu/drm/imagination/Makefile b/drivers/gpu/drm/imagination/Makefile index 56a3d3104a05..534bffd59273 100644 --- a/drivers/gpu/drm/imagination/Makefile +++ b/drivers/gpu/drm/imagination/Makefile @@ -9,6 +9,7 @@ powervr-y := \ pvr_drv.o \ pvr_gem.o \ pvr_mmu.o \ + pvr_power.o \ pvr_vm.o obj-$(CONFIG_DRM_POWERVR) += powervr.o diff --git a/drivers/gpu/drm/imagination/pvr_device.c b/drivers/gpu/drm/imagination/pvr_device.c index 2dd0d8f93c4f..190e5982cfdb 100644 --- a/drivers/gpu/drm/imagination/pvr_device.c +++ b/drivers/gpu/drm/imagination/pvr_device.c @@ -5,6 +5,7 @@ #include "pvr_device_info.h" #include "pvr_fw.h" +#include "pvr_power.h" #include "pvr_rogue_cr_defs.h" #include "pvr_vm.h" @@ -361,6 +362,8 @@ pvr_device_gpu_fini(struct pvr_device *pvr_dev) int pvr_device_init(struct pvr_device *pvr_dev) { + struct drm_device *drm_dev = from_pvr_device(pvr_dev); + struct device *dev = drm_dev->dev; int err; /* Enable and initialize clocks required for the device to operate. */ @@ -368,13 +371,29 @@ pvr_device_init(struct pvr_device *pvr_dev) if (err) return err; + /* Explicitly power the GPU so we can access control registers before the FW is booted. */ + err = pm_runtime_resume_and_get(dev); + if (err) + return err; + /* Map the control registers into memory. */ err = pvr_device_reg_init(pvr_dev); if (err) - return err; + goto err_pm_runtime_put; /* Perform GPU-specific initialization steps. */ - return pvr_device_gpu_init(pvr_dev); + err = pvr_device_gpu_init(pvr_dev); + if (err) + goto err_pm_runtime_put; + + pm_runtime_put(dev); + + return 0; + +err_pm_runtime_put: + pm_runtime_put_sync_suspend(dev); + + return err; } /** @@ -384,11 +403,15 @@ pvr_device_init(struct pvr_device *pvr_dev) void pvr_device_fini(struct pvr_device *pvr_dev) { + struct drm_device *drm_dev = from_pvr_device(pvr_dev); + struct device *dev = drm_dev->dev; + /* * Deinitialization stages are performed in reverse order compared to * the initialization stages in pvr_device_init(). */ pvr_device_gpu_fini(pvr_dev); + pm_runtime_suspend(dev); } bool diff --git a/drivers/gpu/drm/imagination/pvr_device.h b/drivers/gpu/drm/imagination/pvr_device.h index a20fc8e22790..31b14b6afb61 100644 --- a/drivers/gpu/drm/imagination/pvr_device.h +++ b/drivers/gpu/drm/imagination/pvr_device.h @@ -135,6 +135,28 @@ struct pvr_device { /** @fw_dev: Firmware related data. */ struct pvr_fw_device fw_dev; + + struct { + /** @work: Work item for watchdog callback. */ + struct delayed_work work; + + /** @old_kccb_cmds_executed: KCCB command execution count at last watchdog poll. */ + u32 old_kccb_cmds_executed; + + /** @kccb_stall_count: Number of watchdog polls KCCB has been stalled for. */ + u32 kccb_stall_count; + } watchdog; + + /** +* @lost: %true if the device has been lost. +* +* This variable is set if the device has become irretrievably unavailable, e.g. if the +* firmware processor has stopped responding and can not be revived via a hard reset. +*/ + bool lost; + + /** @sched_wq: Workqueue for schedulers. */ + struct workqueue_struct *sched_wq; }; /** diff --git a/drivers/gpu/drm/imagination/pvr_drv.c b/drivers/gpu/drm/imagination/pvr_drv.c index 44a189d7baf3..f44a1f9abf8d 100644 --- a/drivers/gpu/drm/imagination/pvr_drv.c +++ b/drivers/gpu/drm/imagination/pvr_drv.c @@ -4,6 +4,7 @@ #include "pvr_device.h" #include "pvr_drv.h" #include "pvr_gem.h" +#include "pvr_power.h" #include "pvr_rogue_defs.h" #include "pvr_rogue_fwif_client.h" #include "pvr_rogue_fwif_shared.h" @@ -1291,9 +1292,16 @@
[PATCH v4 07/17] drm/imagination: Add GPU ID parsing and firmware loading
Read the GPU ID register at probe time and select the correct features/quirks/enhancements. Use the GPU ID to form the firmware file name and load the firmware. The features/quirks/enhancements arrays are currently hardcoded in the driver for the supported GPUs. We are looking at moving this information to the firmware image. Changes since v3: - Use drm_dev_{enter,exit} Signed-off-by: Sarah Walker --- drivers/gpu/drm/imagination/Makefile | 1 + drivers/gpu/drm/imagination/pvr_device.c | 331 ++- drivers/gpu/drm/imagination/pvr_device.h | 220 drivers/gpu/drm/imagination/pvr_device_info.c | 227 drivers/gpu/drm/imagination/pvr_device_info.h | 135 + drivers/gpu/drm/imagination/pvr_drv.c | 521 +- drivers/gpu/drm/imagination/pvr_drv.h | 107 drivers/gpu/drm/imagination/pvr_fw.h | 20 + 8 files changed, 1560 insertions(+), 2 deletions(-) create mode 100644 drivers/gpu/drm/imagination/pvr_device_info.c create mode 100644 drivers/gpu/drm/imagination/pvr_device_info.h create mode 100644 drivers/gpu/drm/imagination/pvr_fw.h diff --git a/drivers/gpu/drm/imagination/Makefile b/drivers/gpu/drm/imagination/Makefile index 186f920d615b..d713b1280776 100644 --- a/drivers/gpu/drm/imagination/Makefile +++ b/drivers/gpu/drm/imagination/Makefile @@ -5,6 +5,7 @@ subdir-ccflags-y := -I$(srctree)/$(src) powervr-y := \ pvr_device.o \ + pvr_device_info.o \ pvr_drv.o \ obj-$(CONFIG_DRM_POWERVR) += powervr.o diff --git a/drivers/gpu/drm/imagination/pvr_device.c b/drivers/gpu/drm/imagination/pvr_device.c index 9c838c15a987..4d86df0dcded 100644 --- a/drivers/gpu/drm/imagination/pvr_device.c +++ b/drivers/gpu/drm/imagination/pvr_device.c @@ -2,19 +2,31 @@ /* Copyright (c) 2022 Imagination Technologies Ltd. */ #include "pvr_device.h" +#include "pvr_device_info.h" + +#include "pvr_fw.h" +#include "pvr_rogue_cr_defs.h" #include +#include #include #include #include #include #include +#include #include +#include #include +#include #include #include #include +#include + +/* Major number for the supported version of the firmware. */ +#define PVR_FW_VERSION_MAJOR 1 /** * pvr_device_reg_init() - Initialize kernel access to a PowerVR device's @@ -100,6 +112,216 @@ static int pvr_device_clk_init(struct pvr_device *pvr_dev) return 0; } +/** + * pvr_build_firmware_filename() - Construct a PowerVR firmware filename + * @pvr_dev: Target PowerVR device. + * @base: First part of the filename. + * @major: Major version number. + * + * A PowerVR firmware filename consists of three parts separated by underscores + * (``'_'``) along with a '.fw' file suffix. The first part is the exact value + * of @base, the second part is the hardware version string derived from @pvr_fw + * and the final part is the firmware version number constructed from @major with + * a 'v' prefix, e.g. powervr/rogue_4.40.2.51_v1.fw. + * + * The returned string will have been slab allocated and must be freed with + * kfree(). + * + * Return: + * * The constructed filename on success, or + * * Any error returned by kasprintf(). + */ +static char * +pvr_build_firmware_filename(struct pvr_device *pvr_dev, const char *base, + u8 major) +{ + struct pvr_gpu_id *gpu_id = _dev->gpu_id; + + return kasprintf(GFP_KERNEL, "%s_%d.%d.%d.%d_v%d.fw", base, gpu_id->b, +gpu_id->v, gpu_id->n, gpu_id->c, major); +} + +/** + * pvr_request_firmware() - Load firmware for a PowerVR device + * @pvr_dev: Target PowerVR device. + * + * See pvr_build_firmware_filename() for details on firmware file naming. + * + * Return: + * * 0 on success, + * * Any error returned by pvr_build_firmware_filename(), or + * * Any error returned by request_firmware(). + */ +static int +pvr_request_firmware(struct pvr_device *pvr_dev) +{ + struct drm_device *drm_dev = _dev->base; + char *filename; + const struct firmware *fw; + int err; + + filename = pvr_build_firmware_filename(pvr_dev, "powervr/rogue", + PVR_FW_VERSION_MAJOR); + if (IS_ERR(filename)) + return PTR_ERR(filename); + + /* +* This function takes a copy of , meaning we can free our +* instance before returning. +*/ + err = request_firmware(, filename, pvr_dev->base.dev); + if (err) { + drm_err(drm_dev, "failed to load firmware %s (err=%d)\n", + filename, err); + goto err_free_filename; + } + + drm_info(drm_dev, "loaded firmware %s\n", filename); + kfree(filename); + + pvr_dev->fw_dev.firmware = fw; + + return 0; + +err_free_filename: + kfree(filename); + + return err; +} + +/** + * pvr_load_gpu_id() - Load a PowerVR device's GPU ID (BVNC) from control registers. + * + * Sets struct
[PATCH v4 05/17] drm/imagination: Get GPU resources
Acquire clock and register resources, and enable/map as appropriate. Changes since v3: - Remove regulator resource (not used on supported platform) - Use devm helpers - Use devm_clk_get_optional() for optional clocks - Don't prepare clocks on resource acquisition - Drop pvr_device_clk_core_get_freq() helper - Drop pvr_device_reg_fini() - Drop NULLing of clocks in pvr_device_clk_init() - Use dev_err_probe() on clock acquisition failure - Remove PVR_CR_READ/WRITE helper macros - Improve documentation for GPU clocks - Remove regs resource (not used in this commit) Signed-off-by: Sarah Walker --- drivers/gpu/drm/imagination/Makefile | 1 + drivers/gpu/drm/imagination/pvr_device.c | 147 ++ drivers/gpu/drm/imagination/pvr_device.h | 152 +++ drivers/gpu/drm/imagination/pvr_drv.c| 18 ++- 4 files changed, 317 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/imagination/pvr_device.c diff --git a/drivers/gpu/drm/imagination/Makefile b/drivers/gpu/drm/imagination/Makefile index 62ccf0ccbd51..186f920d615b 100644 --- a/drivers/gpu/drm/imagination/Makefile +++ b/drivers/gpu/drm/imagination/Makefile @@ -4,6 +4,7 @@ subdir-ccflags-y := -I$(srctree)/$(src) powervr-y := \ + pvr_device.o \ pvr_drv.o \ obj-$(CONFIG_DRM_POWERVR) += powervr.o diff --git a/drivers/gpu/drm/imagination/pvr_device.c b/drivers/gpu/drm/imagination/pvr_device.c new file mode 100644 index ..9c838c15a987 --- /dev/null +++ b/drivers/gpu/drm/imagination/pvr_device.c @@ -0,0 +1,147 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* Copyright (c) 2022 Imagination Technologies Ltd. */ + +#include "pvr_device.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * pvr_device_reg_init() - Initialize kernel access to a PowerVR device's + * control registers. + * @pvr_dev: Target PowerVR device. + * + * Sets struct pvr_device->regs. + * + * This method of mapping the device control registers into memory ensures that + * they are unmapped when the driver is detached (i.e. no explicit cleanup is + * required). + * + * Return: + * * 0 on success, or + * * Any error returned by devm_platform_ioremap_resource(). + */ +static int +pvr_device_reg_init(struct pvr_device *pvr_dev) +{ + struct drm_device *drm_dev = from_pvr_device(pvr_dev); + struct platform_device *plat_dev = to_platform_device(drm_dev->dev); + void __iomem *regs; + + pvr_dev->regs = NULL; + + regs = devm_platform_ioremap_resource(plat_dev, 0); + if (IS_ERR(regs)) + return dev_err_probe(drm_dev->dev, PTR_ERR(regs), +"failed to ioremap gpu registers\n"); + + pvr_dev->regs = regs; + + return 0; +} + +/** + * pvr_device_clk_init() - Initialize clocks required by a PowerVR device + * @pvr_dev: Target PowerVR device. + * + * Sets struct pvr_device->core_clk, struct pvr_device->sys_clk and + * struct pvr_device->mem_clk. + * + * Three clocks are required by the PowerVR device: core, sys and mem. On + * return, this function guarantees that the clocks are in one of the following + * states: + * + * * All successfully initialized, + * * Core errored, sys and mem uninitialized, + * * Core deinitialized, sys errored, mem uninitialized, or + * * Core and sys deinitialized, mem errored. + * + * Return: + * * 0 on success, + * * Any error returned by devm_clk_get(), or + * * Any error returned by devm_clk_get_optional(). + */ +static int pvr_device_clk_init(struct pvr_device *pvr_dev) +{ + struct drm_device *drm_dev = from_pvr_device(pvr_dev); + struct clk *core_clk; + struct clk *sys_clk; + struct clk *mem_clk; + + core_clk = devm_clk_get(drm_dev->dev, "core"); + if (IS_ERR(core_clk)) + return dev_err_probe(drm_dev->dev, PTR_ERR(core_clk), +"failed to get core clock\n"); + + sys_clk = devm_clk_get_optional(drm_dev->dev, "sys"); + if (IS_ERR(sys_clk)) + return dev_err_probe(drm_dev->dev, PTR_ERR(core_clk), +"failed to get sys clock\n"); + + mem_clk = devm_clk_get_optional(drm_dev->dev, "mem"); + if (IS_ERR(mem_clk)) + return dev_err_probe(drm_dev->dev, PTR_ERR(core_clk), +"failed to get mem clock\n"); + + pvr_dev->core_clk = core_clk; + pvr_dev->sys_clk = sys_clk; + pvr_dev->mem_clk = mem_clk; + + return 0; +} + +/** + * pvr_device_init() - Initialize a PowerVR device + * @pvr_dev: Target PowerVR device. + * + * If this function returns successfully, the device will have been fully + * initialized. Otherwise, any parts of the device initialized before an error + * occurs will be de-initialized before returning. + * + * NOTE: The initialization steps currently taken are the bare minimum
Re: [PATCH 3/5] drm/amdkfd: use vma_is_stack() and vma_is_heap()
On 7/12/23 18:24, Felix Kuehling wrote: > Allocations in the heap and stack tend to be small, with several > allocations sharing the same page. Sharing the same page for different > allocations with different access patterns leads to thrashing when we > migrate data back and forth on GPU and CPU access. To avoid this we > disable HMM migrations for head and stack VMAs. Wonder how well does it really work in practice? AFAIK "heaps" (malloc()) today uses various arenas obtained by mmap() and not a single brk() managed space anymore? And programs might be multithreaded, thus have multiple stacks, while vma_is_stack() will recognize only the initial one... Vlastimil > Regards, > Felix > > > Am 2023-07-12 um 10:42 schrieb Christoph Hellwig: >> On Wed, Jul 12, 2023 at 10:38:29PM +0800, Kefeng Wang wrote: >>> Use the helpers to simplify code. >> Nothing against your addition of a helper, but a GPU driver really >> should have no business even looking at this information.. >> >> >
[PATCH v4 02/17] dt-bindings: gpu: Add Imagination Technologies PowerVR GPU
Add the device tree binding documentation for the Series AXE GPU used in TI AM62 SoCs. Changes since v3: - Remove oneOf in compatible property - Remove power-supply (not used on AM62) Changes since v2: - Add commit message description - Remove mt8173-gpu support (not currently supported) - Drop quotes from $id and $schema - Remove reg: minItems - Drop _clk suffixes from clock-names - Remove operating-points-v2 property and cooling-cells (not currently used) - Add additionalProperties: false - Remove stray blank line at the end of file Signed-off-by: Sarah Walker --- .../devicetree/bindings/gpu/img,powervr.yaml | 68 +++ MAINTAINERS | 7 ++ 2 files changed, 75 insertions(+) create mode 100644 Documentation/devicetree/bindings/gpu/img,powervr.yaml diff --git a/Documentation/devicetree/bindings/gpu/img,powervr.yaml b/Documentation/devicetree/bindings/gpu/img,powervr.yaml new file mode 100644 index ..3292a0440465 --- /dev/null +++ b/Documentation/devicetree/bindings/gpu/img,powervr.yaml @@ -0,0 +1,68 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (c) 2022 Imagination Technologies Ltd. +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/gpu/img,powervr.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Imagination Technologies PowerVR GPU + +maintainers: + - Sarah Walker + +properties: + compatible: +items: + - enum: + - ti,am62-gpu + - const: img,powervr-seriesaxe + + reg: +maxItems: 1 + + clocks: +minItems: 1 +maxItems: 3 + + clock-names: +items: + - const: core + - const: mem + - const: sys +minItems: 1 + + interrupts: +items: + - description: GPU interrupt + + interrupt-names: +items: + - const: gpu + + power-domains: +maxItems: 1 + +required: + - compatible + - reg + - clocks + - clock-names + - interrupts + - interrupt-names + +additionalProperties: false + +examples: + - | +#include +#include + +gpu: gpu@fd0 { +compatible = "ti,am62-gpu", "img,powervr-seriesaxe"; +reg = <0x0fd0 0x2>; +power-domains = <_pds 187>; +clocks = <_clks 187 0>; +clock-names = "core"; +interrupts = ; +interrupt-names = "gpu"; +}; diff --git a/MAINTAINERS b/MAINTAINERS index 9852d6bfdb95..0763388b31ef 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10099,6 +10099,13 @@ IMGTEC IR DECODER DRIVER S: Orphan F: drivers/media/rc/img-ir/ +IMGTEC POWERVR DRM DRIVER +M: Frank Binns +M: Sarah Walker +M: Donald Robson +S: Supported +F: Documentation/devicetree/bindings/gpu/img,powervr.yaml + IMON SOUNDGRAPH USB IR RECEIVER M: Sean Young L: linux-me...@vger.kernel.org -- 2.41.0
[PATCH v4 04/17] drm/imagination: Add skeleton PowerVR driver
This adds the basic skeleton of the driver. The driver registers itself with DRM on probe. Ioctl handlers are currently implemented as stubs. Changes since v3: - Clarify supported GPU generations in driver description - Use drm_dev_unplug() when removing device - Change from_* and to_* functions to macros - Fix IS_PTR/PTR_ERR confusion in pvr_probe() - Remove err_out labels in favour of direct returning - Remove specific am62 compatible match string - Drop MODULE_FIRMWARE() Signed-off-by: Sarah Walker --- MAINTAINERS | 1 + drivers/gpu/drm/Kconfig | 2 + drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/imagination/Kconfig | 15 + drivers/gpu/drm/imagination/Makefile | 9 + drivers/gpu/drm/imagination/pvr_device.h | 153 +++ drivers/gpu/drm/imagination/pvr_drv.c| 510 +++ drivers/gpu/drm/imagination/pvr_drv.h| 22 + 8 files changed, 713 insertions(+) create mode 100644 drivers/gpu/drm/imagination/Kconfig create mode 100644 drivers/gpu/drm/imagination/Makefile create mode 100644 drivers/gpu/drm/imagination/pvr_device.h create mode 100644 drivers/gpu/drm/imagination/pvr_drv.c create mode 100644 drivers/gpu/drm/imagination/pvr_drv.h diff --git a/MAINTAINERS b/MAINTAINERS index 4c3bcc68f152..9371dc92e6b5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10105,6 +10105,7 @@ M: Sarah Walker M: Donald Robson S: Supported F: Documentation/devicetree/bindings/gpu/img,powervr.yaml +F: drivers/gpu/drm/imagination/ F: include/uapi/drm/pvr_drm.h IMON SOUNDGRAPH USB IR RECEIVER diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index afb3b2f5f425..603a57bb2596 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -363,6 +363,8 @@ source "drivers/gpu/drm/solomon/Kconfig" source "drivers/gpu/drm/sprd/Kconfig" +source "drivers/gpu/drm/imagination/Kconfig" + config DRM_HYPERV tristate "DRM Support for Hyper-V synthetic video device" depends on DRM && PCI && MMU && HYPERV diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 2fcaff2e378b..7fe29ba2e769 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -195,3 +195,4 @@ obj-y += gud/ obj-$(CONFIG_DRM_HYPERV) += hyperv/ obj-y += solomon/ obj-$(CONFIG_DRM_SPRD) += sprd/ +obj-$(CONFIG_DRM_POWERVR) += imagination/ diff --git a/drivers/gpu/drm/imagination/Kconfig b/drivers/gpu/drm/imagination/Kconfig new file mode 100644 index ..15efe67f13e1 --- /dev/null +++ b/drivers/gpu/drm/imagination/Kconfig @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: GPL-2.0 OR MIT +# Copyright (c) 2022 Imagination Technologies Ltd. + +config DRM_POWERVR + tristate "Imagination Technologies PowerVR Graphics (Series 6 and later)" + depends on ARM64 + depends on DRM + select DRM_GEM_SHMEM_HELPER + select DRM_SCHED + select FW_LOADER + help + Choose this option if you have a system that has an Imagination + Technologies PowerVR GPU (Series 6 or later). + + If "M" is selected, the module will be called powervr. diff --git a/drivers/gpu/drm/imagination/Makefile b/drivers/gpu/drm/imagination/Makefile new file mode 100644 index ..62ccf0ccbd51 --- /dev/null +++ b/drivers/gpu/drm/imagination/Makefile @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0 OR MIT +# Copyright (c) 2022 Imagination Technologies Ltd. + +subdir-ccflags-y := -I$(srctree)/$(src) + +powervr-y := \ + pvr_drv.o \ + +obj-$(CONFIG_DRM_POWERVR) += powervr.o diff --git a/drivers/gpu/drm/imagination/pvr_device.h b/drivers/gpu/drm/imagination/pvr_device.h new file mode 100644 index ..42224b5247df --- /dev/null +++ b/drivers/gpu/drm/imagination/pvr_device.h @@ -0,0 +1,153 @@ +/* SPDX-License-Identifier: GPL-2.0 OR MIT */ +/* Copyright (c) 2022 Imagination Technologies Ltd. */ + +#ifndef PVR_DEVICE_H +#define PVR_DEVICE_H + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/** + * struct pvr_device - powervr-specific wrapper for drm_device + */ +struct pvr_device { + /** +* @base: The underlying drm_device. +* +* Do not access this member directly, instead call +* from_pvr_device(). +*/ + struct drm_device base; +}; + +/** + * struct pvr_file - powervr-specific data to be assigned to + * drm_file.driver_priv + */ +struct pvr_file { + /** +* @file: A reference to the parent drm_file. +* +* Do not access this member directly, instead call from_pvr_file(). +*/ + struct drm_file *file; + + /** +* @pvr_dev: A reference to the powervr-specific wrapper for the +* associated device. Saves on repeated calls to +* to_pvr_device(). +*/ + struct pvr_device *pvr_dev;
[PATCH v4 03/17] drm/imagination/uapi: Add PowerVR driver UAPI
Add the UAPI implementation for the PowerVR driver. Signed-off-by: Sarah Walker --- MAINTAINERS|1 + include/uapi/drm/pvr_drm.h | 1304 2 files changed, 1305 insertions(+) create mode 100644 include/uapi/drm/pvr_drm.h diff --git a/MAINTAINERS b/MAINTAINERS index 0763388b31ef..4c3bcc68f152 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10105,6 +10105,7 @@ M: Sarah Walker M: Donald Robson S: Supported F: Documentation/devicetree/bindings/gpu/img,powervr.yaml +F: include/uapi/drm/pvr_drm.h IMON SOUNDGRAPH USB IR RECEIVER M: Sean Young diff --git a/include/uapi/drm/pvr_drm.h b/include/uapi/drm/pvr_drm.h new file mode 100644 index ..58533659a0c8 --- /dev/null +++ b/include/uapi/drm/pvr_drm.h @@ -0,0 +1,1304 @@ +/* SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note) OR MIT */ +/* Copyright (c) 2022 Imagination Technologies Ltd. */ + +#ifndef PVR_DRM_UAPI_H +#define PVR_DRM_UAPI_H + +#include "drm.h" + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +/** + * DOC: PowerVR UAPI + * + * The PowerVR IOCTL argument structs have a few limitations in place, in + * addition to the standard kernel restrictions: + * + * - All members must be type-aligned. + * - The overall struct must be padded to 64-bit alignment. + * - Explicit padding is almost always required. This takes the form of + *``_padding_[x]`` members of sufficient size to pad to the next power-of-two + *alignment, where [x] is the offset into the struct in hexadecimal. Arrays + *are never used for alignment. Padding fields must be zeroed; this is + *always checked. + * - Unions may only appear as the last member of a struct. + * - Individual union members may grow in the future. The space between the + *end of a union member and the end of its containing union is considered + *"implicit padding" and must be zeroed. This is always checked. + * + * In addition to the IOCTL argument structs, the PowerVR UAPI makes use of + * DEV_QUERY argument structs. These are used to fetch information about the + * device and runtime. These structs are subject to the same rules set out + * above. + */ + +/** + * struct drm_pvr_obj_array - Container used to pass arrays of objects + * + * It is not unusual to have to extend objects to pass new parameters, and the DRM + * ioctl infrastructure is supporting that by padding ioctl arguments with zeros + * when the data passed by userspace is smaller than the struct defined in the + * drm_ioctl_desc, thus keeping things backward compatible. This type is just + * applying the same concepts to indirect objects passed through arrays referenced + * from the main ioctl arguments structure: the stride basically defines the size + * of the object passed by userspace, which allows the kernel driver to pad with + * zeros when it's smaller than the size of the object it expects. + * + * Use ``DRM_PVR_OBJ_ARRAY()`` to fill object array fields, unless you + * have a very good reason not to. + */ +struct drm_pvr_obj_array { + /** @stride: Stride of object struct. Used for versioning. */ + __u32 stride; + + /** @count: Number of objects in the array. */ + __u32 count; + + /** @array: User pointer to an array of objects. */ + __u64 array; +}; + +/** + * DRM_PVR_OBJ_ARRAY() - Helper macro for filling drm_pvr_obj_array. + * @cnt: Number of elements pointed to py @ptr. + * @ptr: Pointer to start of a C array. + * + * Return: Literal of type drm_pvr_obj_array. + */ +#define DRM_PVR_OBJ_ARRAY(cnt, ptr) \ + { .stride = sizeof((ptr)[0]), .count = (cnt), .array = (__u64)(uintptr_t)(ptr) } + +/** + * DOC: PowerVR IOCTL interface + */ + +/** + * PVR_IOCTL() - Build a PowerVR IOCTL number + * @_ioctl: An incrementing id for this IOCTL. Added to %DRM_COMMAND_BASE. + * @_mode: Must be one of %DRM_IOR, %DRM_IOW or %DRM_IOWR. + * @_data: The type of the args struct passed by this IOCTL. + * + * The struct referred to by @_data must have a ``drm_pvr_ioctl_`` prefix and an + * ``_args suffix``. They are therefore omitted from @_data. + * + * This should only be used to build the constants described below; it should + * never be used to call an IOCTL directly. + * + * Return: An IOCTL number to be passed to ioctl() from userspace. + */ +#define PVR_IOCTL(_ioctl, _mode, _data) \ + _mode(DRM_COMMAND_BASE + (_ioctl), struct drm_pvr_ioctl_##_data##_args) + +#define DRM_IOCTL_PVR_DEV_QUERY PVR_IOCTL(0x00, DRM_IOWR, dev_query) +#define DRM_IOCTL_PVR_CREATE_BO PVR_IOCTL(0x01, DRM_IOWR, create_bo) +#define DRM_IOCTL_PVR_GET_BO_MMAP_OFFSET PVR_IOCTL(0x02, DRM_IOWR, get_bo_mmap_offset) +#define DRM_IOCTL_PVR_CREATE_VM_CONTEXT PVR_IOCTL(0x03, DRM_IOWR, create_vm_context) +#define DRM_IOCTL_PVR_DESTROY_VM_CONTEXT PVR_IOCTL(0x04, DRM_IOW, destroy_vm_context) +#define DRM_IOCTL_PVR_VM_MAP PVR_IOCTL(0x05, DRM_IOW, vm_map) +#define
[PATCH v4 01/17] sizes.h: Add entries between 32G and 64T
From: Matt Coster Signed-off-by: Matt Coster Reviewed-by: Linus Walleij --- include/linux/sizes.h | 9 + 1 file changed, 9 insertions(+) diff --git a/include/linux/sizes.h b/include/linux/sizes.h index 84aa448d8bb3..c3a00b967d18 100644 --- a/include/linux/sizes.h +++ b/include/linux/sizes.h @@ -47,8 +47,17 @@ #define SZ_8G _AC(0x2, ULL) #define SZ_16G _AC(0x4, ULL) #define SZ_32G _AC(0x8, ULL) +#define SZ_64G _AC(0x10, ULL) +#define SZ_128G_AC(0x20, ULL) +#define SZ_256G_AC(0x40, ULL) +#define SZ_512G_AC(0x80, ULL) #define SZ_1T _AC(0x100, ULL) +#define SZ_2T _AC(0x200, ULL) +#define SZ_4T _AC(0x400, ULL) +#define SZ_8T _AC(0x800, ULL) +#define SZ_16T _AC(0x1000, ULL) +#define SZ_32T _AC(0x2000, ULL) #define SZ_64T _AC(0x4000, ULL) #endif /* __LINUX_SIZES_H__ */ -- 2.41.0
[PATCH v4 00/17] Imagination Technologies PowerVR DRM driver
This patch series adds the initial DRM driver for Imagination Technologies PowerVR GPUs, starting with those based on our Rogue architecture. It's worth pointing out that this is a new driver, written from the ground up, rather than a refactored version of our existing downstream driver (pvrsrvkm). This new DRM driver supports: - GEM shmem allocations - dma-buf / PRIME - Per-context userspace managed virtual address space - DRM sync objects (binary and timeline) - Power management suspend / resume - GPU job submission (geometry, fragment, compute, transfer) - META firmware processor - MIPS firmware processor - GPU hang detection and recovery Currently our main focus is on the AXE-1-16M GPU. Testing so far has been done using a TI SK-AM62 board (AXE-1-16M GPU). Firmware for the AXE-1-16M can be found here: https://gitlab.freedesktop.org/frankbinns/linux-firmware/-/tree/powervr A Vulkan driver that works with our downstream kernel driver has already been merged into Mesa [1][2]. Support for this new DRM driver is being maintained in a draft merge request [3], with the branch located here: https://gitlab.freedesktop.org/frankbinns/mesa/-/tree/powervr-winsys Job stream formats are documented at: https://gitlab.freedesktop.org/mesa/mesa/-/blob/f8d2b42ae65c2f16f36a43e0ae39d288431e4263/src/imagination/csbgen/rogue_kmd_stream.xml The Vulkan driver is progressing towards Vulkan 1.0. We're code complete, and are working towards passing conformance. The current combination of this kernel driver with the Mesa Vulkan driver achieves 86.2% conformance. The code in this patch series, along with some of its history, can also be found here: https://gitlab.freedesktop.org/frankbinns/powervr/-/tree/powervr-next This patch series has dependencies on a number of patches not yet merged. They are listed below : maple_tree: split up MA_STATE() macro: https://lore.kernel.org/dri-devel/20230606223130.6132-3-d...@redhat.com/ drm: manager to keep track of GPUs VA mappings: https://lore.kernel.org/dri-devel/20230606223130.6132-4-d...@redhat.com/ drm/sched: Convert drm scheduler to use a work queue rather than kthread: https://lore.kernel.org/dri-devel/20230404002211.3611376-2-matthew.br...@intel.com/ drm/sched: Move schedule policy to scheduler / entity: https://lore.kernel.org/dri-devel/20230404002211.3611376-3-matthew.br...@intel.com/ drm/sched: Add DRM_SCHED_POLICY_SINGLE_ENTITY scheduling policy: https://lore.kernel.org/dri-devel/20230404002211.3611376-4-matthew.br...@intel.com/ drm/sched: Start run wq before TDR in drm_sched_start: https://lore.kernel.org/dri-devel/20230404002211.3611376-6-matthew.br...@intel.com/ drm/sched: Submit job before starting TDR: https://lore.kernel.org/dri-devel/20230404002211.3611376-7-matthew.br...@intel.com/ drm/sched: Add helper to set TDR timeout: https://lore.kernel.org/dri-devel/20230404002211.3611376-8-matthew.br...@intel.com/ drm/sched: Make sure we wait for all dependencies in kill_jobs_cb(): https://lore.kernel.org/dri-devel/20230619071921.3465992-1-boris.brezil...@collabora.com/ drm/sched: Call drm_sched_fence_set_parent() from drm_sched_fence_scheduled(): https://lore.kernel.org/dri-devel/20230623075204.382350-1-boris.brezil...@collabora.com/ [1] https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15243 [2] https://gitlab.freedesktop.org/mesa/mesa/-/tree/main/src/imagination/vulkan [3] https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15507 High level summary of changes: v4: * Implemented hang recovery via firmware hard reset * Add support for partial render jobs * Move to a threaded IRQ * Remove unnecessary read/write and clock helpers * Remove device tree elements not relevant to AXE-1-16M * Clean up resource acquisition * Remove unused DT binding attributes v3: * Use drm_sched for scheduling * Use GPU VA manager * Use runtime PM * Use drm_gem_shmem * GPU watchdog and device loss handling * DT binding changes: remove unused attributes, add additionProperties:false v2: * Redesigned and simplified UAPI based on RFC feedback from XDC 2022 * Support for transfer and partial render jobs * Support for timeline sync objects RFC v1: https://lore.kernel.org/dri-devel/20220815165156.118212-1-sarah.wal...@imgtec.com/ RFC v2: https://lore.kernel.org/dri-devel/20230413103419.293493-1-sarah.wal...@imgtec.com/ v3: https://lore.kernel.org/dri-devel/20230613144800.52657-1-sarah.wal...@imgtec.com/ Matt Coster (1): sizes.h: Add entries between 32G and 64T Sarah Walker (16): dt-bindings: gpu: Add Imagination Technologies PowerVR GPU drm/imagination/uapi: Add PowerVR driver UAPI drm/imagination: Add skeleton PowerVR driver drm/imagination: Get GPU resources drm/imagination: Add GPU register and FWIF headers drm/imagination: Add GPU ID parsing and firmware loading drm/imagination: Add GEM and VM related code drm/imagination: Implement power management drm/imagination: Implement firmware infrastructure and META FW support
[RFC v5 2/3] drm/ttm/tests: Add tests for ttm_device
Test initialization and cleanup of the ttm_device struct, including some error paths. Verify the creation of page pools if use_dma_alloc param is true. Signed-off-by: Karolina Stolarek Reviewed-by: Christian König --- drivers/gpu/drm/ttm/tests/ttm_device_test.c | 158 1 file changed, 158 insertions(+) diff --git a/drivers/gpu/drm/ttm/tests/ttm_device_test.c b/drivers/gpu/drm/ttm/tests/ttm_device_test.c index 76d927d07501..b1b423b68cdf 100644 --- a/drivers/gpu/drm/ttm/tests/ttm_device_test.c +++ b/drivers/gpu/drm/ttm/tests/ttm_device_test.c @@ -8,6 +8,13 @@ #include "ttm_kunit_helpers.h" +struct ttm_device_test_case { + const char *description; + bool use_dma_alloc; + bool use_dma32; + bool pools_init_expected; +}; + static void ttm_device_init_basic(struct kunit *test) { struct ttm_test_devices *priv = test->priv; @@ -37,8 +44,159 @@ static void ttm_device_init_basic(struct kunit *test) ttm_device_fini(ttm_dev); } +static void ttm_device_init_multiple(struct kunit *test) +{ + struct ttm_test_devices *priv = test->priv; + struct ttm_device *ttm_devs; + unsigned int i, num_dev = 3; + int err; + + ttm_devs = kunit_kcalloc(test, num_dev, sizeof(*ttm_devs), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, ttm_devs); + + for (i = 0; i < num_dev; i++) { + err = ttm_device_kunit_init(priv, _devs[i], false, false); + KUNIT_ASSERT_EQ(test, err, 0); + + KUNIT_EXPECT_PTR_EQ(test, ttm_devs[i].dev_mapping, + priv->drm->anon_inode->i_mapping); + KUNIT_ASSERT_NOT_NULL(test, ttm_devs[i].wq); + KUNIT_EXPECT_PTR_EQ(test, ttm_devs[i].funcs, _dev_funcs); + KUNIT_ASSERT_NOT_NULL(test, ttm_devs[i].man_drv[TTM_PL_SYSTEM]); + } + + KUNIT_ASSERT_EQ(test, list_count_nodes(_devs[0].device_list), num_dev); + + for (i = 0; i < num_dev; i++) + ttm_device_fini(_devs[i]); +} + +static void ttm_device_fini_basic(struct kunit *test) +{ + struct ttm_test_devices *priv = test->priv; + struct ttm_device *ttm_dev; + struct ttm_resource_manager *man; + int err; + + ttm_dev = kunit_kzalloc(test, sizeof(*ttm_dev), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, ttm_dev); + + err = ttm_device_kunit_init(priv, ttm_dev, false, false); + KUNIT_ASSERT_EQ(test, err, 0); + + man = ttm_manager_type(ttm_dev, TTM_PL_SYSTEM); + KUNIT_ASSERT_NOT_NULL(test, man); + + ttm_device_fini(ttm_dev); + + KUNIT_ASSERT_FALSE(test, man->use_type); + KUNIT_ASSERT_TRUE(test, list_empty(>lru[0])); + KUNIT_ASSERT_NULL(test, ttm_dev->man_drv[TTM_PL_SYSTEM]); +} + +static void ttm_device_init_no_vma_man(struct kunit *test) +{ + struct ttm_test_devices *priv = test->priv; + struct drm_device *drm = priv->drm; + struct ttm_device *ttm_dev; + struct drm_vma_offset_manager *vma_man; + int err; + + ttm_dev = kunit_kzalloc(test, sizeof(*ttm_dev), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, ttm_dev); + + /* Let's pretend there's no VMA manager allocated */ + vma_man = drm->vma_offset_manager; + drm->vma_offset_manager = NULL; + + err = ttm_device_kunit_init(priv, ttm_dev, false, false); + KUNIT_EXPECT_EQ(test, err, -EINVAL); + + /* Bring the manager back for a graceful cleanup */ + drm->vma_offset_manager = vma_man; +} + +static const struct ttm_device_test_case ttm_device_cases[] = { + { + .description = "No DMA allocations, no DMA32 required", + .use_dma_alloc = false, + .use_dma32 = false, + .pools_init_expected = false, + }, + { + .description = "DMA allocations, DMA32 required", + .use_dma_alloc = true, + .use_dma32 = true, + .pools_init_expected = true, + }, + { + .description = "No DMA allocations, DMA32 required", + .use_dma_alloc = false, + .use_dma32 = true, + .pools_init_expected = false, + }, + { + .description = "DMA allocations, no DMA32 required", + .use_dma_alloc = true, + .use_dma32 = false, + .pools_init_expected = true, + }, +}; + +static void ttm_device_case_desc(const struct ttm_device_test_case *t, char *desc) +{ + strscpy(desc, t->description, KUNIT_PARAM_DESC_SIZE); +} + +KUNIT_ARRAY_PARAM(ttm_device, ttm_device_cases, ttm_device_case_desc); + +static void ttm_device_init_pools(struct kunit *test) +{ + struct ttm_test_devices *priv = test->priv; + const struct ttm_device_test_case *params = test->param_value; + struct ttm_device *ttm_dev; + struct ttm_pool *pool; + struct ttm_pool_type pt; + int err; + + ttm_dev =
[RFC v5 3/3] drm/ttm/tests: Add tests for ttm_pool
Add KUnit tests that exercise page allocation using page pools and freeing pages, either by returning them to the pool or freeing them. Add a basic test for ttm_pool cleanup. Introduce helpers to create a dummy ttm_buffer_object. Signed-off-by: Karolina Stolarek --- drivers/gpu/drm/ttm/tests/Makefile| 1 + drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c | 17 + drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.h | 4 + drivers/gpu/drm/ttm/tests/ttm_pool_test.c | 441 ++ 4 files changed, 463 insertions(+) create mode 100644 drivers/gpu/drm/ttm/tests/ttm_pool_test.c diff --git a/drivers/gpu/drm/ttm/tests/Makefile b/drivers/gpu/drm/ttm/tests/Makefile index 7917805f37af..ec87c4fc1ad5 100644 --- a/drivers/gpu/drm/ttm/tests/Makefile +++ b/drivers/gpu/drm/ttm/tests/Makefile @@ -2,4 +2,5 @@ obj-$(CONFIG_DRM_TTM_KUNIT_TEST) += \ ttm_device_test.o \ +ttm_pool_test.o \ ttm_kunit_helpers.o diff --git a/drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c b/drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c index 5f1499761f16..236d7da65627 100644 --- a/drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c +++ b/drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c @@ -25,6 +25,23 @@ int ttm_device_kunit_init(struct ttm_test_devices *priv, } EXPORT_SYMBOL_GPL(ttm_device_kunit_init); +struct ttm_buffer_object *ttm_bo_kunit_init(struct kunit *test, + struct ttm_test_devices *devs, + size_t size) +{ + struct drm_gem_object gem_obj = { .size = size }; + struct ttm_buffer_object *bo; + + bo = kunit_kzalloc(test, sizeof(*bo), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, bo); + + bo->base = gem_obj; + bo->bdev = devs->ttm_dev; + + return bo; +} +EXPORT_SYMBOL_GPL(ttm_bo_kunit_init); + struct ttm_test_devices *ttm_test_devices_basic(struct kunit *test) { struct ttm_test_devices *devs; diff --git a/drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.h b/drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.h index f9f5bc03e93a..e261e3660d0b 100644 --- a/drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.h +++ b/drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.h @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -24,6 +25,9 @@ int ttm_device_kunit_init(struct ttm_test_devices *priv, struct ttm_device *ttm, bool use_dma_alloc, bool use_dma32); +struct ttm_buffer_object *ttm_bo_kunit_init(struct kunit *test, + struct ttm_test_devices *devs, + size_t size); struct ttm_test_devices *ttm_test_devices_basic(struct kunit *test); struct ttm_test_devices *ttm_test_devices_all(struct kunit *test); diff --git a/drivers/gpu/drm/ttm/tests/ttm_pool_test.c b/drivers/gpu/drm/ttm/tests/ttm_pool_test.c new file mode 100644 index ..31a7825cd31e --- /dev/null +++ b/drivers/gpu/drm/ttm/tests/ttm_pool_test.c @@ -0,0 +1,441 @@ +// SPDX-License-Identifier: GPL-2.0 AND MIT +/* + * Copyright © 2023 Intel Corporation + */ +#include + +#include +#include + +#include "ttm_kunit_helpers.h" + +struct ttm_pool_test_case { + const char *description; + unsigned int order; + bool use_dma_alloc; +}; + +struct ttm_pool_test_priv { + struct ttm_test_devices *devs; + + /* Used to create mock ttm_tts */ + struct ttm_buffer_object *mock_bo; +}; + +static struct ttm_operation_ctx simple_ctx = { + .interruptible = true, + .no_wait_gpu = false, +}; + +static int ttm_pool_test_init(struct kunit *test) +{ + struct ttm_pool_test_priv *priv; + + priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, priv); + + priv->devs = ttm_test_devices_basic(test); + test->priv = priv; + + return 0; +} + +static void ttm_pool_test_fini(struct kunit *test) +{ + struct ttm_pool_test_priv *priv = test->priv; + + if (priv->mock_bo) + ttm_bo_put(priv->mock_bo); + + ttm_test_devices_put(test, priv->devs); +} + +static struct ttm_tt *ttm_tt_kunit_init(struct kunit *test, + uint32_t page_flags, + enum ttm_caching caching, + size_t size) +{ + struct ttm_pool_test_priv *priv = test->priv; + struct ttm_buffer_object *bo; + struct ttm_tt *tt; + int err; + + bo = ttm_bo_kunit_init(test, priv->devs, size); + KUNIT_ASSERT_NOT_NULL(test, bo); + priv->mock_bo = bo; + + tt = kunit_kzalloc(test, sizeof(*tt), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, tt); + + err = ttm_tt_init(tt, priv->mock_bo, page_flags, caching, 0); + KUNIT_ASSERT_EQ(test, err, 0); + + return tt; +} + +static struct ttm_pool *ttm_pool_pre_populated(struct kunit
[RFC v5 0/3] Introduce KUnit tests for TTM subsystem
This series introduces KUnit[1] tests for TTM (Translation Table Manager) subsystem, a memory manager used by graphics drivers to create and manage memory buffers across different memory domains, such as system memory or VRAM. Unit tests implemented here cover two data structures: - ttm_device -- referred as a buffer object device, which stores resource managers and page pools - ttm_pool -- a struct of pools (ttm_pool_type) of different page orders and caching attributes, with pages that can be reused on the next buffer allocation Use kunit_tool script to manually run the tests: $ ./tools/testing/kunit/kunit.py run --kunitconfig=drivers/gpu/drm/ttm/tests To build a kernel with TTM KUnit tests, first enable CONFIG_KUNIT, and then CONFIG_DRM_TTM_KUNIT_TEST. As for now, tests are architecture-agnostic (i.e. KUnit runner uses UML kernel), which means that we have limited coverage in some places. For example, we can't fully test the initialization of global page pools, such as global_write_combined. It is to be decided if we want to stick to UML or use CONFIG_X86 (at least to some extent). These patches are just a beginning of the work to improve the test coverage of TTM. Feel free to suggest changes, test cases or priorities. Many thanks, Karolina v5: - Drop unnecessary brackets in 2/3 - Rebase KConfig file on the top of drm-tip v4: - Test helpers have been changed to make the creation of init/fini functions for each test suite easier: + Decouple device creation from test initialization by adding helpers that initialize ttm_test_devices, a struct which stores DRM/TTM devices, and can be used in test-specific init/finis (see ttm_pool_tests.c for an example) + Introduce generic init/fini functions for tests that only need devices + Add ttm_device field to ttm_test_devices (previously ttm_test_devices_priv) - Make TTM buffer object outlive its TT (Christian) - Add a dedicated struct for ttm_pool_test (struct ttm_pool_test_priv) - Rename functions and structs: + struct ttm_test_devices_priv --> struct ttm_test_devices + ttm_kunit_helper_init_device() --> ttm_device_kunit_init() + ttm_kunit_helper_ttm_bo_init() --> ttm_bo_kunit_init() - Split ttm_kunit_helper_init() into full config (with ttm_device init) and basic (init only with device/drm_device) initialization functions v3: - Rename ttm_kunit_helper_alloc_device() to ttm_kunit_helper_init_device() (Christian) - Don't leak a full-blown drm_gem_object in ttm_kunit_helper_ttm_bo_init(). (Christian). Create a small mock object just to get ttm_tt_init_fields() to init the right number of pages - As a follow up to the change above, delete ttm_kunit_helper_ttm_bo_fini() and just use ttm_bo_put() v2: - Add missing symbol exports in ttm_kunit_helpers.c - Update helpers include to fix compilation issues (didn't catch it as KUnit tests weren't enabled in the kernel I tested, an oversight on my part) - Add checks for ttm_pool fields in ttm_pool_alloc_basic(), including the one for NUMA node id - Rebase the changes on the top of drm-tip [1] - https://www.kernel.org/doc/html/latest/dev-tools/kunit/index.html Karolina Stolarek (3): drm/ttm: Introduce KUnit test drm/ttm/tests: Add tests for ttm_device drm/ttm/tests: Add tests for ttm_pool drivers/gpu/drm/Kconfig | 15 + drivers/gpu/drm/ttm/Makefile | 1 + drivers/gpu/drm/ttm/tests/.kunitconfig| 4 + drivers/gpu/drm/ttm/tests/Makefile| 6 + drivers/gpu/drm/ttm/tests/ttm_device_test.c | 212 + drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c | 115 + drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.h | 41 ++ drivers/gpu/drm/ttm/tests/ttm_pool_test.c | 441 ++ 8 files changed, 835 insertions(+) create mode 100644 drivers/gpu/drm/ttm/tests/.kunitconfig create mode 100644 drivers/gpu/drm/ttm/tests/Makefile create mode 100644 drivers/gpu/drm/ttm/tests/ttm_device_test.c create mode 100644 drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c create mode 100644 drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.h create mode 100644 drivers/gpu/drm/ttm/tests/ttm_pool_test.c -- 2.25.1
[RFC v5 1/3] drm/ttm: Introduce KUnit test
Add the initial version of unit tests for ttm_device struct, together with helper functions. Signed-off-by: Karolina Stolarek --- drivers/gpu/drm/Kconfig | 15 +++ drivers/gpu/drm/ttm/Makefile | 1 + drivers/gpu/drm/ttm/tests/.kunitconfig| 4 + drivers/gpu/drm/ttm/tests/Makefile| 5 + drivers/gpu/drm/ttm/tests/ttm_device_test.c | 54 ++ drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c | 98 +++ drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.h | 37 +++ 7 files changed, 214 insertions(+) create mode 100644 drivers/gpu/drm/ttm/tests/.kunitconfig create mode 100644 drivers/gpu/drm/ttm/tests/Makefile create mode 100644 drivers/gpu/drm/ttm/tests/ttm_device_test.c create mode 100644 drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c create mode 100644 drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.h diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 22c1ba9ea28c..3203204bc63b 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -195,6 +195,21 @@ config DRM_TTM GPU memory types. Will be enabled automatically if a device driver uses it. +config DRM_TTM_KUNIT_TEST +tristate "KUnit tests for TTM" if !KUNIT_ALL_TESTS +default n +depends on DRM && KUNIT +select DRM_TTM +select DRM_EXPORT_FOR_TESTS if m +select DRM_KUNIT_TEST_HELPERS +default KUNIT_ALL_TESTS +help + Enables unit tests for TTM, a GPU memory manager subsystem used + to manage memory buffers. This option is mostly useful for kernel + developers. + + If in doubt, say "N". + config DRM_EXEC tristate depends on DRM diff --git a/drivers/gpu/drm/ttm/Makefile b/drivers/gpu/drm/ttm/Makefile index f906b22959cf..dad298127226 100644 --- a/drivers/gpu/drm/ttm/Makefile +++ b/drivers/gpu/drm/ttm/Makefile @@ -8,3 +8,4 @@ ttm-y := ttm_tt.o ttm_bo.o ttm_bo_util.o ttm_bo_vm.o ttm_module.o \ ttm-$(CONFIG_AGP) += ttm_agp_backend.o obj-$(CONFIG_DRM_TTM) += ttm.o +obj-$(CONFIG_DRM_TTM_KUNIT_TEST) += tests/ diff --git a/drivers/gpu/drm/ttm/tests/.kunitconfig b/drivers/gpu/drm/ttm/tests/.kunitconfig new file mode 100644 index ..75fdce0cd98e --- /dev/null +++ b/drivers/gpu/drm/ttm/tests/.kunitconfig @@ -0,0 +1,4 @@ +CONFIG_KUNIT=y +CONFIG_DRM=y +CONFIG_DRM_KUNIT_TEST_HELPERS=y +CONFIG_DRM_TTM_KUNIT_TEST=y diff --git a/drivers/gpu/drm/ttm/tests/Makefile b/drivers/gpu/drm/ttm/tests/Makefile new file mode 100644 index ..7917805f37af --- /dev/null +++ b/drivers/gpu/drm/ttm/tests/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 AND MIT + +obj-$(CONFIG_DRM_TTM_KUNIT_TEST) += \ +ttm_device_test.o \ +ttm_kunit_helpers.o diff --git a/drivers/gpu/drm/ttm/tests/ttm_device_test.c b/drivers/gpu/drm/ttm/tests/ttm_device_test.c new file mode 100644 index ..76d927d07501 --- /dev/null +++ b/drivers/gpu/drm/ttm/tests/ttm_device_test.c @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: GPL-2.0 AND MIT +/* + * Copyright © 2023 Intel Corporation + */ +#include +#include +#include + +#include "ttm_kunit_helpers.h" + +static void ttm_device_init_basic(struct kunit *test) +{ + struct ttm_test_devices *priv = test->priv; + struct ttm_device *ttm_dev; + struct ttm_resource_manager *ttm_sys_man; + int err; + + ttm_dev = kunit_kzalloc(test, sizeof(*ttm_dev), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, ttm_dev); + + err = ttm_device_kunit_init(priv, ttm_dev, false, false); + KUNIT_ASSERT_EQ(test, err, 0); + + KUNIT_EXPECT_PTR_EQ(test, ttm_dev->funcs, _dev_funcs); + KUNIT_ASSERT_NOT_NULL(test, ttm_dev->wq); + KUNIT_ASSERT_NOT_NULL(test, ttm_dev->man_drv[TTM_PL_SYSTEM]); + + ttm_sys_man = _dev->sysman; + KUNIT_ASSERT_NOT_NULL(test, ttm_sys_man); + KUNIT_EXPECT_TRUE(test, ttm_sys_man->use_tt); + KUNIT_EXPECT_TRUE(test, ttm_sys_man->use_type); + KUNIT_ASSERT_NOT_NULL(test, ttm_sys_man->func); + + KUNIT_EXPECT_PTR_EQ(test, ttm_dev->dev_mapping, + priv->drm->anon_inode->i_mapping); + + ttm_device_fini(ttm_dev); +} + +static struct kunit_case ttm_device_test_cases[] = { + KUNIT_CASE(ttm_device_init_basic), + {} +}; + +static struct kunit_suite ttm_device_test_suite = { + .name = "ttm_device", + .init = ttm_test_devices_init, + .exit = ttm_test_devices_fini, + .test_cases = ttm_device_test_cases, +}; + +kunit_test_suites(_device_test_suite); + +MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c b/drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c new file mode 100644 index ..5f1499761f16 --- /dev/null +++ b/drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: GPL-2.0 AND MIT +/* + * Copyright © 2023 Intel Corporation + */ +#include
Re: [PATCH v3 09/17] drm/imagination: Implement power management
Hi Maxime, On Fri, 2023-07-07 at 14:48 +0200, Maxime Ripard wrote: > On Tue, Jun 13, 2023 at 03:47:52PM +0100, Sarah Walker wrote: > > @@ -503,21 +506,31 @@ pvr_device_init(struct pvr_device *pvr_dev) > > if (err) > > goto err_device_clk_fini; > > > > + /* Explicitly power the GPU so we can access control registers before > > the FW is booted. */ > > + err = pm_runtime_resume_and_get(dev); > > + if (err) > > + goto err_device_clk_fini; > > + > > /* Map the control registers into memory. */ > > err = pvr_device_reg_init(pvr_dev); > > if (err) > > - goto err_device_clk_fini; > > + goto err_pm_runtime_put; > > > > /* Perform GPU-specific initialization steps. */ > > err = pvr_device_gpu_init(pvr_dev); > > if (err) > > goto err_device_reg_fini; > > > > + pm_runtime_put_autosuspend(dev); > > + > > You probably can use pm_runtime_put here Ack > > > @@ -532,12 +545,17 @@ pvr_device_init(struct pvr_device *pvr_dev) > > void > > pvr_device_fini(struct pvr_device *pvr_dev) > > { > > + struct drm_device *drm_dev = from_pvr_device(pvr_dev); > > + struct device *dev = drm_dev->dev; > > + > > /* > >* Deinitialization stages are performed in reverse order compared to > >* the initialization stages in pvr_device_init(). > >*/ > > + pm_runtime_get_sync(dev); > > pvr_device_gpu_fini(pvr_dev); > > pvr_device_reg_fini(pvr_dev); > > AFAIK gpu_fini releases the firmware and reg_fini drops the register > mapping address, I don't think you need the device powered up for that. Very true, we'll fix that :) > > > @@ -130,6 +133,20 @@ struct pvr_device { > > > > /** @fw_dev: Firmware related data. */ > > struct pvr_fw_device fw_dev; > > + > > + struct { > > + /** @work: Work item for watchdog callback. */ > > + struct delayed_work work; > > + > > + /** @old_kccb_cmds_executed: KCCB command execution count at > > last watchdog poll. */ > > + u32 old_kccb_cmds_executed; > > + > > + /** @kccb_stall_count: Number of watchdog polls KCCB has been > > stalled for. */ > > + u32 kccb_stall_count; > > + } watchdog; > > + > > + /** @lost: %true if the device has been lost. */ > > + bool lost; > > The device being "lost" isn't clear to me. Does it mean it's > unresponsive or stuck somehow? The former. For example, this will be set when the firmware has become unresponsive and hard resetting the GPU doesn't resolve this. We'll update the docs to clarify. > > > @@ -1285,9 +1303,15 @@ pvr_probe(struct platform_device *plat_dev) > > > > platform_set_drvdata(plat_dev, drm_dev); > > > > + devm_pm_runtime_enable(_dev->dev); > > + > > + pm_runtime_set_autosuspend_delay(_dev->dev, 50); > > + pm_runtime_use_autosuspend(_dev->dev); > > + pvr_power_init(pvr_dev); > > The name threw me off a bit. It doesn't look like it's power related but > you init the watchdog timer? Yup, we'll update the name to reflect its real purpose. > > I can't really tell from that patch, but if it's not done in a later > patch you'll probably need a call to sprinkle your driver with a few > _mark_last_busy calls (at least in the job submission path?) We weren't doing this before so we'll add some calls in. Thanks Frank > > Maxime
Re: [PATCH v3 05/17] drm/imagination: Get GPU resources
Hi Maxime, On Fri, 2023-07-07 at 14:47 +0200, Maxime Ripard wrote: > On Tue, Jun 13, 2023 at 03:47:48PM +0100, Sarah Walker wrote: > > Acquire clock, regulator and register resources, and enable/map as > > appropriate. > > > > Signed-off-by: Sarah Walker > > --- > > drivers/gpu/drm/imagination/Makefile | 1 + > > drivers/gpu/drm/imagination/pvr_device.c | 271 +++ > > drivers/gpu/drm/imagination/pvr_device.h | 214 ++ > > drivers/gpu/drm/imagination/pvr_drv.c| 11 +- > > 4 files changed, 496 insertions(+), 1 deletion(-) > > create mode 100644 drivers/gpu/drm/imagination/pvr_device.c > > > > diff --git a/drivers/gpu/drm/imagination/Makefile > > b/drivers/gpu/drm/imagination/Makefile > > index 62ccf0ccbd51..186f920d615b 100644 > > --- a/drivers/gpu/drm/imagination/Makefile > > +++ b/drivers/gpu/drm/imagination/Makefile > > @@ -4,6 +4,7 @@ > > subdir-ccflags-y := -I$(srctree)/$(src) > > > > powervr-y := \ > > + pvr_device.o \ > > pvr_drv.o \ > > > > obj-$(CONFIG_DRM_POWERVR) += powervr.o > > diff --git a/drivers/gpu/drm/imagination/pvr_device.c > > b/drivers/gpu/drm/imagination/pvr_device.c > > new file mode 100644 > > index ..790c36cebec1 > > --- /dev/null > > +++ b/drivers/gpu/drm/imagination/pvr_device.c > > @@ -0,0 +1,271 @@ > > +// SPDX-License-Identifier: GPL-2.0 OR MIT > > +/* Copyright (c) 2022 Imagination Technologies Ltd. */ > > + > > +#include "pvr_device.h" > > + > > +#include > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +/** > > + * pvr_device_reg_init() - Initialize kernel access to a PowerVR device's > > + * control registers. > > + * @pvr_dev: Target PowerVR device. > > + * > > + * Sets struct pvr_device->regs. > > + * > > + * This method of mapping the device control registers into memory ensures > > that > > + * they are unmapped when the driver is detached (i.e. no explicit cleanup > > is > > + * required). > > + * > > + * Return: > > + * * 0 on success, or > > + * * Any error returned by devm_platform_ioremap_resource(). > > + */ > > +static int > > +pvr_device_reg_init(struct pvr_device *pvr_dev) > > +{ > > + struct drm_device *drm_dev = from_pvr_device(pvr_dev); > > + struct platform_device *plat_dev = to_platform_device(drm_dev->dev); > > + struct resource *regs_resource; > > + void __iomem *regs; > > + int err; > > + > > + pvr_dev->regs_resource = NULL; > > + pvr_dev->regs = NULL; > > + > > + regs = devm_platform_get_and_ioremap_resource(plat_dev, 0, > > _resource); > > + if (IS_ERR(regs)) { > > + err = PTR_ERR(regs); > > + drm_err(drm_dev, "failed to ioremap gpu registers (err=%d)\n", > > + err); > > + return err; > > + } > > + > > + pvr_dev->regs = regs; > > + pvr_dev->regs_resource = regs_resource; > > Do you actually need the resources somewhere? This is needed when setting up the boot data for the MIPS firmware processor in patch 11 (drm/imagination: Implement MIPS firmware processor and MMU support). We'll move it to that patch instead. > > > + > > + return 0; > > +} > > + > > +/** > > + * pvr_device_reg_fini() - Deinitialize kernel access to a PowerVR device's > > + * control registers. > > + * @pvr_dev: Target PowerVR device. > > + * > > + * This is essentially a no-op, since pvr_device_reg_init() already > > ensures that > > + * struct pvr_device->regs is unmapped when the device is detached. This > > + * function just sets struct pvr_device->regs to %NULL. > > + */ > > +static __always_inline void > > +pvr_device_reg_fini(struct pvr_device *pvr_dev) > > +{ > > + pvr_dev->regs = NULL; > > But if you do, I guess clearing the regs_resource pointer would be nice too. pvr_device_reg_fini() will be gone in the next version. > > > +} > > + > > +/** > > + * pvr_device_clk_init() - Initialize clocks required by a PowerVR device > > + * @pvr_dev: Target PowerVR device. > > + * > > + * Sets struct pvr_device->core_clk, struct pvr_device->sys_clk and > > + * struct pvr_device->mem_clk. > > + * > > + * Three clocks are required by the PowerVR device: core, sys and mem. On > > + * return, this function guarantees that the clocks are in one of the > > following > > + * states: > > + * > > + * * All successfully initialized, > > + * * Core errored, sys and mem uninitialized, > > + * * Core deinitialized, sys errored, mem uninitialized, or > > + * * Core and sys deinitialized, mem errored. > > + * > > + * Return: > > + * * 0 on success, > > + * * Any error returned by devm_clk_get(), or > > + * * Any error returned by clk_prepare_enable(). > > + */ > > +static int pvr_device_clk_init(struct pvr_device *pvr_dev) > > +{ > > + struct drm_device *drm_dev = from_pvr_device(pvr_dev); > > + struct clk *core_clk; > > + struct clk *sys_clk; >
Re: [PATCH v3 04/17] drm/imagination: Add skeleton PowerVR driver
Hi Maxime, Thank you for your feedback (comments below). On Fri, 2023-07-07 at 14:46 +0200, Maxime Ripard wrote: > Hi, > > [I just noticed I dropped the Cc list, resending] > > Thanks for contributing this driver, it's awesome to see it moving > forward. > > And congrats on the documentation too, it's not often we see a driver > that well documented on its v3. > > I've stripped some parts of the patch that weren't relevant to my > review. > > On Tue, Jun 13, 2023 at 03:47:47PM +0100, Sarah Walker wrote: > > +static __always_inline struct pvr_device * > > +to_pvr_device(struct drm_device *drm_dev) > > +{ > > + return container_of(drm_dev, struct pvr_device, base); > > +} > > For that kind of helpers, we're slowly transitioning to using a macro > and container_of_const. This allows to work with const-ness context. Ack > > > +static int > > +pvr_probe(struct platform_device *plat_dev) > > +{ > > + struct pvr_device *pvr_dev; > > + struct drm_device *drm_dev; > > + int err; > > + > > + pvr_dev = devm_drm_dev_alloc(_dev->dev, _drm_driver, > > + struct pvr_device, base); > > + if (IS_ERR(pvr_dev)) { > > + err = IS_ERR(pvr_dev); > > PTR_ERR? Good catch :) > > > + goto err_out; > > The general pattern here is to return directly here, it's simpler to > follow. Ack > > > + } > > + drm_dev = _dev->base; > > + > > + platform_set_drvdata(plat_dev, drm_dev); > > + > > + err = drm_dev_register(drm_dev, 0); > > + if (err) > > + goto err_out; > > I guess it would be simpler here too, but I think you're going to move > things around anyway? > > > +static const struct of_device_id dt_match[] = { > > + { .compatible = "ti,am62-gpu", .data = NULL }, > > + { .compatible = "img,powervr-seriesaxe", .data = NULL }, > > Do you really need both? The binding you documented requires both to be > there, so I think you can either match on the more specific one (and > extend that list when needed) or match the more generic one and be done > with it once and for all. Having both is redundant. We'll drop the more specific one in the next version. > > > + {} > > +}; > > +MODULE_DEVICE_TABLE(of, dt_match); > > + > > +static struct platform_driver pvr_driver = { > > + .probe = pvr_probe, > > + .remove = pvr_remove, > > + .driver = { > > + .name = PVR_DRIVER_NAME, > > + .of_match_table = dt_match, > > + }, > > +}; > > +module_platform_driver(pvr_driver); > > + > > +MODULE_AUTHOR("Imagination Technologies Ltd."); > > +MODULE_DESCRIPTION(PVR_DRIVER_DESC); > > +MODULE_LICENSE("Dual MIT/GPL"); > > +MODULE_IMPORT_NS(DMA_BUF); > > +MODULE_FIRMWARE("powervr/rogue_4.40.2.51_v1.fw"); > > +MODULE_FIRMWARE("powervr/rogue_33.15.11.3_v1.fw"); > > That one should probably be moved to the firmware patch? Ack > > > diff --git a/drivers/gpu/drm/imagination/pvr_drv.h > > b/drivers/gpu/drm/imagination/pvr_drv.h > > new file mode 100644 > > index ..8e6f4a4dde3f > > --- /dev/null > > +++ b/drivers/gpu/drm/imagination/pvr_drv.h > > @@ -0,0 +1,22 @@ > > +/* SPDX-License-Identifier: GPL-2.0 OR MIT */ > > +/* Copyright (c) 2022 Imagination Technologies Ltd. */ > > + > > +#ifndef PVR_DRV_H > > +#define PVR_DRV_H > > + > > +#include "linux/compiler_attributes.h" > > +#include > > + > > +#define PVR_DRIVER_NAME "powervr" > > +#define PVR_DRIVER_DESC "Imagination PowerVR Graphics" > > Do you intend to support the SGX and Rogue GPUs with this driver? If > not, mentioning the generation/architecture name somewhere would be > nice. We don't currently have any plans to support SGX ourselves, so we'll update this, and any other places, to clarify things. Thanks Frank > > Maxime
Re: [PATCH 4/8] drm/ssd130x: Add support for DRM_FORMAT_R1
Geert Uytterhoeven writes: Hello Geert, > Hi Javier, [...] >> > >> > The display should not be updated after .remove(), so I think plain >> > devm_kcalloc() should be fine. >> >> That was precisely my point, that there could be atomic commits even after >> the driver has been removed (e.g: if using DRM fbdev emulation, user-space >> can keep the /dev/fb0 opened and continue updating the framebuffer. That's >> not released until the fd is closed and struct fb_ops .fb_destroy called. >> >> But that's a general rule in DRM, any user-visible resource must not be >> allocated using device managed resources and instead use the drm_device >> managed resources helpers. To make sure that are not released until the >> last call to drm_dev_put(): > > These buffers are not user-visible, so they should not be accessed > after .remove(). When these are accessed, the next step would be > to write the buffer data to the device, which would also fail miserably, > as the regmap, GPIO, and regulator are hardware resources managed > through devm_*(). > Right, given that we do the shadow buffer -> native buffer copy, I thought of it as if as a user-visible (well, user-accessible I guess) but you are correct that's not and trying to write to the device will fail anyways. So devm_* should be enough indeed and if there are problems with that, it would be a different bug in the driver to fix. -- Best regards, Javier Martinez Canillas Core Platforms Red Hat
Re: [PATCH 4/8] drm/ssd130x: Add support for DRM_FORMAT_R1
Hi Javier, On Fri, Jul 14, 2023 at 2:35 PM Javier Martinez Canillas wrote: > Geert Uytterhoeven writes: > > On Fri, Jul 14, 2023 at 12:14 PM Javier Martinez Canillas > > wrote: > >> Geert Uytterhoeven writes: > >> Thanks a lot for your patch, this has been on my TODO for some time! > >> > >> > The native display format is monochrome light-on-dark (R1). > >> > Hence add support for R1, so monochrome applications can avoid the > >> > overhead of back-and-forth conversions between R1 and XR24. > >> > > >> > Signed-off-by: Geert Uytterhoeven > >> > Probably ssd130x->buffer should be allocated on first use. > >> > >> Yes, that makes sense. > >> > >> > And why not allocate the buffers using devm_kcalloc()? > >> > >> I think there are some lifetimes discrepancies between struct device and > >> struct drm_device objects. But we could use drm_device managed resources > >> helpers, i.e: drmm_kzalloc(). > > > > The display should not be updated after .remove(), so I think plain > > devm_kcalloc() should be fine. > > That was precisely my point, that there could be atomic commits even after > the driver has been removed (e.g: if using DRM fbdev emulation, user-space > can keep the /dev/fb0 opened and continue updating the framebuffer. That's > not released until the fd is closed and struct fb_ops .fb_destroy called. > > But that's a general rule in DRM, any user-visible resource must not be > allocated using device managed resources and instead use the drm_device > managed resources helpers. To make sure that are not released until the > last call to drm_dev_put(): These buffers are not user-visible, so they should not be accessed after .remove(). When these are accessed, the next step would be to write the buffer data to the device, which would also fail miserably, as the regmap, GPIO, and regulator are hardware resources managed through devm_*(). Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Re: [PATCH 4/8] drm/ssd130x: Add support for DRM_FORMAT_R1
Geert Uytterhoeven writes: Hello Geert, > Hi Javier, > > On Fri, Jul 14, 2023 at 12:14 PM Javier Martinez Canillas > wrote: >> Geert Uytterhoeven writes: >> Thanks a lot for your patch, this has been on my TODO for some time! >> >> > The native display format is monochrome light-on-dark (R1). >> > Hence add support for R1, so monochrome applications can avoid the >> > overhead of back-and-forth conversions between R1 and XR24. >> > >> > Signed-off-by: Geert Uytterhoeven >> > --- >> > This work interfered with commit 49d7d581ceaf4cf8 ("drm/ssd130x: Don't >> > allocate buffers on each plane update") in drm-misc/for-linux-next, >> > which always allocates the buffer upfront, while it is no longer needed >> > when never using XR24. >> >> you mean R1 here, right ? > > I did mean R1. I think you missed the double negation. > I did indeed. As a non-native english speaker, I find it very hard to parse double negations :) >> It's still used in ssd130x_clear_screen() though. > > I guess it became worthwhile to make ssd130x_clear_screen() > do memset(data_array, 0, ...) and call ssd130x_write_data() directly, > avoiding the pointless reshuffling of black pixels in > ssd130x_update_rect()? > I think so, yeah. >> > Probably ssd130x->buffer should be allocated on first use. >> >> Yes, that makes sense. >> >> > And why not allocate the buffers using devm_kcalloc()? >> >> I think there are some lifetimes discrepancies between struct device and >> struct drm_device objects. But we could use drm_device managed resources >> helpers, i.e: drmm_kzalloc(). > > The display should not be updated after .remove(), so I think plain > devm_kcalloc() should be fine. > That was precisely my point, that there could be atomic commits even after the driver has been removed (e.g: if using DRM fbdev emulation, user-space can keep the /dev/fb0 opened and continue updating the framebuffer. That's not released until the fd is closed and struct fb_ops .fb_destroy called. But that's a general rule in DRM, any user-visible resource must not be allocated using device managed resources and instead use the drm_device managed resources helpers. To make sure that are not released until the last call to drm_dev_put(): https://docs.kernel.org/gpu/drm-internals.html#device-instance-and-driver-handling -- Best regards, Javier Martinez Canillas Core Platforms Red Hat
Re: [PATCH v2 5/6] drm/amdgpu: Log IBs and ring name at coredump
Em 14/07/2023 04:57, Christian König escreveu: Am 13.07.23 um 23:32 schrieb André Almeida: Log the IB addresses used by the hung job along with the stuck ring name. Note that due to nested IBs, the one that caused the reset itself may be in not listed address. Signed-off-by: André Almeida --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 3 +++ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 31 +- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index e1cc83a89d46..cfeaf93934fd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1086,6 +1086,9 @@ struct amdgpu_coredump_info { struct amdgpu_task_info reset_task_info; struct timespec64 reset_time; bool reset_vram_lost; + u64 *ibs; + u32 num_ibs; + char ring_name[16]; }; #endif diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 07546781b8b8..431ccc3d7857 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -5008,12 +5008,24 @@ static ssize_t amdgpu_devcoredump_read(char *buffer, loff_t offset, coredump->adev->reset_dump_reg_value[i]); } + if (coredump->num_ibs) { + drm_printf(, "IBs:\n"); + for (i = 0; i < coredump->num_ibs; i++) + drm_printf(, "\t[%d] 0x%llx\n", i, coredump->ibs[i]); + } + + if (coredump->ring_name[0] != '\0') + drm_printf(, "ring name: %s\n", coredump->ring_name); + return count - iter.remain; } static void amdgpu_devcoredump_free(void *data) { - kfree(data); + struct amdgpu_coredump_info *coredump = data; + + kfree(coredump->ibs); + kfree(coredump); } static void amdgpu_coredump(struct amdgpu_device *adev, bool vram_lost, @@ -5021,6 +5033,8 @@ static void amdgpu_coredump(struct amdgpu_device *adev, bool vram_lost, { struct amdgpu_coredump_info *coredump; struct drm_device *dev = adev_to_drm(adev); + struct amdgpu_job *job = reset_context->job; + int i; coredump = kmalloc(sizeof(*coredump), GFP_NOWAIT); @@ -5038,6 +5052,21 @@ static void amdgpu_coredump(struct amdgpu_device *adev, bool vram_lost, coredump->adev = adev; + if (job && job->num_ibs) { I really really really don't want any dependency of the core dump feature towards the job. Because of the lifetime of job? Do you think implementing amdgpu_job_get()/put() would help here? What we could do is to record the first executed IB VAs in the hw fence, but I'm not sure how useful this is in the first place. I see, any hint here of the timedout job would be helpful AFAIK. We have some internal feature in progress to query the VA of the draw command which cause the waves currently executing in the SQ to be retrieved. + struct amdgpu_ring *ring = to_amdgpu_ring(job->base.sched); + u32 num_ibs = job->num_ibs; + + coredump->ibs = kmalloc_array(num_ibs, sizeof(coredump->ibs), GFP_NOWAIT); This can fail pretty easily. Because of its size? Christian. + if (coredump->ibs) + coredump->num_ibs = num_ibs; + + for (i = 0; i < coredump->num_ibs; i++) + coredump->ibs[i] = job->ibs[i].gpu_addr; + + if (ring) + strncpy(coredump->ring_name, ring->name, 16); + } + ktime_get_ts64(>reset_time); dev_coredumpm(dev->dev, THIS_MODULE, coredump, 0, GFP_NOWAIT,
Re: [PATCH v2 4/6] drm/amdgpu: Limit info in coredump for kernel threads
Em 14/07/2023 04:52, Christian König escreveu: Am 13.07.23 um 23:32 schrieb André Almeida: If a kernel thread caused the reset, the information available to be logged will be limited, so return early in the dump function. Why? The register values and vram lost state should still be valid. Fair enough, I was thinking about the new added information, such as ring and job, that won't be around for this type of thread. I'll drop this patch for the next version. Christian. Signed-off-by: André Almeida --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index e80670420586..07546781b8b8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -4988,10 +4988,14 @@ static ssize_t amdgpu_devcoredump_read(char *buffer, loff_t offset, drm_printf(, "kernel: " UTS_RELEASE "\n"); drm_printf(, "module: " KBUILD_MODNAME "\n"); drm_printf(, "time: %lld.%09ld\n", coredump->reset_time.tv_sec, coredump->reset_time.tv_nsec); - if (coredump->reset_task_info.pid) + if (coredump->reset_task_info.pid) { drm_printf(, "process_name: %s PID: %d\n", coredump->reset_task_info.process_name, coredump->reset_task_info.pid); + } else { + drm_printf(, "GPU reset caused by a kernel thread\n"); + return count - iter.remain; + } if (coredump->reset_vram_lost) drm_printf(, "VRAM is lost due to GPU reset!\n");
[PATCH 2/2] backlight: lp855x: Catch errors when changing brightness
The lp855x_bl_update_status function's return type is int, but it always returns 0, without checking for the results of the write_byte/pwm_ctrl functions called within. Make this function return the return values of the functions it calls, and modify the lp855x_pwm_ctrl function to return errors. Signed-off-by: Artur Weber --- drivers/video/backlight/lp855x_bl.c | 13 - 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/video/backlight/lp855x_bl.c b/drivers/video/backlight/lp855x_bl.c index 349ec324bc1e..61a7f45bfad8 100644 --- a/drivers/video/backlight/lp855x_bl.c +++ b/drivers/video/backlight/lp855x_bl.c @@ -217,7 +217,7 @@ static int lp855x_configure(struct lp855x *lp) return ret; } -static void lp855x_pwm_ctrl(struct lp855x *lp, int br, int max_br) +static int lp855x_pwm_ctrl(struct lp855x *lp, int br, int max_br) { struct pwm_state state; @@ -234,23 +234,26 @@ static void lp855x_pwm_ctrl(struct lp855x *lp, int br, int max_br) state.duty_cycle = div_u64(br * state.period, max_br); state.enabled = state.duty_cycle; - pwm_apply_state(lp->pwm, ); + return pwm_apply_state(lp->pwm, ); } static int lp855x_bl_update_status(struct backlight_device *bl) { struct lp855x *lp = bl_get_data(bl); int brightness = bl->props.brightness; + int ret; if (bl->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK)) brightness = 0; if (lp->mode == PWM_BASED) - lp855x_pwm_ctrl(lp, brightness, bl->props.max_brightness); + ret = lp855x_pwm_ctrl(lp, brightness, + bl->props.max_brightness); else if (lp->mode == REGISTER_BASED) - lp855x_write_byte(lp, lp->cfg->reg_brightness, (u8)brightness); + ret = lp855x_write_byte(lp, lp->cfg->reg_brightness, + (u8)brightness); - return 0; + return ret; } static const struct backlight_ops lp855x_bl_ops = { -- 2.41.0
[PATCH 1/2] backlight: lp855x: Initialize PWM state on first brightness change
As pointed out by Uwe Kleine-König[1], the changes introduced in commit c1ff7da03e16 ("video: backlight: lp855x: Get PWM for PWM mode during probe") caused the PWM state set up by the bootloader to be re-set when the driver is probed. This differs from the behavior from before that patch, where the PWM state would be initialized on the first brightness change. Fix this by moving the PWM state initialization into the PWM control function. Add a new variable, needs_pwm_init, to the device info struct to allow us to check whether we need the initialization, or whether it has already been done. [1] https://lore.kernel.org/lkml/20230614083953.e4kkweddjz7wz...@pengutronix.de/ Fixes: c1ff7da03e16 ("video: backlight: lp855x: Get PWM for PWM mode during probe") Signed-off-by: Artur Weber --- drivers/video/backlight/lp855x_bl.c | 20 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/video/backlight/lp855x_bl.c b/drivers/video/backlight/lp855x_bl.c index 1c9e921bca14..349ec324bc1e 100644 --- a/drivers/video/backlight/lp855x_bl.c +++ b/drivers/video/backlight/lp855x_bl.c @@ -71,6 +71,7 @@ struct lp855x { struct device *dev; struct lp855x_platform_data *pdata; struct pwm_device *pwm; + bool needs_pwm_init; struct regulator *supply; /* regulator for VDD input */ struct regulator *enable; /* regulator for EN/VDDIO input */ }; @@ -220,7 +221,15 @@ static void lp855x_pwm_ctrl(struct lp855x *lp, int br, int max_br) { struct pwm_state state; - pwm_get_state(lp->pwm, ); + if (lp->needs_pwm_init) { + pwm_init_state(lp->pwm, ); + /* Legacy platform data compatibility */ + if (lp->pdata->period_ns > 0) + state.period = lp->pdata->period_ns; + lp->needs_pwm_init = false; + } else { + pwm_get_state(lp->pwm, ); + } state.duty_cycle = div_u64(br * state.period, max_br); state.enabled = state.duty_cycle; @@ -387,7 +396,6 @@ static int lp855x_probe(struct i2c_client *cl) const struct i2c_device_id *id = i2c_client_get_device_id(cl); const struct acpi_device_id *acpi_id = NULL; struct device *dev = >dev; - struct pwm_state pwmstate; struct lp855x *lp; int ret; @@ -470,15 +478,11 @@ static int lp855x_probe(struct i2c_client *cl) else return dev_err_probe(dev, ret, "getting PWM\n"); + lp->needs_pwm_init = false; lp->mode = REGISTER_BASED; dev_dbg(dev, "mode: register based\n"); } else { - pwm_init_state(lp->pwm, ); - /* Legacy platform data compatibility */ - if (lp->pdata->period_ns > 0) - pwmstate.period = lp->pdata->period_ns; - pwm_apply_state(lp->pwm, ); - + lp->needs_pwm_init = true; lp->mode = PWM_BASED; dev_dbg(dev, "mode: PWM based\n"); } -- 2.41.0
[PATCH 0/2] backlight: lp855x: Fixes after c1ff7da03e16
Two small fixes after commit c1ff7da03e16 ("video: backlight: lp855x: Get PWM for PWM mode during probe"), stemming from a review[1] by Uwe Kleine-König. [1] https://lore.kernel.org/all/20230614083953.e4kkweddjz7wz...@pengutronix.de/ Signed-off-by: Artur Weber Artur Weber (2): backlight: lp855x: Initialize PWM state on first brightness change backlight: lp855x: Catch errors when changing brightness drivers/video/backlight/lp855x_bl.c | 33 + 1 file changed, 20 insertions(+), 13 deletions(-) base-commit: 7fcd473a6455450428795d20db7afd2691c92336 -- 2.41.0
Re: [PATCH 1/3] drm/drv: use enum drm_minor_type when appropriate
Hi Simon Thanks! Reviewed-by:JamesZhufortheseries.Best Regards! James Zhu On 2023-07-14 06:46, Simon Ser wrote: This makes it easier to figure out what the "type" variable can be set to when reading the implementation of these functions. Signed-off-by: Simon Ser Cc: Christian König Cc: James Zhu Cc: Marek Olšák Cc: Daniel Vetter --- drivers/gpu/drm/drm_drv.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 12687dd9e1ac..3eda026ffac6 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -84,7 +84,7 @@ DEFINE_STATIC_SRCU(drm_unplug_srcu); */ static struct drm_minor **drm_minor_get_slot(struct drm_device *dev, -unsigned int type) +enum drm_minor_type type) { switch (type) { case DRM_MINOR_PRIMARY: @@ -116,7 +116,7 @@ static void drm_minor_alloc_release(struct drm_device *dev, void *data) } } -static int drm_minor_alloc(struct drm_device *dev, unsigned int type) +static int drm_minor_alloc(struct drm_device *dev, enum drm_minor_type type) { struct drm_minor *minor; unsigned long flags; @@ -160,7 +160,7 @@ static int drm_minor_alloc(struct drm_device *dev, unsigned int type) return 0; } -static int drm_minor_register(struct drm_device *dev, unsigned int type) +static int drm_minor_register(struct drm_device *dev, enum drm_minor_type type) { struct drm_minor *minor; unsigned long flags; @@ -203,7 +203,7 @@ static int drm_minor_register(struct drm_device *dev, unsigned int type) return ret; } -static void drm_minor_unregister(struct drm_device *dev, unsigned int type) +static void drm_minor_unregister(struct drm_device *dev, enum drm_minor_type type) { struct drm_minor *minor; unsigned long flags;
Re: [PATCH 2/3] drm/scheduler: Fix UAF in drm_sched_fence_get_timeline_name
On 14/07/2023 19.18, Christian König wrote: Am 14.07.23 um 12:06 schrieb Asahi Lina: On 14/07/2023 18.57, Christian König wrote: Am 14.07.23 um 11:49 schrieb Asahi Lina: On 14/07/2023 17.43, Christian König wrote: Am 14.07.23 um 10:21 schrieb Asahi Lina: A signaled scheduler fence can outlive its scheduler, since fences are independencly reference counted. Therefore, we can't reference the scheduler in the get_timeline_name() implementation. Fixes oopses on `cat /sys/kernel/debug/dma_buf/bufinfo` when shared dma-bufs reference fences from GPU schedulers that no longer exist. Signed-off-by: Asahi Lina --- drivers/gpu/drm/scheduler/sched_entity.c | 7 ++- drivers/gpu/drm/scheduler/sched_fence.c | 4 +++- include/drm/gpu_scheduler.h | 5 + 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c index b2bbc8a68b30..17f35b0b005a 100644 --- a/drivers/gpu/drm/scheduler/sched_entity.c +++ b/drivers/gpu/drm/scheduler/sched_entity.c @@ -389,7 +389,12 @@ static bool drm_sched_entity_add_dependency_cb(struct drm_sched_entity *entity) /* * Fence is from the same scheduler, only need to wait for - * it to be scheduled + * it to be scheduled. + * + * Note: s_fence->sched could have been freed and reallocated + * as another scheduler. This false positive case is okay, as if + * the old scheduler was freed all of its jobs must have + * signaled their completion fences. This is outright nonsense. As long as an entity for a scheduler exists it is not allowed to free up this scheduler. So this function can't be called like this. As I already explained, the fences can outlive their scheduler. That means *this* entity certainly exists for *this* scheduler, but the *dependency* fence might have come from a past scheduler that was already destroyed along with all of its entities, and its address reused. Well this is function is not about fences, this function is a callback for the entity. That deals with dependency fences, which could have come from any arbitrary source, including another entity and another scheduler. No, they can't. Signaling is certainly mandatory to happen before things are released even if we allow to decouple the dma_fence from it's issuer. That's exactly what I'm saying in my comment. That the fence must be signaled if its creator no longer exists, therefore it's okay to inadvertently wait on its scheduled fence instead of its finished fence (if that one was intended) since everything needs to be signaled at that point anyway. Christian, I'm really getting tired of your tone. I don't appreciate being told my comments are "outright nonsense" when you don't even take the time to understand what the issue is and what I'm trying to do/document. If you aren't interested in working with me, I'm just going to give up on drm_sched, wait until Rust gets workqueue support, and reimplement it in Rust. You can keep your broken fence lifetime semantics and I'll do my own thing. I'm certainly trying to help here, but you seem to have unrealistic expectations. I don't think expecting not to be told my changes are "outright nonsense" is an unrealistic expectation. If you think it is, maybe that's yet another indicator of the culture problems the kernel community has... Well I'm just pointing out that you don't seem to understand the background of the things and just think this is a bug instead of intentional behavior. I made a change, I explained why that change works with a portion of the existing code by updating a comment, and you called that nonsense. It's not even a bug, I'm trying to explain why this part isn't a bug even with the expectation that fences don't outlive the scheduler. This is because I went through the code trying to find problems this approach would cause, ran into this tricky case, thought about it for a while, realized it wasn't a problem, and figured it needed a comment. I perfectly understand what you are trying to do, but you don't seem to understand that this functionality here isn't made for your use case. I do, that's why I'm trying to change things. Right now, this functionality isn't even properly documented, which is why I thought it could be used for my use case, and slowly discovered otherwise. Daniel suggested documenting it, then fixing the mismatches between documentation and reality, which is what I'm doing here. Well I know Daniel for something like 10-15 years or so, I'm pretty sure that he meant that you document the existing state because otherwise this goes against usual patch submission approaches. We can adjust the functionality to better match your requirements, but you can't say it is broken because it doesn't work when you use it not in the way it is intended to be used. I'm saying the idea that a
Re: [PATCH 5/5 v4] accel/qaic: Fix a leak in map_user_pages()
On 7/11/2023 1:51 PM, Dan Carpenter wrote: If get_user_pages_fast() allocates some pages but not as many as we wanted, then the current code leaks those pages. Call put_page() on the pages before returning. Fixes: 129776ac2e38 ("accel/qaic: Add control path") Signed-off-by: Dan Carpenter Reviewed-by: Pranjal Ramajor Asha Kanojiya
Re: [PATCH 4/5 v4] accel/qaic: move and expand integer overflow checks for map_user_pages()
On 7/11/2023 1:51 PM, Dan Carpenter wrote: The integer overflow checking for find_and_map_user_pages() was done in encode_dma(). Presumably this was to do it before the allocation. But it's not super important that the failure path is a fast path and it hurts readability to put the check so far from the where the variable is used. Move the check to find_and_map_user_pages() instead and add some more additional potential integer overflow checks. Fixes: 129776ac2e38 ("accel/qaic: Add control path") Signed-off-by: Dan Carpenter --- no change drivers/accel/qaic/qaic_control.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/accel/qaic/qaic_control.c b/drivers/accel/qaic/qaic_control.c index 23680f5f1902..d5ce36cb351f 100644 --- a/drivers/accel/qaic/qaic_control.c +++ b/drivers/accel/qaic/qaic_control.c @@ -402,6 +402,12 @@ static int find_and_map_user_pages(struct qaic_device *qdev, xfer_start_addr = in_trans->addr + resources->xferred_dma_size; + if (in_trans->size == 0 || + in_trans->addr + in_trans->size < in_trans->addr || + in_trans->addr + resources->xferred_dma_size < in_trans->addr || Why not use xfer_start_addr ? + in_trans->size + offset_in_page(xfer_start_addr) < resources->xferred_dma_size) + return -EINVAL; + need_pages = DIV_ROUND_UP(in_trans->size + offset_in_page(xfer_start_addr) - resources->xferred_dma_size, PAGE_SIZE); @@ -564,9 +570,6 @@ static int encode_dma(struct qaic_device *qdev, void *trans, struct wrapper_list QAIC_MANAGE_EXT_MSG_LENGTH) return -ENOMEM; - if (in_trans->addr + in_trans->size < in_trans->addr || !in_trans->size) - return -EINVAL; - xfer = kmalloc(sizeof(*xfer), GFP_KERNEL); if (!xfer) return -ENOMEM;
Re: [PATCH 3/5 v4] accel/qaic: Add consistent integer overflow checks
On 7/11/2023 1:51 PM, Dan Carpenter wrote: The encode_dma() function has integer overflow checks. The encode_passthrough(), encode_activate() and encode_status() functions did not. I added integer overflow checking everywhere. I also updated the integer overflow checking in encode_dma() to use size_add() so everything is consistent. Fixes: 129776ac2e38 ("accel/qaic: Add control path") Signed-off-by: Dan Carpenter --- v2: no change drivers/accel/qaic/qaic_control.c | 14 ++ 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/accel/qaic/qaic_control.c b/drivers/accel/qaic/qaic_control.c index 752b67aff777..23680f5f1902 100644 --- a/drivers/accel/qaic/qaic_control.c +++ b/drivers/accel/qaic/qaic_control.c @@ -367,7 +367,7 @@ static int encode_passthrough(struct qaic_device *qdev, void *trans, struct wrap if (in_trans->hdr.len % 8 != 0) return -EINVAL; - if (msg_hdr_len + in_trans->hdr.len > QAIC_MANAGE_EXT_MSG_LENGTH) + if (size_add(msg_hdr_len, in_trans->hdr.len) > QAIC_MANAGE_EXT_MSG_LENGTH) return -ENOSPC; trans_wrapper = add_wrapper(wrappers, @@ -558,12 +558,10 @@ static int encode_dma(struct qaic_device *qdev, void *trans, struct wrapper_list msg = >msg; msg_hdr_len = le32_to_cpu(msg->hdr.len); - if (msg_hdr_len > (UINT_MAX - QAIC_MANAGE_EXT_MSG_LENGTH)) - return -EINVAL; - /* There should be enough space to hold at least one ASP entry. */ - if (msg_hdr_len + sizeof(*out_trans) + sizeof(struct wire_addr_size_pair) > - QAIC_MANAGE_EXT_MSG_LENGTH) + if (size_add(msg_hdr_len, +sizeof(*out_trans) + sizeof(struct wire_addr_size_pair)) > Can we have the entire size_add() on same line? +QAIC_MANAGE_EXT_MSG_LENGTH) return -ENOMEM; if (in_trans->addr + in_trans->size < in_trans->addr || !in_trans->size) @@ -635,7 +633,7 @@ static int encode_activate(struct qaic_device *qdev, void *trans, struct wrapper msg = >msg; msg_hdr_len = le32_to_cpu(msg->hdr.len); - if (msg_hdr_len + sizeof(*out_trans) > QAIC_MANAGE_MAX_MSG_LENGTH) + if (size_add(msg_hdr_len, sizeof(*out_trans)) > QAIC_MANAGE_MAX_MSG_LENGTH) return -ENOSPC; if (!in_trans->queue_size) @@ -719,7 +717,7 @@ static int encode_status(struct qaic_device *qdev, void *trans, struct wrapper_l msg = >msg; msg_hdr_len = le32_to_cpu(msg->hdr.len); - if (msg_hdr_len + in_trans->hdr.len > QAIC_MANAGE_MAX_MSG_LENGTH) + if (size_add(msg_hdr_len, in_trans->hdr.len) > QAIC_MANAGE_MAX_MSG_LENGTH) return -ENOSPC; trans_wrapper = add_wrapper(wrappers, sizeof(*trans_wrapper)); Reviewed-by: Pranjal Ramajor Asha Kanojiya
Re: [PATCH 2/5 v4] accel/qaic: tighten bounds checking in decode_message()
On 7/11/2023 1:50 PM, Dan Carpenter wrote: Copy the bounds checking from encode_message() to decode_message(). This patch addresses the following concerns. Ensure that there is enough space for at least one header so that we don't have a negative size later. if (msg_hdr_len < sizeof(*trans_hdr)) Ensure that we have enough space to read the next header from the msg->data. if (msg_len > msg_hdr_len - sizeof(*trans_hdr)) return -EINVAL; Check that the trans_hdr->len is not below the minimum size: if (hdr_len < sizeof(*trans_hdr)) This minimum check ensures that we don't corrupt memory in decode_passthrough() when we do. memcpy(out_trans->data, in_trans->data, len - sizeof(in_trans->hdr)); And finally, use size_add() to prevent an integer overflow: if (size_add(msg_len, hdr_len) > msg_hdr_len) Fixes: 129776ac2e38 ("accel/qaic: Add control path") Signed-off-by: Dan Carpenter Reviewed-by: Pranjal Ramajor Asha Kanojiya
Re: [PATCH 1/5 v4] accel/qaic: tighten bounds checking in encode_message()
On 7/11/2023 1:50 PM, Dan Carpenter wrote: There are several issues in this code. The check at the start of the loop: if (user_len >= user_msg->len) { This check does not ensure that we have enough space for the trans_hdr (8 bytes). Instead the check needs to be: if (user_len > user_msg->len - sizeof(*trans_hdr)) { That subtraction is done as an unsigned long we want to avoid negatives. Add a lower bound to the start of the function. if (user_msg->len < sizeof(*trans_hdr)) There is a second integer underflow which can happen if trans_hdr->len is zero inside the encode_passthrough() function. memcpy(out_trans->data, in_trans->data, in_trans->hdr.len - sizeof(in_trans->hdr)); Instead of adding a check to encode_passthrough() it's better to check in this central place. Add that check: if (trans_hdr->len < sizeof(trans_hdr) The final concern is that the "user_len + trans_hdr->len" might have an integer overflow bug. Use size_add() to prevent that. - if (user_len + trans_hdr->len > user_msg->len) { + if (size_add(user_len, trans_hdr->len) > user_msg->len) { Fixes: 129776ac2e38 ("accel/qaic: Add control path") Signed-off-by: Dan Carpenter Reviewed-by: Pranjal Ramajor Asha Kanojiya
Re: [PATCH 6/8] drm/fb-helper: Pass buffer format via drm_fb_helper_surface_size
Hi Javier, On Fri, Jul 14, 2023 at 12:25 PM Javier Martinez Canillas wrote: > Geert Uytterhoeven writes: > > drm_fb_helper_single_fb_probe() first calls drm_fb_helper_find_sizes(), > > followed by drm_fbdev_generic_helper_fb_probe(): > > - The former tries to find a suitable buffer format, taking into > > account limitations of the whole display pipeline, > > - The latter just calls drm_mode_legacy_fb_format() again. > > > > Simplify this by passing the buffer format between these functions > > via a new buffer format member in the drm_fb_helper_surface_size > > structure. > > > > Signed-off-by: Geert Uytterhoeven > > --- > > [...] > > > - drm_dbg_kms(dev, "surface width(%d), height(%d) and bpp(%d)\n", > > + drm_info(dev, "surface width(%d), height(%d), bpp(%d) and > > format(%p4cc)\n", > > You are promoting a debug printout here to info but that change is not > mentioned in the commit message. If you think this will be useful, maybe > do it as a separate patch ? Oops, that was unintentional. Will fix in v2. > The rest of the patch looks good to me though. > > Reviewed-by: Javier Martinez Canillas Thanks! Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Re: [PATCH 5/8] drm/client: Convert drm_mode_create_dumb() to drm_mode_addfb2()
Hi Simon, On Fri, Jul 14, 2023 at 1:01 PM Simon Ser wrote: > On Thursday, July 13th, 2023 at 15:17, Geert Uytterhoeven > wrote: > > Currently drm_client_buffer_addfb() uses the legacy drm_mode_addfb(), > > which uses bpp and depth to guess the wanted buffer format. > > However, drm_client_buffer_addfb() already knows the exact buffer > > format, so there is no need to convert back and forth between buffer > > format and bpp/depth, and the function can just call drm_mode_addfb2() > > directly instead. > > By any chance, is the commit message wrong? The title refers to > drm_mode_create_dumb(), but the description and code refer to > drm_client_buffer_addfb(). Yes it is, thanks. Originally, I had copied-and-pasted the wrong function name. I thought I had fixed all references, but apparently I missed the one-line summary :-( Will fix in v2. Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Re: [PATCH 4/8] drm/ssd130x: Add support for DRM_FORMAT_R1
Hi Javier, On Fri, Jul 14, 2023 at 12:14 PM Javier Martinez Canillas wrote: > Geert Uytterhoeven writes: > Thanks a lot for your patch, this has been on my TODO for some time! > > > The native display format is monochrome light-on-dark (R1). > > Hence add support for R1, so monochrome applications can avoid the > > overhead of back-and-forth conversions between R1 and XR24. > > > > Signed-off-by: Geert Uytterhoeven > > --- > > This work interfered with commit 49d7d581ceaf4cf8 ("drm/ssd130x: Don't > > allocate buffers on each plane update") in drm-misc/for-linux-next, > > which always allocates the buffer upfront, while it is no longer needed > > when never using XR24. > > you mean R1 here, right ? I did mean R1. I think you missed the double negation. > It's still used in ssd130x_clear_screen() though. I guess it became worthwhile to make ssd130x_clear_screen() do memset(data_array, 0, ...) and call ssd130x_write_data() directly, avoiding the pointless reshuffling of black pixels in ssd130x_update_rect()? > > Probably ssd130x->buffer should be allocated on first use. > > Yes, that makes sense. > > > And why not allocate the buffers using devm_kcalloc()? > > I think there are some lifetimes discrepancies between struct device and > struct drm_device objects. But we could use drm_device managed resources > helpers, i.e: drmm_kzalloc(). The display should not be updated after .remove(), so I think plain devm_kcalloc() should be fine. > > drivers/gpu/drm/solomon/ssd130x.c | 57 ++- > > 1 file changed, 40 insertions(+), 17 deletions(-) > > > > [...] > > > + case DRM_FORMAT_XRGB: > > + dst_pitch = DIV_ROUND_UP(drm_rect_width(rect), 8); > > + buf = ssd130x->buffer; > > + if (!buf) > > + return 0; > > + > > I think this check is not needed anymore now that the driver won't attempt > to update planes for disabled CRTCs ? Probably. We do need it here when allocating on first use. > It's OK for me to be paranoid though, specially after the other issue that > you found. So I'll let you decide if you think is worth to keep the check. I kept the check as I only moved/shifted that part of the code. > Reviewed-by: Javier Martinez Canillas Thanks! Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
[PATCH v4] drm/syncobj: add IOCTL to register an eventfd
Introduce a new DRM_IOCTL_SYNCOBJ_EVENTFD IOCTL which signals an eventfd from a syncobj. This is useful for Wayland compositors to handle wait-before-submit. Wayland clients can send a timeline point to the compositor before the point has materialized yet, then compositors can wait for the point to materialize via this new IOCTL. The existing DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT IOCTL is not suitable because it blocks. Compositors want to integrate the wait with their poll(2)-based event loop. Requirements for new uAPI: - User-space patch: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4262 - IGT: https://lists.freedesktop.org/archives/igt-dev/2023-July/057893.html v2: - Wait for fence when flags is zero - Improve documentation (Pekka) - Rename IOCTL (Christian) - Fix typo in drm_syncobj_add_eventfd() (Christian) v3: - Link user-space + IGT patches - Add reference from overview docs v4: fix IOCTL number conflict with GETFB2 (Vitaly Prosyak) Signed-off-by: Simon Ser Reviewed-by: Christian König Acked-by: Pekka Paalanen Cc: Jason Ekstrand Cc: Daniel Vetter Cc: Bas Nieuwenhuizen Cc: Daniel Stone Cc: James Jones Cc: Austin Shafer Cc: Vitaly Prosyak --- drivers/gpu/drm/drm_internal.h | 2 + drivers/gpu/drm/drm_ioctl.c| 2 + drivers/gpu/drm/drm_syncobj.c | 147 +++-- include/drm/drm_syncobj.h | 6 +- include/uapi/drm/drm.h | 23 ++ 5 files changed, 173 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h index d7e023bbb0d5..ba12acd55139 100644 --- a/drivers/gpu/drm/drm_internal.h +++ b/drivers/gpu/drm/drm_internal.h @@ -245,6 +245,8 @@ int drm_syncobj_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file_private); int drm_syncobj_timeline_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file_private); +int drm_syncobj_eventfd_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_private); int drm_syncobj_reset_ioctl(struct drm_device *dev, void *data, struct drm_file *file_private); int drm_syncobj_signal_ioctl(struct drm_device *dev, void *data, diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 8e9afe7af19c..f03ffbacfe9b 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -701,6 +701,8 @@ static const struct drm_ioctl_desc drm_ioctls[] = { DRM_RENDER_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT, drm_syncobj_timeline_wait_ioctl, DRM_RENDER_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_EVENTFD, drm_syncobj_eventfd_ioctl, + DRM_RENDER_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_RESET, drm_syncobj_reset_ioctl, DRM_RENDER_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_SIGNAL, drm_syncobj_signal_ioctl, diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 0c2be8360525..0f1cb70413af 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -136,6 +136,10 @@ * requirement is inherited from the wait-before-signal behavior required by * the Vulkan timeline semaphore API. * + * Alternatively, _IOCTL_SYNCOBJ_EVENTFD can be used to wait without + * blocking: an eventfd will be signaled when the syncobj is. This is useful to + * integrate the wait in an event loop. + * * * Import/export of syncobjs * - @@ -185,6 +189,7 @@ #include #include +#include #include #include #include @@ -212,6 +217,20 @@ struct syncobj_wait_entry { static void syncobj_wait_syncobj_func(struct drm_syncobj *syncobj, struct syncobj_wait_entry *wait); +struct syncobj_eventfd_entry { + struct list_head node; + struct dma_fence *fence; + struct dma_fence_cb fence_cb; + struct drm_syncobj *syncobj; + struct eventfd_ctx *ev_fd_ctx; + u64 point; + u32 flags; +}; + +static void +syncobj_eventfd_entry_func(struct drm_syncobj *syncobj, + struct syncobj_eventfd_entry *entry); + /** * drm_syncobj_find - lookup and reference a sync object. * @file_private: drm file private pointer @@ -274,6 +293,27 @@ static void drm_syncobj_remove_wait(struct drm_syncobj *syncobj, spin_unlock(>lock); } +static void +syncobj_eventfd_entry_free(struct syncobj_eventfd_entry *entry) +{ + eventfd_ctx_put(entry->ev_fd_ctx); + dma_fence_put(entry->fence); + /* This happens either inside the syncobj lock, or after the node has +* already been removed from the list */ + list_del(>node); + kfree(entry); +} + +static void +drm_syncobj_add_eventfd(struct drm_syncobj *syncobj, + struct syncobj_eventfd_entry *entry) +{ + spin_lock(>lock); +
Re: [Freedreno] [PATCH RFC v1 00/52] drm/crtc: Rename struct drm_crtc::dev to drm_dev
Hi Am 13.07.23 um 17:14 schrieb Tvrtko Ursulin: On 13/07/2023 16:09, Thomas Zimmermann wrote: Hi Am 13.07.23 um 16:41 schrieb Sean Paul: On Thu, Jul 13, 2023 at 9:04 AM Uwe Kleine-König wrote: hello Sean, On Wed, Jul 12, 2023 at 02:31:02PM -0400, Sean Paul wrote: I'd really prefer this patch (series or single) is not accepted. This will cause problems for everyone cherry-picking patches to a downstream kernel (LTS or distro tree). I usually wouldn't expect sympathy here, but the questionable benefit does not outweigh the cost IM[biased]O. I agree that for backports this isn't so nice. However with the split approach (that was argumented against here) it's not soo bad. Patch #1 (and similar changes for the other affected structures) could be trivially backported and with that it doesn't matter if you write dev or drm (or whatever name is chosen in the end); both work in the same way. Patch #1 avoids the need to backport the entire set, however every change occuring after the rename patches will cause conflicts on future cherry-picks. Downstream kernels will have to backport the whole set. Backporting the entire set will create an epoch in downstream kernels where cherry-picking patches preceding this set will need to undergo conflict resolution as well. As mentioned in my previous email, I don't expect sympathy here, it's part of maintaining a downstream kernel, but there is a real cost to kernel consumers. But even with the one-patch-per-rename approach I'd consider the renaming a net win, because ease of understanding code has a big value. It's value is not so easy measurable as "conflicts when backporting", but it also matters in say two years from now, while backporting shouldn't be an issue then any more. You've rightly identified the conjecture in your statement. I've been on both sides of the argument, having written/maintained drm code upstream and cherry-picked changes to a downstream kernel. Perhaps it's because drm's definition of dev is ingrained in my muscle memory, or maybe it's because I don't do a lot of upstream development these days, but I just have a hard time seeing the benefit here. I can only second what Sean writes. I've done quite a bit of backporting of DRM code. It's hard already. And this kind of change is going to to affect almost every backported DRM patch in the coming years. Not just for distribution kernels, but also for upstream's stable series. It's really only possible to do this change over many releases while keeping compatible with the old name. So the more I think about it, the less I like this change. I've done my share of backporting, and still am doing it, so I can say I dislike it as much as anyone, however.. Is this an argument which the kernel as a wider entity typically accepts? If not could it be a slippery slope to start a precedent? IMHO upstream patches should only be judged by their effect on the upstream. Backporting, API stability, out-of-tree drivers, etc should not be a concern. I think that we (the DRM devs) are mostly living up to that ideal. OTOH if a change has been accepted, it's fair to ask how to make it in the least intrusive way. But with this change, it doesn't add up for me. The benefit to Linux is rather cosmetic. And the possible downsides are significant even if we ignore downstream distribution kernels. Merging between DRM trees will be affected, backporting into stable kernels as well, the rename will mess up git blame with rename commits. Best regards Thomas It is a honest question - I am not familiar if there were or were not any similar discussions in the past. My gut feeling is that *if* there is a consensus that something _improves_ the code base significantly, backporting pains should probably not be weighted very heavily as a contra argument. Regards, Tvrtko -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg) OpenPGP_signature Description: OpenPGP digital signature
[PATCH] drm/radeon: ERROR: "foo* bar" should be "foo *bar"
Fix five occurrences of the checkpatch.pl error: ERROR: "foo* bar" should be "foo *bar" ERROR: that open brace { should be on the previous line Signed-off-by: Jie Shi --- drivers/gpu/drm/radeon/radeon_audio.c | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c index d6ccaf24ee0c..a010bc2c155c 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.c +++ b/drivers/gpu/drm/radeon/radeon_audio.c @@ -35,15 +35,14 @@ void dce6_audio_enable(struct radeon_device *rdev, struct r600_audio_pin *pin, u8 enable_mask); -struct r600_audio_pin* r600_audio_get_pin(struct radeon_device *rdev); -struct r600_audio_pin* dce6_audio_get_pin(struct radeon_device *rdev); +struct r600_audio_pin *r600_audio_get_pin(struct radeon_device *rdev); +struct r600_audio_pin *dce6_audio_get_pin(struct radeon_device *rdev); static void radeon_audio_hdmi_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode); static void radeon_audio_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode); -static const u32 pin_offsets[7] = -{ +static const u32 pin_offsets[7] = { (0x5e00 - 0x5e00), (0x5e18 - 0x5e00), (0x5e30 - 0x5e00), @@ -359,7 +358,7 @@ static void radeon_audio_write_latency_fields(struct drm_encoder *encoder, radeon_encoder->audio->write_latency_fields(encoder, connector, mode); } -struct r600_audio_pin* radeon_audio_get_pin(struct drm_encoder *encoder) +struct r600_audio_pin *radeon_audio_get_pin(struct drm_encoder *encoder) { struct radeon_device *rdev = encoder->dev->dev_private; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); @@ -526,7 +525,7 @@ static void radeon_audio_calc_cts(unsigned int clock, int *CTS, int *N, int freq *N, *CTS, freq); } -static const struct radeon_hdmi_acr* radeon_audio_acr(unsigned int clock) +static const struct radeon_hdmi_acr *radeon_audio_acr(unsigned int clock) { static struct radeon_hdmi_acr res; u8 i;
Re: [PATCH 5/8] drm/client: Convert drm_mode_create_dumb() to drm_mode_addfb2()
On Thursday, July 13th, 2023 at 15:17, Geert Uytterhoeven wrote: > Currently drm_client_buffer_addfb() uses the legacy drm_mode_addfb(), > which uses bpp and depth to guess the wanted buffer format. > However, drm_client_buffer_addfb() already knows the exact buffer > format, so there is no need to convert back and forth between buffer > format and bpp/depth, and the function can just call drm_mode_addfb2() > directly instead. By any chance, is the commit message wrong? The title refers to drm_mode_create_dumb(), but the description and code refer to drm_client_buffer_addfb().