[GIT PULL] Nova changes for v6.16
Hi Dave and Sima, Please pull the following nova changes and other dependencies. There are two minor and trivial conflicts with Linus' tree [1] and the CONFIGFS tree [2]. There is also a minor, but slightly less trivial conflict with the Rust Xarray tree with a resolution in [3]. [1] https://lore.kernel.org/all/20250428123825.4acf2...@canb.auug.org.au/ [2] https://lore.kernel.org/all/20250513135521.44a26...@canb.auug.org.au/ [3] https://lore.kernel.org/all/877c344gmp@kernel.org/ The following changes since commit 0af2f6be1b4281385b618cb86ad946eded089ac8: Linux 6.15-rc1 (2025-04-06 13:11:33 -0700) are available in the Git repository at: https://gitlab.freedesktop.org/drm/nova.git tags/nova-next-v6.16-2025-05-20 for you to fetch changes up to 276c53c66e032c8e7cc0da63555f2742eb1afd69: gpu: drm: nova: select AUXILIARY_BUS instead of depending on it (2025-05-15 20:59:32 +0200) Nova changes for v6.16 auxiliary: - bus abstractions - implementation for driver registration - add sample driver drm: - implement __drm_dev_alloc() - DRM core infrastructure Rust abstractions - device, driver and registration - DRM IOCTL - DRM File - GEM object - IntoGEMObject rework - generically implement AlwaysRefCounted through IntoGEMObject - refactor unsound from_gem_obj() into as_ref() - refactor into_gem_obj() into as_raw() driver-core: - merge topic/device-context-2025-04-17 from driver-core tree - implement Devres::access() - fix: doctest build under `!CONFIG_PCI` - accessor for Device::parent() - fix: conditionally expect `dead_code` for `parent()` - impl TryFrom<&Device> bus devices (PCI, platform) nova-core: - remove completed Vec extentions from task list - register auxiliary device for nova-drm - derive useful traits for Chipset - add missing GA100 chipset - take &Device in Gpu::new() - infrastructure to generate register definitions - fix register layout of NV_PMC_BOOT_0 - move Firmware into own (Rust) module - fix: select AUXILIARY_BUS nova-drm: - initial driver skeleton (depends on drm and auxiliary bus abstractions) - fix: select AUXILIARY_BUS Rust (dependencies): - implement Opaque::zeroed() - implement Revocable::try_access_with() - implement Revocable::access() Alexandre Courbot (11): rust/revocable: add try_access_with() convenience method samples: rust: convert PCI rust sample driver to use try_access_with() gpu: nova-core: derive useful traits for Chipset gpu: nova-core: add missing GA100 definition gpu: nova-core: take bound device in Gpu::new gpu: nova-core: define registers layout using helper macro gpu: nova-core: fix layout of NV_PMC_BOOT_0 gpu: nova-core: move Firmware to firmware module samples: rust: select AUXILIARY_BUS instead of depending on it gpu: nova-core: select AUXILIARY_BUS instead of depending on it gpu: drm: nova: select AUXILIARY_BUS instead of depending on it Andrew Ballance (1): gpu: nova-core: remove completed Vec extentions from task list Asahi Lina (6): rust: drm: ioctl: Add DRM ioctl abstraction rust: drm: add driver abstractions rust: drm: add device abstraction rust: drm: add DRM driver registration rust: drm: file: Add File abstraction rust: drm: gem: Add GEM object abstraction Danilo Krummrich (24): rust: device: implement impl_device_context_deref! rust: device: implement impl_device_context_into_aref! rust: device: implement device context for Device rust: platform: preserve device context in AsRef rust: pci: preserve device context in AsRef rust: device: implement Bound device context rust: pci: move iomap_region() to impl Device rust: devres: require a bound device rust: dma: require a bound device Merge tag 'topic/device-context-2025-04-17' into nova-next rust: pci: impl TryFrom<&Device> for &pci::Device rust: platform: impl TryFrom<&Device> for &platform::Device rust: types: add `Opaque::zeroed` rust: device: implement Device::parent() rust: auxiliary: add auxiliary device / driver abstractions rust: auxiliary: add auxiliary registration samples: rust: add Rust auxiliary driver sample drm: drv: implement __drm_dev_alloc() MAINTAINERS: add DRM Rust source files to DRM DRIVERS rust: revocable: implement Revocable::access() rust: devres: implement Devres::access() samples: rust: pci: take advantage of Devres::access() gpu: nova-core: register auxiliary device for nova-drm drm: nova-drm: add initial driver skeleton Lyude Paul (4): rust: drm: gem: Use NonNull for Object::dev rust: drm: gem: Refactor IntoGEMObject::from_gem_obj() to as_ref() rust: drm: gem: s/into_gem_obj
Re: [PATCH v5 2/2] dt-bindings: display: rockchip: Convert cdn-dp-rockchip.txt to yaml
On 20/05/2025 04:47, Chaoyi Chen wrote: > From: Chaoyi Chen > > Convert cdn-dp-rockchip.txt to yaml. > > Add new "port@1" property which represents the CDN DP output to keep > the same style as the other display interfaces. > > This patch also changes the constraints for "phys" and "extcon". For > the original binding, only one phy and the corresponding extcon can > be specified. In the new binding, one or two phys can be specified. > Since the RK3399 has two DP-USB PHYs, specifying one allows output > via the corresponding PHY, while specifying two lets the driver > choose one PHY for output. This rule also applies to extcon, which > provides the cable state for the corresponding PHY. > > Signed-off-by: Chaoyi Chen > --- > Reviewed-by: Krzysztof Kozlowski Best regards, Krzysztof
Re: [PATCH v4 19/30] drm/msm/dpu: get rid of DPU_MDP_PERIPH_0_REMOVED
On 19/05/2025 18:04, Dmitry Baryshkov wrote: From: Dmitry Baryshkov Continue migration to the MDSS-revision based checks and replace DPU_MDP_PERIPH_0_REMOVED feature bit with the core_major_ver >= 8 check. Signed-off-by: Dmitry Baryshkov Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h | 1 - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 1 - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 1 - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_4_sa8775p.h | 1 - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 1 - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_1_sar2130p.h | 1 - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_2_x1e80100.h | 1 - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 3 --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c | 2 +- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 2 +- 10 files changed, 2 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h index 37c88b393c12d8a04395b6e5dffb67211d2db9cd..ae66c338250664f9306a7d431cfa18ca07a916a5 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h @@ -21,7 +21,6 @@ static const struct dpu_caps sm8650_dpu_caps = { static const struct dpu_mdp_cfg sm8650_mdp = { .name = "top_0", .base = 0, .len = 0x494, - .features = BIT(DPU_MDP_PERIPH_0_REMOVED), .clk_ctrls = { [DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 }, }, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h index 785ca2b2e60f073b0a2db0c0c4ed3b2722de033c..85778071bc1347008dbe4522aeb9ca4fd21aa097 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h @@ -21,7 +21,6 @@ static const struct dpu_caps sc8280xp_dpu_caps = { static const struct dpu_mdp_cfg sc8280xp_mdp = { .name = "top_0", .base = 0x0, .len = 0x494, - .features = BIT(DPU_MDP_PERIPH_0_REMOVED), .clk_ctrls = { [DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 }, [DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0 }, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h index 1401a84e0da5754fd2a3661d1421bb9b998271ca..f9676f804f9132296467bc751e11036696afa942 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h @@ -21,7 +21,6 @@ static const struct dpu_caps sm8450_dpu_caps = { static const struct dpu_mdp_cfg sm8450_mdp = { .name = "top_0", .base = 0x0, .len = 0x494, - .features = BIT(DPU_MDP_PERIPH_0_REMOVED), .clk_ctrls = { [DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 }, [DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0 }, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_4_sa8775p.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_4_sa8775p.h index fbbdce36f0ad99d0b1d32d90627ff5b7f3fc2fc9..7462cfc4cf8de4a10326c83d3341dbee76e437e8 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_4_sa8775p.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_4_sa8775p.h @@ -20,7 +20,6 @@ static const struct dpu_caps sa8775p_dpu_caps = { static const struct dpu_mdp_cfg sa8775p_mdp = { .name = "top_0", .base = 0x0, .len = 0x494, - .features = BIT(DPU_MDP_PERIPH_0_REMOVED), .clk_ctrls = { [DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 }, [DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0 }, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h index cc4413432cfdc636e38a56011d39f18d7e94c23a..695ae7581a88b36fa1f28aa3cd0c9166090e940c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h @@ -21,7 +21,6 @@ static const struct dpu_caps sm8550_dpu_caps = { static const struct dpu_mdp_cfg sm8550_mdp = { .name = "top_0", .base = 0, .len = 0x494, - .features = BIT(DPU_MDP_PERIPH_0_REMOVED), .clk_ctrls = { [DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 }, }, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_1_sar2130p.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_1_sar2130p.h index 32f88533154584dc98a515b1ddef27ab2005fecd..9a25113df5aec527baa514aaa61f2b47c2443d27 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_1_sar2130p.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_1_sar2130p.h @@ -21,7 +21,6 @@ static const struc
Re: [PATCH v5 01/40] drm/gpuvm: Don't require obj lock in destructor path
On Mon, May 19, 2025 at 10:51:24AM -0700, Rob Clark wrote: > From: Rob Clark > > See commit a414fe3a2129 ("drm/msm/gem: Drop obj lock in > msm_gem_free_object()") for justification. I asked for a proper commit message in v4. Only referring to a driver commit and let the people figure out how the driver works and what it does in order to motivate a change in the generic infrastructure is simply unreasonable. > Cc: Danilo Krummrich > Signed-off-by: Rob Clark > --- > drivers/gpu/drm/drm_gpuvm.c | 7 +-- > 1 file changed, 5 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/drm_gpuvm.c b/drivers/gpu/drm/drm_gpuvm.c > index f9eb56f24bef..1e89a98caad4 100644 > --- a/drivers/gpu/drm/drm_gpuvm.c > +++ b/drivers/gpu/drm/drm_gpuvm.c > @@ -1511,7 +1511,9 @@ drm_gpuvm_bo_destroy(struct kref *kref) > drm_gpuvm_bo_list_del(vm_bo, extobj, lock); > drm_gpuvm_bo_list_del(vm_bo, evict, lock); > > - drm_gem_gpuva_assert_lock_held(obj); > + if (kref_read(&obj->refcount) > 0) > + drm_gem_gpuva_assert_lock_held(obj); Again, this is broken. What if the reference count drops to zero right after the kref_read() check, but before drm_gem_gpuva_assert_lock_held() is called? Putting conditionals on a refcount is always suspicious. If you still really want this, please guard it with if (unlikely(gpuvm->flags & DRM_GPUVM_MSM_LEGACY_QUIRK)) and get an explicit waiver from Dave / Sima.
Re: [PATCH v1 1/1] drm/panel: ili9341: Remove unused member from struct ili9341
On 19/05/2025 15:33, Andy Shevchenko wrote: struct device *dev from struct ili9341 is not used anywhere, remove it. Signed-off-by: Andy Shevchenko --- drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c index ff39f5dd4097..2b5bd83933e3 100644 --- a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c @@ -173,7 +173,6 @@ struct ili9341_config { }; struct ili9341 { - struct device *dev; const struct ili9341_config *conf; struct drm_panel panel; struct gpio_desc *reset_gpio; Reviewed-by: Neil Armstrong
[PATCH v2] dummycon: Trigger redraw when switching consoles with deferred takeover
Signal vt subsystem to redraw console when switching to dummycon with deferred takeover enabled. Makes the console switch to fbcon and displays the available output. With deferred takeover enabled, dummycon acts as the placeholder until the first output to the console happens. At that point, fbcon takes over. If the output happens while dummycon is not active, it cannot inform fbcon. This is the case if the vt subsystem runs in graphics mode. A typical graphical boot starts plymouth, a display manager and a compositor; all while leaving out dummycon. Switching to a text-mode console leaves the console with dummycon even if a getty terminal has been started. Returning true from dummycon's con_switch helper signals the vt subsystem to redraw the screen. If there's output available dummycon's con_putc{s} helpers trigger deferred takeover of fbcon, which sets a display mode and displays the output. If no output is available, dummycon remains active. v2: - make the comment slightly more verbose (Javier) Signed-off-by: Thomas Zimmermann Reported-by: Andrei Borzenkov Closes: https://bugzilla.suse.com/show_bug.cgi?id=1242191 Tested-by: Andrei Borzenkov Acked-by: Javier Martinez Canillas Fixes: 83d83bebf401 ("console/fbcon: Add support for deferred console takeover") Cc: Hans de Goede Cc: linux-fb...@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: # v4.19+ --- drivers/video/console/dummycon.c | 18 +- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c index 139049368fdc..7d02470f19b9 100644 --- a/drivers/video/console/dummycon.c +++ b/drivers/video/console/dummycon.c @@ -85,6 +85,15 @@ static bool dummycon_blank(struct vc_data *vc, enum vesa_blank_mode blank, /* Redraw, so that we get putc(s) for output done while blanked */ return true; } + +static bool dummycon_switch(struct vc_data *vc) +{ + /* +* Redraw, so that we get putc(s) for output done while switched +* away. Informs deferred consoles to take over the display. +*/ + return true; +} #else static void dummycon_putc(struct vc_data *vc, u16 c, unsigned int y, unsigned int x) { } @@ -95,6 +104,10 @@ static bool dummycon_blank(struct vc_data *vc, enum vesa_blank_mode blank, { return false; } +static bool dummycon_switch(struct vc_data *vc) +{ + return false; +} #endif static const char *dummycon_startup(void) @@ -124,11 +137,6 @@ static bool dummycon_scroll(struct vc_data *vc, unsigned int top, return false; } -static bool dummycon_switch(struct vc_data *vc) -{ - return false; -} - /* * The console `switch' structure for the dummy console * -- 2.49.0
[PATCH RFT v4 14/14] drm/msm/adreno: Switch to the common UBWC config struct
From: Konrad Dybcio Now that Adreno specifics are out of the way, use the common config (but leave the HBB hardcoding in place until that is wired up on the other side). Acked-by: Dmitry Baryshkov Signed-off-by: Konrad Dybcio --- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 20 - drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 76 ++--- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 6 +-- drivers/gpu/drm/msm/adreno/adreno_gpu.h | 45 +++ 4 files changed, 60 insertions(+), 87 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 650e5bac225f372e819130b891f1d020b464f17f..4ab16ba56741896ba5e0003c5528ec98264afb9a 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -833,8 +833,8 @@ static int a5xx_hw_init(struct msm_gpu *gpu) gpu_write(gpu, REG_A5XX_RBBM_AHB_CNTL2, 0x003F); - BUG_ON(adreno_gpu->ubwc_config.highest_bank_bit < 13); - hbb = adreno_gpu->ubwc_config.highest_bank_bit - 13; + BUG_ON(adreno_gpu->ubwc_config->highest_bank_bit < 13); + hbb = adreno_gpu->ubwc_config->highest_bank_bit - 13; gpu_write(gpu, REG_A5XX_TPL1_MODE_CNTL, hbb << 7); gpu_write(gpu, REG_A5XX_RB_MODE_CNTL, hbb << 1); @@ -1754,6 +1754,7 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev) struct msm_drm_private *priv = dev->dev_private; struct platform_device *pdev = priv->gpu_pdev; struct adreno_platform_config *config = pdev->dev.platform_data; + const struct qcom_ubwc_cfg_data *common_cfg; struct a5xx_gpu *a5xx_gpu = NULL; struct adreno_gpu *adreno_gpu; struct msm_gpu *gpu; @@ -1790,15 +1791,14 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev) /* Set up the preemption specific bits and pieces for each ringbuffer */ a5xx_preempt_init(gpu); - /* Set the highest bank bit */ - if (adreno_is_a540(adreno_gpu) || adreno_is_a530(adreno_gpu)) - adreno_gpu->ubwc_config.highest_bank_bit = 15; - else - adreno_gpu->ubwc_config.highest_bank_bit = 14; + /* Inherit the common config and make some necessary fixups */ + common_cfg = qcom_ubwc_config_get_data(); + if (IS_ERR(common_cfg)) + return ERR_CAST(common_cfg); - /* a5xx only supports UBWC 1.0, these are not configurable */ - adreno_gpu->ubwc_config.macrotile_mode = 0; - adreno_gpu->ubwc_config.ubwc_swizzle = 0x7; + /* Copy the data into the internal struct to drop the const qualifier (temporarily) */ + adreno_gpu->_ubwc_config = *common_cfg; + adreno_gpu->ubwc_config = &adreno_gpu->_ubwc_config; adreno_gpu->uche_trap_base = 0x0001ull; diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index e24c67dbfa6e1f82b86a718b77d6d6867320d580..24c7e70bc336608cc836d00a7e9f4675c07e3b35 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -587,64 +587,70 @@ static void a6xx_set_cp_protect(struct msm_gpu *gpu) static int a6xx_calc_ubwc_config(struct adreno_gpu *gpu) { - /* Inherit the common config and make some necessary fixups */ - gpu->common_ubwc_cfg = qcom_ubwc_config_get_data(); - if (IS_ERR(gpu->common_ubwc_cfg)) - return PTR_ERR(gpu->common_ubwc_cfg); + const struct qcom_ubwc_cfg_data *common_cfg; + struct qcom_ubwc_cfg_data *cfg = &gpu->_ubwc_config; - gpu->ubwc_config.ubwc_swizzle = 0x6; - gpu->ubwc_config.macrotile_mode = 0; - gpu->ubwc_config.highest_bank_bit = 15; + /* Inherit the common config and make some necessary fixups */ + common_cfg = qcom_ubwc_config_get_data(); + if (IS_ERR(common_cfg)) + return PTR_ERR(common_cfg); + + /* Copy the data into the internal struct to drop the const qualifier (temporarily) */ + *cfg = *common_cfg; + + cfg->ubwc_swizzle = 0x6; + cfg->highest_bank_bit = 15; if (adreno_is_a610(gpu)) { - gpu->ubwc_config.highest_bank_bit = 13; - gpu->ubwc_config.ubwc_swizzle = 0x7; + cfg->highest_bank_bit = 13; + cfg->ubwc_swizzle = 0x7; } if (adreno_is_a618(gpu)) - gpu->ubwc_config.highest_bank_bit = 14; + cfg->highest_bank_bit = 14; if (adreno_is_a619(gpu)) /* TODO: Should be 14 but causes corruption at e.g. 1920x1200 on DP */ - gpu->ubwc_config.highest_bank_bit = 13; + cfg->highest_bank_bit = 13; if (adreno_is_a619_holi(gpu)) - gpu->ubwc_config.highest_bank_bit = 13; + cfg->highest_bank_bit = 13; if (adreno_is_a621(gpu)) - gpu->ubwc_config.highest_bank_bit = 13; + cfg->highest_bank_bit = 13; -
Re: [PATCH v2] accel/qaic: Add Reliability, Accessibility, Serviceability (RAS)
Reviewed-by: Maciej Falkowski On 5/16/2025 6:06 PM, Jeff Hugo wrote: AIC100 devices generates Reliability, Availability, Serviceability events via MHI QAIC_STATUS channel. Support such events and print a structured log with details of the events, and if the event describes an uncorrected error, reset the device to put it back into service. As these events may not all be reported via other mechanisms like AER, maintain counts of the number of errors observed for each type. Signed-off-by: Jeff Hugo --- v2: -Fix SPDX comment in header -New line before #endif in header -Add a comment about printk() use -Print err_threshold Documentation/ABI/testing/sysfs-driver-qaic | 18 + MAINTAINERS | 1 + drivers/accel/qaic/Makefile | 1 + drivers/accel/qaic/qaic.h | 8 + drivers/accel/qaic/qaic_drv.c | 6 + drivers/accel/qaic/qaic_ras.c | 642 drivers/accel/qaic/qaic_ras.h | 10 + 7 files changed, 686 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-driver-qaic create mode 100644 drivers/accel/qaic/qaic_ras.c create mode 100644 drivers/accel/qaic/qaic_ras.h diff --git a/Documentation/ABI/testing/sysfs-driver-qaic b/Documentation/ABI/testing/sysfs-driver-qaic new file mode 100644 index ..f794fd734163 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-driver-qaic @@ -0,0 +1,18 @@ +What: /sys/bus/pci/drivers/qaic/:XX:XX.X/ce_count +Date: May 2025 +KernelVersion: 6.17 +Contact: dri-devel@lists.freedesktop.org +Description: Number of correctable errors received from device since driver is loaded. + +What: /sys/bus/pci/drivers/qaic/:XX:XX.X/ue_count +Date: May 2025 +KernelVersion: 6.17 +Contact: dri-devel@lists.freedesktop.org +Description: Number of uncorrectable errors received from device since driver is loaded. + +What: /sys/bus/pci/drivers/qaic/:XX:XX.X/ue_nonfatal_count +Date: May 2025 +KernelVersion: 6.17 +Contact: dri-devel@lists.freedesktop.org +Description: Number of uncorrectable non-fatal errors received from device since driver + is loaded. diff --git a/MAINTAINERS b/MAINTAINERS index fe9773af465a..5801adfe4927 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -19916,6 +19916,7 @@ L: linux-arm-...@vger.kernel.org L:dri-devel@lists.freedesktop.org S:Supported T:git https://gitlab.freedesktop.org/drm/misc/kernel.git +F: Documentation/ABI/testing/sysfs-driver-qaic F:Documentation/accel/qaic/ F:drivers/accel/qaic/ F:include/uapi/drm/qaic_accel.h diff --git a/drivers/accel/qaic/Makefile b/drivers/accel/qaic/Makefile index 35e883515629..1106b876f737 100644 --- a/drivers/accel/qaic/Makefile +++ b/drivers/accel/qaic/Makefile @@ -10,6 +10,7 @@ qaic-y := \ qaic_control.o \ qaic_data.o \ qaic_drv.o \ + qaic_ras.o \ qaic_timesync.o \ sahara.o diff --git a/drivers/accel/qaic/qaic.h b/drivers/accel/qaic/qaic.h index 0dbb8e32e4b9..3fa47385aae4 100644 --- a/drivers/accel/qaic/qaic.h +++ b/drivers/accel/qaic/qaic.h @@ -167,6 +167,14 @@ struct qaic_device { struct workqueue_struct *bootlog_wq; /* Synchronizes access of pages in MHI bootlog device */ struct mutexbootlog_mutex; + /* MHI RAS channel device */ + struct mhi_device *ras_ch; + /* Correctable error count */ + unsigned intce_count; + /* Un-correctable error count */ + unsigned intue_count; + /* Un-correctable non-fatal error count */ + unsigned intue_nf_count; }; struct qaic_drm_device { diff --git a/drivers/accel/qaic/qaic_drv.c b/drivers/accel/qaic/qaic_drv.c index 3b415e2c9431..e31bcb0ecfc9 100644 --- a/drivers/accel/qaic/qaic_drv.c +++ b/drivers/accel/qaic/qaic_drv.c @@ -29,6 +29,7 @@ #include "mhi_controller.h" #include "qaic.h" #include "qaic_debugfs.h" +#include "qaic_ras.h" #include "qaic_timesync.h" #include "sahara.h" @@ -695,6 +696,10 @@ static int __init qaic_init(void) if (ret) pr_debug("qaic: qaic_bootlog_register failed %d\n", ret); + ret = qaic_ras_register(); + if (ret) + pr_debug("qaic: qaic_ras_register failed %d\n", ret); + return 0; free_mhi: @@ -722,6 +727,7 @@ static void __exit qaic_exit(void) * reinitializing the link_up state after the cleanup is done. */ link_up = true; + qaic_ras_unregister(); qaic_bootlog_unregister(); qaic_timesync_deinit(); sahara_unregister(); diff --git a/drivers/accel/qaic/qaic_ras.c b/drivers/accel/qaic/qaic_ras.c new file mode 100644 index ..39c6f9cf98cc --- /dev/null +++ b/drivers/accel/qaic/qaic_ras.c @@ -0,0 +1,642 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/
[PATCH] drm/vc4: tests: pv_muxing: Fix locking
>state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->state); - - drm_modeset_drop_locks(&ctx); - drm_modeset_acquire_fini(&ctx); - return 0; } static struct kunit_case vc4_pv_muxing_tests[] = { KUNIT_CASE_PARAM(drm_vc4_test_pv_muxing, --- base-commit: a5806cd506af5a7c19bcd596e4708b5c464bfd21 change-id: 20250520-drm-vc4-kunit-fixes-a681715c4409 Best regards, -- Maxime Ripard
Re: [PATCH v2] drm/tests: Drop drm_kunit_helper_acquire_ctx_alloc()
; drivers/gpu/drm/drm_modeset_lock.c:318 > drivers/gpu/drm/drm_modeset_lock.c:396) drm (P) > drm_atomic_get_connector_state (drm.mod.c:?) drm > vc4_mock_atomic_add_output (drivers/gpu/drm/vc4/tests/vc4_mock_output.c:?) > vc4 > drm_vc4_test_pv_muxing (drivers/gpu/drm/vc4/tests/vc4_test_pv_muxing.c:688) > vc4 > kunit_try_run_case (lib/kunit/test.c:400) kunit > kunit_generic_run_threadfn_adapter (lib/kunit/try-catch.c:31) kunit > kthread (kernel/kthread.c:466) > ret_from_fork (arch/arm64/kernel/entry.S:863) > > I can run more tests if you'd like, decode the stack traces. Sorry I couldn't get to this sooner, and thanks for the awesome report. I've just sent a fix, let me know if it also works for you: https://lore.kernel.org/dri-devel/20250520-drm-vc4-kunit-fixes-v1-1-ca281e485...@kernel.org/ Maxime signature.asc Description: PGP signature
Patch "drm/vmwgfx: Fix a deadlock in dma buf fence polling" has been added to the 5.10-stable tree
This is a note to let you know that I've just added the patch titled drm/vmwgfx: Fix a deadlock in dma buf fence polling to the 5.10-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: drm-vmwgfx-fix-a-deadlock-in-dma-buf-fence-polling.patch and it can be found in the queue-5.10 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let know about it. >From e58337100721f3cc0c7424a18730e4f39844934f Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Mon, 22 Jul 2024 14:41:13 -0400 Subject: drm/vmwgfx: Fix a deadlock in dma buf fence polling From: Zack Rusin commit e58337100721f3cc0c7424a18730e4f39844934f upstream. Introduce a version of the fence ops that on release doesn't remove the fence from the pending list, and thus doesn't require a lock to fix poll->fence wait->fence unref deadlocks. vmwgfx overwrites the wait callback to iterate over the list of all fences and update their status, to do that it holds a lock to prevent the list modifcations from other threads. The fence destroy callback both deletes the fence and removes it from the list of pending fences, for which it holds a lock. dma buf polling cb unrefs a fence after it's been signaled: so the poll calls the wait, which signals the fences, which are being destroyed. The destruction tries to acquire the lock on the pending fences list which it can never get because it's held by the wait from which it was called. Old bug, but not a lot of userspace apps were using dma-buf polling interfaces. Fix those, in particular this fixes KDE stalls/deadlock. Signed-off-by: Zack Rusin Fixes: 2298e804e96e ("drm/vmwgfx: rework to new fence interface, v2") Cc: Broadcom internal kernel review list Cc: dri-devel@lists.freedesktop.org Cc: # v6.2+ Reviewed-by: Maaz Mombasawala Reviewed-by: Martin Krastev Link: https://patchwork.freedesktop.org/patch/msgid/20240722184313.181318-2-zack.ru...@broadcom.com [Minor context change fixed] Signed-off-by: Zhi Yang Signed-off-by: He Zhe Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/vmwgfx/vmwgfx_fence.c | 17 +++-- 1 file changed, 7 insertions(+), 10 deletions(-) --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c @@ -32,7 +32,6 @@ #define VMW_FENCE_WRAP (1 << 31) struct vmw_fence_manager { - int num_fence_objects; struct vmw_private *dev_priv; spinlock_t lock; struct list_head fence_list; @@ -113,13 +112,13 @@ static void vmw_fence_obj_destroy(struct { struct vmw_fence_obj *fence = container_of(f, struct vmw_fence_obj, base); - struct vmw_fence_manager *fman = fman_from_fence(fence); - spin_lock(&fman->lock); - list_del_init(&fence->head); - --fman->num_fence_objects; - spin_unlock(&fman->lock); + if (!list_empty(&fence->head)) { + spin_lock(&fman->lock); + list_del_init(&fence->head); + spin_unlock(&fman->lock); + } fence->destroy(fence); } @@ -250,7 +249,6 @@ static const struct dma_fence_ops vmw_fe .release = vmw_fence_obj_destroy, }; - /** * Execute signal actions on fences recently signaled. * This is done from a workqueue so we don't have to execute @@ -353,7 +351,6 @@ static int vmw_fence_obj_init(struct vmw goto out_unlock; } list_add_tail(&fence->head, &fman->fence_list); - ++fman->num_fence_objects; out_unlock: spin_unlock(&fman->lock); @@ -402,7 +399,7 @@ static bool vmw_fence_goal_new_locked(st { u32 goal_seqno; u32 *fifo_mem; - struct vmw_fence_obj *fence; + struct vmw_fence_obj *fence, *next_fence; if (likely(!fman->seqno_valid)) return false; @@ -413,7 +410,7 @@ static bool vmw_fence_goal_new_locked(st return false; fman->seqno_valid = false; - list_for_each_entry(fence, &fman->fence_list, head) { + list_for_each_entry_safe(fence, next_fence, &fman->fence_list, head) { if (!list_empty(&fence->seq_passed_actions)) { fman->seqno_valid = true; vmw_mmio_write(fence->base.seqno, Patches currently in stable-queue which might be from zack.ru...@broadcom.com are queue-5.10/drm-vmwgfx-fix-a-deadlock-in-dma-buf-fence-polling.patch
[PATCH] drm/arm/komeda: Register sysfs groups through driver core
From: Shixiong Ou [WHY] If the call to sysfs_create_group() fails, there is no need to call function sysfs_remove_group(). But if calling sysfs_create_group() fails, it will go to label 'err_cleanup:' in komeda_dev_create(), and it will call komeda_dev_destroy() laterly. [HOW] Register sysfs groups through driver core. Signed-off-by: Shixiong Ou --- .../gpu/drm/arm/display/komeda/komeda_dev.c | 60 --- .../gpu/drm/arm/display/komeda/komeda_drv.c | 51 2 files changed, 51 insertions(+), 60 deletions(-) diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c index 5ba62e637a61..a285fec3be23 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c @@ -53,58 +53,6 @@ static void komeda_debugfs_init(struct komeda_dev *mdev) &mdev->err_verbosity); } -static ssize_t -core_id_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct komeda_dev *mdev = dev_to_mdev(dev); - - return sysfs_emit(buf, "0x%08x\n", mdev->chip.core_id); -} -static DEVICE_ATTR_RO(core_id); - -static ssize_t -config_id_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct komeda_dev *mdev = dev_to_mdev(dev); - struct komeda_pipeline *pipe = mdev->pipelines[0]; - union komeda_config_id config_id; - int i; - - memset(&config_id, 0, sizeof(config_id)); - - config_id.max_line_sz = pipe->layers[0]->hsize_in.end; - config_id.n_pipelines = mdev->n_pipelines; - config_id.n_scalers = pipe->n_scalers; - config_id.n_layers = pipe->n_layers; - config_id.n_richs = 0; - for (i = 0; i < pipe->n_layers; i++) { - if (pipe->layers[i]->layer_type == KOMEDA_FMT_RICH_LAYER) - config_id.n_richs++; - } - return sysfs_emit(buf, "0x%08x\n", config_id.value); -} -static DEVICE_ATTR_RO(config_id); - -static ssize_t -aclk_hz_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct komeda_dev *mdev = dev_to_mdev(dev); - - return sysfs_emit(buf, "%lu\n", clk_get_rate(mdev->aclk)); -} -static DEVICE_ATTR_RO(aclk_hz); - -static struct attribute *komeda_sysfs_entries[] = { - &dev_attr_core_id.attr, - &dev_attr_config_id.attr, - &dev_attr_aclk_hz.attr, - NULL, -}; - -static struct attribute_group komeda_sysfs_attr_group = { - .attrs = komeda_sysfs_entries, -}; - static int komeda_parse_pipe_dt(struct komeda_pipeline *pipe) { struct device_node *np = pipe->of_node; @@ -253,12 +201,6 @@ struct komeda_dev *komeda_dev_create(struct device *dev) clk_disable_unprepare(mdev->aclk); - err = sysfs_create_group(&dev->kobj, &komeda_sysfs_attr_group); - if (err) { - DRM_ERROR("create sysfs group failed.\n"); - goto err_cleanup; - } - mdev->err_verbosity = KOMEDA_DEV_PRINT_ERR_EVENTS; komeda_debugfs_init(mdev); @@ -278,8 +220,6 @@ void komeda_dev_destroy(struct komeda_dev *mdev) const struct komeda_dev_funcs *funcs = mdev->funcs; int i; - sysfs_remove_group(&dev->kobj, &komeda_sysfs_attr_group); - debugfs_remove_recursive(mdev->debugfs_root); if (mdev->aclk) diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c index 358c1512b087..598d2f985dad 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c @@ -4,6 +4,7 @@ * Author: James.Qian.Wang * */ +#include #include #include #include @@ -20,6 +21,55 @@ struct komeda_drv { struct komeda_kms_dev *kms; }; +static ssize_t +aclk_hz_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct komeda_dev *mdev = dev_to_mdev(dev); + + return sysfs_emit(buf, "%lu\n", clk_get_rate(mdev->aclk)); +} +static DEVICE_ATTR_RO(aclk_hz); + +static ssize_t +config_id_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct komeda_dev *mdev = dev_to_mdev(dev); + struct komeda_pipeline *pipe = mdev->pipelines[0]; + union komeda_config_id config_id; + int i; + + memset(&config_id, 0, sizeof(config_id)); + + config_id.max_line_sz = pipe->layers[0]->hsize_in.end; + config_id.n_pipelines = mdev->n_pipelines; + config_id.n_scalers = pipe->n_scalers; + config_id.n_layers = pipe->n_layers; + config_id.n_richs = 0; + for (i = 0; i < pipe->n_layers; i++) { + if (pipe->layers[i]->layer_type == KOMEDA_FMT_RICH_LAYER) + config_id.n_richs++; + } + return sysfs_emit(buf, "0x%08x\n", config_id.value); +} +static DEVICE_ATTR_RO(config_id); + +static ssize_t +core_id_show(struct device *dev, struct device_attri
[PATCH] drm/i915/dp: Allow HBR3 without TPS4 support for eDP panels
Commit 584cf613c24a ("drm/i915/dp: Reject HBR3 when sink doesn't support TPS4") introduced a blanket rejection of HBR3 link rate when the sink does not support TPS4. While this was intended to address instability observed on certain eDP panels [1], the TPS4 requirement is only mandated for DPRX and not for eDPRX. This change inadvertently causes blank screens on some eDP panels that do not advertise TPS4 support, and require HBR3 to operate at their fixed native resolution. To restore functionality for such panels do not reject HBR3 when sink doesn't support TPS4. Instead reject HBR3 for specific panel that are not able to handle HBR3 [1]. [1] https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/5969 Fixes: 584cf613c24a ("drm/i915/dp: Reject HBR3 when sink doesn't support TPS4") Cc: sta...@vger.kernel.org Cc: Jani Nikula Cc: Ville Syrjälä Signed-off-by: Ankit Nautiyal --- drivers/gpu/drm/display/drm_dp_helper.c | 2 ++ drivers/gpu/drm/i915/display/intel_dp.c | 21 ++--- include/drm/display/drm_dp_helper.h | 7 +++ 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c index f2a6559a2710..bf66489c9202 100644 --- a/drivers/gpu/drm/display/drm_dp_helper.c +++ b/drivers/gpu/drm/display/drm_dp_helper.c @@ -2526,6 +2526,8 @@ static const struct dpcd_quirk dpcd_quirk_list[] = { { OUI(0x00, 0x0C, 0xE7), DEVICE_ID_ANY, false, BIT(DP_DPCD_QUIRK_HBLANK_EXPANSION_REQUIRES_DSC) }, /* Apple MacBookPro 2017 15 inch eDP Retina panel reports too low DP_MAX_LINK_RATE */ { OUI(0x00, 0x10, 0xfa), DEVICE_ID(101, 68, 21, 101, 98, 97), false, BIT(DP_DPCD_QUIRK_CAN_DO_MAX_LINK_RATE_3_24_GBPS) }, + /* Novatek panel */ + { OUI(0x38, 0xEC, 0x11), DEVICE_ID_ANY, false, BIT(DP_DPCD_QUIRK_HBR3) }, }; #undef OUI diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 21297bc4cc00..0bfc84cbd50d 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -184,13 +184,13 @@ static int max_dprx_rate(struct intel_dp *intel_dp) max_rate = drm_dp_bw_code_to_link_rate(intel_dp->dpcd[DP_MAX_LINK_RATE]); /* -* Some broken eDP sinks illegally declare support for -* HBR3 without TPS4, and are unable to produce a stable -* output. Reject HBR3 when TPS4 is not available. +* Some broken eDP sinks declare support for HBR3 but are unable to +* produce a stable output. For these panel reject HBR3. */ - if (max_rate >= 81 && !drm_dp_tps4_supported(intel_dp->dpcd)) { + if (max_rate >= 81 && + drm_dp_has_quirk(&intel_dp->desc, DP_DPCD_QUIRK_HBR3)) { drm_dbg_kms(display->drm, - "[ENCODER:%d:%s] Rejecting HBR3 due to missing TPS4 support\n", + "[ENCODER:%d:%s] Rejecting HBR3 due to DP_DPCD_QUIRK_HBR3\n", encoder->base.base.id, encoder->base.name); max_rate = 54; } @@ -4296,15 +4296,14 @@ intel_edp_set_sink_rates(struct intel_dp *intel_dp) if (rate == 0) break; - /* -* Some broken eDP sinks illegally declare support for -* HBR3 without TPS4, and are unable to produce a stable -* output. Reject HBR3 when TPS4 is not available. +* Some broken eDP sinks declare support for HBR3 but are unable to +* produce a stable output. For these panel reject HBR3. */ - if (rate >= 81 && !drm_dp_tps4_supported(intel_dp->dpcd)) { + if (rate >= 81 && + drm_dp_has_quirk(&intel_dp->desc, DP_DPCD_QUIRK_HBR3)) { drm_dbg_kms(display->drm, - "[ENCODER:%d:%s] Rejecting HBR3 due to missing TPS4 support\n", + "[ENCODER:%d:%s] Rejecting HBR3 due to DP_DPCD_QUIRK_HBR3\n", encoder->base.base.id, encoder->base.name); break; } diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h index e4ca35143ff9..5e60a37b61ce 100644 --- a/include/drm/display/drm_dp_helper.h +++ b/include/drm/display/drm_dp_helper.h @@ -814,6 +814,13 @@ enum drm_dp_quirk { * requires enabling DSC. */ DP_DPCD_QUIRK_HBLANK_EXPANSION_REQUIRES_DSC, + + /** +* @DP_DPCD_QUIRK_HBR3: +* +* The device supports HBR3 but is unable to produce stable output. +*/ + DP_DPCD_QUIRK_HBR3, }; /** -- 2.45.2
[PATCH] Documentation : fb : sstfb.rst : Fixed spelling mistake.
fixed document with spelling mistake changes made : 1. "tweeks" to "tweaks" Signed-off-by: Rujra Bhatt --- Documentation/fb/sstfb.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/fb/sstfb.rst b/Documentation/fb/sstfb.rst index 88d5a52b1..6cefa974a 100644 --- a/Documentation/fb/sstfb.rst +++ b/Documentation/fb/sstfb.rst @@ -192,7 +192,7 @@ Todo - Get rid of the previous paragraph. - Buy more coffee. - test/port to other arch. -- try to add panning using tweeks with front and back buffer . +- try to add panning using tweaks with front and back buffer . - try to implement accel on voodoo2, this board can actually do a lot in 2D even if it was sold as a 3D only board ... -- 2.43.0
Re: [PATCH v4 01/10] dt-bindings: npu: rockchip,rknn: Add bindings
On Mon, May 19, 2025 at 03:43:33PM GMT, Tomeu Vizoso wrote: > Add the bindings for the Neural Processing Unit IP from Rockchip. > > v2: > - Adapt to new node structure (one node per core, each with its own > IOMMU) > - Several misc. fixes from Sebastian Reichel > > v3: > - Split register block in its constituent subblocks, and only require > the ones that the kernel would ever use (Nicolas Frattaroli) > - Group supplies (Rob Herring) > - Explain the way in which the top core is special (Rob Herring) > > v4: > - Change required node name to npu@ (Rob Herring and Krzysztof Kozlowski) > - Remove unneeded items: (Krzysztof Kozlowski) > - Fix use of minItems/maxItems (Krzysztof Kozlowski) > - Add reg-names to list of required properties (Krzysztof Kozlowski) > - Fix example (Krzysztof Kozlowski) > > Signed-off-by: Tomeu Vizoso > Signed-off-by: Sebastian Reichel This order of SoB is still odd. You as person sending it should be the last signing person. Are you sure you are using b4 for managing trailers? I would expect it to re-order these on every update and this is already v4. > --- > .../bindings/npu/rockchip,rknn-core.yaml | 149 > + Filename matching compatible, so rockchip,rk3588-rknn-core.yaml > 1 file changed, 149 insertions(+) > > diff --git a/Documentation/devicetree/bindings/npu/rockchip,rknn-core.yaml > b/Documentation/devicetree/bindings/npu/rockchip,rknn-core.yaml > new file mode 100644 > index > ..fafd0b01da215c7396262012988e364ef07ea137 > --- /dev/null > +++ b/Documentation/devicetree/bindings/npu/rockchip,rknn-core.yaml > @@ -0,0 +1,149 @@ > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/npu/rockchip,rknn-core.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: Neural Processing Unit IP from Rockchip > + > +maintainers: > + - Tomeu Vizoso > + > +description: > + Rockchip IP for accelerating inference of neural networks, based on > NVIDIA's > + open source NVDLA IP. > + > + There is to be a node per each core in the NPU. In Rockchip's design there > + will be one core that is special and needs to be powered on before any of > the > + other cores can be used. This special core is called the top core and > should > + have the compatible string that corresponds to top cores. > + > +properties: > + $nodename: > +pattern: '^npu@[a-f0-9]+$' > + > + compatible: > +oneOf: Drop... if you followed my advice you would notice it is not necessary. > + - enum: > + - rockchip,rk3588-rknn-core-top > + - enum: > + - rockchip,rk3588-rknn-core My comments were only partially implemented. This syntax is really not readable and not necessary and I asked to make it part of previous enum. This is just one enum: compatible: enum: - foo - bar Best regards, Krzysztof
[PATCH v5 01/10] dt-bindings: npu: rockchip,rknn: Add bindings
Add the bindings for the Neural Processing Unit IP from Rockchip. v2: - Adapt to new node structure (one node per core, each with its own IOMMU) - Several misc. fixes from Sebastian Reichel v3: - Split register block in its constituent subblocks, and only require the ones that the kernel would ever use (Nicolas Frattaroli) - Group supplies (Rob Herring) - Explain the way in which the top core is special (Rob Herring) v4: - Change required node name to npu@ (Rob Herring and Krzysztof Kozlowski) - Remove unneeded items: (Krzysztof Kozlowski) - Fix use of minItems/maxItems (Krzysztof Kozlowski) - Add reg-names to list of required properties (Krzysztof Kozlowski) - Fix example (Krzysztof Kozlowski) v5: - Rename file to rockchip,rk3588-rknn-core.yaml (Krzysztof Kozlowski) - Streamline compatible property (Krzysztof Kozlowski) Signed-off-by: Sebastian Reichel Signed-off-by: Tomeu Vizoso --- .../bindings/npu/rockchip,rk3588-rknn-core.yaml| 147 + 1 file changed, 147 insertions(+) diff --git a/Documentation/devicetree/bindings/npu/rockchip,rk3588-rknn-core.yaml b/Documentation/devicetree/bindings/npu/rockchip,rk3588-rknn-core.yaml new file mode 100644 index ..9eb426367afcbc03c387d43c4b8250cdd1b9ee86 --- /dev/null +++ b/Documentation/devicetree/bindings/npu/rockchip,rk3588-rknn-core.yaml @@ -0,0 +1,147 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/npu/rockchip,rk3588-rknn-core.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Neural Processing Unit IP from Rockchip + +maintainers: + - Tomeu Vizoso + +description: + Rockchip IP for accelerating inference of neural networks, based on NVIDIA's + open source NVDLA IP. + + There is to be a node per each core in the NPU. In Rockchip's design there + will be one core that is special and needs to be powered on before any of the + other cores can be used. This special core is called the top core and should + have the compatible string that corresponds to top cores. + +properties: + $nodename: +pattern: '^npu@[a-f0-9]+$' + + compatible: +enum: + - rockchip,rk3588-rknn-core-top + - rockchip,rk3588-rknn-core + + reg: +maxItems: 3 + + reg-names: +items: + - const: pc + - const: cna + - const: core + + clocks: +minItems: 2 +maxItems: 4 + + clock-names: +items: + - const: aclk + - const: hclk + - const: npu + - const: pclk +minItems: 2 + + interrupts: +maxItems: 1 + + iommus: +maxItems: 1 + + npu-supply: true + + power-domains: +maxItems: 1 + + resets: +maxItems: 2 + + reset-names: +items: + - const: srst_a + - const: srst_h + + sram-supply: true + +required: + - compatible + - reg + - reg-names + - clocks + - clock-names + - interrupts + - iommus + - power-domains + - resets + - reset-names + - npu-supply + - sram-supply + +allOf: + - if: + properties: +compatible: + contains: +enum: + - rockchip,rknn-core-top +then: + properties: +clocks: + minItems: 4 + +clock-names: + minItems: 4 + - if: + properties: +compatible: + contains: +enum: + - rockchip,rknn-core +then: + properties: +clocks: + maxItems: 2 +clock-names: + maxItems: 2 + +additionalProperties: false + +examples: + - | +#include +#include +#include +#include +#include + +bus { + #address-cells = <2>; + #size-cells = <2>; + + npu@fdab { +compatible = "rockchip,rk3588-rknn-core-top"; +reg = <0x0 0xfdab 0x0 0x1000>, + <0x0 0xfdab1000 0x0 0x1000>, + <0x0 0xfdab3000 0x0 0x1000>; +reg-names = "pc", "cna", "core"; +assigned-clocks = <&scmi_clk SCMI_CLK_NPU>; +assigned-clock-rates = <2>; +clocks = <&cru ACLK_NPU0>, <&cru HCLK_NPU0>, + <&scmi_clk SCMI_CLK_NPU>, <&cru PCLK_NPU_ROOT>; +clock-names = "aclk", "hclk", "npu", "pclk"; +interrupts = ; +iommus = <&rknn_mmu_top>; +npu-supply = <&vdd_npu_s0>; +power-domains = <&power RK3588_PD_NPUTOP>; +resets = <&cru SRST_A_RKNN0>, <&cru SRST_H_RKNN0>; +reset-names = "srst_a", "srst_h"; +sram-supply = <&vdd_npu_mem_s0>; + }; +}; +... -- 2.49.0
[RFT PATCH v4 00/14] Add a single source of truth for UBWC configuration data
As discussed a lot in the past, the UBWC config must be coherent across a number of IP blocks (currently display and GPU, but it also may/will concern camera/video as the drivers evolve). So far, we've been trying to keep the values reasonable in each of the two drivers separately, but it really make sense to do so, especially given certain fields (see [1]) may need to be gathered dynamically. This series introduces a Single Source of Truth (SSOT) database to be consumed by multimedia drivers as needed. [1] https://lore.kernel.org/linux-arm-msm/20250410-topic-smem_dramc-v2-0-dead15264...@oss.qualcomm.com/ Signed-off-by: Konrad Dybcio --- Changes in v4: - Stub out qcom_ubwc_config_get_data() - Move the select for QCOM_UBWC_CONFIG to DRM_MSM - Use a define for UBWC_SWIZZLE_ENABLE_LVL2 in a6xx_gpu.c - Pick up tags - Link to v3: https://lore.kernel.org/r/20250517-topic-ubwc_central-v3-0-3c8465565...@oss.qualcomm.com Changes in v3: - Rearrange some patches some more (Dmitry and I talked off-list, hopefully this version is reasonably sane) - Throw the error returned by qcom_ubwc_config_get_data(), don't always assume it's -EINVAL (so that we can EPROBE_DEFER in the future if the SMEM driver that provides DDR info decides not to come up..) - Scream if ubwc_swizzle doesn't match - Drop dropping the ubwc_swizzle override (needs some testing in the wild) - Move long statements out of declaration space - explicitly define UBWC swizzling levels - Fix the SAR2130P omission - Pardon the funny ordering, but since it's intended to all go through drm, I attempted to strike a balance between clear, separate changes/fixes and logical succession - Link to v2: https://lore.kernel.org/r/20250514-topic-ubwc_central-v2-0-09ecbc0a0...@oss.qualcomm.com Changes in v2: - Rearrange some patches - Don't zeroalloc a copy of ubwc_config, store a full struct inside adreno_gpu instead (temporary solution until we trust the central db on the HBB value) - Improve some commit messages - Fix up SM6125's config - Don't break userspace abi (hbb value) - Don't keep mdss_reg_bus_bw in ubwc_config - Add the last patch warning if there are inconsistencies (I don't insist on it getting merged, but I think it's a good idea for the time being) - Link to v1: https://lore.kernel.org/r/20250508-topic-ubwc_central-v1-0-035c4c5cb...@oss.qualcomm.com --- Konrad Dybcio (14): soc: qcom: Add UBWC config provider drm/msm: Offset MDSS HBB value by 13 drm/msm: Use the central UBWC config database drm/msm/a6xx: Get a handle to the common UBWC config drm/msm/a6xx: Resolve the meaning of AMSBC drm/msm/a6xx: Simplify uavflagprd_inv detection drm/msm/a6xx: Resolve the meaning of UBWC_MODE drm/msm/a6xx: Replace '2' with BIT(1) in level2_swizzling_dis calc drm/msm/a6xx: Resolve the meaning of rgb565_predicator drm/msm/a6xx: Simplify min_acc_len calculation soc: qcom: ubwc: Fix SM6125's ubwc_swizzle value soc: qcom: ubwc: Add #defines for UBWC swizzle bits soc: qcom: ubwc: Fill in UBWC swizzle cfg for platforms that lack one drm/msm/adreno: Switch to the common UBWC config struct drivers/gpu/drm/msm/Kconfig | 1 + drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 20 +- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 138 ++-- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 6 +- drivers/gpu/drm/msm/adreno/adreno_gpu.h | 46 +--- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 6 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 4 +- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 7 +- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 2 +- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 3 +- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 2 +- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h | 2 +- drivers/gpu/drm/msm/msm_mdss.c | 333 +--- drivers/gpu/drm/msm/msm_mdss.h | 28 --- drivers/soc/qcom/Kconfig| 8 + drivers/soc/qcom/Makefile | 1 + drivers/soc/qcom/ubwc_config.c | 267 ++ include/linux/soc/qcom/ubwc.h | 74 +++ 18 files changed, 519 insertions(+), 429 deletions(-) --- base-commit: edef457004774e598fc4c1b7d1d4f0bcd9d0bb30 change-id: 20250430-topic-ubwc_central-53c540f019e5 Best regards, -- Konrad Dybcio
Re: [PATCH v2 2/5] drm/ast: Use helpers for programming gamma ramps and palettes
Hi Am 20.05.25 um 13:08 schrieb Javier Martinez Canillas: Thomas Zimmermann writes: Hello Thomas, Replace ast's code for programming the hardware gamma/palette LUT with DRM helpers. Either load provided data or program a default. Set the individual entries with a callback. Each gamma/palette value is given as 3 individual 16-bit values for red, green and blue. The driver reduces them to 8 bit to make them fit into hardware registers. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas I think this patch was acked by Jocelyn, not me. You can fix it just before merging the patch. No need to resend the series IMO. Oh, indeed! Thanks for letting me know. I'll fix that before merging the patch. Best regards Thomas -- -- 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)
Re: [PATCH v5 15/24] drm/msm/dsi/phy: Define PHY_CMN_CTRL_0 bitfields
On 03/05/2025 00:44, Dmitry Baryshkov wrote: > On Wed, Apr 30, 2025 at 03:00:45PM +0200, Krzysztof Kozlowski wrote: >> Add bitfields for PHY_CMN_CTRL_0 registers to avoid hard-coding bit >> masks and shifts and make the code a bit more readable. >> >> Signed-off-by: Krzysztof Kozlowski >> >> --- >> >> Changes in v5: >> 1. New patch >> --- >> drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 9 ++--- >> drivers/gpu/drm/msm/registers/display/dsi_phy_7nm.xml | 11 ++- >> 2 files changed, 16 insertions(+), 4 deletions(-) >> >> diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c >> b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c >> index >> ca1a120f630a3650bf6d9f9d426cccea88c22e7f..7ef0aa7ff41b7d10d2630405c3d2f541957f19ea >> 100644 >> --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c >> +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c >> @@ -362,17 +362,19 @@ static int dsi_pll_7nm_lock_status(struct dsi_pll_7nm >> *pll) >> static void dsi_pll_disable_pll_bias(struct dsi_pll_7nm *pll) >> { >> u32 data = readl(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0); > > This (and several following functions) should be triggering a warning > regarding empty line after variable declaration block. Hey Dmitry, I am implementing all the feedback and probably rebasing but to clarify this part: There is no checkpatch --strict warning here exactly for the reason I was saying. For readability there should be no empty line after because such statements are expected to be together. I don't mind of course adding one, so I will implement the change. Best regards, Krzysztof
[PATCH v5 06/10] accel/rocket: Add IOCTL for BO creation
This uses the SHMEM DRM helpers and we map right away to the CPU and NPU sides, as all buffers are expected to be accessed from both. v2: - Sync the IOMMUs for the other cores when mapping and unmapping. v3: - Make use of GPL-2.0-only for the copyright notice (Jeff Hugo) Reviewed-by: Jeffrey Hugo Signed-off-by: Tomeu Vizoso --- drivers/accel/rocket/Makefile| 3 +- drivers/accel/rocket/rocket_device.c | 4 ++ drivers/accel/rocket/rocket_device.h | 2 + drivers/accel/rocket/rocket_drv.c| 7 +- drivers/accel/rocket/rocket_gem.c| 131 +++ drivers/accel/rocket/rocket_gem.h| 26 +++ include/uapi/drm/rocket_accel.h | 44 7 files changed, 215 insertions(+), 2 deletions(-) diff --git a/drivers/accel/rocket/Makefile b/drivers/accel/rocket/Makefile index abdd75f2492eaecf8bf5e78a2ac150ea19ac3e96..4deef267f9e1238c4d8bd108dcc8afd9dc8b2b8f 100644 --- a/drivers/accel/rocket/Makefile +++ b/drivers/accel/rocket/Makefile @@ -5,4 +5,5 @@ obj-$(CONFIG_DRM_ACCEL_ROCKET) := rocket.o rocket-y := \ rocket_core.o \ rocket_device.o \ - rocket_drv.o + rocket_drv.o \ + rocket_gem.o diff --git a/drivers/accel/rocket/rocket_device.c b/drivers/accel/rocket/rocket_device.c index 97e32d19a1b4a36177b8039b67b4892887daa880..ee81810dd171ef1cdb1582c1bbe5099c669e42cc 100644 --- a/drivers/accel/rocket/rocket_device.c +++ b/drivers/accel/rocket/rocket_device.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "rocket_device.h" @@ -21,10 +22,13 @@ int rocket_device_init(struct rocket_device *rdev) if (err) return err; + mutex_init(&rdev->iommu_lock); + return 0; } void rocket_device_fini(struct rocket_device *rdev) { + mutex_destroy(&rdev->iommu_lock); rocket_core_fini(&rdev->cores[0]); } diff --git a/drivers/accel/rocket/rocket_device.h b/drivers/accel/rocket/rocket_device.h index 55f4da252cfbd1f102c56e5009472deff59aaaec..2e22aa2b95252a2850a40c3271a91cb3aca578ae 100644 --- a/drivers/accel/rocket/rocket_device.h +++ b/drivers/accel/rocket/rocket_device.h @@ -14,6 +14,8 @@ struct rocket_device { struct clk_bulk_data clks[2]; + struct mutex iommu_lock; + struct rocket_core *cores; unsigned int num_cores; }; diff --git a/drivers/accel/rocket/rocket_drv.c b/drivers/accel/rocket/rocket_drv.c index d1a1be32760feed864db86963b9942f1e37b17eb..685499537a0a8a206452b745ff23f9ff170b35db 100644 --- a/drivers/accel/rocket/rocket_drv.c +++ b/drivers/accel/rocket/rocket_drv.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -15,6 +16,7 @@ #include #include "rocket_drv.h" +#include "rocket_gem.h" static int rocket_open(struct drm_device *dev, struct drm_file *file) @@ -43,6 +45,8 @@ rocket_postclose(struct drm_device *dev, struct drm_file *file) static const struct drm_ioctl_desc rocket_drm_driver_ioctls[] = { #define ROCKET_IOCTL(n, func) \ DRM_IOCTL_DEF_DRV(ROCKET_##n, rocket_ioctl_##func, 0) + + ROCKET_IOCTL(CREATE_BO, create_bo), }; DEFINE_DRM_ACCEL_FOPS(rocket_accel_driver_fops); @@ -52,9 +56,10 @@ DEFINE_DRM_ACCEL_FOPS(rocket_accel_driver_fops); * - 1.0 - initial interface */ static const struct drm_driver rocket_drm_driver = { - .driver_features= DRIVER_COMPUTE_ACCEL, + .driver_features= DRIVER_COMPUTE_ACCEL | DRIVER_GEM, .open = rocket_open, .postclose = rocket_postclose, + .gem_create_object = rocket_gem_create_object, .ioctls = rocket_drm_driver_ioctls, .num_ioctls = ARRAY_SIZE(rocket_drm_driver_ioctls), .fops = &rocket_accel_driver_fops, diff --git a/drivers/accel/rocket/rocket_gem.c b/drivers/accel/rocket/rocket_gem.c new file mode 100644 index ..8a8a7185daac4740081293aae6945c9b2bbeb2dd --- /dev/null +++ b/drivers/accel/rocket/rocket_gem.c @@ -0,0 +1,131 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright 2024-2025 Tomeu Vizoso */ + +#include +#include +#include +#include +#include + +#include "rocket_device.h" +#include "rocket_gem.h" + +static void rocket_gem_bo_free(struct drm_gem_object *obj) +{ + struct rocket_device *rdev = to_rocket_device(obj->dev); + struct rocket_gem_object *bo = to_rocket_bo(obj); + struct sg_table *sgt; + + drm_WARN_ON(obj->dev, bo->base.pages_use_count > 1); + + mutex_lock(&rdev->iommu_lock); + + sgt = drm_gem_shmem_get_pages_sgt(&bo->base); + + /* Unmap this object from the IOMMUs for cores > 0 */ + for (unsigned int core = 1; core < rdev->num_cores; core++) { + struct iommu_domain *domain = iommu_get_domain_for_dev(rdev->cores[core].dev); + size_t unmapped = iommu_unmap(domain, sgt->sgl->dma_address, bo->siz
Re: [PATCH v4 07/30] drm/msm/dpu: remove DSPP_SC7180_MASK
On 19/05/2025 18:04, Dmitry Baryshkov wrote: From: Dmitry Baryshkov Stop declaring DPU_DSPP_PCC as a part of the DSPP features, use the presence of the PCC sblk to check whether PCC is present in the hardware or not. Signed-off-by: Dmitry Baryshkov Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h | 4 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_14_msm8937.h | 1 - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_15_msm8917.h | 1 - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_16_msm8953.h | 1 - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_7_msm8996.h | 2 -- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 2 -- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_2_sdm660.h | 2 -- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_3_sdm630.h | 1 - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h | 4 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_1_sdm670.h | 2 -- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h | 4 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 4 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_2_sm7150.h | 2 -- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_3_sm6150.h | 1 - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_4_sm6125.h | 1 - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h | 4 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h | 1 - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h | 1 - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_4_sm6350.h | 1 - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h | 1 - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_9_sm6375.h | 1 - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h | 4 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 1 - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 4 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 4 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_4_sa8775p.h | 4 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 4 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_1_sar2130p.h | 4 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_2_x1e80100.h | 4 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 2 -- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c | 2 +- 31 files changed, 1 insertion(+), 73 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h index 61420821a5f2dd5e56b8336c898290a2552c77fa..b14d0d6886f019c8fa06047baf734e38696f14ce 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h @@ -189,22 +189,18 @@ static const struct dpu_dspp_cfg sm8650_dspp[] = { { .name = "dspp_0", .id = DSPP_0, .base = 0x54000, .len = 0x1800, - .features = DSPP_SC7180_MASK, .sblk = &sdm845_dspp_sblk, }, { .name = "dspp_1", .id = DSPP_1, .base = 0x56000, .len = 0x1800, - .features = DSPP_SC7180_MASK, .sblk = &sdm845_dspp_sblk, }, { .name = "dspp_2", .id = DSPP_2, .base = 0x58000, .len = 0x1800, - .features = DSPP_SC7180_MASK, .sblk = &sdm845_dspp_sblk, }, { .name = "dspp_3", .id = DSPP_3, .base = 0x5a000, .len = 0x1800, - .features = DSPP_SC7180_MASK, .sblk = &sdm845_dspp_sblk, }, }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_14_msm8937.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_14_msm8937.h index 39027a21c6feecfba2d164799d9d982fc282d06b..c0b4db94777c42efd941fdd52993b854ab54c694 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_14_msm8937.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_14_msm8937.h @@ -116,7 +116,6 @@ static const struct dpu_dspp_cfg msm8937_dspp[] = { { .name = "dspp_0", .id = DSPP_0, .base = 0x54000, .len = 0x1800, - .features = DSPP_SC7180_MASK, .sblk = &msm8998_dspp_sblk, }, }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_15_msm8917.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_15_msm8917.h index 8d1b43ea1663cfbf35bed7b913d5d0bd16757162..d3e4c48be306a04b457cc002910eb018a3f13154 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_15_msm8917.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_15_msm8917.h @@ -103,7 +103,6 @@ static const struct dpu_dspp_cfg msm8917_dspp[] = { { .name = "dspp_0", .id = DSPP_0, .base = 0x54000, .len = 0x1800, - .features = DSPP_SC7180_MASK, .sblk = &msm8998_dspp_sblk, }, }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_16_msm8953.h b/drivers/gpu/drm/msm
Re: [PATCH v2 3/3] drm/panfrost: show device-wide list of DRM GEM objects over DebugFS
Hi Steven, On 08.05.2025 11:42, Steven Price wrote: > On 07/05/2025 17:07, Adrián Larumbe wrote: > > This change is essentially a Panfrost port of commit a3707f53eb3f > > ("drm/panthor: show device-wide list of DRM GEM objects over DebugFS"). > > > > The DebugFS file is almost the same as in Panthor, minus the GEM object > > usage flags, since Panfrost has no kernel-only BO's. > > > > Two additional GEM state flags which are displayed but aren't relevant > > to Panthor are 'Purged' and 'Purgeable', since Panfrost implements an > > explicit shrinker and a madvise ioctl to flag objects as reclaimable. > > > > Signed-off-by: Adrián Larumbe > > Minor point, but you've used "ptdev" rather than "pfdev" several times > in this patch - it would be good to avoid this. I've noticed I also forgot to fix the spelling when porting some devfreq fix code from Panthor some time ago. I'll send a new patch within the same series to fix thosoe too. > I'm also seeing a splat when running this, see below. I haven't got my > head around how this is happening, but I see it when glmark quits at the > end of the test. > > Steve > > [ 399.505066] Unable to handle kernel NULL pointer dereference at virtual > address 0004 when write > [ 399.515519] [0004] *pgd= > [ 399.519541] Internal error: Oops: 805 [#1] SMP ARM > [ 399.524896] Modules linked in: panfrost gpu_sched drm_shmem_helper > [ 399.531817] CPU: 1 UID: 1000 PID: 316 Comm: glmark2-es2-drm Not tainted > 6.15.0-rc5-00731-g9cc5b4d7da27 #1 NONE > [ 399.543098] Hardware name: Rockchip (Device Tree) > [ 399.548350] PC is at panfrost_gem_free_object+0x8c/0x160 [panfrost] > [ 399.555371] LR is at trace_contention_end+0x4c/0xfc > [ 399.560822] pc : []lr : []psr: 60010013 > [ 399.567823] sp : f22b1df8 ip : c2163e00 fp : c4b15800 > [ 399.573658] r10: 0009 r9 : c5f94c40 r8 : c4b15850 > [ 399.579492] r7 : c4b15884 r6 : c7813614 r5 : c5f94f30 r4 : c7813400 > [ 399.586784] r3 : r2 : r1 : r0 : c5f94f30 > [ 399.594075] Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment > none > [ 399.602048] Control: 10c5387d Table: 06c6c06a DAC: 0051 > [ 399.608465] Register r0 information: slab kmalloc-1k start c5f94c00 > pointer offset 816 size 1024 > [ 399.618296] Register r1 information: NULL pointer > [ 399.623551] Register r2 information: NULL pointer > [ 399.628804] Register r3 information: NULL pointer > [ 399.634057] Register r4 information: slab kmalloc-1k start c7813400 > pointer offset 0 size 1024 > [ 399.643690] Register r5 information: slab kmalloc-1k start c5f94c00 > pointer offset 816 size 1024 > [ 399.653517] Register r6 information: slab kmalloc-1k start c7813400 > pointer offset 532 size 1024 > [ 399.663344] Register r7 information: slab kmalloc-1k start c4b15800 > pointer offset 132 size 1024 > [ 399.673171] Register r8 information: slab kmalloc-1k start c4b15800 > pointer offset 80 size 1024 > [ 399.682901] Register r9 information: slab kmalloc-1k start c5f94c00 > pointer offset 64 size 1024 > [ 399.692631] Register r10 information: non-paged memory > [ 399.698370] Register r11 information: slab kmalloc-1k start c4b15800 > pointer offset 0 size 1024 > [ 399.708101] Register r12 information: non-slab/vmalloc memory > [ 399.714521] Process glmark2-es2-drm (pid: 316, stack limit = 0x178bc4ea) > [ 399.722009] Stack: (0xf22b1df8 to 0xf22b2000) > [ 399.726874] 1de0: > c4b15884 > [ 399.736012] 1e00: c7813400 c4b15800 0007 c4b15884 c4b15850 c6815000 > 0009 c0bb3824 > [ 399.745150] 1e20: 40086409 c7860800 c15fd008 0008 c0bb588c > c6815630 013c > [ 399.754288] 1e40: e280 c1b35650 b235e000 f22b1f5c 0008 > f22b1e74 bec37550 > [ 399.763426] 1e60: c6815630 c694ea00 c0bb47cc 0051 0007 > > [ 399.772564] 1e80: > > [ 399.781701] 1ea0: > > [ 399.790839] 1ec0: > > [ 399.799977] 1ee0: 356cc46f > 40086409 > [ 399.809115] 1f00: c694ea00 c03000c0 bec37550 c694ea00 c6815000 0006 > c4bf9b70 c058d694 > [ 399.818253] 1f20: b2b47000 f22b1f50 0001 c03002f0 c5f60900 > b235e000 > [ 399.827391] 1f40: 007e9000 c053d874 f22b1f50 0001 f22b1f50 f22b1f50 > 004e0b14 c5f60940 > [ 399.836528] 1f60: b235e000 b2b46fff c4abec0c b09e3000 b2bc > 356cc46f > [ 399.845666] 1f80: 0003 004e6b40 bec37550 40086409 0036 c03002f0 > c6815000 0036 > [ 399.854805] 1fa0: 01cb32a0 c03000c0 004e6b40 bec37550 0006 40086409 > bec37550 0007 > [ 399.863943] 1fc0: 004e6b40 bec37550 40086409 0036 > 01
Re: [PATCH v5 08/12] drm: renesas: rz-du: mipi_dsi: Use mHz for D-PHY frequency calculations
Hi Prabhakar, Thank you for the patch. On Mon, May 12, 2025 at 07:23:26PM +0100, Prabhakar wrote: > From: Lad Prabhakar > > Pass the HSFREQ in milli-Hz to the `dphy_init()` callback to improve > precision, especially for the RZ/V2H(P) SoC, where PLL dividers require > high accuracy. I have a hard time imagining the need for milliHz accuracy. Could you please explain why that is needed on V2H ? > These changes prepare the driver for upcoming RZ/V2H(P) SoC support. > > Co-developed-by: Fabrizio Castro > Signed-off-by: Fabrizio Castro > Signed-off-by: Lad Prabhakar > Reviewed-by: Biju Das > --- > v4->v5: > - Added Reviewed tag from Biju > > v3->v4: > - Used MILLI instead of KILO > - Made use of mul_u32_u32() for multiplication > > v2->v3: > - Replaced `unsigned long long` with `u64` > - Replaced *_mhz with *_millihz` in functions > > v1->v2: > - No changes > --- > drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c | 13 - > 1 file changed, 8 insertions(+), 5 deletions(-) > > diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > index 5fc607be0c46..f93519613662 100644 > --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > @@ -31,7 +31,7 @@ > struct rzg2l_mipi_dsi; > > struct rzg2l_mipi_dsi_hw_info { > - int (*dphy_init)(struct rzg2l_mipi_dsi *dsi, unsigned long hsfreq); > + int (*dphy_init)(struct rzg2l_mipi_dsi *dsi, u64 hsfreq_millihz); > void (*dphy_exit)(struct rzg2l_mipi_dsi *dsi); > u32 phy_reg_offset; > u32 link_reg_offset; > @@ -200,8 +200,9 @@ static u32 rzg2l_mipi_dsi_link_read(struct rzg2l_mipi_dsi > *dsi, u32 reg) > */ > > static int rzg2l_mipi_dsi_dphy_init(struct rzg2l_mipi_dsi *dsi, > - unsigned long hsfreq) > + u64 hsfreq_millihz) > { > + unsigned long hsfreq = DIV_ROUND_CLOSEST_ULL(hsfreq_millihz, MILLI); > const struct rzg2l_mipi_dsi_timings *dphy_timings; > unsigned int i; > u32 dphyctrl0; > @@ -274,6 +275,7 @@ static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi > *dsi, > const struct drm_display_mode *mode) > { > unsigned long hsfreq, vclk_rate; > + u64 hsfreq_millihz; > unsigned int bpp; > u32 txsetr; > u32 clstptsetr; > @@ -305,9 +307,9 @@ static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi > *dsi, > if (vclk_rate != mode->clock * MILLI) > dev_info(dsi->dev, "Requested vclk rate %lu, actual %lu > mismatch\n", >mode->clock * MILLI, vclk_rate); > - hsfreq = DIV_ROUND_CLOSEST_ULL(vclk_rate * bpp, dsi->lanes); > + hsfreq_millihz = DIV_ROUND_CLOSEST_ULL(mul_u32_u32(vclk_rate, bpp * > MILLI), dsi->lanes); > > - ret = dsi->info->dphy_init(dsi, hsfreq); > + ret = dsi->info->dphy_init(dsi, hsfreq_millihz); > if (ret < 0) > goto err_phy; > > @@ -315,6 +317,7 @@ static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi > *dsi, > txsetr = TXSETR_DLEN | TXSETR_NUMLANEUSE(dsi->lanes - 1) | TXSETR_CLEN; > rzg2l_mipi_dsi_link_write(dsi, TXSETR, txsetr); > > + hsfreq = DIV_ROUND_CLOSEST_ULL(hsfreq_millihz, MILLI); > /* >* Global timings characteristic depends on high speed Clock Frequency >* Currently MIPI DSI-IF just supports maximum FHD@60 with: > @@ -776,7 +779,7 @@ static int rzg2l_mipi_dsi_probe(struct platform_device > *pdev) >* mode->clock and format are not available. So initialize DPHY with >* timing parameters for 80Mbps. >*/ > - ret = dsi->info->dphy_init(dsi, 8000); > + ret = dsi->info->dphy_init(dsi, 8000ULL * MILLI); > if (ret < 0) > goto err_phy; > -- Regards, Laurent Pinchart
Re: [RFC 1/2] drm/i915: Expose local memory information via sysfs
Hi Krzysztof, [...] > +static ssize_t > +vram_total_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) > +{ > + struct device *dev = kobj_to_dev(kobj->parent); > + struct intel_memory_region *mr; > + > + mr = intel_memory_region_by_type(kdev_minor_to_i915(dev), > INTEL_MEMORY_LOCAL); intel_memory_region_by_type() may return a NULL, which would cause NULLPTR dereference on emit here and in other places where you call this function. > + > + return sysfs_emit(buf, "%llu\n", mr->total); > +} > + > +static const struct kobj_attribute vram_total_attr = > +__ATTR(vram_total, 0444, vram_total_show, NULL); > + > +static ssize_t > +vram_avail_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) > +{ > + struct device *dev = kobj_to_dev(kobj->parent); > + struct intel_memory_region *mr; > + u64 unallocated_size; > + u64 dummy; > + > + mr = intel_memory_region_by_type(kdev_minor_to_i915(dev), > INTEL_MEMORY_LOCAL); > + intel_memory_region_avail(mr, &unallocated_size, &dummy); > + > + return sysfs_emit(buf, "%llu\n", unallocated_size); > +} > + > +static const struct kobj_attribute vram_avail_attr = > +__ATTR(vram_available, 0444, vram_avail_show, NULL); > + > + > +static ssize_t > +vram_total_visible_show(struct kobject *kobj, struct kobj_attribute *attr, > char *buf) > +{ > + struct device *dev = kobj_to_dev(kobj->parent); > + struct intel_memory_region *mr; > + > + mr = intel_memory_region_by_type(kdev_minor_to_i915(dev), > INTEL_MEMORY_LOCAL); > + > + return sysfs_emit(buf, "%llu\n", resource_size(&mr->io)); > +} > + > +static const struct kobj_attribute vram_total_visible_attr = > +__ATTR(vram_total_cpu_visible, 0444, vram_total_visible_show, NULL); > + > +static ssize_t > +vram_avail_visible_show(struct kobject *kobj, struct kobj_attribute *attr, > char *buf) > +{ > + struct device *dev = kobj_to_dev(kobj->parent); > + struct intel_memory_region *mr; > + u64 unallocated_cpu_visible_size; > + u64 dummy; > + > + mr = intel_memory_region_by_type(kdev_minor_to_i915(dev), > INTEL_MEMORY_LOCAL); > + intel_memory_region_avail(mr, &dummy, &unallocated_cpu_visible_size); > + > + return sysfs_emit(buf, "%llu\n", unallocated_cpu_visible_size); > +} > + > +static const struct kobj_attribute vram_avail_visible_attr = > +__ATTR(vram_available_cpu_visible, 0444, vram_avail_visible_show, NULL); > + > +int intel_memory_region_setup_sysfs(struct drm_i915_private *i915) > +{ > + static const struct attribute *const files[] = { > + &vram_total_attr.attr, > + &vram_avail_attr.attr, > + &vram_total_visible_attr.attr, > + &vram_avail_visible_attr.attr, > + NULL > + }; > + struct device *kdev = i915->drm.primary->kdev; > + int err; > + > + /* Skip this function completely if the system does not support lmem */ > + if(!intel_memory_region_by_type(i915, INTEL_MEMORY_LOCAL)) > + return 0; > + > + memory_info_dir = kobject_create_and_add("memory_info", &kdev->kobj); > + if (!memory_info_dir) { > + drm_warn(&i915->drm, "Failed to create memory_info sysfs > directory\n"); > + return -EAGAIN; Maybe ENOMEM would be better? EAGAIN suggests that we have some confidence that retrying this call will yield a different result. [...] Best Regards, Krzysztof
Re: [PATCH v5 09/12] drm: renesas: rz-du: mipi_dsi: Add feature flag for 16BPP support
Hi Prabhakar, Thank you for the patch. On Mon, May 12, 2025 at 07:23:27PM +0100, Prabhakar wrote: > From: Lad Prabhakar > > Introduce the `RZ_MIPI_DSI_FEATURE_16BPP` flag in `rzg2l_mipi_dsi_hw_info` > to indicate support for 16BPP pixel formats. The RZ/V2H(P) SoC supports > 16BPP, whereas this feature is missing on the RZ/G2L SoC. > > Update the `mipi_dsi_host_attach()` function to check this flag before > allowing 16BPP formats. If the SoC does not support 16BPP, return an error > to prevent incorrect format selection. > > This change enables finer-grained format support control for different > SoC variants. > > Co-developed-by: Fabrizio Castro > Signed-off-by: Fabrizio Castro > Signed-off-by: Lad Prabhakar > Reviewed-by: Biju Das Reviewed-by: Laurent Pinchart > --- > v4->v5: > - Updated RZ_MIPI_DSI_FEATURE_16BPP macro to use BIT(0) > - Added Reviewed tag from Biju > > v3->v4: > - No changes > > v2->v3: > - No changes > > v1->v2: > - Renamed RZ_MIPI_DSI_FEATURE_16BPP > --- > drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c | 11 +++ > 1 file changed, 11 insertions(+) > > diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > index f93519613662..55a1c1b043c8 100644 > --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > @@ -28,6 +28,8 @@ > > #include "rzg2l_mipi_dsi_regs.h" > > +#define RZ_MIPI_DSI_FEATURE_16BPPBIT(0) > + > struct rzg2l_mipi_dsi; > > struct rzg2l_mipi_dsi_hw_info { > @@ -37,6 +39,7 @@ struct rzg2l_mipi_dsi_hw_info { > u32 link_reg_offset; > unsigned long max_dclk; > unsigned long min_dclk; > + u8 features; > }; > > struct rzg2l_mipi_dsi { > @@ -643,8 +646,16 @@ static int rzg2l_mipi_dsi_host_attach(struct > mipi_dsi_host *host, > > switch (mipi_dsi_pixel_format_to_bpp(device->format)) { > case 24: > + break; > case 18: > break; > + case 16: > + if (!(dsi->info->features & RZ_MIPI_DSI_FEATURE_16BPP)) { > + dev_err(dsi->dev, "Unsupported format 0x%04x\n", > + device->format); > + return -EINVAL; > + } > + break; > default: > dev_err(dsi->dev, "Unsupported format 0x%04x\n", > device->format); > return -EINVAL; -- Regards, Laurent Pinchart
Re: [PATCH v5 07/12] drm: renesas: rz-du: mipi_dsi: Make "rst" reset control optional for RZ/V2H(P)
Hi Prabhakar, On Mon, May 12, 2025 at 07:23:25PM +0100, Prabhakar wrote: > From: Lad Prabhakar > > In preparation for adding support for the Renesas RZ/V2H(P) SoC, make the > "rst" reset control optional in the MIPI DSI driver. The RZ/V2H(P) SoC > does not provide this reset line, and attempting to acquire it using the > mandatory API causes probe failure. > > Switching to devm_reset_control_get_optional_exclusive() ensures > compatibility with both SoCs that provide this reset line and those that > do not, such as RZ/V2H(P). > > Signed-off-by: Lad Prabhakar Reviewed-by: Laurent Pinchart > --- > v4->v5: > - New patch > --- > drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > index 00c2bc6e9d6c..5fc607be0c46 100644 > --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > @@ -748,7 +748,7 @@ static int rzg2l_mipi_dsi_probe(struct platform_device > *pdev) > if (IS_ERR(dsi->vclk)) > return PTR_ERR(dsi->vclk); > > - dsi->rstc = devm_reset_control_get_exclusive(dsi->dev, "rst"); > + dsi->rstc = devm_reset_control_get_optional_exclusive(dsi->dev, "rst"); > if (IS_ERR(dsi->rstc)) > return dev_err_probe(dsi->dev, PTR_ERR(dsi->rstc), >"failed to get rst\n"); -- Regards, Laurent Pinchart
Re: [RFC 0/2] Introduce a sysfs interface for lmem information
Hi Krzysztof, > This series introduces a way for applications to read local memory > information via files in the sysfs. So far the only way to do this was > via i915_query ioctl. This is slightly less handy than sysfs for > external users. "So far the only way to do this was via i915_query ioctl. This is slightly less handy than sysfs for external users." -> "So far the only way to do this was via i915_query ioctl, which is slightly less handy than sysfs for external users." - otherwise it might seem you are relating to the "sysfs" approach. Best Regards, Krzysztof
Re: [PATCH v5 10/12] drm: renesas: rz-du: mipi_dsi: Add dphy_late_init() callback for RZ/V2H(P)
Hi Prabhakar, Thank you for the patch. On Mon, May 12, 2025 at 07:23:28PM +0100, Prabhakar wrote: > From: Lad Prabhakar > > Introduce the `dphy_late_init` callback in `rzg2l_mipi_dsi_hw_info` to > allow additional D-PHY register configurations after enabling data and > clock lanes. This is required for the RZ/V2H(P) SoC but not for the > RZ/G2L SoC. > > Modify `rzg2l_mipi_dsi_startup()` to invoke `dphy_late_init` if defined, > ensuring SoC-specific initialization is performed only when necessary. > > This change prepares for RZ/V2H(P) SoC support while maintaining > compatibility with existing platforms. > > Co-developed-by: Fabrizio Castro > Signed-off-by: Fabrizio Castro > Signed-off-by: Lad Prabhakar > Reviewed-by: Biju Das > --- > v4->v5: > - Added Reviewed tag from Biju > > v3->v4: > - No changes > > v2->v3: > - No changes > > v1->v2: > - No changes > --- > drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c | 4 > 1 file changed, 4 insertions(+) > > diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > index 55a1c1b043c8..e1ce21a9ddb3 100644 > --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > @@ -34,6 +34,7 @@ struct rzg2l_mipi_dsi; > > struct rzg2l_mipi_dsi_hw_info { > int (*dphy_init)(struct rzg2l_mipi_dsi *dsi, u64 hsfreq_millihz); > + void (*dphy_late_init)(struct rzg2l_mipi_dsi *dsi); As this is called at startup time I would have called it dphy_startup. Up to you. Reviewed-by: Laurent Pinchart > void (*dphy_exit)(struct rzg2l_mipi_dsi *dsi); > u32 phy_reg_offset; > u32 link_reg_offset; > @@ -320,6 +321,9 @@ static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi > *dsi, > txsetr = TXSETR_DLEN | TXSETR_NUMLANEUSE(dsi->lanes - 1) | TXSETR_CLEN; > rzg2l_mipi_dsi_link_write(dsi, TXSETR, txsetr); > > + if (dsi->info->dphy_late_init) > + dsi->info->dphy_late_init(dsi); > + > hsfreq = DIV_ROUND_CLOSEST_ULL(hsfreq_millihz, MILLI); > /* >* Global timings characteristic depends on high speed Clock Frequency -- Regards, Laurent Pinchart
[PATCH v2] drm/sitronix: Remove broken backwards-compatibility layer
When moving the Sitronix DRM drivers and renaming their Kconfig symbols, the old symbols were kept, aiming to provide a seamless migration path when running "make olddefconfig" or "make oldconfig". However, the old compatibility symbols are not visible. Hence unless they are selected by another symbol (which they are not), they can never be enabled, and no backwards compatibility is provided. Drop the broken mechanism and the old symbols. Fixes: 9b8f32002cddf792 ("drm/sitronix: move tiny Sitronix drivers to their own subdir") Signed-off-by: Geert Uytterhoeven --- v2: - Drop backwards-compatibility instead of fixing it. --- drivers/gpu/drm/sitronix/Kconfig | 10 -- 1 file changed, 10 deletions(-) diff --git a/drivers/gpu/drm/sitronix/Kconfig b/drivers/gpu/drm/sitronix/Kconfig index c069d0d417753bcf..25cae32e5c3ec113 100644 --- a/drivers/gpu/drm/sitronix/Kconfig +++ b/drivers/gpu/drm/sitronix/Kconfig @@ -10,10 +10,6 @@ config DRM_ST7571_I2C if M is selected the module will be called st7571-i2c. -config TINYDRM_ST7586 - tristate - default n - config DRM_ST7586 tristate "DRM support for Sitronix ST7586 display panels" depends on DRM && SPI @@ -21,17 +17,12 @@ config DRM_ST7586 select DRM_KMS_HELPER select DRM_GEM_DMA_HELPER select DRM_MIPI_DBI - default TINYDRM_ST7586 help DRM driver for the following Sitronix ST7586 panels: * LEGO MINDSTORMS EV3 If M is selected the module will be called st7586. -config TINYDRM_ST7735R - tristate - default n - config DRM_ST7735R tristate "DRM support for Sitronix ST7715R/ST7735R display panels" depends on DRM && SPI @@ -40,7 +31,6 @@ config DRM_ST7735R select DRM_GEM_DMA_HELPER select DRM_MIPI_DBI select BACKLIGHT_CLASS_DEVICE - default TINYDRM_ST7735R help DRM driver for Sitronix ST7715R/ST7735R with one of the following LCDs: -- 2.43.0
Re: [RFC 2/2] drm/i915: Add protections to sysfs local memory information
Hi Krzysztof, > Introduce a CAP_PERFMON check when accessing sysfs entries related to > local memory information. Also introduce a intel_memory_info_paranoid > sysctl parameter, which allows the administrator to control whether the > check is enforced. If we decide that this patch is neede, I think we should squash it with the first one to introduce a mechanism that can already be secured. [...] > > +static u32 intel_memory_info_paranoid = 1; Maybe change that to "intel_memory_info_restrictive"? "Paranoid" relates to extreme fearfulness/paranoia/anxiety, which might seem a bit over the top :) Best Regards, Krzysztof
Re: [PATCH v4 14/30] drm/msm/dpu: get rid of DPU_INTF_STATUS_SUPPORTED
On 19/05/2025 18:04, Dmitry Baryshkov wrote: From: Dmitry Baryshkov Continue migration to the MDSS-revision based checks and replace DPU_INTF_STATUS_SUPPORTED feature bit with the core_major_ver >= 5 check. Signed-off-by: Dmitry Baryshkov Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 3 +-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 2 -- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c| 3 +-- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 1244dd59648d11123c507a1369f28f952d047fd5..4482f2fe6f04e58408b55994d885ea1c717c6a07 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -105,8 +105,7 @@ (BIT(DPU_PINGPONG_DITHER) | BIT(DPU_PINGPONG_DSC)) #define INTF_SC7180_MASK \ - (BIT(DPU_INTF_INPUT_CTRL) | \ -BIT(DPU_INTF_STATUS_SUPPORTED)) + (BIT(DPU_INTF_INPUT_CTRL)) #define WB_SDM845_MASK (BIT(DPU_WB_LINE_MODE) | \ BIT(DPU_WB_UBWC) | \ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h index bf6b2392efb47fa8c3e3c5d17f1a72341872e18b..e1c6df3a3b72ffb5a816bd18266a35abe723fbd9 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -143,12 +143,10 @@ enum { * INTF sub-blocks * @DPU_INTF_INPUT_CTRL Supports the setting of pp block from which * pixel data arrives to this INTF - * @DPU_INTF_STATUS_SUPPORTED INTF block has INTF_STATUS register * @DPU_INTF_MAX */ enum { DPU_INTF_INPUT_CTRL = 0x1, - DPU_INTF_STATUS_SUPPORTED, DPU_INTF_MAX }; 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 8f9733aad2dec3a9b5464d55b00f350348842911..54c2e984ef0ce604e3eda49595d2816ea41bd7fd 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c @@ -308,9 +308,8 @@ static void dpu_hw_intf_get_status( struct dpu_hw_intf_status *s) { struct dpu_hw_blk_reg_map *c = &intf->hw; - unsigned long cap = intf->cap->features; - if (cap & BIT(DPU_INTF_STATUS_SUPPORTED)) + if (intf->mdss_ver->core_major_ver >= 5) s->is_en = DPU_REG_READ(c, INTF_STATUS) & BIT(0); else s->is_en = DPU_REG_READ(c, INTF_TIMING_ENGINE_EN); Reviewed-by: Neil Armstrong
Re: [PATCH v3 16/19] nova-core: Add support for VBIOS ucode extraction for boot
Hi Danilo, On 5/14/2025 12:23 PM, Danilo Krummrich wrote: > I feel like this patch utilizes the Option type way too much and > often without actual need. Can you please also double check? > I found one other instance (vbios.fwsec_image). Other than that, all others are required AFAICS. >> + >> +if cfg!(debug_assertions) { >> +// Debugging (dumps the table data to dmesg): >> +if let Some(ref mut last_entry_bytes) = last_entry_bytes { >> +last_entry_bytes.push(byte, GFP_KERNEL)?; >> + >> +let last_entry_bytes_len = last_entry_bytes.len(); >> +if last_entry_bytes_len == entry_len { >> +pr_info!("Last entry bytes: {:02x?}\n", >> &last_entry_bytes[..]); > > Please use dev_dbg!(). > This required passing down the pdev here, but did that, thanks. >> +*last_entry_bytes = KVec::new(); >> +} >> +} >> +} >> +} >> + >> +Ok(PmuLookupTable { >> +version: data[0], >> +header_len: header_len as u8, >> +entry_len: entry_len as u8, >> +entry_count: entry_count as u8, >> +table_data, >> +}) >> +} >> + >> +fn lookup_index(&self, idx: u8) -> Result { >> +if idx >= self.entry_count { >> +return Err(EINVAL); >> +} >> + >> +let index = (idx as usize) * self.entry_len as usize; >> +PmuLookupTableEntry::new(&self.table_data[index..]) >> +} >> + >> +// find entry by type value >> +fn find_entry_by_type(&self, entry_type: u8) -> >> Result { >> +for i in 0..self.entry_count { >> +let entry = self.lookup_index(i)?; >> +if entry.application_id == entry_type { >> +return Ok(entry); >> +} >> +} >> + >> +Err(EINVAL) >> +} >> +} >> + >> +/// The FwSecBiosImage structure contains the PMU table and the Falcon >> Ucode. >> +/// The PMU table contains voltage/frequency tables as well as a pointer to >> the >> +/// Falcon Ucode. >> +impl FwSecBiosImage { >> +fn setup_falcon_data( >> +&mut self, >> +pdev: &pci::Device, >> +pci_at_image: &PciAtBiosImage, >> +first_fwsec_image: &FwSecBiosImage, >> +) -> Result<()> { > > Just Result will do. > Fixed. >> +let mut offset = pci_at_image.falcon_data_ptr(pdev)? as usize; >> + >> +// The falcon data pointer assumes that the PciAt and FWSEC images >> +// are contiguous in memory. However, testing shows the EFI image >> sits in >> +// between them. So calculate the offset from the end of the PciAt >> image >> +// rather than the start of it. Compensate. >> +offset -= pci_at_image.base.data.len(); >> + >> +// The offset is now from the start of the first Fwsec image, >> however >> +// the offset points to a location in the second Fwsec image. Since >> +// the fwsec images are contiguous, subtract the length of the >> first Fwsec >> +// image from the offset to get the offset to the start of the >> second >> +// Fwsec image. >> +offset -= first_fwsec_image.base.data.len(); >> + >> +self.falcon_data_offset = Some(offset); >> + >> +// The PmuLookupTable starts at the offset of the falcon data >> pointer >> +self.pmu_lookup_table = >> Some(PmuLookupTable::new(&self.base.data[offset..])?); >> + >> +match self >> +.pmu_lookup_table >> +.as_ref() >> +.ok_or(EINVAL)? >> +.find_entry_by_type(FALCON_UCODE_ENTRY_APPID_FWSEC_PROD) >> +{ >> +Ok(entry) => { >> +let mut ucode_offset = entry.data as usize; >> +ucode_offset -= pci_at_image.base.data.len(); >> +ucode_offset -= first_fwsec_image.base.data.len(); >> +self.falcon_ucode_offset = Some(ucode_offset); >> +if cfg!(debug_assertions) { >> +// Print the v3_desc header for debugging >> +let v3_desc = self.fwsec_header(pdev.as_ref())?; >> +pr_info!("PmuLookupTableEntry v3_desc: {:#?}\n", >> v3_desc); >> +} >> +} >> +Err(e) => { >> +dev_err!( >> +pdev.as_ref(), >> +"PmuLookupTableEntry not found, error: {:?}\n", >> +e >> +); >> +} >> +} >> +Ok(()) >> +} >> + >> +/// TODO: These were borrowed from the old code for integrating this >> module >> +/// with the outside world. They should be cleaned up and integrated >> properly. > > Okay, won't review for now then. 🙂 In the next revision, we are removing this TODO and can continue review. :) thanks, - Joel
Re: [PATCH v2] drm/sitronix: Remove broken backwards-compatibility layer
Geert Uytterhoeven writes: Hello Geert, > When moving the Sitronix DRM drivers and renaming their Kconfig symbols, > the old symbols were kept, aiming to provide a seamless migration path > when running "make olddefconfig" or "make oldconfig". > > However, the old compatibility symbols are not visible. Hence unless > they are selected by another symbol (which they are not), they can never > be enabled, and no backwards compatibility is provided. > > Drop the broken mechanism and the old symbols. > > Fixes: 9b8f32002cddf792 ("drm/sitronix: move tiny Sitronix drivers to their > own subdir") > Signed-off-by: Geert Uytterhoeven > --- Acked-by: Javier Martinez Canillas -- Best regards, Javier Martinez Canillas Core Platforms Red Hat
Re: [PATCH v5 08/10] accel/rocket: Add IOCTLs for synchronizing memory accesses
Hi Tomeu, Am Dienstag, dem 20.05.2025 um 12:27 +0200 schrieb Tomeu Vizoso: > The NPU cores have their own access to the memory bus, and this isn't > cache coherent with the CPUs. > > Add IOCTLs so userspace can mark when the caches need to be flushed, and > also when a writer job needs to be waited for before the buffer can be > accessed from the CPU. > > Initially based on the same IOCTLs from the Etnaviv driver. > > v2: > - Don't break UABI by reordering the IOCTL IDs (Jeff Hugo) > > v3: > - Check that padding fields in IOCTLs are zero (Jeff Hugo) > > Signed-off-by: Tomeu Vizoso > --- > drivers/accel/rocket/rocket_drv.c | 2 + > drivers/accel/rocket/rocket_gem.c | 80 > +++ > drivers/accel/rocket/rocket_gem.h | 5 +++ > include/uapi/drm/rocket_accel.h | 37 ++ > 4 files changed, 124 insertions(+) > > diff --git a/drivers/accel/rocket/rocket_drv.c > b/drivers/accel/rocket/rocket_drv.c > index > fef9b93372d3f65c41c1ac35a9bfa0c01ee721a5..c06e66939e6c39909fe08bef3c4f301b07bf8fbf > 100644 > --- a/drivers/accel/rocket/rocket_drv.c > +++ b/drivers/accel/rocket/rocket_drv.c > @@ -59,6 +59,8 @@ static const struct drm_ioctl_desc > rocket_drm_driver_ioctls[] = { > > ROCKET_IOCTL(CREATE_BO, create_bo), > ROCKET_IOCTL(SUBMIT, submit), > + ROCKET_IOCTL(PREP_BO, prep_bo), > + ROCKET_IOCTL(FINI_BO, fini_bo), > }; > > DEFINE_DRM_ACCEL_FOPS(rocket_accel_driver_fops); > diff --git a/drivers/accel/rocket/rocket_gem.c > b/drivers/accel/rocket/rocket_gem.c > index > 8a8a7185daac4740081293aae6945c9b2bbeb2dd..cdc5238a93fa5978129dc1ac8ec8de955160dc18 > 100644 > --- a/drivers/accel/rocket/rocket_gem.c > +++ b/drivers/accel/rocket/rocket_gem.c > @@ -129,3 +129,83 @@ int rocket_ioctl_create_bo(struct drm_device *dev, void > *data, struct drm_file * > > return ret; > } > + > +static inline enum dma_data_direction rocket_op_to_dma_dir(u32 op) > +{ > + if (op & ROCKET_PREP_READ) > + return DMA_FROM_DEVICE; > + else if (op & ROCKET_PREP_WRITE) > + return DMA_TO_DEVICE; > + else > + return DMA_BIDIRECTIONAL; > +} This has copied over the bug fixed in etnaviv commit 58979ad6330a ("drm/etnaviv: fix DMA direction handling for cached RW buffers") Regards, Lucas
[PATCH RFT v4 09/14] drm/msm/a6xx: Resolve the meaning of rgb565_predicator
From: Konrad Dybcio It's supposed to be on when the UBWC encoder version is >= 4.0. Drop the per-GPU assignments. Reviewed-by: Dmitry Baryshkov Signed-off-by: Konrad Dybcio --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 7 ++- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index a20b57e964d31adb22f0b79a5178b45f0f5ec5d5..32017e2730a9059a16ef551363660b72d7f991c8 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -592,7 +592,6 @@ static int a6xx_calc_ubwc_config(struct adreno_gpu *gpu) if (IS_ERR(gpu->common_ubwc_cfg)) return PTR_ERR(gpu->common_ubwc_cfg); - gpu->ubwc_config.rgb565_predicator = 0; gpu->ubwc_config.min_acc_len = 0; gpu->ubwc_config.ubwc_swizzle = 0x6; gpu->ubwc_config.macrotile_mode = 0; @@ -619,7 +618,6 @@ static int a6xx_calc_ubwc_config(struct adreno_gpu *gpu) if (adreno_is_a623(gpu)) { gpu->ubwc_config.highest_bank_bit = 16; - gpu->ubwc_config.rgb565_predicator = 1; gpu->ubwc_config.macrotile_mode = 1; } @@ -633,13 +631,11 @@ static int a6xx_calc_ubwc_config(struct adreno_gpu *gpu) adreno_is_a740_family(gpu)) { /* TODO: get ddr type from bootloader and use 2 for LPDDR4 */ gpu->ubwc_config.highest_bank_bit = 16; - gpu->ubwc_config.rgb565_predicator = 1; gpu->ubwc_config.macrotile_mode = 1; } if (adreno_is_a663(gpu)) { gpu->ubwc_config.highest_bank_bit = 13; - gpu->ubwc_config.rgb565_predicator = 1; gpu->ubwc_config.macrotile_mode = 1; gpu->ubwc_config.ubwc_swizzle = 0x4; } @@ -668,6 +664,7 @@ static void a6xx_set_ubwc_config(struct msm_gpu *gpu) */ BUG_ON(adreno_gpu->ubwc_config.highest_bank_bit < 13); u32 hbb = adreno_gpu->ubwc_config.highest_bank_bit - 13; + bool rgb565_predicator = cfg->ubwc_enc_version >= UBWC_4_0; u32 level2_swizzling_dis = !(cfg->ubwc_swizzle & BIT(1)); bool ubwc_mode = qcom_ubwc_get_ubwc_mode(cfg); bool amsbc = cfg->ubwc_enc_version >= UBWC_3_0; @@ -680,7 +677,7 @@ static void a6xx_set_ubwc_config(struct msm_gpu *gpu) gpu_write(gpu, REG_A6XX_RB_NC_MODE_CNTL, level2_swizzling_dis << 12 | - adreno_gpu->ubwc_config.rgb565_predicator << 11 | + rgb565_predicator << 11 | hbb_hi << 10 | amsbc << 4 | adreno_gpu->ubwc_config.min_acc_len << 3 | hbb_lo << 1 | ubwc_mode); -- 2.49.0
Re: [PATCH v4 15/30] drm/msm/dpu: get rid of DPU_INTF_INPUT_CTRL
On 19/05/2025 18:04, Dmitry Baryshkov wrote: From: Dmitry Baryshkov Continue migration to the MDSS-revision based checks and replace DPU_INTF_INPUT_CTRL feature bit with the core_major_ver >= 5 check. Signed-off-by: Dmitry Baryshkov Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h | 4 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h | 4 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 6 -- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_2_sm7150.h | 4 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_3_sm6150.h | 3 --- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_4_sm6125.h | 2 -- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h | 4 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h | 2 -- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h | 1 - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_4_sm6350.h | 2 -- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h | 1 - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_9_sm6375.h | 1 - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h | 4 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 3 --- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 9 - drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 4 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_4_sa8775p.h | 8 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 4 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_1_sar2130p.h | 4 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_2_x1e80100.h | 9 - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 3 --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 11 --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 2 +- 23 files changed, 1 insertion(+), 94 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h index bbdb7e1668fee33cb7d99a7cb8ab001e58f079be..88582fc257dea342f05b93dae6afe986eb7f32d0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h @@ -364,7 +364,6 @@ static const struct dpu_intf_cfg sm8650_intf[] = { { .name = "intf_0", .id = INTF_0, .base = 0x34000, .len = 0x280, - .features = INTF_SC7180_MASK, .type = INTF_DP, .controller_id = MSM_DP_CONTROLLER_0, .prog_fetch_lines_worst_case = 24, @@ -373,7 +372,6 @@ static const struct dpu_intf_cfg sm8650_intf[] = { }, { .name = "intf_1", .id = INTF_1, .base = 0x35000, .len = 0x300, - .features = INTF_SC7180_MASK, .type = INTF_DSI, .controller_id = MSM_DSI_CONTROLLER_0, .prog_fetch_lines_worst_case = 24, @@ -383,7 +381,6 @@ static const struct dpu_intf_cfg sm8650_intf[] = { }, { .name = "intf_2", .id = INTF_2, .base = 0x36000, .len = 0x300, - .features = INTF_SC7180_MASK, .type = INTF_DSI, .controller_id = MSM_DSI_CONTROLLER_1, .prog_fetch_lines_worst_case = 24, @@ -393,7 +390,6 @@ static const struct dpu_intf_cfg sm8650_intf[] = { }, { .name = "intf_3", .id = INTF_3, .base = 0x37000, .len = 0x280, - .features = INTF_SC7180_MASK, .type = INTF_DP, .controller_id = MSM_DP_CONTROLLER_1, .prog_fetch_lines_worst_case = 24, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h index 6c8ef23099a8212f33780d27a76991e9955a9bc3..bcab869aafbe1e23e0267bbad377fc10d8c6256d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h @@ -301,7 +301,6 @@ static const struct dpu_intf_cfg sm8150_intf[] = { { .name = "intf_0", .id = INTF_0, .base = 0x6a000, .len = 0x280, - .features = INTF_SC7180_MASK, .type = INTF_DP, .controller_id = MSM_DP_CONTROLLER_0, .prog_fetch_lines_worst_case = 24, @@ -310,7 +309,6 @@ static const struct dpu_intf_cfg sm8150_intf[] = { }, { .name = "intf_1", .id = INTF_1, .base = 0x6a800, .len = 0x2bc, - .features = INTF_SC7180_MASK, .type = INTF_DSI, .controller_id = MSM_DSI_CONTROLLER_0, .prog_fetch_lines_worst_case = 24, @@ -320,7 +318,6 @@ static const struct dpu_intf_cfg sm8150_intf[] = { }, { .name = "intf_2", .id = INTF_2, .base = 0x6b000, .len = 0x2bc, - .features =
Re: 6.15-rc6/regression/bisected - after commit f1c6be3999d2 error appeared: *ERROR* dc_dmub_srv_log_diagnostic_data: DMCUB error
[AMD Official Use Only - AMD Internal Distribution Only] Hi Mike, Could you more details about your setup, and how you were able to repro it ? -- Regards, Jay From: Mikhail Gavrilov Sent: Tuesday, May 20, 2025 5:33 AM To: Pillai, Aurabindo ; Chung, ChiaHsuan (Tom) ; Wu, Ray ; Wheeler, Daniel ; Deucher, Alexander ; amd-gfx list ; dri-devel ; Linux List Kernel Mailing ; Linux regressions mailing list Subject: 6.15-rc6/regression/bisected - after commit f1c6be3999d2 error appeared: *ERROR* dc_dmub_srv_log_diagnostic_data: DMCUB error Hi, After commit f1c6be3999d2 error appears: [ 1421.701677] amdgpu :03:00.0: [drm] *ERROR* dc_dmub_srv_log_diagnostic_data: DMCUB error - collecting diagnostic data [ 1421.896810] amdgpu :03:00.0: [drm] *ERROR* dc_dmub_srv_log_diagnostic_data: DMCUB error - collecting diagnostic data [ 1422.088397] amdgpu :03:00.0: [drm] *ERROR* dc_dmub_srv_log_diagnostic_data: DMCUB error - collecting diagnostic data [ 1426.448674] amdgpu :03:00.0: amdgpu: SMU: I'm not done with your previous command: SMN_C2PMSG_66:0x0012 SMN_C2PMSG_82:0x0005 [ 1426.448804] amdgpu :03:00.0: amdgpu: Failed to export SMU metrics table! [ 1430.149443] amdgpu :03:00.0: amdgpu: SMU: I'm not done with your previous command: SMN_C2PMSG_66:0x0012 SMN_C2PMSG_82:0x0005 [ 1430.149456] amdgpu :03:00.0: amdgpu: Failed to export SMU metrics table! [ 1433.846389] amdgpu :03:00.0: amdgpu: SMU: I'm not done with your previous command: SMN_C2PMSG_66:0x0012 SMN_C2PMSG_82:0x0005 [ 1433.846400] amdgpu :03:00.0: amdgpu: Failed to export SMU metrics table! [ 1437.543718] amdgpu :03:00.0: amdgpu: SMU: I'm not done with your previous command: SMN_C2PMSG_66:0x0012 SMN_C2PMSG_82:0x0005 [ 1437.543727] amdgpu :03:00.0: amdgpu: Failed to export SMU metrics table! [ 1439.966738] watchdog: CPU28: Watchdog detected hard LOCKUP on cpu 28 [ 1439.966742] Modules linked in: uinput rfcomm snd_seq_dummy snd_hrtimer nft_queue nfnetlink_queue nf_conntrack_netbios_ns nf_conntrack_broadcast nft_fib_inet nft_fib_ipv4 nft_fib_ipv6 nft_fib nft_reject_inet nf_reject_ipv4 nf_reject_ipv6 nft_reject nft_ct nft_chain_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 ip_set nf_tables qrtr bnep sunrpc binfmt_misc amd_atl intel_rapl_msr intel_rapl_common mt7921e mt7921_common mt792x_lib mt76_connac_lib edac_mce_amd mt76 btusb btrtl btintel snd_hda_codec_realtek btbcm btmtk snd_hda_codec_generic snd_hda_scodec_component kvm_amd snd_hda_codec_hdmi mac80211 bluetooth vfat snd_hda_intel fat snd_intel_dspcfg kvm snd_intel_sdw_acpi snd_hda_codec snd_hda_core spd5118 snd_hwdep libarc4 snd_seq irqbypass snd_seq_device wmi_bmof cfg80211 r8169 rapl joydev snd_pcm snd_timer i2c_piix4 pcspkr k10temp i2c_smbus snd realtek rfkill soundcore gpio_amdpt gpio_generic loop nfnetlink zram lz4hc_compress lz4_compress amdgpu amdxcp i2c_algo_bit drm_ttm_helper ttm drm_exec polyval_clmulni [ 1439.966788] gpu_sched nvme polyval_generic ghash_clmulni_intel drm_suballoc_helper drm_panel_backlight_quirks ucsi_ccg sha512_ssse3 nvme_core drm_buddy typec_ucsi sha256_ssse3 drm_display_helper nvme_keyring typec sha1_ssse3 nvme_auth sp5100_tco cec video wmi fuse [ 1439.966799] irq event stamp: 235192 [ 1439.966800] hardirqs last enabled at (235191): [] asm_exc_page_fault+0x26/0x30 [ 1439.966805] hardirqs last disabled at (235192): [] irqentry_enter+0x57/0x60 [ 1439.966808] softirqs last enabled at (234272): [] handle_softirqs+0x579/0x840 [ 1439.966810] softirqs last disabled at (234263): [] __irq_exit_rcu+0x126/0x240 [ 1439.966813] CPU: 28 UID: 1000 PID: 209499 Comm: cc1 Tainted: G WL 6.15.0-rc5-01-3ce9925823c7d6bb0e6eb951bf2db0e9e182582d+ #1 PREEMPT(lazy) [ 1439.966817] Tainted: [W]=WARN, [L]=SOFTLOCKUP [ 1439.966818] Hardware name: ASRock B650I Lightning WiFi/B650I Lightning WiFi, BIOS 3.08 09/18/2024 [ 1439.966819] RIP: 0010:delay_halt_mwaitx+0x20/0x50 And then the system hangs after SOFTLOCKUP. Bisect says that this is commit f1c6be3999d2 Author: Aurabindo Pillai Date: Wed Apr 16 11:26:54 2025 -0400 drm/amd/display: more liberal vmin/vmax update for freesync [Why] FAMS2 expects vmin/vmax to be updated in the case when freesync is off, but supported. But we only update it when freesync is enabled. [How] Change the vsync handler such that dc_stream_adjust_vmin_vmax() its called irrespective of whether freesync is enabled. If freesync is supported, then there is no harm in updating vmin/vmax registers. Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3546 Reviewed-by: ChiaHsuan Chung Signed-off-by: Aurabindo Pillai Signed-off-by: Ray Wu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher (cherry picked from commit cfb2d41831ee5647a4ae0ea7c24971a92d5dfa0d) Cc: sta...@vger.kernel.org drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 16 +++- 1 file changed, 1
[PATCH v2] dt-bindings: display: bridge: renesas, dsi: allow properties from dsi-controller
From: Hugo Villeneuve Allow to inherit valid properties from the dsi-controller. This fixes the following warning when adding a panel property: rzg2lc.dtb: dsi@1085: '#address-cells', '#size-cells', 'panel@0' do not match any of the regexes: 'pinctrl-[0-9]+' from schema $id: http://devicetree.org/schemas/display/bridge/renesas,dsi.yaml# Also add a panel property to the example. Signed-off-by: Hugo Villeneuve --- V1 -> V2: add separate example --- .../bindings/display/bridge/renesas,dsi.yaml | 67 ++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/display/bridge/renesas,dsi.yaml b/Documentation/devicetree/bindings/display/bridge/renesas,dsi.yaml index e08c24633926b..5a99d9b9635e7 100644 --- a/Documentation/devicetree/bindings/display/bridge/renesas,dsi.yaml +++ b/Documentation/devicetree/bindings/display/bridge/renesas,dsi.yaml @@ -128,7 +128,7 @@ required: - power-domains - ports -additionalProperties: false +unevaluatedProperties: false examples: - | @@ -180,4 +180,69 @@ examples: }; }; }; + + - | +#include + +dsi1: dsi@1086 { +#address-cells = <1>; +#size-cells = <0>; +compatible = "renesas,r9a07g044-mipi-dsi", "renesas,rzg2l-mipi-dsi"; +reg = <0x1086 0x2>; +interrupts = , + , + , + , + , + , + ; +interrupt-names = "seq0", "seq1", "vin1", "rcv", + "ferr", "ppi", "debug"; +clocks = <&cpg CPG_MOD R9A07G044_MIPI_DSI_PLLCLK>, + <&cpg CPG_MOD R9A07G044_MIPI_DSI_SYSCLK>, + <&cpg CPG_MOD R9A07G044_MIPI_DSI_ACLK>, + <&cpg CPG_MOD R9A07G044_MIPI_DSI_PCLK>, + <&cpg CPG_MOD R9A07G044_MIPI_DSI_VCLK>, + <&cpg CPG_MOD R9A07G044_MIPI_DSI_LPCLK>; +clock-names = "pllclk", "sysclk", "aclk", "pclk", "vclk", "lpclk"; +resets = <&cpg R9A07G044_MIPI_DSI_CMN_RSTB>, + <&cpg R9A07G044_MIPI_DSI_ARESET_N>, + <&cpg R9A07G044_MIPI_DSI_PRESET_N>; +reset-names = "rst", "arst", "prst"; +power-domains = <&cpg>; + +panel@0 { +compatible = "rocktech,jh057n00900"; +reg = <0>; +vcc-supply = <®_2v8_p>; +iovcc-supply = <®_1v8_p>; +reset-gpios = <&gpio3 13 GPIO_ACTIVE_LOW>; + +port { +panel_in: endpoint { +remote-endpoint = <&dsi1_out>; +}; +}; +}; + +ports { +#address-cells = <1>; +#size-cells = <0>; + +port@0 { +reg = <0>; +dsi1_in: endpoint { +remote-endpoint = <&du_out_dsi1>; +}; +}; + +port@1 { +reg = <1>; +dsi1_out: endpoint { +data-lanes = <1 2 3 4>; +remote-endpoint = <&panel_in>; +}; +}; +}; +}; ... base-commit: 7c1a9408ce5f34ded5a85db81cf80e0975901685 -- 2.39.5
Re: [PATCH v3 16/19] nova-core: Add support for VBIOS ucode extraction for boot
On 5/20/2025 11:01 AM, Danilo Krummrich wrote: > On Tue, May 20, 2025 at 09:43:42AM -0400, Joel Fernandes wrote: >> On 5/20/2025 5:30 AM, Danilo Krummrich wrote: >>> On Tue, May 20, 2025 at 03:55:06AM -0400, Joel Fernandes wrote: On 5/13/2025 1:19 PM, Danilo Krummrich wrote: > On Wed, May 07, 2025 at 10:52:43PM +0900, Alexandre Courbot wrote: >> >> So the code here now looks like the below, definitely better, thanks! : >> >> if let (Some(second_ref), Some(first), Some(pci_at)) = >> (second.as_mut(), first_fwsec_image, pci_at_image) >> { >> second_ref >> .setup_falcon_data(pdev, &pci_at, &first) >> .inspect_err(|e| { >> dev_err!(..) >> })?; >> Ok(Vbios { fwsec_image: second.take().ok_or(EINVAL)? }) >> } else { >> dev_err!( >> pdev.as_ref(), >> "Missing required images for falcon data setup, >> skipping\n" >> ); >> Err(EINVAL) >> } > > Sorry, my code-snipped was incorrect indeed. Let me paste what I actually > intended (and this time properly compile checked) and should be even better: > > if let (Some(mut second), Some(first), Some(pci_at)) = > (second_fwsec_image, first_fwsec_image, pci_at_image) > { > second > .setup_falcon_data(pdev, &pci_at, &first) > .inspect_err(|e| { > dev_err!(pdev.as_ref(), "Falcon data setup failed: {:?}\n", > e) > })?; > > Ok(Vbios(second)) > } else { > dev_err!( > pdev.as_ref(), > "Missing required images for falcon data setup, skipping\n" > ); > > Err(EINVAL) > } > > So, with this second is the actual value and not just a reference. :) > > And the methods can become: > > pub(crate) fn fwsec_header(&self, pdev: &device::Device) -> > Result<&FalconUCodeDescV3> { > self.0.fwsec_header(pdev) > } > > pub(crate) fn fwsec_ucode(&self, pdev: &device::Device) -> > Result<&[u8]> { > self.0.fwsec_ucode(pdev, self.fwsec_header(pdev)?) > } > > pub(crate) fn fwsec_sigs(&self, pdev: &device::Device) -> Result<&[u8]> > { > self.0.fwsec_sigs(pdev, self.fwsec_header(pdev)?) > } I made this change and it LGTM. Thanks! I did not do the '.0' though since I want to keep the readability, lets see in the next revision if that looks good. >>> In general, I feel like a lot of those Option come from a programming >>> pattern >>> that is very common in C, i.e. allocate a structure (stack or heap) and then >>> initialize its fields. >>> >>> In Rust you should aim to initialize all the fields of a structure when you >>> create the instance. Option as a return type of a function is common, but >>> it's >>> always a bit suspicious when there is an Option field in a struct. >> >> I looked into it, I could not git rid of those ones because we need to >> initialize in the "impl TryFrom for BiosImage {" >> >> 0xE0 => Ok(BiosImage::FwSec(FwSecBiosImage { >> base, >> falcon_data_offset: None, >> pmu_lookup_table: None, >> falcon_ucode_offset: None, >> })), >> >> And these fields will not be determined until much later, because as is the >> case >> with the earlier example, these fields cannot be determined until all the >> images >> are parsed. > > You should not use TryFrom, but instead use a normal constructor, such as > > BiosImage::new(base_bios_image) > > and do the parsing within this constructor. > > If you want a helper type with Options while parsing that's totally fine, but > the final result can clearly be without Options. For instance: > > struct Data { > image: KVec, > } > > impl Data { > fn new() -> Result { > let parser = DataParser::new(); > > Self { image: parser.parse()? } > } > > fn load_image(&self) { > ... > } > } > > struct DataParser { > // Only some images have a checksum. > checksum: Option, > // Some images have an extra offset. > offset: Option, > // Some images need to be patched. > patch: Option>, > image: KVec, > } > > impl DataParser { > fn new() -> Self { > Self { >checksum: None, >offset: None, >patch: None, >bytes: KVec::new(), > } > } > > fn parse(self) -> Result> { > // Fetch all the required data. > self.fetch_checksum()?; > self.fetch_offset()?; > self.fetch_patch()?; >
[PATCH v4] dma-buf: heaps: Introduce a new heap for reserved memory
Some reserved memory regions might have particular memory setup or attributes that make them good candidates for heaps. Let's provide a heap type that will create a new heap for each reserved memory region flagged as such. Signed-off-by: Maxime Ripard --- Hi, This series is the follow-up of the discussion that John and I had some time ago here: https://lore.kernel.org/all/candhncqujn6bh3kxkf65bwitylvqsd9892-xtfdhhqqyrro...@mail.gmail.com/ The initial problem we were discussing was that I'm currently working on a platform which has a memory layout with ECC enabled. However, enabling the ECC has a number of drawbacks on that platform: lower performance, increased memory usage, etc. So for things like framebuffers, the trade-off isn't great and thus there's a memory region with ECC disabled to allocate from for such use cases. After a suggestion from John, I chose to first start using heap allocations flags to allow for userspace to ask for a particular ECC setup. This is then backed by a new heap type that runs from reserved memory chunks flagged as such, and the existing DT properties to specify the ECC properties. After further discussion, it was considered that flags were not the right solution, and relying on the names of the heaps would be enough to let userspace know the kind of buffer it deals with. Thus, even though the uAPI part of it has been dropped in this second version, we still need a driver to create heaps out of carved-out memory regions. In addition to the original usecase, a similar driver can be found in BSPs from most vendors, so I believe it would be a useful addition to the kernel. I submitted a draft PR to the DT schema for the bindings used in this PR: https://github.com/devicetree-org/dt-schema/pull/138 Let me know what you think, Maxime --- Changes in v4: - Rebased on 6.15-rc7 - Map buffers only when map is actually called, not at allocation time - Deal with restricted-dma-pool and shared-dma-pool - Reword Kconfig options - Properly report dma_map_sgtable failures - Link to v3: https://lore.kernel.org/r/20250407-dma-buf-ecc-heap-v3-0-97cdd36a5...@kernel.org Changes in v3: - Reworked global variable patch - Link to v2: https://lore.kernel.org/r/20250401-dma-buf-ecc-heap-v2-0-043fd006a...@kernel.org Changes in v2: - Add vmap/vunmap operations - Drop ECC flags uapi - Rebase on top of 6.14 - Link to v1: https://lore.kernel.org/r/20240515-dma-buf-ecc-heap-v1-0-54cbbd049...@kernel.org --- drivers/dma-buf/heaps/Kconfig | 8 + drivers/dma-buf/heaps/Makefile| 1 + drivers/dma-buf/heaps/carveout_heap.c | 388 ++ 3 files changed, 397 insertions(+) diff --git a/drivers/dma-buf/heaps/Kconfig b/drivers/dma-buf/heaps/Kconfig index a5eef06c422644e8aadaf5aff2bd9a33c49c1ba3..1ce4f6828d8c06bfdd7bc2e5127707f1778586e6 100644 --- a/drivers/dma-buf/heaps/Kconfig +++ b/drivers/dma-buf/heaps/Kconfig @@ -1,5 +1,13 @@ +config DMABUF_HEAPS_CARVEOUT + bool "DMA-BUF Carveout Heaps" + depends on DMABUF_HEAPS + help + Choose this option to enable the carveout dmabuf heap. The carveout + heap is backed by pages from reserved memory regions flagged as + exportable. If in doubt, say Y. + config DMABUF_HEAPS_SYSTEM bool "DMA-BUF System Heap" depends on DMABUF_HEAPS help Choose this option to enable the system dmabuf heap. The system heap diff --git a/drivers/dma-buf/heaps/Makefile b/drivers/dma-buf/heaps/Makefile index 974467791032ffb8a7aba17b1407d9a19b3f3b44..b734647ad5c84f449106748160258e372f153df2 100644 --- a/drivers/dma-buf/heaps/Makefile +++ b/drivers/dma-buf/heaps/Makefile @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_DMABUF_HEAPS_CARVEOUT)+= carveout_heap.o obj-$(CONFIG_DMABUF_HEAPS_SYSTEM) += system_heap.o obj-$(CONFIG_DMABUF_HEAPS_CMA) += cma_heap.o diff --git a/drivers/dma-buf/heaps/carveout_heap.c b/drivers/dma-buf/heaps/carveout_heap.c new file mode 100644 index ..3fac190545bc6f853c18a614f6d89176ed2d7df6 --- /dev/null +++ b/drivers/dma-buf/heaps/carveout_heap.c @@ -0,0 +1,388 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include +#include +#include + +struct carveout_heap_priv { + struct dma_heap *heap; + struct gen_pool *pool; +}; + +struct carveout_heap_buffer_priv { + struct mutex lock; + struct list_head attachments; + + unsigned long num_pages; + struct carveout_heap_priv *heap; + phys_addr_t paddr; + void *vaddr; + unsigned int vmap_cnt; +}; + +struct carveout_heap_attachment { + struct list_head head; + struct sg_table table; + + struct device *dev; + bool mapped; +}; + +static int carveout_heap_attach(struct dma_buf *buf, + struct dma_buf_attachment *attachment) +{ + struct carveout_heap_buffer_priv *priv = buf->priv; + struct c
Re: [PATCH v5 01/40] drm/gpuvm: Don't require obj lock in destructor path
On Tue, May 20, 2025 at 07:57:36AM -0700, Rob Clark wrote: > On Tue, May 20, 2025 at 12:23 AM Danilo Krummrich wrote: > > On Mon, May 19, 2025 at 10:51:24AM -0700, Rob Clark wrote: > > > diff --git a/drivers/gpu/drm/drm_gpuvm.c b/drivers/gpu/drm/drm_gpuvm.c > > > index f9eb56f24bef..1e89a98caad4 100644 > > > --- a/drivers/gpu/drm/drm_gpuvm.c > > > +++ b/drivers/gpu/drm/drm_gpuvm.c > > > @@ -1511,7 +1511,9 @@ drm_gpuvm_bo_destroy(struct kref *kref) > > > drm_gpuvm_bo_list_del(vm_bo, extobj, lock); > > > drm_gpuvm_bo_list_del(vm_bo, evict, lock); > > > > > > - drm_gem_gpuva_assert_lock_held(obj); > > > + if (kref_read(&obj->refcount) > 0) > > > + drm_gem_gpuva_assert_lock_held(obj); > > > > Again, this is broken. What if the reference count drops to zero right after > > the kref_read() check, but before drm_gem_gpuva_assert_lock_held() is > > called? > > No, it is not. If you find yourself having this race condition, then > you already have bigger problems. There are only two valid cases when > drm_gpuvm_bo_destroy() is called. Either: > > 1) You somehow hold a reference to the GEM object, in which case the > refcount will be a positive integer. Maybe you race but on either > side of the race you have a value that is greater than zero. > 2) Or, you are calling this in the GEM object destructor path, in > which case no one else should have a reference to the object, so it > isn't possible to race What about: 3) You destroy the VM_BO, because the VM is destroyed, but someone else (e.g. another VM) holds a reference of this BO, which is dropped concurrently? Please don't tell me "but MSM doesn't do that". This is generic infrastructure, it is perfectly valid for drivers to do that. > If the refcount drops to zero after the check, you are about to blow > up regardless. Exactly, that's why the whole approach of removing the reference count a VM_BO has on the BO, i.e. the proposed DRM_GPUVM_VA_WEAK_REF is broken. As mentioned, make it DRM_GPUVM_MSM_LEGACY_QUIRK and get an approval from Dave / Sima for it. You can't make DRM_GPUVM_VA_WEAK_REF work as a generic thing without breaking the whole design and lifetimes of GPUVM. We'd just end up with tons of traps for drivers with lots of WARN_ON() paths and footguns like the one above if a driver works slightly different than MSM.
[PATCH] drm/sitronix: Fix broken backwards-compatibility layer
When moving the Sitronix DRM drivers and renaming their Kconfig symbols, the old symbols were kept, aiming to provide a seamless migration path when running "make olddefconfig" or "make oldconfig". However, the old compatibility symbols are not visible. Hence unless they are selected by another symbol (which they are not), they can never be enabled, and no backwards compatibility is provided. Fix this by making them visible, and inverting the selection logic. Add comments to make it clear why there are two symbols with the same description. Fixes: 9b8f32002cddf792 ("drm/sitronix: move tiny Sitronix drivers to their own subdir") Signed-off-by: Geert Uytterhoeven --- arch/arm/configs/davinci_all_defconfig must be updated after this has hit upstream. --- drivers/gpu/drm/sitronix/Kconfig | 14 -- 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/sitronix/Kconfig b/drivers/gpu/drm/sitronix/Kconfig index c069d0d417753bcf..8b3565b8eca3918e 100644 --- a/drivers/gpu/drm/sitronix/Kconfig +++ b/drivers/gpu/drm/sitronix/Kconfig @@ -10,9 +10,11 @@ config DRM_ST7571_I2C if M is selected the module will be called st7571-i2c. +# To be removed once all users have updated their (def)configs config TINYDRM_ST7586 - tristate - default n + tristate "DRM support for Sitronix ST7586 display panels" + depends on DRM && SPI + select DRM_ST7586 config DRM_ST7586 tristate "DRM support for Sitronix ST7586 display panels" @@ -21,16 +23,17 @@ config DRM_ST7586 select DRM_KMS_HELPER select DRM_GEM_DMA_HELPER select DRM_MIPI_DBI - default TINYDRM_ST7586 help DRM driver for the following Sitronix ST7586 panels: * LEGO MINDSTORMS EV3 If M is selected the module will be called st7586. +# To be removed once all users have updated their (def)configs config TINYDRM_ST7735R - tristate - default n + tristate "DRM support for Sitronix ST7715R/ST7735R display panels" + depends on DRM && SPI + select DRM_ST7735R config DRM_ST7735R tristate "DRM support for Sitronix ST7715R/ST7735R display panels" @@ -40,7 +43,6 @@ config DRM_ST7735R select DRM_GEM_DMA_HELPER select DRM_MIPI_DBI select BACKLIGHT_CLASS_DEVICE - default TINYDRM_ST7735R help DRM driver for Sitronix ST7715R/ST7735R with one of the following LCDs: -- 2.43.0
Re: [PATCH] drm/sitronix: Fix broken backwards-compatibility layer
Hi Am 20.05.25 um 14:40 schrieb Geert Uytterhoeven: When moving the Sitronix DRM drivers and renaming their Kconfig symbols, the old symbols were kept, aiming to provide a seamless migration path when running "make olddefconfig" or "make oldconfig". However, the old compatibility symbols are not visible. Hence unless they are selected by another symbol (which they are not), they can never be enabled, and no backwards compatibility is provided. Fix this by making them visible, and inverting the selection logic. Add comments to make it clear why there are two symbols with the same description. These symbols were only meant for variants of 'make oldconfig' to pick up th enew symbols. They where never for being selected manually. Best regards Thomas Fixes: 9b8f32002cddf792 ("drm/sitronix: move tiny Sitronix drivers to their own subdir") Signed-off-by: Geert Uytterhoeven --- arch/arm/configs/davinci_all_defconfig must be updated after this has hit upstream. --- drivers/gpu/drm/sitronix/Kconfig | 14 -- 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/sitronix/Kconfig b/drivers/gpu/drm/sitronix/Kconfig index c069d0d417753bcf..8b3565b8eca3918e 100644 --- a/drivers/gpu/drm/sitronix/Kconfig +++ b/drivers/gpu/drm/sitronix/Kconfig @@ -10,9 +10,11 @@ config DRM_ST7571_I2C if M is selected the module will be called st7571-i2c. +# To be removed once all users have updated their (def)configs config TINYDRM_ST7586 - tristate - default n + tristate "DRM support for Sitronix ST7586 display panels" + depends on DRM && SPI + select DRM_ST7586 config DRM_ST7586 tristate "DRM support for Sitronix ST7586 display panels" @@ -21,16 +23,17 @@ config DRM_ST7586 select DRM_KMS_HELPER select DRM_GEM_DMA_HELPER select DRM_MIPI_DBI - default TINYDRM_ST7586 help DRM driver for the following Sitronix ST7586 panels: * LEGO MINDSTORMS EV3 If M is selected the module will be called st7586. +# To be removed once all users have updated their (def)configs config TINYDRM_ST7735R - tristate - default n + tristate "DRM support for Sitronix ST7715R/ST7735R display panels" + depends on DRM && SPI + select DRM_ST7735R config DRM_ST7735R tristate "DRM support for Sitronix ST7715R/ST7735R display panels" @@ -40,7 +43,6 @@ config DRM_ST7735R select DRM_GEM_DMA_HELPER select DRM_MIPI_DBI select BACKLIGHT_CLASS_DEVICE - default TINYDRM_ST7735R help DRM driver for Sitronix ST7715R/ST7735R with one of the following LCDs: -- -- 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)
Re: [PATCH v5 02/12] drm: renesas: rz-du: Add support for RZ/V2H(P) SoC
Hi Prabhakar, Thank you for the patch. On Mon, May 12, 2025 at 07:23:20PM +0100, Prabhakar wrote: > From: Lad Prabhakar > > The LCD controller (LCDC) on the RZ/V2H(P) SoC is composed of Frame > Compression Processor (FCPVD), Video Signal Processor (VSPD), and > Display Unit (DU). > > There is one LCDC unit available on the RZ/V2H(P) SoC which is connected > to the DSI. > > Signed-off-by: Lad Prabhakar > Reviewed-by: Biju Das Reviewed-by: Laurent Pinchart > --- > v4->v5: > - Added reviewed tag from Biju > > v3->v4: > - No changes > > v2->v3: > - No changes > > v1->v2: > - No changes > --- > drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c | 11 +++ > 1 file changed, 11 insertions(+) > > diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c > b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c > index 5e40f0c1e7b0..e1aa6a719529 100644 > --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c > +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c > @@ -50,9 +50,20 @@ static const struct rzg2l_du_device_info > rzg2l_du_r9a07g044_info = { > } > }; > > +static const struct rzg2l_du_device_info rzg2l_du_r9a09g057_info = { > + .channels_mask = BIT(0), > + .routes = { > + [RZG2L_DU_OUTPUT_DSI0] = { > + .possible_outputs = BIT(0), > + .port = 0, > + }, > + }, > +}; > + > static const struct of_device_id rzg2l_du_of_table[] = { > { .compatible = "renesas,r9a07g043u-du", .data = > &rzg2l_du_r9a07g043u_info }, > { .compatible = "renesas,r9a07g044-du", .data = > &rzg2l_du_r9a07g044_info }, > + { .compatible = "renesas,r9a09g057-du", .data = > &rzg2l_du_r9a09g057_info }, > { /* sentinel */ } > }; > -- Regards, Laurent Pinchart
Re: [PATCH v5 01/12] dt-bindings: display: renesas,rzg2l-du: Add support for RZ/V2H(P) SoC
Hi Prabhakar, Thank you for the patch. On Mon, May 12, 2025 at 07:23:19PM +0100, Prabhakar wrote: > From: Lad Prabhakar > > The DU block on the RZ/V2H(P) SoC is identical to the one found on the > RZ/G2L SoC. However, it only supports the DSI interface, whereas the > RZ/G2L supports both DSI and DPI interfaces. > > Due to this difference, a SoC-specific compatible string > 'renesas,r9a09g057-du' is added for the RZ/V2H(P) SoC. > > Signed-off-by: Lad Prabhakar > Reviewed-by: Krzysztof Kozlowski > Reviewed-by: Biju Das Reviewed-by: Laurent Pinchart > --- > v4->v5: > - Added reviewed tag from Biju > > v3->v4: > - No changes > > v2->v3: > - Collected reviewed tag from Krzysztof > > v1->v2: > - Kept the sort order for schema validation > - Added `port@1: false` for RZ/V2H(P) SoC > --- > .../bindings/display/renesas,rzg2l-du.yaml| 23 ++- > 1 file changed, 22 insertions(+), 1 deletion(-) > > diff --git a/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml > b/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml > index 95e3d5e74b87..1e32d14b6edb 100644 > --- a/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml > +++ b/Documentation/devicetree/bindings/display/renesas,rzg2l-du.yaml > @@ -20,6 +20,7 @@ properties: >- enum: >- renesas,r9a07g043u-du # RZ/G2UL >- renesas,r9a07g044-du # RZ/G2{L,LC} > + - renesas,r9a09g057-du # RZ/V2H(P) >- items: >- enum: >- renesas,r9a07g054-du# RZ/V2L > @@ -101,7 +102,12 @@ allOf: > >required: > - port@0 > -else: > + - if: > + properties: > +compatible: > + contains: > +const: renesas,r9a07g044-du > +then: >properties: > ports: >properties: > @@ -113,6 +119,21 @@ allOf: >required: > - port@0 > - port@1 > + - if: > + properties: > +compatible: > + contains: > +const: renesas,r9a09g057-du > +then: > + properties: > +ports: > + properties: > +port@0: > + description: DSI > +port@1: false > + > + required: > +- port@0 > > examples: ># RZ/G2L DU -- Regards, Laurent Pinchart
Re: [PATCH v5 03/12] drm: renesas: rz-du: mipi_dsi: Add min check for VCLK range
Hi Prabhakar, On Mon, May 12, 2025 at 07:23:21PM +0100, Prabhakar wrote: > From: Lad Prabhakar > > The VCLK range for Renesas RZ/G2L SoC is 148.5 MHz to 5.803 MHz. Add a I would write "5.803 MHz to 148.5 MHz" as ranges are usually expressed in increasing order. Reviewed-by: Laurent Pinchart > minimum clock check in the mode_valid callback to ensure that the clock > value does not fall below the valid range. > > Co-developed-by: Fabrizio Castro > Signed-off-by: Fabrizio Castro > Signed-off-by: Lad Prabhakar > Reviewed-by: Biju Das > --- > v4->v5: > - No changes > > v3->v4: > - No changes > > v2->v3: > - No changes > > v1->v2: > - Added reviewed tag from Biju > --- > drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > index 4550c6d84796..ec8baecb9ba5 100644 > --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > @@ -584,6 +584,9 @@ rzg2l_mipi_dsi_bridge_mode_valid(struct drm_bridge > *bridge, > if (mode->clock > 148500) > return MODE_CLOCK_HIGH; > > + if (mode->clock < 5803) > + return MODE_CLOCK_LOW; > + > return MODE_OK; > } > -- Regards, Laurent Pinchart
Re: [PATCH AUTOSEL 5.15 090/153] drm/amd/display: fix dcn4x init failed
On Tue, May 06, 2025 at 11:00:58AM -0400, Alex Deucher wrote: On Mon, May 5, 2025 at 7:16 PM Sasha Levin wrote: From: Charlene Liu [ Upstream commit 23ef388a84c72b0614a6c10f866ffeac7e807719 ] [why] failed due to cmdtable not created. switch atombios cmdtable as default. Reviewed-by: Alvin Lee Signed-off-by: Charlene Liu Signed-off-by: Zaeem Mohamed Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin Support for DCN 4 was added in 6.11 I think so there is no need to backport DCN 4.x fixes to kernels older than 6.11. I'll drop it from older trees, thanks! -- Thanks, Sasha
Re: [PATCH v4 05/40] iommu/io-pgtable-arm: Add quirk to quiet WARN_ON()
On Tue, May 20, 2025 at 02:06:09PM +0100, Robin Murphy wrote: > On 2025-05-20 12:31 pm, Will Deacon wrote: > > On Thu, May 15, 2025 at 07:48:39AM -0700, Rob Clark wrote: > > > On Thu, May 15, 2025 at 7:33 AM Will Deacon wrote: > > > > On Wed, May 14, 2025 at 10:53:19AM -0700, Rob Clark wrote: > > > > > diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h > > > > > index bba2a51c87d2..639b8f4fb87d 100644 > > > > > --- a/include/linux/io-pgtable.h > > > > > +++ b/include/linux/io-pgtable.h > > > > > @@ -88,6 +88,13 @@ struct io_pgtable_cfg { > > > > > * > > > > > * IO_PGTABLE_QUIRK_ARM_HD: Enables dirty tracking in stage 1 > > > > > pagetable. > > > > > * IO_PGTABLE_QUIRK_ARM_S2FWB: Use the FWB format for the > > > > > MemAttrs bits > > > > > + * > > > > > + * IO_PGTABLE_QUIRK_NO_WARN_ON: Do not WARN_ON() on conflicting > > > > > + * mappings, but silently return -EEXISTS. Normally an > > > > > attempt > > > > > + * to map over an existing mapping would indicate some > > > > > sort of > > > > > + * kernel bug, which would justify the WARN_ON(). But for > > > > > GPU > > > > > + * drivers, this could be under control of userspace. > > > > > Which > > > > > + * deserves an error return, but not to spam dmesg. > > > > > */ > > > > >#define IO_PGTABLE_QUIRK_ARM_NS BIT(0) > > > > >#define IO_PGTABLE_QUIRK_NO_PERMS BIT(1) > > > > > @@ -97,6 +104,7 @@ struct io_pgtable_cfg { > > > > >#define IO_PGTABLE_QUIRK_ARM_OUTER_WBWA BIT(6) > > > > >#define IO_PGTABLE_QUIRK_ARM_HD BIT(7) > > > > >#define IO_PGTABLE_QUIRK_ARM_S2FWB BIT(8) > > > > > + #define IO_PGTABLE_QUIRK_NO_WARN_ON BIT(9) > > > > > > > > This feels a bit fragile to me: > > > >* IOMMU-API users of io-pgtable shouldn't be passing this quirk > > > > but might end up doing so to paper over driver bugs. > > > > > > > >* Low-level users of io-pgtable who expose page-table operations to > > > > userspace need to pass the quirk, but might well not bother because > > > > well-behaved userspace doesn't trigger the warning. > > > > > > > > So overall, it's all a bit unsatisfactory. Is there a way we could have > > > > the warnings only when invoked via the IOMMU API? > > > > > > iommu drivers _not_ setting this flag seems like a good way to achieve > > > that ;-) > > > > > > The alternative is to move the warns to the iommu driver... but they > > > could just as easily remove the WARN_ON()s as they could set the > > > NO_WARN_ON quirk, so :shrug:? > > > > Bah, I also don't have a good idea to improve this, so I guess I'll take > > what you have for now. > > Hmm, just a nit on reflection, how about fixing up the name to just > IO_PGTABLE_QUIRK_NO_WARN? Given that it's already quite long, and we have a > well-established DMA_ATTR_NO_WARN with equivalent semantics over in the DMA > API. Sure, I'll do that now... Will
Re: [PATCH v5 04/12] drm: renesas: rz-du: mipi_dsi: Simplify HSFREQ calculation
Hi Prabhakar, Thank you for the patch. On Mon, May 12, 2025 at 07:23:22PM +0100, Prabhakar wrote: > From: Lad Prabhakar > > Simplify the high-speed clock frequency (HSFREQ) calculation by removing > the redundant multiplication and division by 8. The updated equation: > > hsfreq = (mode->clock * bpp) / (dsi->lanes); You can drop the parentheses around the second factor. You can actuall drop all prentheses. > > produces the same result while improving readability and clarity. > > Additionally, update the comment to clarify the relationship between HS > clock bit frequency, HS byte clock frequency, and HSFREQ. > > Signed-off-by: Lad Prabhakar > Reviewed-by: Biju Das > --- > v4->v5: > - No changes > > v3->v4: > - No changes > > v2->v3: > - No changes > > v1->v2: > - Added Reviewed-by tag from Biju > --- > drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > index ec8baecb9ba5..c5f698cd74f1 100644 > --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > @@ -277,10 +277,10 @@ static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi > *dsi, >* hsclk: DSI HS Byte clock frequency (Hz) >* lanes: number of data lanes >* > - * hsclk(bit) = hsclk(byte) * 8 > + * hsclk(bit) = hsclk(byte) * 8 = hsfreq >*/ > bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); > - hsfreq = (mode->clock * bpp * 8) / (8 * dsi->lanes); > + hsfreq = (mode->clock * bpp) / dsi->lanes; You can drop the parentheses here too. Reviewed-by: Laurent Pinchart > > ret = pm_runtime_resume_and_get(dsi->dev); > if (ret < 0) -- Regards, Laurent Pinchart
Re: [PATCH AUTOSEL 6.6 229/294] drm/amd/display/dc: enable oem i2c support for DCE 12.x
On Tue, May 06, 2025 at 11:02:34AM -0400, Alex Deucher wrote: On Mon, May 5, 2025 at 7:04 PM Sasha Levin wrote: From: Alex Deucher [ Upstream commit 2ed83f2cc41e8f7ced1c0610ec2b0821c5522ed5 ] Use the value pulled from the vbios just like newer chips. Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin This is a new feature not a bug fix and this change only makes sense with the other changes in kernel 6.15. I'll drop it, thanks! -- Thanks, Sasha
Re: [PATCH AUTOSEL 6.14 248/642] drm/amdgpu: add dce_v6_0_soft_reset() to DCE6
On Tue, May 06, 2025 at 11:05:15AM -0400, Alex Deucher wrote: On Mon, May 5, 2025 at 6:24 PM Sasha Levin wrote: From: Alexandre Demers [ Upstream commit ab23db6d08efdda5d13d01a66c593d0e57f8917f ] DCE6 was missing soft reset, but it was easily identifiable under radeon. This should be it, pretty much as it is done under DCE8 and DCE10. Signed-off-by: Alexandre Demers Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin This is not stable material. Dropped, thanks! -- Thanks, Sasha
Re: [PATCH] drm/sitronix: Fix broken backwards-compatibility layer
Thomas Zimmermann writes: > Hi > > Am 20.05.25 um 15:09 schrieb Geert Uytterhoeven: >> Hi Thomas, >> >> On Tue, 20 May 2025 at 15:04, Thomas Zimmermann wrote: >>> Am 20.05.25 um 14:40 schrieb Geert Uytterhoeven: When moving the Sitronix DRM drivers and renaming their Kconfig symbols, the old symbols were kept, aiming to provide a seamless migration path when running "make olddefconfig" or "make oldconfig". However, the old compatibility symbols are not visible. Hence unless they are selected by another symbol (which they are not), they can never be enabled, and no backwards compatibility is provided. Fix this by making them visible, and inverting the selection logic. Add comments to make it clear why there are two symbols with the same description. >>> These symbols were only meant for variants of 'make oldconfig' to pick >>> up th enew symbols. They where never for being selected manually. >> But that pick-up does not work, unfortunately... >> (I know, I had one of them enabled in one of my configs ;-) > > I see. > >> >> The alternative is to just drop the old symbols, and ignore current users. >> Which is not that uncommon... > > If there's no easy fix for the current setup, I'd prefer removing the > old symbols. > I agree. When this was discussed, I argued that we should just remove the old symbols and let kernel packagers to deal with it. As Geert said, it's not uncommon for Kconfig symbols names to change over time... -- Best regards, Javier Martinez Canillas Core Platforms Red Hat
Re: [PATCH v1] drm/panel-edp: Add support for AUO G156HAN03.0 panel
Hi, On Tue, May 20, 2025 at 5:43 AM wrote: > > From: Ernest Van Hoecke > > AUO G156HAN03.0 EDID: > > 00 ff ff ff ff ff ff 00 06 af ed 30 00 00 00 00 > 1a 1c 01 04 a5 22 13 78 02 05 b5 94 59 59 92 28 > 1d 50 54 00 00 00 01 01 01 01 01 01 01 01 01 01 > 01 01 01 01 01 01 78 37 80 b4 70 38 2e 40 6c 30 > aa 00 58 c1 10 00 00 18 00 00 00 0f 00 00 00 00 > 00 00 00 00 00 00 00 00 00 20 00 00 00 fe 00 41 > 55 4f 0a 20 20 20 20 20 20 20 20 20 00 00 00 fe > 00 47 31 35 36 48 41 4e 30 33 2e 30 20 0a 00 bb > > Signed-off-by: Ernest Van Hoecke > --- > drivers/gpu/drm/panel/panel-edp.c | 1 + > 1 file changed, 1 insertion(+) Reviewed-by: Douglas Anderson Pushed to drm-misc-next: [1/1] drm/panel-edp: Add support for AUO G156HAN03.0 panel commit: a4b4e3fd536763b3405c70ef97a6e7f9af8a00dc
Re: [PATCH v2 3/3] drm/panfrost: show device-wide list of DRM GEM objects over DebugFS
Hi Steven, Thanks for the fix, I've tested it and it fixes the outstanding issue. However, including the perfcnt sample buffer in the DebugFS GEMs file raises the question of what to do with its labelling, because it isn't exposed to UM through a handle, so my previous assumption about not needing to handle static labels when tagging BO's within the driver no longer holds. This might require some quick rewrite so that the sample BO can be displayed with a fitting name. On 19.05.2025 17:02, Steven Price wrote: > On 15/05/2025 19:04, Daniel Stone wrote: > > Hi Steven, > > > > On Thu, 8 May 2025 at 11:42, Steven Price wrote: > >> I'm also seeing a splat when running this, see below. I haven't got my > >> head around how this is happening, but I see it when glmark quits at the > >> end of the test. > >> > >> [ 399.505066] Unable to handle kernel NULL pointer dereference at virtual > >> address 0004 when write > >> [...] > >> [ 399.882216] Call trace: > >> [ 399.88] panfrost_gem_free_object [panfrost] from > >> drm_gem_handle_delete+0x84/0xb0 > >> [ 399.893813] drm_gem_handle_delete from drm_ioctl+0x2b8/0x4f4 > >> [ 399.900237] drm_ioctl from sys_ioctl+0x428/0xe30 > >> [ 399.905496] sys_ioctl from ret_fast_syscall+0x0/0x1c > > > > S. Let's assume it has to actually occur in > > panfrost_gem_debugfs_bo_rm(), since that's all that's changed here. > > > > I don't think pfdev can be NULL here, because we've already > > dereferenced ptdev and written to a structure member earlier in > > panfrost_gem_free_object(). I don't think it can be the debugfs mutex, > > because a) that's initialised with the device, and b) wouldn't be > > offset 0x4. > > > > I'm looking then at list_del_init(&bo->debugfs.node), which would > > effectively execute bo->debugfs.node->next->prev = > > bo->debugfs.node->prev. So if bo->debugfs.node->next was NULL, that > > would explain a write to 0x4 on 32-bit systems. > > So I finally got some time to do some debugging on this. And you are > absolutely correct on where the fault is triggered. > > The cause of it is that panfrost_gem_debugfs_bo_add() is called from > panfrost_gem_create(), but that isn't the only place that Panfrost GEM > objects are created - it turns out panfrost_perfcnt_enable_locked() also > calls drm_gem_shmem_create(). And in that case the list next/prev > pointers are left set to NULL, causing things to blow up when the GEM > object is freed. > > The below patch gets things working, or alternatively just init the list > in panfrost_gem_create_object() if we don't want to include the perfcnt > buffer in the list. > Steve > > ---8<-- > diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c > b/drivers/gpu/drm/panfrost/panfrost_gem.c > index fe2cdbe8baf0..51da13cd81f0 100644 > --- a/drivers/gpu/drm/panfrost/panfrost_gem.c > +++ b/drivers/gpu/drm/panfrost/panfrost_gem.c > @@ -297,13 +297,14 @@ struct drm_gem_object > *panfrost_gem_create_object(struct drm_device *dev, size_t > obj->base.map_wc = !pfdev->coherent; > mutex_init(&obj->label.lock); > > + panfrost_gem_debugfs_bo_add(pfdev, obj); > + > return &obj->base.base; > } > > struct panfrost_gem_object * > panfrost_gem_create(struct drm_device *dev, size_t size, u32 flags) > { > - struct panfrost_device *pfdev = dev->dev_private; > struct drm_gem_shmem_object *shmem; > struct panfrost_gem_object *bo; > > @@ -319,8 +320,6 @@ panfrost_gem_create(struct drm_device *dev, size_t > size, u32 flags) > bo->noexec = !!(flags & PANFROST_BO_NOEXEC); > bo->is_heap = !!(flags & PANFROST_BO_HEAP); > > - panfrost_gem_debugfs_bo_add(pfdev, bo); > - > return bo; > }
Re: [PATCH] drm/sitronix: Fix broken backwards-compatibility layer
Hi Thomas, On Tue, 20 May 2025 at 15:04, Thomas Zimmermann wrote: > Am 20.05.25 um 14:40 schrieb Geert Uytterhoeven: > > When moving the Sitronix DRM drivers and renaming their Kconfig symbols, > > the old symbols were kept, aiming to provide a seamless migration path > > when running "make olddefconfig" or "make oldconfig". > > > > However, the old compatibility symbols are not visible. Hence unless > > they are selected by another symbol (which they are not), they can never > > be enabled, and no backwards compatibility is provided. > > > > Fix this by making them visible, and inverting the selection logic. > > Add comments to make it clear why there are two symbols with the same > > description. > > These symbols were only meant for variants of 'make oldconfig' to pick > up th enew symbols. They where never for being selected manually. But that pick-up does not work, unfortunately... (I know, I had one of them enabled in one of my configs ;-) The alternative is to just drop the old symbols, and ignore current users. Which is not that uncommon... 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] drm/sitronix: Fix broken backwards-compatibility layer
Hi Am 20.05.25 um 15:09 schrieb Geert Uytterhoeven: Hi Thomas, On Tue, 20 May 2025 at 15:04, Thomas Zimmermann wrote: Am 20.05.25 um 14:40 schrieb Geert Uytterhoeven: When moving the Sitronix DRM drivers and renaming their Kconfig symbols, the old symbols were kept, aiming to provide a seamless migration path when running "make olddefconfig" or "make oldconfig". However, the old compatibility symbols are not visible. Hence unless they are selected by another symbol (which they are not), they can never be enabled, and no backwards compatibility is provided. Fix this by making them visible, and inverting the selection logic. Add comments to make it clear why there are two symbols with the same description. These symbols were only meant for variants of 'make oldconfig' to pick up th enew symbols. They where never for being selected manually. But that pick-up does not work, unfortunately... (I know, I had one of them enabled in one of my configs ;-) I see. The alternative is to just drop the old symbols, and ignore current users. Which is not that uncommon... If there's no easy fix for the current setup, I'd prefer removing the old symbols. Best regards Thomas Gr{oetje,eeting}s, Geert -- -- 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)
Re: [PATCH v5 01/40] drm/gpuvm: Don't require obj lock in destructor path
On Tue, May 20, 2025 at 12:23 AM Danilo Krummrich wrote: > > On Mon, May 19, 2025 at 10:51:24AM -0700, Rob Clark wrote: > > From: Rob Clark > > > > See commit a414fe3a2129 ("drm/msm/gem: Drop obj lock in > > msm_gem_free_object()") for justification. > > I asked for a proper commit message in v4. Sorry, I forgot that, here is what I am adding: Destroying a GEM object is a special case. Acquiring the resv lock when the object is being freed can cause a locking order inversion between reservation_ww_class_mutex and fs_reclaim. This deadlock is not actually possible, because no one should be already holding the lock when free_object() is called. Unfortunately lockdep is not aware of this detail. So when the refcount drops to zero, we pretend it is already locked. > Only referring to a driver commit and let the people figure out how the driver > works and what it does in order to motivate a change in the generic > infrastructure is simply unreasonable. > > > Cc: Danilo Krummrich > > Signed-off-by: Rob Clark > > --- > > drivers/gpu/drm/drm_gpuvm.c | 7 +-- > > 1 file changed, 5 insertions(+), 2 deletions(-) > > > > diff --git a/drivers/gpu/drm/drm_gpuvm.c b/drivers/gpu/drm/drm_gpuvm.c > > index f9eb56f24bef..1e89a98caad4 100644 > > --- a/drivers/gpu/drm/drm_gpuvm.c > > +++ b/drivers/gpu/drm/drm_gpuvm.c > > @@ -1511,7 +1511,9 @@ drm_gpuvm_bo_destroy(struct kref *kref) > > drm_gpuvm_bo_list_del(vm_bo, extobj, lock); > > drm_gpuvm_bo_list_del(vm_bo, evict, lock); > > > > - drm_gem_gpuva_assert_lock_held(obj); > > + if (kref_read(&obj->refcount) > 0) > > + drm_gem_gpuva_assert_lock_held(obj); > > Again, this is broken. What if the reference count drops to zero right after > the kref_read() check, but before drm_gem_gpuva_assert_lock_held() is called? No, it is not. If you find yourself having this race condition, then you already have bigger problems. There are only two valid cases when drm_gpuvm_bo_destroy() is called. Either: 1) You somehow hold a reference to the GEM object, in which case the refcount will be a positive integer. Maybe you race but on either side of the race you have a value that is greater than zero. 2) Or, you are calling this in the GEM object destructor path, in which case no one else should have a reference to the object, so it isn't possible to race If the refcount drops to zero after the check, you are about to blow up regardless. BR, -R > Putting conditionals on a refcount is always suspicious. > > If you still really want this, please guard it with > > if (unlikely(gpuvm->flags & DRM_GPUVM_MSM_LEGACY_QUIRK)) > > and get an explicit waiver from Dave / Sima. >
Re: [PATCH v5 3/3] drm/xe: Add WA BB to capture active context utilization
On Tue, May 20, 2025 at 10:01:59AM +0100, Tvrtko Ursulin wrote: Hi, One question below in the context of the missing workarounds series I am working on: On 09/05/2025 17:12, Umesh Nerlige Ramappa wrote: 8>< +#define CONTEXT_ACTIVE 1ULL +static void xe_lrc_setup_utilization(struct xe_lrc *lrc) +{ + u32 *cmd; + + cmd = lrc->bb_per_ctx_bo->vmap.vaddr; + + *cmd++ = MI_STORE_REGISTER_MEM | MI_SRM_USE_GGTT | MI_SRM_ADD_CS_OFFSET; + *cmd++ = ENGINE_ID(0).addr; + *cmd++ = __xe_lrc_engine_id_ggtt_addr(lrc); + *cmd++ = 0; + + *cmd++ = MI_STORE_DATA_IMM | MI_SDI_GGTT | MI_SDI_NUM_DW(1); + *cmd++ = __xe_lrc_ctx_timestamp_ggtt_addr(lrc); + *cmd++ = 0; + *cmd++ = lower_32_bits(CONTEXT_ACTIVE); + + if (lrc_to_xe(lrc)->info.has_64bit_timestamp) { + *cmd++ = MI_STORE_DATA_IMM | MI_SDI_GGTT | MI_SDI_NUM_DW(1); + *cmd++ = __xe_lrc_ctx_timestamp_udw_ggtt_addr(lrc); + *cmd++ = 0; + *cmd++ = upper_32_bits(CONTEXT_ACTIVE); + } + + *cmd++ = MI_BATCH_BUFFER_END; Matt Roper raised the suggestion in another series that we should always use the iosys helpers for writing into mapped BOs. Later I realised this code uses the same shortcut as I did. I probably even lifted the concept since I placed my function right next to this one. :) So question is what is the definitive recommended way to write into mapped BOs? Is the direct writes shortcut acceptable, or this also needs changing? right, I missed that during review. We may have a problem in !x86 if we have __iomem here. So yes, we need to change. So probably: cmd = &lrc->bb_per_ctx_bo->vmap; xe_map_write32(xe, cmd, MI_STORE_REGISTER_MEM | MI_SRM_USE_GGTT | MI_SRM_ADD_CS_OFFSET); xe_map_write32(xe, cmd, ENGINE_ID(0).addr); ... maybe we could add an iosys_map_wr_many() that would be a variadic version with offset incr and hopefully the check for is_iomem in a single place. Another option would be a local buffer that we memcpy at the end. +Thomas Zimmerman / +Sima Lucas De Marchi + + xe_lrc_write_ctx_reg(lrc, CTX_BB_PER_CTX_PTR, +xe_bo_ggtt_addr(lrc->bb_per_ctx_bo) | 1); Btw here code uses the iosys helpers. It is a different BO but they are created/mapped the same AFAICT. Regards, Tvrtko
Re: [PATCH v5 05/12] drm: renesas: rz-du: mipi_dsi: Use VCLK for HSFREQ calculation
Hi Prabhakar, On Mon, 12 May 2025 at 20:23, Prabhakar wrote: > From: Lad Prabhakar > > Update the RZ/G2L MIPI DSI driver to calculate HSFREQ using the actual > VCLK rate instead of the mode clock. The relationship between HSCLK and > VCLK is: > > vclk * bpp <= hsclk * 8 * lanes > > Retrieve the VCLK rate using `clk_get_rate(dsi->vclk)`, ensuring that > HSFREQ accurately reflects the clock rate set in hardware, leading to > better precision in data transmission. > > Additionally, use `DIV_ROUND_CLOSEST_ULL` for a more precise division > when computing `hsfreq`. Also, update unit conversions to use correct > scaling factors for better clarity and correctness. > > Since `clk_get_rate()` returns the clock rate in Hz, update the HSFREQ > threshold comparisons to use Hz instead of kHz to ensure correct behavior. > > Co-developed-by: Fabrizio Castro > Signed-off-by: Fabrizio Castro > Signed-off-by: Lad Prabhakar > Reviewed-by: Biju Das > --- > v4->v5: > - Added dev_info() to print the VCLK rate if it doesn't match the > requested rate. > - Added Reviewed-by tag from Biju > > v3->v4: > - Used MILLI instead of KILO Thanks for the update! > --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > @@ -269,6 +271,12 @@ static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi > *dsi, > u32 golpbkt; > int ret; > > + ret = pm_runtime_resume_and_get(dsi->dev); > + if (ret < 0) > + return ret; > + > + clk_set_rate(dsi->vclk, mode->clock * MILLI); drm_display_mode.clock is in kHz, so s/MILLI/KILO/ > + > /* > * Relationship between hsclk and vclk must follow > * vclk * bpp = hsclk * 8 * lanes > @@ -280,13 +288,11 @@ static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi > *dsi, > * hsclk(bit) = hsclk(byte) * 8 = hsfreq > */ > bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); > - hsfreq = (mode->clock * bpp) / dsi->lanes; > - > - ret = pm_runtime_resume_and_get(dsi->dev); > - if (ret < 0) > - return ret; > - > - clk_set_rate(dsi->vclk, mode->clock * 1000); > + vclk_rate = clk_get_rate(dsi->vclk); > + if (vclk_rate != mode->clock * MILLI) > + dev_info(dsi->dev, "Requested vclk rate %lu, actual %lu > mismatch\n", > +mode->clock * MILLI, vclk_rate); Likewise. > + hsfreq = DIV_ROUND_CLOSEST_ULL(vclk_rate * bpp, dsi->lanes); > > ret = rzg2l_mipi_dsi_dphy_init(dsi, hsfreq); > if (ret < 0) 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 v3 16/19] nova-core: Add support for VBIOS ucode extraction for boot
On Tue, May 20, 2025 at 09:43:42AM -0400, Joel Fernandes wrote: > On 5/20/2025 5:30 AM, Danilo Krummrich wrote: > > On Tue, May 20, 2025 at 03:55:06AM -0400, Joel Fernandes wrote: > >> On 5/13/2025 1:19 PM, Danilo Krummrich wrote: > >>> On Wed, May 07, 2025 at 10:52:43PM +0900, Alexandre Courbot wrote: > > So the code here now looks like the below, definitely better, thanks! : > > if let (Some(second_ref), Some(first), Some(pci_at)) = > (second.as_mut(), first_fwsec_image, pci_at_image) > { > second_ref > .setup_falcon_data(pdev, &pci_at, &first) > .inspect_err(|e| { > dev_err!(..) > })?; > Ok(Vbios { fwsec_image: second.take().ok_or(EINVAL)? }) > } else { > dev_err!( > pdev.as_ref(), > "Missing required images for falcon data setup, > skipping\n" > ); > Err(EINVAL) > } Sorry, my code-snipped was incorrect indeed. Let me paste what I actually intended (and this time properly compile checked) and should be even better: if let (Some(mut second), Some(first), Some(pci_at)) = (second_fwsec_image, first_fwsec_image, pci_at_image) { second .setup_falcon_data(pdev, &pci_at, &first) .inspect_err(|e| { dev_err!(pdev.as_ref(), "Falcon data setup failed: {:?}\n", e) })?; Ok(Vbios(second)) } else { dev_err!( pdev.as_ref(), "Missing required images for falcon data setup, skipping\n" ); Err(EINVAL) } So, with this second is the actual value and not just a reference. :) And the methods can become: pub(crate) fn fwsec_header(&self, pdev: &device::Device) -> Result<&FalconUCodeDescV3> { self.0.fwsec_header(pdev) } pub(crate) fn fwsec_ucode(&self, pdev: &device::Device) -> Result<&[u8]> { self.0.fwsec_ucode(pdev, self.fwsec_header(pdev)?) } pub(crate) fn fwsec_sigs(&self, pdev: &device::Device) -> Result<&[u8]> { self.0.fwsec_sigs(pdev, self.fwsec_header(pdev)?) } However, I don't understand why they're not just implemented for FwSecBiosImage itself this way. You can just implement Deref for Vbios then. > > In general, I feel like a lot of those Option come from a programming > > pattern > > that is very common in C, i.e. allocate a structure (stack or heap) and then > > initialize its fields. > > > > In Rust you should aim to initialize all the fields of a structure when you > > create the instance. Option as a return type of a function is common, but > > it's > > always a bit suspicious when there is an Option field in a struct. > > I looked into it, I could not git rid of those ones because we need to > initialize in the "impl TryFrom for BiosImage {" > > 0xE0 => Ok(BiosImage::FwSec(FwSecBiosImage { > base, > falcon_data_offset: None, > pmu_lookup_table: None, > falcon_ucode_offset: None, > })), > > And these fields will not be determined until much later, because as is the > case > with the earlier example, these fields cannot be determined until all the > images > are parsed. You should not use TryFrom, but instead use a normal constructor, such as BiosImage::new(base_bios_image) and do the parsing within this constructor. If you want a helper type with Options while parsing that's totally fine, but the final result can clearly be without Options. For instance: struct Data { image: KVec, } impl Data { fn new() -> Result { let parser = DataParser::new(); Self { image: parser.parse()? } } fn load_image(&self) { ... } } struct DataParser { // Only some images have a checksum. checksum: Option, // Some images have an extra offset. offset: Option, // Some images need to be patched. patch: Option>, image: KVec, } impl DataParser { fn new() -> Self { Self { checksum: None, offset: None, patch: None, bytes: KVec::new(), } } fn parse(self) -> Result> { // Fetch all the required data. self.fetch_checksum()?; self.fetch_offset()?; self.fetch_patch()?; self.fetch_byes()?; // Doesn't do anything if `checksum == None`. self.validate_checksum()?; // Doesn't do an
Re: [RFC 0/2] Introduce a sysfs interface for lmem information
(+ Tvrtko, Rodrigo and Jani) Quoting Krzysztof Niemiec (2025-05-19 18:34:14) > Hi, > > This series introduces a way for applications to read local memory > information via files in the sysfs. So far the only way to do this was > via i915_query ioctl. This is slightly less handy than sysfs for > external users. Additionally, the ioctl has a capability check which > limits which users of a system might use it to get information. > > The goals of this series are: > > 1) Introduce a simpler interface to access lmem information, > 2) Lift the CAP_PERFMON check on that information, OR provide >the administrator with a way to optionally lift it. > > The first patch introduces the general mechanism without protections. > This will effectively lift a capability check on obtaining the memory > information. The second patch introduces that check back inside the > _show() functions, but also adds a sysctl parameter allowing to override > the checks, if an administrator so decides. > > I'm sending this as RFC because I have a feeling that there's no > consensus whether memory information exposed in the patch should be > protected or not. Showing it to any user is strictly speaking an info > leak, but the severity thereof might be considered not that high, so I'd > rather leave it up to discussion first. > > If we decide for lifting the check, the first patch is sufficient. Nack on that. CPU memory footprint and GPU memory footprint have a very different nature. This was discussed to quite a length, please refer to mailing list archives. > If we > decide against it, the second patch protects the information by default, > but with a way to expose it as a conscious decision of the admin. I find > it a decent compromise. No need for the added complexity if we were to add a sysfs. If a sysfs is added, it can be made root readable by default but system admin is free to chown or chmod the file for more relaxed access. Back in the original discussion time, this was omitted for lack of users. Even now, userspace/sysadmin could already essentially use setuid helper process that will only report the memory statistics. So I'm not really fully convinced this is needed at all. And if it is to be added for the convenience of usersppace, it should probably then be considered to be a standard interface across DRM drivers ala fdinfo or cgroups. Regards, Joonas > > This change has been requested in these parallel issues for i915 and Xe: > > https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/14153 > https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/4861 > > Thanks > Krzysztof > > Krzysztof Niemiec (2): > drm/i915: Expose local memory information via sysfs > drm/i915: Add protections to sysfs local memory information > > drivers/gpu/drm/i915/i915_sysfs.c | 6 + > drivers/gpu/drm/i915/intel_memory_region.c | 136 + > drivers/gpu/drm/i915/intel_memory_region.h | 3 + > 3 files changed, 145 insertions(+) > > -- > 2.45.2 > _
Re: [PATCH v3 16/19] nova-core: Add support for VBIOS ucode extraction for boot
On 5/20/2025 5:30 AM, Danilo Krummrich wrote: > On Tue, May 20, 2025 at 03:55:06AM -0400, Joel Fernandes wrote: >> On 5/13/2025 1:19 PM, Danilo Krummrich wrote: >>> On Wed, May 07, 2025 at 10:52:43PM +0900, Alexandre Courbot wrote: @@ -238,6 +239,8 @@ pub(crate) fn new( let _sec2_falcon = Falconnew(pdev.as_ref(), spec.chipset, bar, true)?; +let _bios = Vbios::new(pdev, bar)?; >>> >>> Please add a comment why, even though unused, it is important to create this >>> instance. >>> >>> Also, please use `_` if it's not intended to ever be used. >> >> If I add a comment, it will simply be removed by the next patch. I can add >> that >> though so it makes it more clear. > > I recommend to add such comments, because then reviewers don't stumble over > it. > :-) Point taken and fixed! ;-) >>> +pdev.as_ref(), +"Found BIOS image: size: {:#x}, type: {}, last: {}\n", +full_image.image_size_bytes()?, +full_image.image_type_str(), +full_image.is_last() +); + +// Get references to images we will need after the loop, in order to +// setup the falcon data offset. +match full_image { +BiosImage::PciAt(image) => { +pci_at_image = Some(image); +} +BiosImage::FwSec(image) => { +if first_fwsec_image.is_none() { +first_fwsec_image = Some(image); +} else { +second_fwsec_image = Some(image); +} +} +// For now we don't need to handle these +BiosImage::Efi(_image) => {} +BiosImage::Nbsi(_image) => {} +} +} + +// Using all the images, setup the falcon data pointer in Fwsec. +// We need mutable access here, so we handle the Option manually. +let final_fwsec_image = { +let mut second = second_fwsec_image; // Take ownership of the option + +if let (Some(second), Some(first), Some(pci_at)) = +(second.as_mut(), first_fwsec_image, pci_at_image) +{ +second +.setup_falcon_data(pdev, &pci_at, &first) +.inspect_err(|e| { +dev_err!(pdev.as_ref(), "Falcon data setup failed: {:?}\n", e) +})?; +} else { +dev_err!( +pdev.as_ref(), +"Missing required images for falcon data setup, skipping\n" +); +return Err(EINVAL); >>> >>> This means that if second == None we fail, which makes sense, so why store >>> an >>> Option in Vbios? All methods of Vbios fail if fwsec_image == None. >>> >> >> Well, if first and pci_at are None, we will fail as well. Not just second. >> But >> we don't know until we finish parsing all the images in the prior loop, if we >> found all the images. So we store it as Option during the prior loop, and >> check >> it later. Right? > > My point is not that second is an option within this function -- that's fine. > I > don't want the Vbios type to store an Option, because that doesn't make sense. > I.e. it should be > > struct Vbios { > fwsec_image: FwSecBiosImage, > } > > or just > > struct Vbios(FwSecBiosImage); > > which is the same, rather than > > struct Vbios { > fwsec_image: Option, > } > > because Vbios::new() fails anyways if any of the images is None, i.e. > vbios.fwsec_image can't ever be None. > > The code below does that for you, i.e. it returns an instance of Vbios without > the inner Option. But your code below does Vbios(second) where Vbios is an option.. > +} +second +}; >>> >>> I think this should be: >>> >>> let mut second = second_fwsec_image; >>> >>> if let (Some(second), Some(first), Some(pci_at)) = >>> (second.as_mut(), first_fwsec_image, pci_at_image) >>> { >>> second >>> .setup_falcon_data(pdev, &pci_at, &first) >>> .inspect_err(|e| { >>> dev_err!(pdev.as_ref(), "Falcon data setup failed: {:?}\n", >>> e) >>> })?; >>> >>> Ok(Vbios(second) I can't do that become second is a mutable reference in the above snippet. But this works: Ok(Vbios { fwsec_image: second.take().ok_or(EINVAL)? }) (This did require changing 'Some(second)' to 'Some(second_ref)', see below.) >>> } else { >>> dev_err!( >>> pdev.as_ref(), >>>
Re: [PATCH v4 05/40] iommu/io-pgtable-arm: Add quirk to quiet WARN_ON()
On 2025-05-20 12:31 pm, Will Deacon wrote: On Thu, May 15, 2025 at 07:48:39AM -0700, Rob Clark wrote: On Thu, May 15, 2025 at 7:33 AM Will Deacon wrote: On Wed, May 14, 2025 at 10:53:19AM -0700, Rob Clark wrote: From: Rob Clark In situations where mapping/unmapping sequence can be controlled by userspace, attempting to map over a region that has not yet been unmapped is an error. But not something that should spam dmesg. Now that there is a quirk, we can also drop the selftest_running flag, and use the quirk instead for selftests. Signed-off-by: Rob Clark Acked-by: Robin Murphy Signed-off-by: Rob Clark --- drivers/iommu/io-pgtable-arm.c | 27 ++- include/linux/io-pgtable.h | 8 2 files changed, 22 insertions(+), 13 deletions(-) [...] diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h index bba2a51c87d2..639b8f4fb87d 100644 --- a/include/linux/io-pgtable.h +++ b/include/linux/io-pgtable.h @@ -88,6 +88,13 @@ struct io_pgtable_cfg { * * IO_PGTABLE_QUIRK_ARM_HD: Enables dirty tracking in stage 1 pagetable. * IO_PGTABLE_QUIRK_ARM_S2FWB: Use the FWB format for the MemAttrs bits + * + * IO_PGTABLE_QUIRK_NO_WARN_ON: Do not WARN_ON() on conflicting + * mappings, but silently return -EEXISTS. Normally an attempt + * to map over an existing mapping would indicate some sort of + * kernel bug, which would justify the WARN_ON(). But for GPU + * drivers, this could be under control of userspace. Which + * deserves an error return, but not to spam dmesg. */ #define IO_PGTABLE_QUIRK_ARM_NS BIT(0) #define IO_PGTABLE_QUIRK_NO_PERMS BIT(1) @@ -97,6 +104,7 @@ struct io_pgtable_cfg { #define IO_PGTABLE_QUIRK_ARM_OUTER_WBWA BIT(6) #define IO_PGTABLE_QUIRK_ARM_HD BIT(7) #define IO_PGTABLE_QUIRK_ARM_S2FWB BIT(8) + #define IO_PGTABLE_QUIRK_NO_WARN_ON BIT(9) This feels a bit fragile to me: * IOMMU-API users of io-pgtable shouldn't be passing this quirk but might end up doing so to paper over driver bugs. * Low-level users of io-pgtable who expose page-table operations to userspace need to pass the quirk, but might well not bother because well-behaved userspace doesn't trigger the warning. So overall, it's all a bit unsatisfactory. Is there a way we could have the warnings only when invoked via the IOMMU API? iommu drivers _not_ setting this flag seems like a good way to achieve that ;-) The alternative is to move the warns to the iommu driver... but they could just as easily remove the WARN_ON()s as they could set the NO_WARN_ON quirk, so :shrug:? Bah, I also don't have a good idea to improve this, so I guess I'll take what you have for now. Hmm, just a nit on reflection, how about fixing up the name to just IO_PGTABLE_QUIRK_NO_WARN? Given that it's already quite long, and we have a well-established DMA_ATTR_NO_WARN with equivalent semantics over in the DMA API. Cheers, Robin.
Re: [PATCH v4 05/40] iommu/io-pgtable-arm: Add quirk to quiet WARN_ON()
On Thu, May 15, 2025 at 07:48:39AM -0700, Rob Clark wrote: > On Thu, May 15, 2025 at 7:33 AM Will Deacon wrote: > > > > On Wed, May 14, 2025 at 10:53:19AM -0700, Rob Clark wrote: > > > From: Rob Clark > > > > > > In situations where mapping/unmapping sequence can be controlled by > > > userspace, attempting to map over a region that has not yet been > > > unmapped is an error. But not something that should spam dmesg. > > > > > > Now that there is a quirk, we can also drop the selftest_running > > > flag, and use the quirk instead for selftests. > > > > > > Signed-off-by: Rob Clark > > > Acked-by: Robin Murphy > > > Signed-off-by: Rob Clark > > > --- > > > drivers/iommu/io-pgtable-arm.c | 27 ++- > > > include/linux/io-pgtable.h | 8 > > > 2 files changed, 22 insertions(+), 13 deletions(-) > > > > [...] > > > > > diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h > > > index bba2a51c87d2..639b8f4fb87d 100644 > > > --- a/include/linux/io-pgtable.h > > > +++ b/include/linux/io-pgtable.h > > > @@ -88,6 +88,13 @@ struct io_pgtable_cfg { > > >* > > >* IO_PGTABLE_QUIRK_ARM_HD: Enables dirty tracking in stage 1 > > > pagetable. > > >* IO_PGTABLE_QUIRK_ARM_S2FWB: Use the FWB format for the MemAttrs > > > bits > > > + * > > > + * IO_PGTABLE_QUIRK_NO_WARN_ON: Do not WARN_ON() on conflicting > > > + * mappings, but silently return -EEXISTS. Normally an attempt > > > + * to map over an existing mapping would indicate some sort of > > > + * kernel bug, which would justify the WARN_ON(). But for GPU > > > + * drivers, this could be under control of userspace. Which > > > + * deserves an error return, but not to spam dmesg. > > >*/ > > > #define IO_PGTABLE_QUIRK_ARM_NS BIT(0) > > > #define IO_PGTABLE_QUIRK_NO_PERMS BIT(1) > > > @@ -97,6 +104,7 @@ struct io_pgtable_cfg { > > > #define IO_PGTABLE_QUIRK_ARM_OUTER_WBWA BIT(6) > > > #define IO_PGTABLE_QUIRK_ARM_HD BIT(7) > > > #define IO_PGTABLE_QUIRK_ARM_S2FWB BIT(8) > > > + #define IO_PGTABLE_QUIRK_NO_WARN_ON BIT(9) > > > > This feels a bit fragile to me: > > * IOMMU-API users of io-pgtable shouldn't be passing this quirk > > but might end up doing so to paper over driver bugs. > > > > * Low-level users of io-pgtable who expose page-table operations to > > userspace need to pass the quirk, but might well not bother because > > well-behaved userspace doesn't trigger the warning. > > > > So overall, it's all a bit unsatisfactory. Is there a way we could have > > the warnings only when invoked via the IOMMU API? > > iommu drivers _not_ setting this flag seems like a good way to achieve that > ;-) > > The alternative is to move the warns to the iommu driver... but they > could just as easily remove the WARN_ON()s as they could set the > NO_WARN_ON quirk, so :shrug:? Bah, I also don't have a good idea to improve this, so I guess I'll take what you have for now. Will
[PATCH RFT v4 11/14] soc: qcom: ubwc: Fix SM6125's ubwc_swizzle value
From: Konrad Dybcio The value of 7 (a.k.a. GENMASK(2, 0), a.k.a. disabling levels 1-3 of swizzling) is what we want on this platform (and others with a UBWC 1.0 encoder). Fix it to make mesa happy (the hardware doesn't care about the 2 higher bits, as they weren't consumed on this platform). Reviewed-by: Dmitry Baryshkov Signed-off-by: Konrad Dybcio --- drivers/soc/qcom/ubwc_config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/soc/qcom/ubwc_config.c b/drivers/soc/qcom/ubwc_config.c index 7d220259829f0e57268f30b323ae985cf44672f4..7002744631341796d08fa197efa2202b3018cc3e 100644 --- a/drivers/soc/qcom/ubwc_config.c +++ b/drivers/soc/qcom/ubwc_config.c @@ -103,7 +103,7 @@ static const struct qcom_ubwc_cfg_data sm6115_data = { static const struct qcom_ubwc_cfg_data sm6125_data = { .ubwc_enc_version = UBWC_1_0, .ubwc_dec_version = UBWC_3_0, - .ubwc_swizzle = 1, + .ubwc_swizzle = 7, .highest_bank_bit = 14, }; -- 2.49.0
Re: [PATCH v5 05/12] drm: renesas: rz-du: mipi_dsi: Use VCLK for HSFREQ calculation
Hi Prabhakar, On Mon, May 12, 2025 at 07:23:23PM +0100, Prabhakar wrote: > From: Lad Prabhakar > > Update the RZ/G2L MIPI DSI driver to calculate HSFREQ using the actual > VCLK rate instead of the mode clock. The relationship between HSCLK and > VCLK is: > > vclk * bpp <= hsclk * 8 * lanes > > Retrieve the VCLK rate using `clk_get_rate(dsi->vclk)`, ensuring that > HSFREQ accurately reflects the clock rate set in hardware, leading to > better precision in data transmission. > > Additionally, use `DIV_ROUND_CLOSEST_ULL` for a more precise division > when computing `hsfreq`. Also, update unit conversions to use correct > scaling factors for better clarity and correctness. > > Since `clk_get_rate()` returns the clock rate in Hz, update the HSFREQ > threshold comparisons to use Hz instead of kHz to ensure correct behavior. > > Co-developed-by: Fabrizio Castro > Signed-off-by: Fabrizio Castro > Signed-off-by: Lad Prabhakar > Reviewed-by: Biju Das > --- > v4->v5: > - Added dev_info() to print the VCLK rate if it doesn't match the > requested rate. > - Added Reviewed-by tag from Biju > > v3->v4: > - Used MILLI instead of KILO > > v2->v3: > - No changes > > v1->v2: > - No changes > --- > .../gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c| 30 +++ > 1 file changed, 18 insertions(+), 12 deletions(-) > > diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > index c5f698cd74f1..3f6988303e63 100644 > --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > @@ -8,6 +8,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -15,6 +16,7 @@ > #include > #include > #include > +#include > > #include > #include > @@ -199,7 +201,7 @@ static int rzg2l_mipi_dsi_dphy_init(struct rzg2l_mipi_dsi > *dsi, > /* All DSI global operation timings are set with recommended setting */ > for (i = 0; i < ARRAY_SIZE(rzg2l_mipi_dsi_global_timings); ++i) { > dphy_timings = &rzg2l_mipi_dsi_global_timings[i]; > - if (hsfreq <= dphy_timings->hsfreq_max) > + if (hsfreq <= (dphy_timings->hsfreq_max * MILLI)) No need for the inner parentheses. > break; > } > > @@ -258,7 +260,7 @@ static void rzg2l_mipi_dsi_dphy_exit(struct > rzg2l_mipi_dsi *dsi) > static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi *dsi, > const struct drm_display_mode *mode) > { > - unsigned long hsfreq; > + unsigned long hsfreq, vclk_rate; > unsigned int bpp; > u32 txsetr; > u32 clstptsetr; > @@ -269,6 +271,12 @@ static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi > *dsi, > u32 golpbkt; > int ret; > > + ret = pm_runtime_resume_and_get(dsi->dev); > + if (ret < 0) > + return ret; > + > + clk_set_rate(dsi->vclk, mode->clock * MILLI); > + > /* >* Relationship between hsclk and vclk must follow >* vclk * bpp = hsclk * 8 * lanes > @@ -280,13 +288,11 @@ static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi > *dsi, >* hsclk(bit) = hsclk(byte) * 8 = hsfreq >*/ > bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); > - hsfreq = (mode->clock * bpp) / dsi->lanes; > - > - ret = pm_runtime_resume_and_get(dsi->dev); > - if (ret < 0) > - return ret; > - > - clk_set_rate(dsi->vclk, mode->clock * 1000); > + vclk_rate = clk_get_rate(dsi->vclk); > + if (vclk_rate != mode->clock * MILLI) > + dev_info(dsi->dev, "Requested vclk rate %lu, actual %lu > mismatch\n", > + mode->clock * MILLI, vclk_rate); There's a high risk that the requested rate won't be achieved exactly. Do we really want to print a non-debug message to the kernel log every time ? > + hsfreq = DIV_ROUND_CLOSEST_ULL(vclk_rate * bpp, dsi->lanes); I doubt DIV_ROUND_CLOSEST_ULL() will make any difference in practice given that you can't have more than 4 lanes, but that's fine. > > ret = rzg2l_mipi_dsi_dphy_init(dsi, hsfreq); > if (ret < 0) > @@ -304,12 +310,12 @@ static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi > *dsi, >* - data lanes: maximum 4 lanes >* Therefore maximum hsclk will be 891 Mbps. >*/ > - if (hsfreq > 445500) { > + if (hsfreq > 44550) { > clkkpt = 12; > clkbfht = 15; > clkstpt = 48; > golpbkt = 75; > - } else if (hsfreq > 25) { > + } else if (hsfreq > 25000) { > clkkpt = 7; > clkbfht = 8; > clkstpt = 27; > @@ -753,7 +759,7 @@ static int rzg2l_mipi_dsi_probe(struct platform_device > *pdev) >* mode->clock and format are not available. So initialize DPHY with >* timing parameters for 80Mbps. >*/ > - ret = rzg2l_mipi_dsi_dphy_ini
Re: [PATCH v5 06/12] drm: renesas: rz-du: mipi_dsi: Add OF data support
Hi Prabhakar, Thank you for the patch. On Mon, May 12, 2025 at 07:23:24PM +0100, Prabhakar wrote: > From: Lad Prabhakar > > In preparation for adding support for the Renesas RZ/V2H(P) SoC, this patch > introduces a mechanism to pass SoC-specific information via OF data in the > DSI driver. This enables the driver to adapt dynamically to various > SoC-specific requirements without hardcoding configurations. > > The MIPI DSI interface on the RZ/V2H(P) SoC is nearly identical to the one > on the RZ/G2L SoC. While the LINK registers are shared between the two > SoCs, the D-PHY registers differ. Also the VCLK range differs on both these > SoCs. To accommodate these differences `struct rzg2l_mipi_dsi_hw_info` is > introduced and as now passed as OF data. > > These changes lay the groundwork for the upcoming RZ/V2H(P) SoC support by > allowing SoC-specific data to be passed through OF. > > Co-developed-by: Fabrizio Castro > Signed-off-by: Fabrizio Castro > Signed-off-by: Lad Prabhakar > Reviewed-by: Biju Das > --- > v4->v5: > - Dropped RZ_MIPI_DSI_FEATURE_DPHY_RST feature flag > - Added Reviewed tag from Biju > > v3->v4: > - No changes > > v2->v3: > - Dropped !dsi->info check in rzg2l_mipi_dsi_probe() as it is not needed. > > v1->v2: > - Added DPHY_RST as feature flag > --- > .../gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c| 51 ++- > .../drm/renesas/rz-du/rzg2l_mipi_dsi_regs.h | 2 - > 2 files changed, 38 insertions(+), 15 deletions(-) > > diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > index 3f6988303e63..00c2bc6e9d6c 100644 > --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c > @@ -28,10 +28,23 @@ > > #include "rzg2l_mipi_dsi_regs.h" > > +struct rzg2l_mipi_dsi; > + > +struct rzg2l_mipi_dsi_hw_info { > + int (*dphy_init)(struct rzg2l_mipi_dsi *dsi, unsigned long hsfreq); > + void (*dphy_exit)(struct rzg2l_mipi_dsi *dsi); > + u32 phy_reg_offset; > + u32 link_reg_offset; > + unsigned long max_dclk; > + unsigned long min_dclk; I'd put min before max. > +}; > + > struct rzg2l_mipi_dsi { > struct device *dev; > void __iomem *mmio; > > + const struct rzg2l_mipi_dsi_hw_info *info; > + > struct reset_control *rstc; > struct reset_control *arstc; > struct reset_control *prstc; > @@ -164,22 +177,22 @@ static const struct rzg2l_mipi_dsi_timings > rzg2l_mipi_dsi_global_timings[] = { > > static void rzg2l_mipi_dsi_phy_write(struct rzg2l_mipi_dsi *dsi, u32 reg, > u32 data) > { > - iowrite32(data, dsi->mmio + reg); > + iowrite32(data, dsi->mmio + dsi->info->phy_reg_offset + reg); > } > > static void rzg2l_mipi_dsi_link_write(struct rzg2l_mipi_dsi *dsi, u32 reg, > u32 data) > { > - iowrite32(data, dsi->mmio + LINK_REG_OFFSET + reg); > + iowrite32(data, dsi->mmio + dsi->info->link_reg_offset + reg); > } > > static u32 rzg2l_mipi_dsi_phy_read(struct rzg2l_mipi_dsi *dsi, u32 reg) > { > - return ioread32(dsi->mmio + reg); > + return ioread32(dsi->mmio + dsi->info->phy_reg_offset + reg); > } > > static u32 rzg2l_mipi_dsi_link_read(struct rzg2l_mipi_dsi *dsi, u32 reg) > { > - return ioread32(dsi->mmio + LINK_REG_OFFSET + reg); > + return ioread32(dsi->mmio + dsi->info->link_reg_offset + reg); > } > > /* > - > @@ -294,7 +307,7 @@ static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi > *dsi, >mode->clock * MILLI, vclk_rate); > hsfreq = DIV_ROUND_CLOSEST_ULL(vclk_rate * bpp, dsi->lanes); > > - ret = rzg2l_mipi_dsi_dphy_init(dsi, hsfreq); > + ret = dsi->info->dphy_init(dsi, hsfreq); > if (ret < 0) > goto err_phy; > > @@ -337,7 +350,7 @@ static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi > *dsi, > return 0; > > err_phy: > - rzg2l_mipi_dsi_dphy_exit(dsi); > + dsi->info->dphy_exit(dsi); > pm_runtime_put(dsi->dev); > > return ret; > @@ -345,7 +358,7 @@ static int rzg2l_mipi_dsi_startup(struct rzg2l_mipi_dsi > *dsi, > > static void rzg2l_mipi_dsi_stop(struct rzg2l_mipi_dsi *dsi) > { > - rzg2l_mipi_dsi_dphy_exit(dsi); > + dsi->info->dphy_exit(dsi); > pm_runtime_put(dsi->dev); > } > > @@ -587,10 +600,12 @@ rzg2l_mipi_dsi_bridge_mode_valid(struct drm_bridge > *bridge, >const struct drm_display_info *info, >const struct drm_display_mode *mode) > { > - if (mode->clock > 148500) > + struct rzg2l_mipi_dsi *dsi = bridge_to_rzg2l_mipi_dsi(bridge); > + > + if (mode->clock > dsi->info->max_dclk) > return MODE_CLOCK_HIGH; > > - if (mode->clock < 5803) > + if (mode->clock < dsi->info->min_dclk) > return MODE_CLOCK_LOW; > > return MODE_OK; > @@ -716,6 +731,8 @
[PATCH v9 1/9] optee: sync secure world ABI headers
Update the header files describing the secure world ABI, both with and without FF-A. The ABI is extended to deal with protected memory, but as usual backward compatible. Signed-off-by: Jens Wiklander --- drivers/tee/optee/optee_ffa.h | 27 --- drivers/tee/optee/optee_msg.h | 84 ++- drivers/tee/optee/optee_smc.h | 37 ++- 3 files changed, 130 insertions(+), 18 deletions(-) diff --git a/drivers/tee/optee/optee_ffa.h b/drivers/tee/optee/optee_ffa.h index 257735ae5b56..cc257e7956a3 100644 --- a/drivers/tee/optee/optee_ffa.h +++ b/drivers/tee/optee/optee_ffa.h @@ -81,7 +81,7 @@ * as the second MSG arg struct for * OPTEE_FFA_YIELDING_CALL_WITH_ARG. *Bit[31:8]: Reserved (MBZ) - * w5: Bitfield of secure world capabilities OPTEE_FFA_SEC_CAP_* below, + * w5: Bitfield of OP-TEE capabilities OPTEE_FFA_SEC_CAP_* * w6: The maximum secure world notification number * w7: Not used (MBZ) */ @@ -94,6 +94,8 @@ #define OPTEE_FFA_SEC_CAP_ASYNC_NOTIF BIT(1) /* OP-TEE supports probing for RPMB device if needed */ #define OPTEE_FFA_SEC_CAP_RPMB_PROBE BIT(2) +/* OP-TEE supports Protected Memory for secure data path */ +#define OPTEE_FFA_SEC_CAP_PROTMEM BIT(3) #define OPTEE_FFA_EXCHANGE_CAPABILITIES OPTEE_FFA_BLOCKING_CALL(2) @@ -108,7 +110,7 @@ * * Return register usage: * w3:Error code, 0 on success - * w4-w7: Note used (MBZ) + * w4-w7: Not used (MBZ) */ #define OPTEE_FFA_UNREGISTER_SHM OPTEE_FFA_BLOCKING_CALL(3) @@ -119,16 +121,31 @@ * Call register usage: * w3:Service ID, OPTEE_FFA_ENABLE_ASYNC_NOTIF * w4: Notification value to request bottom half processing, should be - * less than OPTEE_FFA_MAX_ASYNC_NOTIF_VALUE. + * less than OPTEE_FFA_MAX_ASYNC_NOTIF_VALUE * w5-w7: Not used (MBZ) * * Return register usage: * w3:Error code, 0 on success - * w4-w7: Note used (MBZ) + * w4-w7: Not used (MBZ) */ #define OPTEE_FFA_ENABLE_ASYNC_NOTIF OPTEE_FFA_BLOCKING_CALL(5) -#define OPTEE_FFA_MAX_ASYNC_NOTIF_VALUE 64 +#define OPTEE_FFA_MAX_ASYNC_NOTIF_VALUE64 + +/* + * Release Protected memory + * + * Call register usage: + * w3:Service ID, OPTEE_FFA_RECLAIM_PROTMEM + * w4:Shared memory handle, lower bits + * w5:Shared memory handle, higher bits + * w6-w7: Not used (MBZ) + * + * Return register usage: + * w3:Error code, 0 on success + * w4-w7: Note used (MBZ) + */ +#define OPTEE_FFA_RELEASE_PROTMEM OPTEE_FFA_BLOCKING_CALL(8) /* * Call with struct optee_msg_arg as argument in the supplied shared memory diff --git a/drivers/tee/optee/optee_msg.h b/drivers/tee/optee/optee_msg.h index e8840a82b983..22130e967dc5 100644 --- a/drivers/tee/optee/optee_msg.h +++ b/drivers/tee/optee/optee_msg.h @@ -133,13 +133,13 @@ struct optee_msg_param_rmem { }; /** - * struct optee_msg_param_fmem - ffa memory reference parameter + * struct optee_msg_param_fmem - FF-A memory reference parameter * @offs_lower: Lower bits of offset into shared memory reference * @offs_upper: Upper bits of offset into shared memory reference * @internal_offs: Internal offset into the first page of shared memory *reference * @size: Size of the buffer - * @global_id:Global identifier of Shared memory + * @global_id:Global identifier of the shared memory */ struct optee_msg_param_fmem { u32 offs_low; @@ -165,7 +165,7 @@ struct optee_msg_param_value { * @attr: attributes * @tmem: parameter by temporary memory reference * @rmem: parameter by registered memory reference - * @fmem: parameter by ffa registered memory reference + * @fmem: parameter by FF-A registered memory reference * @value: parameter by opaque value * @octets:parameter by octet string * @@ -296,6 +296,18 @@ struct optee_msg_arg { */ #define OPTEE_MSG_FUNCID_GET_OS_REVISION 0x0001 +/* + * Values used in OPTEE_MSG_CMD_LEND_PROTMEM below + * OPTEE_MSG_PROTMEM_RESERVED Reserved + * OPTEE_MSG_PROTMEM_SECURE_VIDEO_PLAY Secure Video Playback + * OPTEE_MSG_PROTMEM_TRUSTED_UITrused UI + * OPTEE_MSG_PROTMEM_SECURE_VIDEO_RECORD Secure Video Recording + */ +#define OPTEE_MSG_PROTMEM_RESERVED 0 +#define OPTEE_MSG_PROTMEM_SECURE_VIDEO_PLAY1 +#define OPTEE_MSG_PROTMEM_TRUSTED_UI 2 +#define OPTEE_MSG_PROTMEM_SECURE_VIDEO_RECORD 3 + /* * Do a secure call with struct optee_msg_arg as argument * The OPTEE_MSG_CMD_* below defines what goes in struct optee_msg_arg::cmd @@ -337,15 +349,63 @@ struct optee_msg_arg { * OPTEE_MSG_CMD_STOP_ASYNC_NOTIF informs secure world that from now is * normal world unable to process asynchronous notifications. Typically * used when the driver is shut down. + * + * OPTEE_MSG_CMD_LEND_PROTMEM lends protected memory. The passed normal + * physical memory is protected from normal world acces
[PATCH v9 3/9] tee: implement protected DMA-heap
Implement DMA heap for protected DMA-buf allocation in the TEE subsystem. Restricted memory refers to memory buffers behind a hardware enforced firewall. It is not accessible to the kernel during normal circumstances but rather only accessible to certain hardware IPs or CPUs executing in higher or differently privileged mode than the kernel itself. This interface allows to allocate and manage such protected memory buffers via interaction with a TEE implementation. The protected memory is allocated for a specific use-case, like Secure Video Playback, Trusted UI, or Secure Video Recording where certain hardware devices can access the memory. The DMA-heaps are enabled explicitly by the TEE backend driver. The TEE backend drivers needs to implement protected memory pool to manage the protected memory. Signed-off-by: Jens Wiklander --- drivers/tee/Makefile | 1 + drivers/tee/tee_heap.c| 487 ++ drivers/tee/tee_private.h | 6 + include/linux/tee_core.h | 65 + 4 files changed, 559 insertions(+) create mode 100644 drivers/tee/tee_heap.c diff --git a/drivers/tee/Makefile b/drivers/tee/Makefile index 5488cba30bd2..949a6a79fb06 100644 --- a/drivers/tee/Makefile +++ b/drivers/tee/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_TEE) += tee.o tee-objs += tee_core.o +tee-objs += tee_heap.o tee-objs += tee_shm.o tee-objs += tee_shm_pool.o obj-$(CONFIG_OPTEE) += optee/ diff --git a/drivers/tee/tee_heap.c b/drivers/tee/tee_heap.c new file mode 100644 index ..a332805f9f26 --- /dev/null +++ b/drivers/tee/tee_heap.c @@ -0,0 +1,487 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2025, Linaro Limited + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tee_private.h" + +struct tee_dma_heap { + struct dma_heap *heap; + enum tee_dma_heap_id id; + struct tee_protmem_pool *pool; + struct tee_device *teedev; + /* Protects pool and teedev above */ + struct mutex mu; +}; + +struct tee_heap_buffer { + struct tee_protmem_pool *pool; + struct tee_device *teedev; + size_t size; + size_t offs; + struct sg_table table; +}; + +struct tee_heap_attachment { + struct sg_table table; + struct device *dev; +}; + +struct tee_protmem_static_pool { + struct tee_protmem_pool pool; + struct gen_pool *gen_pool; + phys_addr_t pa_base; + void *base; +}; + +#if IS_ENABLED(CONFIG_DMABUF_HEAPS) +static DEFINE_XARRAY_ALLOC(tee_dma_heap); + +static int copy_sg_table(struct sg_table *dst, struct sg_table *src) +{ + struct scatterlist *dst_sg; + struct scatterlist *src_sg; + int ret; + int i; + + ret = sg_alloc_table(dst, src->orig_nents, GFP_KERNEL); + if (ret) + return ret; + + dst_sg = dst->sgl; + for_each_sgtable_sg(src, src_sg, i) { + sg_set_page(dst_sg, sg_page(src_sg), src_sg->length, + src_sg->offset); + dst_sg = sg_next(dst_sg); + } + + return 0; +} + +static int tee_heap_attach(struct dma_buf *dmabuf, + struct dma_buf_attachment *attachment) +{ + struct tee_heap_buffer *buf = dmabuf->priv; + struct tee_heap_attachment *a; + int ret; + + a = kzalloc(sizeof(*a), GFP_KERNEL); + if (!a) + return -ENOMEM; + + ret = copy_sg_table(&a->table, &buf->table); + if (ret) { + kfree(a); + return ret; + } + + a->dev = attachment->dev; + attachment->priv = a; + + return 0; +} + +static void tee_heap_detach(struct dma_buf *dmabuf, + struct dma_buf_attachment *attachment) +{ + struct tee_heap_attachment *a = attachment->priv; + + sg_free_table(&a->table); + kfree(a); +} + +static struct sg_table * +tee_heap_map_dma_buf(struct dma_buf_attachment *attachment, +enum dma_data_direction direction) +{ + struct tee_heap_attachment *a = attachment->priv; + int ret; + + ret = dma_map_sgtable(attachment->dev, &a->table, direction, + DMA_ATTR_SKIP_CPU_SYNC); + if (ret) + return ERR_PTR(ret); + + return &a->table; +} + +static void tee_heap_unmap_dma_buf(struct dma_buf_attachment *attachment, + struct sg_table *table, + enum dma_data_direction direction) +{ + struct tee_heap_attachment *a = attachment->priv; + + WARN_ON(&a->table != table); + + dma_unmap_sgtable(attachment->dev, table, direction, + DMA_ATTR_SKIP_CPU_SYNC); +} + +static void tee_heap_buf_free(struct dma_buf *dmabuf) +{ + struct tee_heap_buffer *buf = dmabuf->priv; + struct tee_device *teedev = buf->teedev; + + buf->pool->ops-
[PATCH v9 8/9] optee: FF-A: dynamic protected memory allocation
Add support in the OP-TEE backend driver dynamic protected memory allocation with FF-A. The protected memory pools for dynamically allocated protected memory are instantiated when requested by user-space. This instantiation can fail if OP-TEE doesn't support the requested use-case of protected memory. Restricted memory pools based on a static carveout or dynamic allocation can coexist for different use-cases. We use only dynamic allocation with FF-A. Signed-off-by: Jens Wiklander --- drivers/tee/optee/Makefile| 1 + drivers/tee/optee/ffa_abi.c | 147 - drivers/tee/optee/optee_private.h | 13 +- drivers/tee/optee/protmem.c | 332 ++ 4 files changed, 490 insertions(+), 3 deletions(-) create mode 100644 drivers/tee/optee/protmem.c diff --git a/drivers/tee/optee/Makefile b/drivers/tee/optee/Makefile index a6eff388d300..ad7049c1c107 100644 --- a/drivers/tee/optee/Makefile +++ b/drivers/tee/optee/Makefile @@ -4,6 +4,7 @@ optee-objs += core.o optee-objs += call.o optee-objs += notif.o optee-objs += rpc.o +optee-objs += protmem.o optee-objs += supp.o optee-objs += device.o optee-objs += smc_abi.o diff --git a/drivers/tee/optee/ffa_abi.c b/drivers/tee/optee/ffa_abi.c index f3af5666bb11..b9cbd733e5c6 100644 --- a/drivers/tee/optee/ffa_abi.c +++ b/drivers/tee/optee/ffa_abi.c @@ -649,6 +649,124 @@ static int optee_ffa_do_call_with_arg(struct tee_context *ctx, return optee_ffa_yielding_call(ctx, &data, rpc_arg, system_thread); } +static int do_call_lend_protmem(struct optee *optee, u64 cookie, u32 use_case) +{ + struct optee_shm_arg_entry *entry; + struct optee_msg_arg *msg_arg; + struct tee_shm *shm; + u_int offs; + int rc; + + msg_arg = optee_get_msg_arg(optee->ctx, 1, &entry, &shm, &offs); + if (IS_ERR(msg_arg)) + return PTR_ERR(msg_arg); + + msg_arg->cmd = OPTEE_MSG_CMD_ASSIGN_PROTMEM; + msg_arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT; + msg_arg->params[0].u.value.a = cookie; + msg_arg->params[0].u.value.b = use_case; + + rc = optee->ops->do_call_with_arg(optee->ctx, shm, offs, false); + if (rc) + goto out; + if (msg_arg->ret != TEEC_SUCCESS) { + rc = -EINVAL; + goto out; + } + +out: + optee_free_msg_arg(optee->ctx, entry, offs); + return rc; +} + +static int optee_ffa_lend_protmem(struct optee *optee, struct tee_shm *protmem, + u16 *end_points, unsigned int ep_count, + u32 use_case) +{ + struct ffa_device *ffa_dev = optee->ffa.ffa_dev; + const struct ffa_mem_ops *mem_ops = ffa_dev->ops->mem_ops; + const struct ffa_msg_ops *msg_ops = ffa_dev->ops->msg_ops; + struct ffa_send_direct_data data; + struct ffa_mem_region_attributes *mem_attr; + struct ffa_mem_ops_args args = { + .use_txbuf = true, + .tag = use_case, + }; + struct page *page; + struct scatterlist sgl; + unsigned int n; + int rc; + + mem_attr = kcalloc(ep_count, sizeof(*mem_attr), GFP_KERNEL); + for (n = 0; n < ep_count; n++) { + mem_attr[n].receiver = end_points[n]; + mem_attr[n].attrs = FFA_MEM_RW; + } + args.attrs = mem_attr; + args.nattrs = ep_count; + + page = phys_to_page(protmem->paddr); + sg_init_table(&sgl, 1); + sg_set_page(&sgl, page, protmem->size, 0); + + args.sg = &sgl; + rc = mem_ops->memory_lend(&args); + kfree(mem_attr); + if (rc) + return rc; + + rc = do_call_lend_protmem(optee, args.g_handle, use_case); + if (rc) + goto err_reclaim; + + rc = optee_shm_add_ffa_handle(optee, protmem, args.g_handle); + if (rc) + goto err_unreg; + + protmem->sec_world_id = args.g_handle; + + return 0; + +err_unreg: + data = (struct ffa_send_direct_data){ + .data0 = OPTEE_FFA_RELEASE_PROTMEM, + .data1 = (u32)args.g_handle, + .data2 = (u32)(args.g_handle >> 32), + }; + msg_ops->sync_send_receive(ffa_dev, &data); +err_reclaim: + mem_ops->memory_reclaim(args.g_handle, 0); + return rc; +} + +static int optee_ffa_reclaim_protmem(struct optee *optee, +struct tee_shm *protmem) +{ + struct ffa_device *ffa_dev = optee->ffa.ffa_dev; + const struct ffa_msg_ops *msg_ops = ffa_dev->ops->msg_ops; + const struct ffa_mem_ops *mem_ops = ffa_dev->ops->mem_ops; + u64 global_handle = protmem->sec_world_id; + struct ffa_send_direct_data data = { + .data0 = OPTEE_FFA_RELEASE_PROTMEM, + .data1 = (u32)global_handle, + .data2 = (u32)(global_handle >> 32) + }; + int rc; + + optee_shm_rem_ffa_handle(optee, glob
[PATCH v9 9/9] optee: smc abi: dynamic protected memory allocation
Add support in the OP-TEE backend driver for dynamic protected memory allocation using the SMC ABI. Signed-off-by: Jens Wiklander --- drivers/tee/optee/smc_abi.c | 102 ++-- 1 file changed, 85 insertions(+), 17 deletions(-) diff --git a/drivers/tee/optee/smc_abi.c b/drivers/tee/optee/smc_abi.c index f3cae8243785..6b3fbe7f0909 100644 --- a/drivers/tee/optee/smc_abi.c +++ b/drivers/tee/optee/smc_abi.c @@ -965,6 +965,70 @@ static int optee_smc_do_call_with_arg(struct tee_context *ctx, return rc; } +static int optee_smc_lend_protmem(struct optee *optee, struct tee_shm *protmem, + u16 *end_points, unsigned int ep_count, + u32 use_case) +{ + struct optee_shm_arg_entry *entry; + struct optee_msg_arg *msg_arg; + struct tee_shm *shm; + u_int offs; + int rc; + + msg_arg = optee_get_msg_arg(optee->ctx, 2, &entry, &shm, &offs); + if (IS_ERR(msg_arg)) + return PTR_ERR(msg_arg); + + msg_arg->cmd = OPTEE_MSG_CMD_LEND_PROTMEM; + msg_arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT; + msg_arg->params[0].u.value.a = use_case; + msg_arg->params[1].attr = OPTEE_MSG_ATTR_TYPE_TMEM_INPUT; + msg_arg->params[1].u.tmem.buf_ptr = protmem->paddr; + msg_arg->params[1].u.tmem.size = protmem->size; + msg_arg->params[1].u.tmem.shm_ref = (u_long)protmem; + + rc = optee->ops->do_call_with_arg(optee->ctx, shm, offs, false); + if (rc) + goto out; + if (msg_arg->ret != TEEC_SUCCESS) { + rc = -EINVAL; + goto out; + } + protmem->sec_world_id = (u_long)protmem; + +out: + optee_free_msg_arg(optee->ctx, entry, offs); + return rc; +} + +static int optee_smc_reclaim_protmem(struct optee *optee, +struct tee_shm *protmem) +{ + struct optee_shm_arg_entry *entry; + struct optee_msg_arg *msg_arg; + struct tee_shm *shm; + u_int offs; + int rc; + + msg_arg = optee_get_msg_arg(optee->ctx, 1, &entry, &shm, &offs); + if (IS_ERR(msg_arg)) + return PTR_ERR(msg_arg); + + msg_arg->cmd = OPTEE_MSG_CMD_RECLAIM_PROTMEM; + msg_arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_RMEM_INPUT; + msg_arg->params[0].u.rmem.shm_ref = (u_long)protmem; + + rc = optee->ops->do_call_with_arg(optee->ctx, shm, offs, false); + if (rc) + goto out; + if (msg_arg->ret != TEEC_SUCCESS) + rc = -EINVAL; + +out: + optee_free_msg_arg(optee->ctx, entry, offs); + return rc; +} + /* * 5. Asynchronous notification */ @@ -1216,6 +1280,8 @@ static const struct optee_ops optee_ops = { .do_call_with_arg = optee_smc_do_call_with_arg, .to_msg_param = optee_to_msg_param, .from_msg_param = optee_from_msg_param, + .lend_protmem = optee_smc_lend_protmem, + .reclaim_protmem = optee_smc_reclaim_protmem, }; static int enable_async_notif(optee_invoke_fn *invoke_fn) @@ -1586,11 +1652,14 @@ static inline int optee_load_fw(struct platform_device *pdev, static int optee_protmem_pool_init(struct optee *optee) { + bool protm = optee->smc.sec_caps & OPTEE_SMC_SEC_CAP_PROTMEM; + bool dyn_protm = optee->smc.sec_caps & +OPTEE_SMC_SEC_CAP_DYNAMIC_PROTMEM; enum tee_dma_heap_id heap_id = TEE_DMA_HEAP_SECURE_VIDEO_PLAY; - struct tee_protmem_pool *pool; - int rc; + struct tee_protmem_pool *pool = ERR_PTR(-EINVAL); + int rc = -EINVAL; - if (optee->smc.sec_caps & OPTEE_SMC_SEC_CAP_PROTMEM) { + if (protm) { union { struct arm_smccc_res smccc; struct optee_smc_get_protmem_config_result result; @@ -1598,26 +1667,26 @@ static int optee_protmem_pool_init(struct optee *optee) optee->smc.invoke_fn(OPTEE_SMC_GET_PROTMEM_CONFIG, 0, 0, 0, 0, 0, 0, 0, &res.smccc); - if (res.result.status != OPTEE_SMC_RETURN_OK) { - pr_err("Secure Data Path service not available\n"); - return 0; - } - rc = optee_set_dma_mask(optee, res.result.pa_width); + if (res.result.status == OPTEE_SMC_RETURN_OK) + rc = optee_set_dma_mask(optee, res.result.pa_width); if (!rc) pool = tee_protmem_static_pool_alloc(res.result.start, res.result.size); - if (IS_ERR(pool)) - return PTR_ERR(pool); + } + if (dyn_protm && IS_ERR(pool)) + pool = optee_protmem_alloc_dyn_pool(optee, heap_id); + + if (!IS_ERR(pool)) { rc = tee_device_register_dma_heap(optee->teedev, heap_id, poo
[PATCH v9 5/9] tee: new ioctl to a register tee_shm from a dmabuf file descriptor
From: Etienne Carriere Add a userspace API to create a tee_shm object that refers to a dmabuf reference. Userspace registers the dmabuf file descriptor as in a tee_shm object. The registration is completed with a tee_shm returned file descriptor. Userspace is free to close the dmabuf file descriptor after it has been registered since all the resources are now held via the new tee_shm object. Closing the tee_shm file descriptor will eventually release all resources used by the tee_shm object when all references are released. The new IOCTL, TEE_IOC_SHM_REGISTER_FD, supports dmabuf references to physically contiguous memory buffers. Dmabuf references acquired from the TEE DMA-heap can be used as protected memory for Secure Video Path and such use cases. It depends on the TEE and the TEE driver if dmabuf references acquired by other means can be used. A new tee_shm flag is added to identify tee_shm objects built from a registered dmabuf, TEE_SHM_DMA_BUF. Signed-off-by: Etienne Carriere Signed-off-by: Olivier Masse Signed-off-by: Jens Wiklander --- drivers/tee/tee_core.c| 63 +- drivers/tee/tee_private.h | 10 drivers/tee/tee_shm.c | 111 -- include/linux/tee_core.h | 1 + include/linux/tee_drv.h | 10 include/uapi/linux/tee.h | 31 +++ 6 files changed, 221 insertions(+), 5 deletions(-) diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c index 5259b8223c27..0e9d9e5872a4 100644 --- a/drivers/tee/tee_core.c +++ b/drivers/tee/tee_core.c @@ -353,11 +353,49 @@ tee_ioctl_shm_register(struct tee_context *ctx, return ret; } +static int +tee_ioctl_shm_register_fd(struct tee_context *ctx, + struct tee_ioctl_shm_register_fd_data __user *udata) +{ + struct tee_ioctl_shm_register_fd_data data; + struct tee_shm *shm; + long ret; + + if (copy_from_user(&data, udata, sizeof(data))) + return -EFAULT; + + /* Currently no input flags are supported */ + if (data.flags) + return -EINVAL; + + shm = tee_shm_register_fd(ctx, data.fd); + if (IS_ERR(shm)) + return -EINVAL; + + data.id = shm->id; + data.flags = shm->flags; + data.size = shm->size; + + if (copy_to_user(udata, &data, sizeof(data))) + ret = -EFAULT; + else + ret = tee_shm_get_fd(shm); + + /* +* When user space closes the file descriptor the shared memory +* should be freed or if tee_shm_get_fd() failed then it will +* be freed immediately. +*/ + tee_shm_put(shm); + return ret; +} + static int param_from_user_memref(struct tee_context *ctx, struct tee_param_memref *memref, struct tee_ioctl_param *ip) { struct tee_shm *shm; + size_t offs = 0; /* * If a NULL pointer is passed to a TA in the TEE, @@ -388,6 +426,26 @@ static int param_from_user_memref(struct tee_context *ctx, tee_shm_put(shm); return -EINVAL; } + + if (shm->flags & TEE_SHM_DMA_BUF) { + struct tee_shm_dmabuf_ref *ref; + + ref = container_of(shm, struct tee_shm_dmabuf_ref, shm); + if (ref->parent_shm) { + /* +* The shm already has one reference to +* ref->parent_shm so we are clear of 0. +* We're getting another reference since +* this shm will be used in the parameter +* list instead of the shm we got with +* tee_shm_get_from_id() above. +*/ + refcount_inc(&ref->parent_shm->refcount); + tee_shm_put(shm); + shm = ref->parent_shm; + offs = ref->offset; + } + } } else if (ctx->cap_memref_null) { /* Pass NULL pointer to OP-TEE */ shm = NULL; @@ -395,7 +453,7 @@ static int param_from_user_memref(struct tee_context *ctx, return -EINVAL; } - memref->shm_offs = ip->a; + memref->shm_offs = ip->a + offs; memref->size = ip->b; memref->shm = shm; @@ -841,6 +899,8 @@ static long tee_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) return tee_ioctl_shm_alloc(ctx, uarg); case TEE_IOC_SHM_REGISTER: return tee_ioctl_shm_register(ctx, uarg); + case TEE_IOC_SHM_REGISTER_FD: + return tee_ioctl_shm_register_fd(ctx, uarg); case TEE_IOC_OPEN_SESSION: return tee
[PATCH v9 4/9] tee: refactor params_from_user()
Break out the memref handling into a separate helper function. No change in behavior. Signed-off-by: Jens Wiklander Reviewed-by: Sumit Garg --- drivers/tee/tee_core.c | 94 -- 1 file changed, 54 insertions(+), 40 deletions(-) diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c index d113679b1e2d..5259b8223c27 100644 --- a/drivers/tee/tee_core.c +++ b/drivers/tee/tee_core.c @@ -353,6 +353,55 @@ tee_ioctl_shm_register(struct tee_context *ctx, return ret; } +static int param_from_user_memref(struct tee_context *ctx, + struct tee_param_memref *memref, + struct tee_ioctl_param *ip) +{ + struct tee_shm *shm; + + /* +* If a NULL pointer is passed to a TA in the TEE, +* the ip.c IOCTL parameters is set to TEE_MEMREF_NULL +* indicating a NULL memory reference. +*/ + if (ip->c != TEE_MEMREF_NULL) { + /* +* If we fail to get a pointer to a shared +* memory object (and increase the ref count) +* from an identifier we return an error. All +* pointers that has been added in params have +* an increased ref count. It's the callers +* responibility to do tee_shm_put() on all +* resolved pointers. +*/ + shm = tee_shm_get_from_id(ctx, ip->c); + if (IS_ERR(shm)) + return PTR_ERR(shm); + + /* +* Ensure offset + size does not overflow +* offset and does not overflow the size of +* the referred shared memory object. +*/ + if ((ip->a + ip->b) < ip->a || + (ip->a + ip->b) > shm->size) { + tee_shm_put(shm); + return -EINVAL; + } + } else if (ctx->cap_memref_null) { + /* Pass NULL pointer to OP-TEE */ + shm = NULL; + } else { + return -EINVAL; + } + + memref->shm_offs = ip->a; + memref->size = ip->b; + memref->shm = shm; + + return 0; +} + static int params_from_user(struct tee_context *ctx, struct tee_param *params, size_t num_params, struct tee_ioctl_param __user *uparams) @@ -360,8 +409,8 @@ static int params_from_user(struct tee_context *ctx, struct tee_param *params, size_t n; for (n = 0; n < num_params; n++) { - struct tee_shm *shm; struct tee_ioctl_param ip; + int rc; if (copy_from_user(&ip, uparams + n, sizeof(ip))) return -EFAULT; @@ -384,45 +433,10 @@ static int params_from_user(struct tee_context *ctx, struct tee_param *params, case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT: case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT: case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT: - /* -* If a NULL pointer is passed to a TA in the TEE, -* the ip.c IOCTL parameters is set to TEE_MEMREF_NULL -* indicating a NULL memory reference. -*/ - if (ip.c != TEE_MEMREF_NULL) { - /* -* If we fail to get a pointer to a shared -* memory object (and increase the ref count) -* from an identifier we return an error. All -* pointers that has been added in params have -* an increased ref count. It's the callers -* responibility to do tee_shm_put() on all -* resolved pointers. -*/ - shm = tee_shm_get_from_id(ctx, ip.c); - if (IS_ERR(shm)) - return PTR_ERR(shm); - - /* -* Ensure offset + size does not overflow -* offset and does not overflow the size of -* the referred shared memory object. -*/ - if ((ip.a + ip.b) < ip.a || - (ip.a + ip.b) > shm->size) { - tee_shm_put(shm); - return -EINVAL; - } - } else if (ctx->cap_memref_null) { - /* Pass NULL pointer to OP-TEE */ - shm = NULL; - } else { -
[PATCH v9 7/9] optee: support protected memory allocation
Add support in the OP-TEE backend driver for protected memory allocation. The support is limited to only the SMC ABI and for secure video buffers. OP-TEE is probed for the range of protected physical memory and a memory pool allocator is initialized if OP-TEE have support for such memory. Signed-off-by: Jens Wiklander --- drivers/tee/optee/core.c | 10 +++ drivers/tee/optee/optee_private.h | 2 ++ drivers/tee/optee/smc_abi.c | 45 +-- 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c index c75fddc83576..4b14a7ac56f9 100644 --- a/drivers/tee/optee/core.c +++ b/drivers/tee/optee/core.c @@ -56,6 +56,15 @@ int optee_rpmb_intf_rdev(struct notifier_block *intf, unsigned long action, return 0; } +int optee_set_dma_mask(struct optee *optee, u_int pa_width) +{ + u64 mask = DMA_BIT_MASK(min(64, pa_width)); + + optee->teedev->dev.dma_mask = &optee->teedev->dev.coherent_dma_mask; + + return dma_set_mask_and_coherent(&optee->teedev->dev, mask); +} + static void optee_bus_scan(struct work_struct *work) { WARN_ON(optee_enumerate_devices(PTA_CMD_GET_DEVICES_SUPP)); @@ -181,6 +190,7 @@ void optee_remove_common(struct optee *optee) tee_device_unregister(optee->supp_teedev); tee_device_unregister(optee->teedev); + tee_device_unregister_all_dma_heaps(optee->teedev); tee_shm_pool_free(optee->pool); optee_supp_uninit(&optee->supp); mutex_destroy(&optee->call_queue.mutex); diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h index dc0f355ef72a..5e3c34802121 100644 --- a/drivers/tee/optee/optee_private.h +++ b/drivers/tee/optee/optee_private.h @@ -272,6 +272,8 @@ struct optee_call_ctx { extern struct blocking_notifier_head optee_rpmb_intf_added; +int optee_set_dma_mask(struct optee *optee, u_int pa_width); + int optee_notif_init(struct optee *optee, u_int max_key); void optee_notif_uninit(struct optee *optee); int optee_notif_wait(struct optee *optee, u_int key, u32 timeout); diff --git a/drivers/tee/optee/smc_abi.c b/drivers/tee/optee/smc_abi.c index f0c3ac1103bb..f3cae8243785 100644 --- a/drivers/tee/optee/smc_abi.c +++ b/drivers/tee/optee/smc_abi.c @@ -1584,6 +1584,42 @@ static inline int optee_load_fw(struct platform_device *pdev, } #endif +static int optee_protmem_pool_init(struct optee *optee) +{ + enum tee_dma_heap_id heap_id = TEE_DMA_HEAP_SECURE_VIDEO_PLAY; + struct tee_protmem_pool *pool; + int rc; + + if (optee->smc.sec_caps & OPTEE_SMC_SEC_CAP_PROTMEM) { + union { + struct arm_smccc_res smccc; + struct optee_smc_get_protmem_config_result result; + } res; + + optee->smc.invoke_fn(OPTEE_SMC_GET_PROTMEM_CONFIG, 0, 0, 0, 0, +0, 0, 0, &res.smccc); + if (res.result.status != OPTEE_SMC_RETURN_OK) { + pr_err("Secure Data Path service not available\n"); + return 0; + } + rc = optee_set_dma_mask(optee, res.result.pa_width); + if (!rc) + pool = tee_protmem_static_pool_alloc(res.result.start, +res.result.size); + if (IS_ERR(pool)) + return PTR_ERR(pool); + + rc = tee_device_register_dma_heap(optee->teedev, heap_id, pool); + if (rc) + goto err; + } + + return 0; +err: + pool->ops->destroy_pool(pool); + return rc; +} + static int optee_probe(struct platform_device *pdev) { optee_invoke_fn *invoke_fn; @@ -1679,7 +1715,7 @@ static int optee_probe(struct platform_device *pdev) optee = kzalloc(sizeof(*optee), GFP_KERNEL); if (!optee) { rc = -ENOMEM; - goto err_free_pool; + goto err_free_shm_pool; } optee->ops = &optee_ops; @@ -1752,6 +1788,10 @@ static int optee_probe(struct platform_device *pdev) pr_info("Asynchronous notifications enabled\n"); } + rc = optee_protmem_pool_init(optee); + if (rc) + goto err_notif_uninit; + /* * Ensure that there are no pre-existing shm objects before enabling * the shm cache so that there's no chance of receiving an invalid @@ -1787,6 +1827,7 @@ static int optee_probe(struct platform_device *pdev) optee_disable_shm_cache(optee); optee_smc_notif_uninit_irq(optee); optee_unregister_devices(); + tee_device_unregister_all_dma_heaps(optee->teedev); err_notif_uninit: optee_notif_uninit(optee); err_close_ctx: @@ -1803,7 +1844,7 @@ static int optee_probe(struct platform_device *pdev) tee_device_unregister(optee->teedev
[PATCH v9 0/9] TEE subsystem for protected dma-buf allocations
Hi, This patch set allocates the protected DMA-bufs from a DMA-heap instantiated from the TEE subsystem. The TEE subsystem handles the DMA-buf allocations since it is the TEE (OP-TEE, AMD-TEE, TS-TEE, or perhaps a future QTEE) which sets up the protection for the memory used for the DMA-bufs. The DMA-heap uses a protected memory pool provided by the backend TEE driver, allowing it to choose how to allocate the protected physical memory. The allocated DMA-bufs must be imported with a new TEE_IOC_SHM_REGISTER_FD before they can be passed as arguments when requesting services from the secure world. Three use-cases (Secure Video Playback, Trusted UI, and Secure Video Recording) have been identified so far to serve as examples of what can be expected. The use-cases have predefined DMA-heap names, "protected,secure-video", "protected,trusted-ui", and "protected,secure-video-record". The backend driver registers protected memory pools for the use-cases it supports. Each use-case has its own protected memory pool since different use-cases require isolation from different parts of the system. A protected memory pool can be based on a static carveout instantiated while probing the TEE backend driver, or dynamically allocated from CMA (dma_alloc_pages()) and made protected as needed by the TEE. This can be tested on a RockPi 4B+ with the following steps: repo init -u https://github.com/jenswi-linaro/manifest.git -m rockpi4.xml \ -b prototype/sdp-v9 repo sync -j8 cd build make toolchains -j$(nproc) make all -j$(nproc) # Copy ../out/rockpi4.img to an SD card and boot the RockPi from that # Connect a monitor to the RockPi # login and at the prompt: gst-launch-1.0 videotestsrc ! \ aesenc key=1f9423681beb9a79215820f6bda73d0f \ iv=e9aa8e834d8d70b7e0d254ff670dd718 serialize-iv=true ! \ aesdec key=1f9423681beb9a79215820f6bda73d0f ! \ kmssink The aesdec module has been hacked to use an OP-TEE TA to decrypt the stream into protected DMA-bufs which are consumed by the kmssink. The primitive QEMU tests from previous patch sets can be tested on RockPi in the same way using: xtest --sdp-basic The primitive tests are tested on QEMU with the following steps: repo init -u https://github.com/jenswi-linaro/manifest.git -m qemu_v8.xml \ -b prototype/sdp-v9 repo sync -j8 cd build make toolchains -j$(nproc) make SPMC_AT_EL=1 all -j$(nproc) make SPMC_AT_EL=1 run-only # login and at the prompt: xtest --sdp-basic The SPMC_AT_EL=1 parameter configures the build with FF-A and an SPMC at S-EL1 inside OP-TEE. The parameter can be changed to SPMC_AT_EL=n to test without FF-A using the original SMC ABI instead. Please remember to do %make arm-tf-clean for TF-A to be rebuilt properly using the new configuration. https://optee.readthedocs.io/en/latest/building/prerequisites.html list dependencies required to build the above. The primitive tests are pretty basic, mostly checking that a Trusted Application in the secure world can access and manipulate the memory. There are also some negative tests for out of bounds buffers, etc. Thanks, Jens Changes since V8: * Using dma_alloc_pages() instead of cma_alloc() so the direct dependency on CMA can be removed together with the patches "cma: export cma_alloc() and cma_release()" and "dma-contiguous: export dma_contiguous_default_area". The patch * Renaming the patch "tee: add tee_shm_alloc_cma_phys_mem()" to "tee: add tee_shm_alloc_dma_mem()" * Setting DMA mask for the OP-TEE TEE device based on input from the secure world instead of relying on the parent device so following patches are removed: "tee: tee_device_alloc(): copy dma_mask from parent device" and "optee: pass parent device to tee_device_alloc()". * Adding Sumit Garg's R-B to "tee: refactor params_from_user()" * In the patch "tee: implement protected DMA-heap", map the physical memory passed to tee_protmem_static_pool_alloc(). Changes since V7: * Adding "dma-buf: dma-heap: export declared functions", "cma: export cma_alloc() and cma_release()", and "dma-contiguous: export dma_contiguous_default_area" to export the symbols needed to keep the TEE subsystem as a load module. * Removing CONFIG_TEE_DMABUF_HEAP and CONFIG_TEE_CMA since they aren't needed any longer. * Addressing review comments in "optee: sync secure world ABI headers" * Better align protected memory pool initialization between the smc-abi and ffa-abi parts of the optee driver. * Removing the patch "optee: account for direction while converting parameters" Changes since V6: * Restricted memory is now known as protected memory since to use the same term as https://docs.vulkan.org/guide/latest/protected.html. Update all patches to consistently use protected memory. * In "tee: implement protected DMA-heap" add the hidden config option TEE_DMABUF_HEAP to tell if the DMABUF_HEAPS functions are available for the TEE subsystem * Adding "tee: refactor params_from_user()", broken out from t
[PATCH v9 2/9] dma-buf: dma-heap: export declared functions
Export the dma-buf heap functions declared in . Signed-off-by: Jens Wiklander --- drivers/dma-buf/dma-heap.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c index 3cbe87d4a464..cdddf0e24dce 100644 --- a/drivers/dma-buf/dma-heap.c +++ b/drivers/dma-buf/dma-heap.c @@ -202,6 +202,7 @@ void *dma_heap_get_drvdata(struct dma_heap *heap) { return heap->priv; } +EXPORT_SYMBOL(dma_heap_get_drvdata); /** * dma_heap_get_name - get heap name @@ -214,6 +215,7 @@ const char *dma_heap_get_name(struct dma_heap *heap) { return heap->name; } +EXPORT_SYMBOL(dma_heap_get_name); /** * dma_heap_add - adds a heap to dmabuf heaps @@ -303,6 +305,7 @@ struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info) kfree(heap); return err_ret; } +EXPORT_SYMBOL(dma_heap_add); static char *dma_heap_devnode(const struct device *dev, umode_t *mode) { -- 2.43.0
[PATCH v9 6/9] tee: add tee_shm_alloc_dma_mem()
Add tee_shm_alloc_dma_mem() to allocate DMA memory. The memory is represented by a tee_shm object using the new flag TEE_SHM_DMA_MEM to identify it as DMA memory. The allocated memory will later be lent to the TEE to be used as protected memory. Signed-off-by: Jens Wiklander --- drivers/tee/tee_shm.c| 74 ++-- include/linux/tee_core.h | 5 +++ 2 files changed, 77 insertions(+), 2 deletions(-) diff --git a/drivers/tee/tee_shm.c b/drivers/tee/tee_shm.c index e1ed52ee0a16..92a6a35e1a1e 100644 --- a/drivers/tee/tee_shm.c +++ b/drivers/tee/tee_shm.c @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include #include #include @@ -13,9 +15,14 @@ #include #include #include -#include #include "tee_private.h" +struct tee_shm_dma_mem { + struct tee_shm shm; + dma_addr_t dma_addr; + struct page *page; +}; + static void shm_put_kernel_pages(struct page **pages, size_t page_count) { size_t n; @@ -49,7 +56,14 @@ static void tee_shm_release(struct tee_device *teedev, struct tee_shm *shm) struct tee_shm *parent_shm = NULL; void *p = shm; - if (shm->flags & TEE_SHM_DMA_BUF) { + if (shm->flags & TEE_SHM_DMA_MEM) { + struct tee_shm_dma_mem *dma_mem; + + dma_mem = container_of(shm, struct tee_shm_dma_mem, shm); + p = dma_mem; + dma_free_pages(&teedev->dev, shm->size, dma_mem->page, + dma_mem->dma_addr, DMA_BIDIRECTIONAL); + } else if (shm->flags & TEE_SHM_DMA_BUF) { struct tee_shm_dmabuf_ref *ref; ref = container_of(shm, struct tee_shm_dmabuf_ref, shm); @@ -306,6 +320,62 @@ struct tee_shm *tee_shm_alloc_priv_buf(struct tee_context *ctx, size_t size) } EXPORT_SYMBOL_GPL(tee_shm_alloc_priv_buf); +/** + * tee_shm_alloc_dma_mem() - Allocate DMA memory as shared memory object + * @ctx: Context that allocates the shared memory + * @page_count:Number of pages + * + * The allocated memory is expected to be lent (made inaccessible to the + * kernel) to the TEE while it's used and returned (accessible to the + * kernel again) before it's freed. + * + * This function should normally only be used internally in the TEE + * drivers. + * + * @returns a pointer to 'struct tee_shm' + */ +struct tee_shm *tee_shm_alloc_dma_mem(struct tee_context *ctx, + size_t page_count) +{ + struct tee_device *teedev = ctx->teedev; + struct tee_shm_dma_mem *dma_mem; + dma_addr_t dma_addr; + struct page *page; + + if (!tee_device_get(teedev)) + return ERR_PTR(-EINVAL); + + page = dma_alloc_pages(&teedev->dev, page_count * PAGE_SIZE, + &dma_addr, DMA_BIDIRECTIONAL, GFP_KERNEL); + if (!page) + goto err_put_teedev; + + dma_mem = kzalloc(sizeof(*dma_mem), GFP_KERNEL); + if (!dma_mem) + goto err_free_pages; + + refcount_set(&dma_mem->shm.refcount, 1); + dma_mem->shm.ctx = ctx; + dma_mem->shm.paddr = page_to_phys(page); + dma_mem->dma_addr = dma_addr; + dma_mem->page = page; + dma_mem->shm.size = page_count * PAGE_SIZE; + dma_mem->shm.flags = TEE_SHM_DMA_MEM; + + teedev_ctx_get(ctx); + + return &dma_mem->shm; + +err_free_pages: + dma_free_pages(&teedev->dev, page_count * PAGE_SIZE, page, dma_addr, + DMA_BIDIRECTIONAL); +err_put_teedev: + tee_device_put(teedev); + + return ERR_PTR(-ENOMEM); +} +EXPORT_SYMBOL_GPL(tee_shm_alloc_dma_mem); + int tee_dyn_shm_alloc_helper(struct tee_shm *shm, size_t size, size_t align, int (*shm_register)(struct tee_context *ctx, struct tee_shm *shm, diff --git a/include/linux/tee_core.h b/include/linux/tee_core.h index 02c07f661349..925690e1020b 100644 --- a/include/linux/tee_core.h +++ b/include/linux/tee_core.h @@ -29,6 +29,8 @@ #define TEE_SHM_POOL BIT(2) /* Memory allocated from pool */ #define TEE_SHM_PRIV BIT(3) /* Memory private to TEE driver */ #define TEE_SHM_DMA_BUFBIT(4) /* Memory with dma-buf handle */ +#define TEE_SHM_DMA_MEMBIT(5) /* Memory allocated with */ + /* dma_alloc_pages() */ #define TEE_DEVICE_FLAG_REGISTERED 0x1 #define TEE_MAX_DEV_NAME_LEN 32 @@ -310,6 +312,9 @@ void *tee_get_drvdata(struct tee_device *teedev); */ struct tee_shm *tee_shm_alloc_priv_buf(struct tee_context *ctx, size_t size); +struct tee_shm *tee_shm_alloc_dma_mem(struct tee_context *ctx, + size_t page_count); + int tee_dyn_shm_alloc_helper(struct tee_shm *shm, size_t size, size_t align, int (*shm_register)(struct tee_context *ctx,
Re: [PATCH v2] drm/amd/display: adds kernel-doc comment for dc_stream_remove_writeback()
On 5/19/25 20:06, James wrote: On Mon, May 5, 2025, at 9:02 AM, Alex Hung wrote: Reviewed-by: Alex Hung On 5/3/25 15:18, James Flowers wrote: Adds kernel-doc for externally linked dc_stream_remove_writeback function. Signed-off-by: James Flowers --- V1 -> V2: Corrected checkpatch warnings and errors drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 8 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c index e6e41678525f..b883fb24fa12 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -569,6 +569,14 @@ bool dc_stream_fc_disable_writeback(struct dc *dc, return true; } +/** + * dc_stream_remove_writeback() - Disables writeback and removes writeback info. + * @dc: Display core control structure. + * @stream: Display core stream state. + * @dwb_pipe_inst: Display writeback pipe. + * + * Return: returns true on success, false otherwise. + */ bool dc_stream_remove_writeback(struct dc *dc, struct dc_stream_state *stream, uint32_t dwb_pipe_inst) Hi, I am just following up on this to see if it’s been applied, or if any adjustments are still needed. It's in amd-staging-drm-next: https://gitlab.freedesktop.org/agd5f/linux/-/commit/04abe7201d51a094d0edd3e00399a8afa2cd2d4f Best regards, James Flowers
Re: [PATCH v3 16/19] nova-core: Add support for VBIOS ucode extraction for boot
On Tue, May 20, 2025 at 11:11:12AM -0400, Joel Fernandes wrote: > On 5/20/2025 11:01 AM, Danilo Krummrich wrote: > > I made this change and it LGTM. Thanks! I did not do the '.0' though since I > want to keep the readability, lets see in the next revision if that looks > good. I think readability, is just as good with `.0`, but I'm fine with either. > >>> In general, I feel like a lot of those Option come from a programming > >>> pattern > >>> that is very common in C, i.e. allocate a structure (stack or heap) and > >>> then > >>> initialize its fields. > >>> > >>> In Rust you should aim to initialize all the fields of a structure when > >>> you > >>> create the instance. Option as a return type of a function is common, but > >>> it's > >>> always a bit suspicious when there is an Option field in a struct. > >> > >> I looked into it, I could not git rid of those ones because we need to > >> initialize in the "impl TryFrom for BiosImage {" > >> > >> 0xE0 => Ok(BiosImage::FwSec(FwSecBiosImage { > >> base, > >> falcon_data_offset: None, > >> pmu_lookup_table: None, > >> falcon_ucode_offset: None, > >> })), > >> > >> And these fields will not be determined until much later, because as is > >> the case > >> with the earlier example, these fields cannot be determined until all the > >> images > >> are parsed. > > > > You should not use TryFrom, but instead use a normal constructor, such as > > > > BiosImage::new(base_bios_image) > > > > and do the parsing within this constructor. > > > > If you want a helper type with Options while parsing that's totally fine, > > but > > the final result can clearly be without Options. For instance: > > > > struct Data { > >image: KVec, > > } > > > > impl Data { > >fn new() -> Result { > > let parser = DataParser::new(); > > > > Self { image: parser.parse()? } > >} > > > >fn load_image(&self) { > > ... > >} > > } > > > > struct DataParser { > >// Only some images have a checksum. > >checksum: Option, > >// Some images have an extra offset. > >offset: Option, > >// Some images need to be patched. > >patch: Option>, > >image: KVec, > > } > > > > impl DataParser { > >fn new() -> Self { > > Self { > > checksum: None, > > offset: None, > > patch: None, > > bytes: KVec::new(), > > } > >} > > > >fn parse(self) -> Result> { > > // Fetch all the required data. > > self.fetch_checksum()?; > > self.fetch_offset()?; > > self.fetch_patch()?; > > self.fetch_byes()?; > > > > // Doesn't do anything if `checksum == None`. > > self.validate_checksum()?; > > > > // Doesn't do anything if `offset == None`. > > self.apply_offset()?; > > > > // Doesn't do anything if `patch == None`. > > self.apply_patch()?; > > > > // Return the final image. > > self.image > >} > > } > > > > I think the pattern here is the same, but in this example you keep working > > with > > the DataParser, instead of a new instance of Data. > > I think this would be a fundamental rewrite of the patch. I am Ok with looking > into it as a future item, but right now I am not sure if it justifies not > using > Option for these few. There's a lot of immediate work we have to do for boot, > lets please not block the patch on just this if that's Ok with you. If you > want, > I could add a TODO here. Honestly, I don't think it'd be too bad to fix this up. It's "just" a bit of juggling fields and moving code around. The actual code should not change much. Having Option where the corresponding value T isn't actually optional is extremely confusing and makes it hard for everyone, but especially new contributors, to understand the code and can easily trick people into taking wrong assumptions. Making the code reasonably accessible for (new) contributors is one of the objectives of nova and one of the learnings from nouveau. Hence, let's get this right from the get-go please.
Re: [PATCH v5 00/40] drm/msm: sparse / "VM_BIND" support
On Mon, 19 May 2025 10:51:23 -0700, Rob Clark wrote: > Conversion to DRM GPU VA Manager[1], and adding support for Vulkan Sparse > Memory[2] in the form of: > > 1. A new VM_BIND submitqueue type for executing VM MSM_SUBMIT_BO_OP_MAP/ >MAP_NULL/UNMAP commands > > 2. A new VM_BIND ioctl to allow submitting batches of one or more >MAP/MAP_NULL/UNMAP commands to a VM_BIND submitqueue > > [...] Applied io-pgtable change to iommu (arm/smmu/updates), thanks! [05/40] iommu/io-pgtable-arm: Add quirk to quiet WARN_ON() https://git.kernel.org/iommu/c/3318f7b5cefb Cheers, -- Will https://fixes.arm64.dev https://next.arm64.dev https://will.arm64.dev
[PATCH v5 0/3] drm: Create a tas info option for wedge events
This patchset implements a request made by Xaver Hugl about wedge events: "I'd really like to have the PID of the client that triggered the GPU reset, so that we can kill it if multiple resets are triggered in a row (or switch to software rendering if it's KWin itself) and show a user-friendly notification about why their app(s) crashed, but that can be added later." >From >https://lore.kernel.org/dri-devel/CAFZQkGwJ4qgHV8WTp2=svJ_VXhb-+Y8_VNtKB=jlsk6dqmy...@mail.gmail.com/ For testing, I've used amdgpu's debug_mask options debug_disable_soft_recovery and debug_disable_gpu_ring_reset to test both wedge event paths in the driver. To trigger a ring timeout, I've used this app: https://gitlab.freedesktop.org/andrealmeid/gpu-timeout Thanks! Changelog: v5: - Change from app to task also in structs, commit message and docs - Add a check for NULL or empty task name string v4: - Change from APP to TASK - Add defines for event_string and pid_string length v3: - Make comm_string and pid_string empty when there's no app info - Change "app that caused ..." to "app involved ..." - Clarify that devcoredump have more information about what happened v2: - Rebased on top of drm/drm-next - Added new patch for documentation André Almeida (3): drm: Create a task info option for wedge events drm/doc: Add a section about "Task information" for the wedge API drm/amdgpu: Make use of drm_wedge_task_info Documentation/gpu/drm-uapi.rst | 17 + drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 19 +-- drivers/gpu/drm/amd/amdgpu/amdgpu_job.c| 6 +- drivers/gpu/drm/drm_drv.c | 19 +++ drivers/gpu/drm/i915/gt/intel_reset.c | 3 ++- drivers/gpu/drm/xe/xe_device.c | 3 ++- include/drm/drm_device.h | 8 include/drm/drm_drv.h | 3 ++- 8 files changed, 68 insertions(+), 10 deletions(-) -- 2.49.0
[PATCH v5 2/3] drm/doc: Add a section about "Task information" for the wedge API
Add a section about "Task information" for the wedge API. Reviewed-by: Krzysztof Karas Reviewed-by: Raag Jadav Signed-off-by: André Almeida --- v5: - Change app to task in the text as well v4: - Change APP to TASK v3: - Change "app that caused ..." to "app involved ..." - Clarify that devcoredump have more information about what happened - Update that PID and APP will be empty if there's no app info --- Documentation/gpu/drm-uapi.rst | 17 + 1 file changed, 17 insertions(+) diff --git a/Documentation/gpu/drm-uapi.rst b/Documentation/gpu/drm-uapi.rst index 69f72e71a96e..24aa9f320ebc 100644 --- a/Documentation/gpu/drm-uapi.rst +++ b/Documentation/gpu/drm-uapi.rst @@ -446,6 +446,23 @@ telemetry information (devcoredump, syslog). This is useful because the first hang is usually the most critical one which can result in consequential hangs or complete wedging. +Task information +--- + +The information about which application (if any) was involved in the device +wedging is useful for userspace if they want to notify the user about what +happened (e.g. the compositor display a message to the user "The +caused a graphical error and the system recovered") or to implement policies +(e.g. the daemon may "ban" an task that keeps resetting the device). If the task +information is available, the uevent will display as ``PID=`` and +``TASK=``. Otherwise, ``PID`` and ``TASK`` will not appear in the +event string. + +The reliability of this information is driver and hardware specific, and should +be taken with a caution regarding it's precision. To have a big picture of what +really happened, the devcoredump file provides should have much more detailed +information about the device state and about the event. + Consumer prerequisites -- -- 2.49.0
[PATCH v5 3/3] drm/amdgpu: Make use of drm_wedge_task_info
To notify userspace about which task (if any) made the device get in a wedge state, make use of drm_wedge_task_info parameter, filling it with the task PID and name. Signed-off-by: André Almeida --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 19 +-- drivers/gpu/drm/amd/amdgpu/amdgpu_job.c| 6 +- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index d27091d5929c..c29c924aa506 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -6362,8 +6362,23 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, atomic_set(&adev->reset_domain->reset_res, r); - if (!r) - drm_dev_wedged_event(adev_to_drm(adev), DRM_WEDGE_RECOVERY_NONE, NULL); + if (!r) { + struct drm_wedge_task_info aux, *info = NULL; + + if (job) { + struct amdgpu_task_info *ti; + + ti = amdgpu_vm_get_task_info_pasid(adev, job->pasid); + if (ti) { + aux.pid = ti->pid; + aux.comm = ti->process_name; + info = &aux; + amdgpu_vm_put_task_info(ti); + } + } + + drm_dev_wedged_event(adev_to_drm(adev), DRM_WEDGE_RECOVERY_NONE, info); + } return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c index a47b2eb301e5..5cb17e62df57 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c @@ -89,6 +89,7 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job) { struct amdgpu_ring *ring = to_amdgpu_ring(s_job->sched); struct amdgpu_job *job = to_amdgpu_job(s_job); + struct drm_wedge_task_info aux, *info = NULL; struct amdgpu_task_info *ti; struct amdgpu_device *adev = ring->adev; int idx; @@ -127,6 +128,9 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job) dev_err(adev->dev, "Process information: process %s pid %d thread %s pid %d\n", ti->process_name, ti->tgid, ti->task_name, ti->pid); + aux.pid = ti->pid; + aux.comm = ti->process_name; + info = &aux; amdgpu_vm_put_task_info(ti); } @@ -166,7 +170,7 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job) if (amdgpu_ring_sched_ready(ring)) drm_sched_start(&ring->sched, 0); dev_err(adev->dev, "Ring %s reset succeeded\n", ring->sched.name); - drm_dev_wedged_event(adev_to_drm(adev), DRM_WEDGE_RECOVERY_NONE, NULL); + drm_dev_wedged_event(adev_to_drm(adev), DRM_WEDGE_RECOVERY_NONE, info); goto exit; } dev_err(adev->dev, "Ring %s reset failure\n", ring->sched.name); -- 2.49.0
[PATCH v5 1/3] drm: Create a task info option for wedge events
When a device get wedged, it might be caused by a guilty application. For userspace, knowing which task was the cause can be useful for some situations, like for implementing a policy, logs or for giving a chance for the compositor to let the user know what task caused the problem. This is an optional argument, when the task info is not available, the PID and TASK string won't appear in the event string. Sometimes just the PID isn't enough giving that the task might be already dead by the time userspace will try to check what was this PID's name, so to make the life easier also notify what's the task's name in the user event. Acked-by: Rodrigo Vivi (for i915 and xe) Reviewed-by: Krzysztof Karas Signed-off-by: André Almeida --- v5: - s/app/task for struct and commit message as well - move defines to drm_drv.c - validates if comm is not NULL and it's not empty v4: s/APP/TASK v3: Make comm_string and pid_string empty when there's no app info --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_job.c| 2 +- drivers/gpu/drm/drm_drv.c | 19 +++ drivers/gpu/drm/i915/gt/intel_reset.c | 3 ++- drivers/gpu/drm/xe/xe_device.c | 3 ++- include/drm/drm_device.h | 8 include/drm/drm_drv.h | 3 ++- 7 files changed, 31 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 4d1b54f58495..d27091d5929c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -6363,7 +6363,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, atomic_set(&adev->reset_domain->reset_res, r); if (!r) - drm_dev_wedged_event(adev_to_drm(adev), DRM_WEDGE_RECOVERY_NONE); + drm_dev_wedged_event(adev_to_drm(adev), DRM_WEDGE_RECOVERY_NONE, NULL); return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c index acb21fc8b3ce..a47b2eb301e5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c @@ -166,7 +166,7 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job) if (amdgpu_ring_sched_ready(ring)) drm_sched_start(&ring->sched, 0); dev_err(adev->dev, "Ring %s reset succeeded\n", ring->sched.name); - drm_dev_wedged_event(adev_to_drm(adev), DRM_WEDGE_RECOVERY_NONE); + drm_dev_wedged_event(adev_to_drm(adev), DRM_WEDGE_RECOVERY_NONE, NULL); goto exit; } dev_err(adev->dev, "Ring %s reset failure\n", ring->sched.name); diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 3dc7acd56b1d..84e78ce21b65 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -538,10 +538,14 @@ static const char *drm_get_wedge_recovery(unsigned int opt) } } +#define WEDGE_STR_LEN 32 +#define PID_LEN 15 + /** * drm_dev_wedged_event - generate a device wedged uevent * @dev: DRM device * @method: method(s) to be used for recovery + * @info: optional information about the guilty task * * This generates a device wedged uevent for the DRM device specified by @dev. * Recovery @method\(s) of choice will be sent in the uevent environment as @@ -554,13 +558,13 @@ static const char *drm_get_wedge_recovery(unsigned int opt) * * Returns: 0 on success, negative error code otherwise. */ -int drm_dev_wedged_event(struct drm_device *dev, unsigned long method) +int drm_dev_wedged_event(struct drm_device *dev, unsigned long method, +struct drm_wedge_task_info *info) { const char *recovery = NULL; unsigned int len, opt; - /* Event string length up to 28+ characters with available methods */ - char event_string[32]; - char *envp[] = { event_string, NULL }; + char event_string[WEDGE_STR_LEN], pid_string[PID_LEN] = "", comm_string[TASK_COMM_LEN] = ""; + char *envp[] = { event_string, NULL, NULL, NULL }; len = scnprintf(event_string, sizeof(event_string), "%s", "WEDGED="); @@ -582,6 +586,13 @@ int drm_dev_wedged_event(struct drm_device *dev, unsigned long method) drm_info(dev, "device wedged, %s\n", method == DRM_WEDGE_RECOVERY_NONE ? "but recovered through reset" : "needs recovery"); + if (info && ((info->comm && info->comm[0] != '\0'))) { + snprintf(pid_string, sizeof(pid_string), "PID=%u", info->pid); + snprintf(comm_string, sizeof(comm_string), "TASK=%s", info->comm); + envp[1] = pid_string; + envp[2] = comm_string; + } + return kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp); } EXPOR
Re: [PATCH v2] dt-bindings: display: bridge: renesas,dsi: allow properties from dsi-controller
On Tue, 20 May 2025 17:00:11 +0100 Conor Dooley wrote: > On Tue, May 20, 2025 at 04:58:12PM +0100, Conor Dooley wrote: > > On Tue, May 20, 2025 at 11:11:12AM -0400, Hugo Villeneuve wrote: > > > From: Hugo Villeneuve > > > > > > Allow to inherit valid properties from the dsi-controller. This fixes the > > > following warning when adding a panel property: > > > > > > rzg2lc.dtb: dsi@1085: '#address-cells', '#size-cells', 'panel@0' do > > > not > > > match any of the regexes: 'pinctrl-[0-9]+' > > > from schema $id: > > > http://devicetree.org/schemas/display/bridge/renesas,dsi.yaml# > > > > > > Also add a panel property to the example. > > > > I don't think adding the example should be in the same patch as a fix. > > Or am I misunderstanding, and this is a new type of usage, rather than a > fix? Hi Conor, it is more like a new type of usage. -- Hugo Villeneuve
Re: [PATCH v9 03/10] drm/sched: add device name to the drm_sched_process_job event
Le 19/05/2025 à 17:34, Danilo Krummrich a écrit : On Thu, Apr 24, 2025 at 10:38:15AM +0200, Pierre-Eric Pelloux-Prayer wrote: diff --git a/drivers/gpu/drm/scheduler/gpu_scheduler_trace.h b/drivers/gpu/drm/scheduler/gpu_scheduler_trace.h index f56e77e7f6d0..713df3516a17 100644 --- a/drivers/gpu/drm/scheduler/gpu_scheduler_trace.h +++ b/drivers/gpu/drm/scheduler/gpu_scheduler_trace.h @@ -42,6 +42,7 @@ DECLARE_EVENT_CLASS(drm_sched_job, __field(uint64_t, id) __field(u32, job_count) __field(int, hw_job_count) +__string(dev, dev_name(sched_job->sched->dev)) Using the sched_job->sched pointer here and in other trace events implies that the trace event must not be called before the sched_job->sched has been set, i.e. in drm_sched_job_arm(). Please document this for the corresponding trace events. This is not a new requirement as sched and s_fence were already used by the trace events. Still it's a good idea to document this, so I'll update the comment added in the documentation patch. Thanks, Pierre-Eric
Re: [PATCH v3 16/19] nova-core: Add support for VBIOS ucode extraction for boot
On 5/20/2025 11:36 AM, Danilo Krummrich wrote: >>> If you want a helper type with Options while parsing that's totally fine, >>> but >>> the final result can clearly be without Options. For instance: >>> >>> struct Data { >>>image: KVec, >>> } >>> >>> impl Data { >>>fn new() -> Result { >>> let parser = DataParser::new(); >>> >>> Self { image: parser.parse()? } >>>} >>> >>>fn load_image(&self) { >>> ... >>>} >>> } >>> >>> struct DataParser { >>>// Only some images have a checksum. >>>checksum: Option, >>>// Some images have an extra offset. >>>offset: Option, >>>// Some images need to be patched. >>>patch: Option>, >>>image: KVec, >>> } >>> >>> impl DataParser { >>>fn new() -> Self { >>> Self { >>> checksum: None, >>> offset: None, >>> patch: None, >>> bytes: KVec::new(), >>> } >>>} >>> >>>fn parse(self) -> Result> { >>> // Fetch all the required data. >>> self.fetch_checksum()?; >>> self.fetch_offset()?; >>> self.fetch_patch()?; >>> self.fetch_byes()?; >>> >>> // Doesn't do anything if `checksum == None`. >>> self.validate_checksum()?; >>> >>> // Doesn't do anything if `offset == None`. >>> self.apply_offset()?; >>> >>> // Doesn't do anything if `patch == None`. >>> self.apply_patch()?; >>> >>> // Return the final image. >>> self.image >>>} >>> } >>> >>> I think the pattern here is the same, but in this example you keep working >>> with >>> the DataParser, instead of a new instance of Data. >> I think this would be a fundamental rewrite of the patch. I am Ok with >> looking >> into it as a future item, but right now I am not sure if it justifies not >> using >> Option for these few. There's a lot of immediate work we have to do for boot, >> lets please not block the patch on just this if that's Ok with you. If you >> want, >> I could add a TODO here. > > Honestly, I don't think it'd be too bad to fix this up. It's "just" a bit of > juggling fields and moving code around. The actual code should not change > much. > > Having Option where the corresponding value T isn't actually optional is > extremely confusing and makes it hard for everyone, but especially new > contributors, to understand the code and can easily trick people into taking > wrong assumptions. > > Making the code reasonably accessible for (new) contributors is one of the > objectives of nova and one of the learnings from nouveau. I implemented the Data parsing pattern like the following, the final FwSecBiosImage will not have optional fields as you suggested. It does get rid of 2 additional fields as well which are not needed after vbios parsing completes. https://git.kernel.org/pub/scm/linux/kernel/git/jfern/linux.git/commit/?h=nova/vbios&id=8cc852fe5573890596a91a2a935b3af24dcb9f04 Hope that looks Ok now! I am open to naming FwSecBiosPartial as FwSecBiosData if that's better. The full file after the change: https://git.kernel.org/pub/scm/linux/kernel/git/jfern/linux.git/tree/drivers/gpu/nova-core/vbios.rs?h=nova/vbios&id=8cc852fe5573890596a91a2a935b3af24dcb9f04 thanks, - Joel
[PATCH v3 0/4] rust: drm: gem: More (and final) cleanup
Look mom, no generic soup! Anyway - this is just the last of the cleanup stuff I ended up while working on cleaning up the gem shmem patch series. It simplifies the use of generics and also adds a type alias for some very long types currently in use. Also, drop one unused constant I noticed. Applies on top of nova/nova-next: https://gitlab.freedesktop.org/drm/nova/-/tree/nova-next Lyude Paul (4): rust: drm: gem: Simplify use of generics rust: drm: gem: Add DriverFile type alias rust: drm: gem: Drop Object::SIZE rust: drm: Use gem::BaseDriverObject in driver::Driver drivers/gpu/drm/nova/driver.rs | 4 +- drivers/gpu/drm/nova/gem.rs| 9 ++- rust/kernel/drm/device.rs | 17 +++--- rust/kernel/drm/driver.rs | 5 +- rust/kernel/drm/gem/mod.rs | 108 +++-- 5 files changed, 70 insertions(+), 73 deletions(-) base-commit: 276c53c66e032c8e7cc0da63555f2742eb1afd69 -- 2.49.0
[PATCH v3 4/4] rust: drm: Use gem::BaseDriverObject in driver::Driver
One of the original intents with the gem bindings was that drivers could specify additional gem implementations, in order to enable for driver private gem objects. This wasn't really possible however, as up until now our GEM bindings have always assumed that the only GEM object we would run into was driver::Driver::Object - meaning that implementing another GEM object type would result in all of the BaseDriverObject callbacks assuming the wrong type. This is a pretty easy fix though, all we need to do is specify a BaseDriverObject in driver::Driver instead of an AllocImpl, and then add an associated type for AllocImpl in BaseDriverObject. That way each BaseDriverObject has its own AllocImpl allowing it to know which type to provide in BaseDriverObject callbacks, and driver::Driver can simply go through the BaseDriverObject to its AllocImpl type in order to get access to ALLOC_OPS. So, let's do this and update Nova for these changes. Signed-off-by: Lyude Paul --- drivers/gpu/drm/nova/driver.rs | 4 ++-- drivers/gpu/drm/nova/gem.rs| 1 + rust/kernel/drm/device.rs | 17 ++--- rust/kernel/drm/driver.rs | 2 +- rust/kernel/drm/gem/mod.rs | 11 +++ 5 files changed, 21 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/nova/driver.rs b/drivers/gpu/drm/nova/driver.rs index b28b2e05cc156..58e534cf3ed39 100644 --- a/drivers/gpu/drm/nova/driver.rs +++ b/drivers/gpu/drm/nova/driver.rs @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 -use kernel::{auxiliary, c_str, device::Core, drm, drm::gem, drm::ioctl, prelude::*, types::ARef}; +use kernel::{auxiliary, c_str, device::Core, drm, drm::ioctl, prelude::*, types::ARef}; use crate::file::File; use crate::gem::NovaObject; @@ -57,7 +57,7 @@ fn probe(adev: &auxiliary::Device, _info: &Self::IdInfo) -> Result; +type Object = NovaObject; const INFO: drm::DriverInfo = INFO; diff --git a/drivers/gpu/drm/nova/gem.rs b/drivers/gpu/drm/nova/gem.rs index 68f93c9675611..a3024922f0d90 100644 --- a/drivers/gpu/drm/nova/gem.rs +++ b/drivers/gpu/drm/nova/gem.rs @@ -18,6 +18,7 @@ pub(crate) struct NovaObject {} impl gem::BaseDriverObject for NovaObject { type Driver = NovaDriver; +type Object = gem::Object; fn new(_dev: &NovaDevice, _size: usize) -> impl PinInit { try_pin_init!(NovaObject {}) diff --git a/rust/kernel/drm/device.rs b/rust/kernel/drm/device.rs index 74c9a3dd719e3..6fc6995be637d 100644 --- a/rust/kernel/drm/device.rs +++ b/rust/kernel/drm/device.rs @@ -60,6 +60,9 @@ pub struct Device { data: T::Data, } +/// A type alias for referring to the [`AllocImpl`] implementation for a DRM driver. +type DriverAllocImpl = <::Object as drm::gem::BaseDriverObject>::Object; + impl Device { const VTABLE: bindings::drm_driver = drm_legacy_fields! { load: None, @@ -70,13 +73,13 @@ impl Device { master_set: None, master_drop: None, debugfs_init: None, -gem_create_object: T::Object::ALLOC_OPS.gem_create_object, -prime_handle_to_fd: T::Object::ALLOC_OPS.prime_handle_to_fd, -prime_fd_to_handle: T::Object::ALLOC_OPS.prime_fd_to_handle, -gem_prime_import: T::Object::ALLOC_OPS.gem_prime_import, -gem_prime_import_sg_table: T::Object::ALLOC_OPS.gem_prime_import_sg_table, -dumb_create: T::Object::ALLOC_OPS.dumb_create, -dumb_map_offset: T::Object::ALLOC_OPS.dumb_map_offset, +gem_create_object: DriverAllocImplALLOC_OPS.gem_create_object, +prime_handle_to_fd: DriverAllocImplALLOC_OPS.prime_handle_to_fd, +prime_fd_to_handle: DriverAllocImplALLOC_OPS.prime_fd_to_handle, +gem_prime_import: DriverAllocImplALLOC_OPS.gem_prime_import, +gem_prime_import_sg_table: DriverAllocImplALLOC_OPS.gem_prime_import_sg_table, +dumb_create: DriverAllocImplALLOC_OPS.dumb_create, +dumb_map_offset: DriverAllocImplALLOC_OPS.dumb_map_offset, show_fdinfo: None, fbdev_probe: None, diff --git a/rust/kernel/drm/driver.rs b/rust/kernel/drm/driver.rs index 2be2a2d318e03..a77747edac80e 100644 --- a/rust/kernel/drm/driver.rs +++ b/rust/kernel/drm/driver.rs @@ -106,7 +106,7 @@ pub trait Driver { type Data: Sync + Send; /// The type used to manage memory for this driver. -type Object: AllocImpl; +type Object: drm::gem::BaseDriverObject; /// The type used to represent a DRM File (client) type File: drm::file::DriverFile; diff --git a/rust/kernel/drm/gem/mod.rs b/rust/kernel/drm/gem/mod.rs index 8944fc7a815a2..3c45883011d49 100644 --- a/rust/kernel/drm/gem/mod.rs +++ b/rust/kernel/drm/gem/mod.rs @@ -26,16 +26,19 @@ pub trait BaseDriverObject: Sync + Send + Sized { /// Parent `Driver` for this object. type Driver: drm::Driver; +/// The GEM object type that will be passed to various callbacks. +type Object: AllocImpl; + /// Create a new driver data object for a GEM obje
[PATCH v3 2/4] rust: drm: gem: Add DriverFile type alias
Just to reduce the clutter with the File<…> types in gem.rs. Signed-off-by: Lyude Paul --- V3: * Rename ObjectFile to DriverFile Signed-off-by: Lyude Paul --- rust/kernel/drm/gem/mod.rs | 23 --- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/rust/kernel/drm/gem/mod.rs b/rust/kernel/drm/gem/mod.rs index 1974e1316ecb1..a60d133e3c3b4 100644 --- a/rust/kernel/drm/gem/mod.rs +++ b/rust/kernel/drm/gem/mod.rs @@ -14,6 +14,13 @@ }; use core::{mem, ops::Deref, ptr::NonNull}; +/// A type alias for retrieving a [`Driver`]s [`DriverFile`] implementation from its +/// [`DriverObject`] implementation. +/// +/// [`Driver`]: drm::Driver +/// [`DriverFile`]: drm::file::DriverFile +pub type DriverFile = drm::File<<::Driver as drm::Driver>::File>; + /// GEM object functions, which must be implemented by drivers. pub trait BaseDriverObject: Sync + Send + Sized { /// Parent `Driver` for this object. @@ -23,19 +30,12 @@ pub trait BaseDriverObject: Sync + Send + Sized { fn new(dev: &drm::Device, size: usize) -> impl PinInit; /// Open a new handle to an existing object, associated with a File. -fn open( -_obj: &::Object, -_file: &drm::File<::File>, -) -> Result { +fn open(_obj: &::Object, _file: &DriverFile) -> Result { Ok(()) } /// Close a handle to an existing object, associated with a File. -fn close( -_obj: &::Object, -_file: &drm::File<::File>, -) { -} +fn close(_obj: &::Object, _file: &DriverFile) {} } /// Trait that represents a GEM object subtype @@ -79,7 +79,8 @@ extern "C" fn open_callback( raw_file: *mut bindings::drm_file, ) -> core::ffi::c_int { // SAFETY: `open_callback` is only ever called with a valid pointer to a `struct drm_file`. -let file = unsafe { drm::File::<::File>::as_ref(raw_file) }; +let file = unsafe { DriverFileas_ref(raw_file) }; + // SAFETY: `open_callback` is specified in the AllocOps structure for `DriverObject`, // ensuring that `raw_obj` is contained within a `DriverObject` let obj = unsafe { <::Object as IntoGEMObject>::as_ref(raw_obj) }; @@ -95,7 +96,7 @@ extern "C" fn close_callback( raw_file: *mut bindings::drm_file, ) { // SAFETY: `open_callback` is only ever called with a valid pointer to a `struct drm_file`. -let file = unsafe { drm::File::<::File>::as_ref(raw_file) }; +let file = unsafe { DriverFileas_ref(raw_file) }; // SAFETY: `close_callback` is specified in the AllocOps structure for `Object`, ensuring // that `raw_obj` is indeed contained within a `Object`. -- 2.49.0
Re: [PATCH v4 04/40] drm/sched: Add enqueue credit limit
n Tue, May 20, 2025 at 12:54 PM Danilo Krummrich wrote: > > On Tue, May 20, 2025 at 09:07:05AM -0700, Rob Clark wrote: > > On Tue, May 20, 2025 at 12:06 AM Danilo Krummrich wrote: > > > > > > On Thu, May 15, 2025 at 12:56:38PM -0700, Rob Clark wrote: > > > > On Thu, May 15, 2025 at 11:56 AM Danilo Krummrich > > > > wrote: > > > > > > > > > > On Thu, May 15, 2025 at 10:40:15AM -0700, Rob Clark wrote: > > > > > > On Thu, May 15, 2025 at 10:30 AM Danilo Krummrich > > > > > > wrote: > > > > > > > > > > > > > > (Cc: Boris) > > > > > > > > > > > > > > On Thu, May 15, 2025 at 12:22:18PM -0400, Connor Abbott wrote: > > > > > > > > For some context, other drivers have the concept of a > > > > > > > > "synchronous" > > > > > > > > VM_BIND ioctl which completes immediately, and drivers > > > > > > > > implement it by > > > > > > > > waiting for the whole thing to finish before returning. > > > > > > > > > > > > > > Nouveau implements sync by issuing a normal async VM_BIND and > > > > > > > subsequently > > > > > > > waits for the out-fence synchronously. > > > > > > > > > > > > As Connor mentioned, we'd prefer it to be async rather than > > > > > > blocking, > > > > > > in normal cases, otherwise with drm native context for using native > > > > > > UMD in guest VM, you'd be blocking the single host/VMM virglrender > > > > > > thread. > > > > > > > > > > > > The key is we want to keep it async in the normal cases, and not > > > > > > have > > > > > > weird edge case CTS tests blow up from being _too_ async ;-) > > > > > > > > > > I really wonder why they don't blow up in Nouveau, which also support > > > > > full > > > > > asynchronous VM_BIND. Mind sharing which tests blow up? :) > > > > > > > > Maybe it was > > > > dEQP-VK.sparse_resources.buffer.ssbo.sparse_residency.buffer_size_2_24, > > > > > > The test above is part of the smoke testing I do for nouveau, but I > > > haven't seen > > > such issues yet for nouveau. > > > > nouveau is probably not using async binds for everything? Or maybe > > I'm just pointing to the wrong test. > > Let me double check later on. > > > > > but I might be mixing that up, I'd have to back out this patch and see > > > > where things blow up, which would take many hours. > > > > > > Well, you said that you never had this issue with "real" workloads, but > > > only > > > with VK CTS, so I really think we should know what we are trying to fix > > > here. > > > > > > We can't just add new generic infrastructure without reasonable and *well > > > understood* justification. > > > > What is not well understood about this? We need to pre-allocate > > memory that we likely don't need for pagetables. > > > > In the worst case, a large # of async PAGE_SIZE binds, you end up > > needing to pre-allocate 3 pgtable pages (4 lvl pgtable) per one page > > of mapping. Queue up enough of those and you can explode your memory > > usage. > > Well, the general principle how this can OOM is well understood, sure. What's > not well understood is how we run in this case. I think we should also > understand what test causes the issue and why other drivers are not affected > (yet). Once again, it's well understood why other drivers aren't affected. They have both synchronous and asynchronous VM_BINDs in the uabi, and the userspace driver uses synchronous VM_BIND for everything except sparse mappings. For freedreno we tried to change that because async works better for native context, which exposed the pre-existing issue with async VM_BINDs causing the whole system to hang when we run out of memory since more mappings started being async. I think it would be possible in theory for other drivers to forward synchronous VM_BINDs asynchronously to the host as long as the host kernel executes them synchronously, so maybe other drivers won't have a problem with native context support. But it will still be possible to make them fall over if you poke them the right way. Connor > > > > > There definitely was one where I was seeing >5k VM_BIND jobs pile up, > > > > so absolutely throttling like this is needed. > > > > > > I still don't understand why the kernel must throttle this? If userspace > > > uses > > > async VM_BIND, it obviously can't spam the kernel infinitely without > > > running > > > into an OOM case. > > > > It is a valid question about whether the kernel or userspace should be > > the one to do the throttling. > > > > I went for doing it in the kernel because the kernel has better > > knowledge of how much it needs to pre-allocate. > > > > (There is also the side point, that this pre-allocated memory is not > > charged to the calling process from a PoV of memory accounting. So > > with that in mind it seems like a good idea for the kernel to throttle > > memory usage.) > > That's a very valid point, maybe we should investigate in the direction of > addressing this, rather than trying to work around it in the scheduler, where > we > can only set an arbitrary credit limit. > > > >
[PATCH 1/2] drm: rcar-du: rzg2l_mipi_dsi: Implement host transfers
From: Hugo Villeneuve Add support for sending MIPI DSI command packets from the host to a peripheral. This is required for panels that need configuration before they accept video data. Based on Renesas Linux kernel v5.10 repos [1]. Link: https://github.com/renesas-rz/rz_linux-cip.git Cc: Biju Das Cc: Chris Brandt Signed-off-by: Hugo Villeneuve --- .../gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c| 174 ++ .../drm/renesas/rz-du/rzg2l_mipi_dsi_regs.h | 56 ++ 2 files changed, 230 insertions(+) diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c index dc6ab012cdb69..77d3a31ff8e35 100644 --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c @@ -6,6 +6,7 @@ */ #include #include +#include #include #include #include @@ -23,9 +24,12 @@ #include #include #include +#include #include "rzg2l_mipi_dsi_regs.h" +#define RZG2L_DCS_BUF_SIZE 128 /* Maximum DCS buffer size in external memory. */ + struct rzg2l_mipi_dsi { struct device *dev; void __iomem *mmio; @@ -44,6 +48,10 @@ struct rzg2l_mipi_dsi { unsigned int num_data_lanes; unsigned int lanes; unsigned long mode_flags; + + /* DCS buffer pointers when using external memory. */ + dma_addr_t dcs_buf_phys; + u8 *dcs_buf_virt; }; static inline struct rzg2l_mipi_dsi * @@ -651,9 +659,168 @@ static int rzg2l_mipi_dsi_host_detach(struct mipi_dsi_host *host, return 0; } +static ssize_t rzg2l_mipi_dsi_read_response(struct rzg2l_mipi_dsi *dsi, + const struct mipi_dsi_msg *msg) +{ + u8 *msg_rx = msg->rx_buf; + u16 size; + u8 datatype; + u32 result; + + result = rzg2l_mipi_dsi_link_read(dsi, RXRSS0R); + if (result & RXRSS0R_RXPKTDFAIL) { + dev_err(dsi->dev, "packet rx data did not save correctly\n"); + return -EPROTO; + } + + if (result & RXRSS0R_RXFAIL) { + dev_err(dsi->dev, "packet rx failure\n"); + return -EPROTO; + } + + if (!(result & RXRSS0R_RXSUC)) + return -EPROTO; + + datatype = FIELD_GET(RXRSS0R_DT, result); + + switch (datatype) { + case 0: + dev_dbg(dsi->dev, "ACK\n"); + return 0; + case MIPI_DSI_RX_END_OF_TRANSMISSION: + dev_dbg(dsi->dev, "EoTp\n"); + return 0; + case MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT: + dev_dbg(dsi->dev, "Acknowledge and error report: $%02x%02x\n", + (u8)FIELD_GET(RXRSS0R_DATA1, result), + (u8)FIELD_GET(RXRSS0R_DATA0, result)); + return 0; + case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE: + case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE: + msg_rx[0] = FIELD_GET(RXRSS0R_DATA0, result); + return 1; + case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE: + case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE: + msg_rx[0] = FIELD_GET(RXRSS0R_DATA0, result); + msg_rx[1] = FIELD_GET(RXRSS0R_DATA1, result); + return 2; + case MIPI_DSI_RX_GENERIC_LONG_READ_RESPONSE: + case MIPI_DSI_RX_DCS_LONG_READ_RESPONSE: + size = FIELD_GET(RXRSS0R_WC, result); + + if (size > msg->rx_len) { + dev_err(dsi->dev, "rx buffer too small"); + return -ENOSPC; + } + + memcpy(msg_rx, dsi->dcs_buf_virt, size); + return size; + default: + dev_err(dsi->dev, "unhandled response type: %02x\n", datatype); + return -EPROTO; + } +} + +static ssize_t rzg2l_mipi_dsi_host_transfer(struct mipi_dsi_host *host, + const struct mipi_dsi_msg *msg) +{ + struct rzg2l_mipi_dsi *dsi = host_to_rzg2l_mipi_dsi(host); + struct mipi_dsi_packet packet; + bool need_bta; + u32 value; + int ret; + + ret = mipi_dsi_create_packet(&packet, msg); + if (ret < 0) + return ret; + + /* Terminate operation after this descriptor is finished */ + value = SQCH0DSC0AR_NXACT_TERM; + + if (msg->flags & MIPI_DSI_MSG_REQ_ACK) { + need_bta = true; /* Message with explicitly requested ACK */ + value |= FIELD_PREP(SQCH0DSC0AR_BTA, SQCH0DSC0AR_BTA_NON_READ); + } else if (msg->rx_buf && msg->rx_len > 0) { + need_bta = true; /* Read request */ + value |= FIELD_PREP(SQCH0DSC0AR_BTA, SQCH0DSC0AR_BTA_READ); + } else { + need_bta = false; + value |= FIELD_PREP(SQCH0DSC0AR_BTA, SQCH0DSC0AR_BTA_NONE); + } + + /* Set transmission speed */ + if (msg->flags & MIPI_DSI_MSG_USE_LPM) +
[PATCH 2/2] drm: rcar-du: rzg2l_mipi_dsi: Set DCS maximum return packet size
From: Hugo Villeneuve The default value of 1 will result in long read commands payload not being saved to memory. Fix by setting this value to the DMA buffer size. Cc: Biju Das Cc: Chris Brandt Signed-off-by: Hugo Villeneuve --- drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c | 10 ++ drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi_regs.h | 4 2 files changed, 14 insertions(+) diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c index 77d3a31ff8e35..bfff17e55d126 100644 --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c @@ -547,6 +547,7 @@ static void rzg2l_mipi_dsi_atomic_enable(struct drm_bridge *bridge, const struct drm_display_mode *mode; struct drm_connector *connector; struct drm_crtc *crtc; + u32 value; int ret; connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder); @@ -559,6 +560,15 @@ static void rzg2l_mipi_dsi_atomic_enable(struct drm_bridge *bridge, rzg2l_mipi_dsi_set_display_timing(dsi, mode); + /* +* The default value of 1 will result in long read commands payload +* not being saved to memory. Set to the DMA buffer size. +*/ + value = rzg2l_mipi_dsi_link_read(dsi, DSISETR); + value &= ~DSISETR_MRPSZ; + value |= FIELD_PREP(DSISETR_MRPSZ, RZG2L_DCS_BUF_SIZE); + rzg2l_mipi_dsi_link_write(dsi, DSISETR, value); + ret = rzg2l_mipi_dsi_start_hs_clock(dsi); if (ret < 0) goto err_stop; diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi_regs.h b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi_regs.h index 33cd669bc74b1..0a783d1ea8fe1 100644 --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi_regs.h +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi_regs.h @@ -81,6 +81,10 @@ #define RSTSR_SWRSTLP (1 << 1) #define RSTSR_SWRSTHS (1 << 0) +/* DSI Set Register */ +#define DSISETR0x120 +#define DSISETR_MRPSZ GENMASK(15, 0) + /* Rx Result Save Slot 0 Register */ #define RXRSS0R0x240 #define RXRSS0R_RXPKTDFAIL BIT(28) -- 2.39.5
[PATCH v3 1/5] drm/panfrost: Add BO labelling to Panfrost
Functions for labelling UM-exposed an internal BOs are provided. An example of the latter would be the Perfcnt sample buffer. This commit is done in preparation of a following one that will allow UM to set BO labels through a new ioctl(). Signed-off-by: Adrián Larumbe Reviewed-by: Steven Price --- drivers/gpu/drm/panfrost/panfrost_gem.c | 42 + drivers/gpu/drm/panfrost/panfrost_gem.h | 17 ++ 2 files changed, 59 insertions(+) diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c index 963f04ba2de6..4c5be7ccc9cc 100644 --- a/drivers/gpu/drm/panfrost/panfrost_gem.c +++ b/drivers/gpu/drm/panfrost/panfrost_gem.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* Copyright 2019 Linaro, Ltd, Rob Herring */ +#include #include #include #include @@ -35,6 +36,9 @@ static void panfrost_gem_free_object(struct drm_gem_object *obj) */ WARN_ON_ONCE(!list_empty(&bo->mappings.list)); + kfree_const(bo->label.str); + mutex_destroy(&bo->label.lock); + if (bo->sgts) { int i; int n_sgt = bo->base.base.size / SZ_2M; @@ -260,6 +264,7 @@ struct drm_gem_object *panfrost_gem_create_object(struct drm_device *dev, size_t mutex_init(&obj->mappings.lock); obj->base.base.funcs = &panfrost_gem_funcs; obj->base.map_wc = !pfdev->coherent; + mutex_init(&obj->label.lock); return &obj->base.base; } @@ -302,3 +307,40 @@ panfrost_gem_prime_import_sg_table(struct drm_device *dev, return obj; } + +void +panfrost_gem_set_label(struct drm_gem_object *obj, const char *label) +{ + struct panfrost_gem_object *bo = to_panfrost_bo(obj); + const char *old_label; + + scoped_guard(mutex, &bo->label.lock) { + old_label = bo->label.str; + bo->label.str = label; + } + + kfree_const(old_label); +} + +void +panfrost_gem_internal_set_label(struct drm_gem_object *obj, const char *label) +{ + struct panfrost_gem_object *bo = to_panfrost_bo(obj); + const char *str; + + /* We should never attempt labelling a UM-exposed GEM object */ + if (drm_WARN_ON(bo->base.base.dev, bo->base.base.handle_count > 0)) + return; + + if (!label) + return; + + str = kstrdup_const(label, GFP_KERNEL); + if (!str) { + /* Failing to allocate memory for a label isn't a fatal condition */ + drm_warn(bo->base.base.dev, "Not enough memory to allocate BO label"); + return; + } + + panfrost_gem_set_label(obj, str); +} diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.h b/drivers/gpu/drm/panfrost/panfrost_gem.h index 7516b7ecf7fe..6c187b9b66fc 100644 --- a/drivers/gpu/drm/panfrost/panfrost_gem.h +++ b/drivers/gpu/drm/panfrost/panfrost_gem.h @@ -41,6 +41,20 @@ struct panfrost_gem_object { */ size_t heap_rss_size; + /** +* @label: BO tagging fields. The label can be assigned within the +* driver itself or through a specific IOCTL. +*/ + struct { + /** +* @label.str: Pointer to NULL-terminated string, +*/ + const char *str; + + /** @lock.str: Protects access to the @label.str field. */ + struct mutex lock; + } label; + bool noexec :1; bool is_heap:1; }; @@ -89,4 +103,7 @@ void panfrost_gem_teardown_mappings_locked(struct panfrost_gem_object *bo); int panfrost_gem_shrinker_init(struct drm_device *dev); void panfrost_gem_shrinker_cleanup(struct drm_device *dev); +void panfrost_gem_set_label(struct drm_gem_object *obj, const char *label); +void panfrost_gem_internal_set_label(struct drm_gem_object *obj, const char *label); + #endif /* __PANFROST_GEM_H__ */ base-commit: 9ff4fdf4f44b69237c0afc1d3a8dac916ce66f3e -- 2.48.1
[PATCH v3 2/5] drm/panfrost: Internally label some BOs
Perfcnt samples buffer is not exposed to UM, but we would like to keep a tag on it as a potential debug aid. PRIME imported GEM buffers are UM exposed, but since the usual Panfrost UM driver code path is not followed in their creation, they might remain unlabelled for their entire lifetime, so a generic tag was deemed preferable. The tag is assigned before a UM handle is created so it doesn't contradict the logic about labelling internal BOs. Signed-off-by: Adrián Larumbe --- drivers/gpu/drm/panfrost/panfrost_gem.c | 10 ++ drivers/gpu/drm/panfrost/panfrost_perfcnt.c | 2 ++ 2 files changed, 12 insertions(+) diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c index 4c5be7ccc9cc..04483d5fb45d 100644 --- a/drivers/gpu/drm/panfrost/panfrost_gem.c +++ b/drivers/gpu/drm/panfrost/panfrost_gem.c @@ -305,6 +305,16 @@ panfrost_gem_prime_import_sg_table(struct drm_device *dev, bo = to_panfrost_bo(obj); bo->noexec = true; + /* +* We assign this generic label because this function cannot +* be reached through any of the Panfrost UM driver-specific +* code paths, unless one is given by explicitly calling the +* SET_LABEL_BO ioctl. It is therefore preferable to have a +* blanket BO tag that tells us the object was imported from +* another driver than nothing at all. +*/ + panfrost_gem_internal_set_label(obj, "GEM PRIME buffer"); + return obj; } diff --git a/drivers/gpu/drm/panfrost/panfrost_perfcnt.c b/drivers/gpu/drm/panfrost/panfrost_perfcnt.c index 52befead08c6..563f16bae543 100644 --- a/drivers/gpu/drm/panfrost/panfrost_perfcnt.c +++ b/drivers/gpu/drm/panfrost/panfrost_perfcnt.c @@ -111,6 +111,8 @@ static int panfrost_perfcnt_enable_locked(struct panfrost_device *pfdev, goto err_put_mapping; perfcnt->buf = map.vaddr; + panfrost_gem_internal_set_label(&bo->base, "Perfcnt sample buffer"); + /* * Invalidate the cache and clear the counters to start from a fresh * state. -- 2.48.1
Re: [PATCH] drm/msm/dsi/dsi_phy_10nm: Fix missing initial VCO rate
On Tue, May 20, 2025 at 01:13:26PM +0200, Krzysztof Kozlowski wrote: > Driver unconditionally saves current state on first init in > dsi_pll_10nm_init(), but does not save the VCO rate, only some of the > divider registers. The state is then restored during probe/enable via > msm_dsi_phy_enable() -> msm_dsi_phy_pll_restore_state() -> > dsi_10nm_pll_restore_state(). > > Restoring calls dsi_pll_10nm_vco_set_rate() with > pll_10nm->vco_current_rate=0, which basically overwrites existing rate of > VCO and messes with clock hierarchy, by setting frequency to 0 to clock > tree. This makes anyway little sense - VCO rate was not saved, so > should not be restored. > > If PLL was not configured configure it to minimum rate to avoid glitches > and configuring entire in clock hierarchy to 0 Hz. > > Suggested-by: Dmitry Baryshkov > Link: > https://lore.kernel.org/r/sz4kbwy5nwsebgf64ia7uq4ee7wbsa5uy3xmlqwcstsbntzcov@ew3dcyjdzmi2/ > Signed-off-by: Krzysztof Kozlowski Fixes? > > --- > > Not tested on hardware. > --- > drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c | 7 +++ > 1 file changed, 7 insertions(+) > > diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c > b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c > index 9812b4d69197..af2e30f3f842 100644 > --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c > +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c > @@ -704,6 +704,13 @@ static int dsi_pll_10nm_init(struct msm_dsi_phy *phy) > /* TODO: Remove this when we have proper display handover support */ > msm_dsi_phy_pll_save_state(phy); > > + /* > + * Store also proper vco_current_rate, because its value will be used in > + * dsi_10nm_pll_restore_state(). > + */ > + if (!dsi_pll_10nm_vco_recalc_rate(&pll_10nm->clk_hw, VCO_REF_CLK_RATE)) > + pll_10nm->vco_current_rate = pll_10nm->phy->cfg->min_pll_rate; > + > return 0; > } > > -- > 2.45.2 > -- With best wishes Dmitry
Re: [PATCH V8 40/43] drm/colorop: Add 3D LUT support to color pipeline
On 2025-05-19 19:43, Simon Ser wrote: > On Sunday, May 18th, 2025 at 00:32, Xaver Hugl wrote: > >>> We can always make the property mutable on drivers that support it in >> >>> the future, much like the zpos property. I think we should keep it >>> immutable for now. >> >> Sure, but I don't see any reason for immutability with an enum >> property - it can just limit the possible values to what it supports, >> and that can be only one value. Either way, it's not a big issue. > > Immutability is a clear indication that a property has a fixed read-only > value which can't be switched by user-space. That's also the pattern > used everywhere in the KMS uAPI, so I think it's better to remain > consistent here. I was envisioning this to be a driver-caps thing, but I agree if we make this mutable it can still serve that function but with different/future HW possibly support other interpolation schemes. Harry
[PATCH 6.1.y v2 2/2] drm/msm/dpu: move dpu_encoder's connector assignment to atomic_enable()
From: Abhinav Kumar [ Upstream commit aedf02e46eb549dac8db4821a6b9f0c6bf6e3990 ] For cases where the crtc's connectors_changed was set without enable/active getting toggled , there is an atomic_enable() call followed by an atomic_disable() but without an atomic_mode_set(). This results in a NULL ptr access for the dpu_encoder_get_drm_fmt() call in the atomic_enable() as the dpu_encoder's connector was cleared in the atomic_disable() but not re-assigned as there was no atomic_mode_set() call. Fix the NULL ptr access by moving the assignment for atomic_enable() and also use drm_atomic_get_new_connector_for_encoder() to get the connector from the atomic_state. Fixes: 25fdd5933e4c ("drm/msm: Add SDM845 DPU support") Reported-by: Dmitry Baryshkov Closes: https://gitlab.freedesktop.org/drm/msm/-/issues/59 Suggested-by: Dmitry Baryshkov Reviewed-by: Dmitry Baryshkov Tested-by: Dmitry Baryshkov # SM8350-HDK Patchwork: https://patchwork.freedesktop.org/patch/606729/ Link: https://lore.kernel.org/r/20240731191723.3050932-1-quic_abhin...@quicinc.com Signed-off-by: Abhinav Kumar [Minor conflict resolved due to code context change.] Signed-off-by: Jianqi Ren Signed-off-by: He Zhe --- Verified the build test --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index c7fcd617b48c..94f352253c74 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1101,8 +1101,6 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, cstate->num_mixers = num_lm; - dpu_enc->connector = conn_state->connector; - for (i = 0; i < dpu_enc->num_phys_encs; i++) { struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; @@ -1192,6 +1190,9 @@ static void dpu_encoder_virt_atomic_enable(struct drm_encoder *drm_enc, dpu_enc = to_dpu_encoder_virt(drm_enc); mutex_lock(&dpu_enc->enc_lock); + + dpu_enc->connector = drm_atomic_get_new_connector_for_encoder(state, drm_enc); + cur_mode = &dpu_enc->base.crtc->state->adjusted_mode; trace_dpu_enc_enable(DRMID(drm_enc), cur_mode->hdisplay, -- 2.34.1
[PATCH 6.1.y v2 1/2] drm/msm/disp/dpu: use atomic enable/disable callbacks for encoder functions
From: Vinod Polimera [ Upstream commit c0cd12a5d29fa36a8e2ebac7b8bec50c1a41fb57 ] Use atomic variants for encoder callback functions such that certain states like self-refresh can be accessed as part of enable/disable sequence. Signed-off-by: Kalyan Thota Signed-off-by: Vinod Polimera Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/524738/ Link: https://lore.kernel.org/r/164797-31063-12-git-send-email-quic_vpoli...@quicinc.com Signed-off-by: Dmitry Baryshkov Signed-off-by: Jianqi Ren Signed-off-by: He Zhe --- Verified the build test --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 5f8345016ffe..c7fcd617b48c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1182,7 +1182,8 @@ void dpu_encoder_virt_runtime_resume(struct drm_encoder *drm_enc) mutex_unlock(&dpu_enc->enc_lock); } -static void dpu_encoder_virt_enable(struct drm_encoder *drm_enc) +static void dpu_encoder_virt_atomic_enable(struct drm_encoder *drm_enc, + struct drm_atomic_state *state) { struct dpu_encoder_virt *dpu_enc = NULL; int ret = 0; @@ -1218,7 +1219,8 @@ static void dpu_encoder_virt_enable(struct drm_encoder *drm_enc) mutex_unlock(&dpu_enc->enc_lock); } -static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc) +static void dpu_encoder_virt_atomic_disable(struct drm_encoder *drm_enc, + struct drm_atomic_state *state) { struct dpu_encoder_virt *dpu_enc = NULL; int i = 0; @@ -2407,8 +2409,8 @@ static void dpu_encoder_frame_done_timeout(struct timer_list *t) static const struct drm_encoder_helper_funcs dpu_encoder_helper_funcs = { .atomic_mode_set = dpu_encoder_virt_atomic_mode_set, - .disable = dpu_encoder_virt_disable, - .enable = dpu_encoder_virt_enable, + .atomic_disable = dpu_encoder_virt_atomic_disable, + .atomic_enable = dpu_encoder_virt_atomic_enable, .atomic_check = dpu_encoder_virt_atomic_check, }; -- 2.34.1
Re: [PATCH] Documentation: dma-buf: heaps: Add naming guidelines
On Tue, May 20, 2025 at 12:00:53PM +0200, Maxime Ripard wrote: > +Naming Convention > += > + > +A good heap name is a name that: > + > +- Is stable, and won't change from one version to the other; > + > +- Describes the memory region the heap will allocate from, and will > + uniquely identify it in a given platform; > + > +- Doesn't use implementation details, such as the allocator; > + > +- Can describe intended usage. > + > +For example, assuming a platform with a reserved memory region located > +at the RAM address 0x4200, intended to allocate video framebuffers, > +and backed by the CMA kernel allocator. Good names would be > +`memory@4200` or `video@4200`, but `cma-video` wouldn't. Looks good, thanks! Reviewed-by: Bagas Sanjaya -- An old man doll... just what I always wanted! - Clara signature.asc Description: PGP signature