[Bug 205089] amdgpu : drm:amdgpu_cs_ioctl : Failed to initialize parser -125
https://bugzilla.kernel.org/show_bug.cgi?id=205089 MasterCATZ (masterc...@hotmail.com) changed: What|Removed |Added CC||masterc...@hotmail.com --- Comment #37 from MasterCATZ (masterc...@hotmail.com) --- Now my R9 290 keeps doing this with the latest drivers on Ubuntu 22.04 Every time I try watching anime through kodi -- You may reply to this email to add a comment. You are receiving this mail because: You are watching the assignee of the bug.
[PATCH 1/1] drm/i915/guc: Remove unnecessary GuC err capture noise
GuC error capture blurts some debug messages about empty register lists for certain register types on engines during firmware initialization. These are not errors or warnings, so get rid of them. Signed-off-by: Alan Previn --- .../gpu/drm/i915/gt/uc/intel_guc_capture.c| 77 +-- 1 file changed, 2 insertions(+), 75 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c index c4e25966d3e9..97a32e610c30 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c @@ -420,72 +420,6 @@ guc_capture_get_device_reglist(struct intel_guc *guc) return default_lists; } -static const char * -__stringify_owner(u32 owner) -{ - switch (owner) { - case GUC_CAPTURE_LIST_INDEX_PF: - return "PF"; - case GUC_CAPTURE_LIST_INDEX_VF: - return "VF"; - default: - return "unknown"; - } - - return ""; -} - -static const char * -__stringify_type(u32 type) -{ - switch (type) { - case GUC_CAPTURE_LIST_TYPE_GLOBAL: - return "Global"; - case GUC_CAPTURE_LIST_TYPE_ENGINE_CLASS: - return "Class"; - case GUC_CAPTURE_LIST_TYPE_ENGINE_INSTANCE: - return "Instance"; - default: - return "unknown"; - } - - return ""; -} - -static const char * -__stringify_engclass(u32 class) -{ - switch (class) { - case GUC_RENDER_CLASS: - return "Render"; - case GUC_VIDEO_CLASS: - return "Video"; - case GUC_VIDEOENHANCE_CLASS: - return "VideoEnhance"; - case GUC_BLITTER_CLASS: - return "Blitter"; - case GUC_COMPUTE_CLASS: - return "Compute"; - default: - return "unknown"; - } - - return ""; -} - -static void -guc_capture_warn_with_list_info(struct drm_i915_private *i915, char *msg, - u32 owner, u32 type, u32 classid) -{ - if (type == GUC_CAPTURE_LIST_TYPE_GLOBAL) - drm_dbg(>drm, "GuC-capture: %s for %s %s-Registers.\n", msg, - __stringify_owner(owner), __stringify_type(type)); - else - drm_dbg(>drm, "GuC-capture: %s for %s %s-Registers on %s-Engine\n", msg, - __stringify_owner(owner), __stringify_type(type), - __stringify_engclass(classid)); -} - static int guc_capture_list_init(struct intel_guc *guc, u32 owner, u32 type, u32 classid, struct guc_mmio_reg *ptr, u16 num_entries) @@ -501,11 +435,8 @@ guc_capture_list_init(struct intel_guc *guc, u32 owner, u32 type, u32 classid, return -ENODEV; match = guc_capture_get_one_list(reglists, owner, type, classid); - if (!match) { - guc_capture_warn_with_list_info(i915, "Missing register list init", owner, type, - classid); + if (!match) return -ENODATA; - } for (i = 0; i < num_entries && i < match->num_regs; ++i) { ptr[i].offset = match->list[i].reg.reg; @@ -556,7 +487,6 @@ int intel_guc_capture_getlistsize(struct intel_guc *guc, u32 owner, u32 type, u32 classid, size_t *size) { - struct drm_i915_private *i915 = guc_to_gt(guc)->i915; struct intel_guc_state_capture *gc = guc->capture; struct __guc_capture_ads_cache *cache = >ads_cache[owner][type][classid]; int num_regs; @@ -570,11 +500,8 @@ intel_guc_capture_getlistsize(struct intel_guc *guc, u32 owner, u32 type, u32 cl } num_regs = guc_cap_list_num_regs(gc, owner, type, classid); - if (!num_regs) { - guc_capture_warn_with_list_info(i915, "Missing register list size", - owner, type, classid); + if (!num_regs) return -ENODATA; - } *size = PAGE_ALIGN((sizeof(struct guc_debug_capture_list)) + (num_regs * sizeof(struct guc_mmio_reg))); -- 2.25.1
[PATCH 0/1] Remove unnecessary GuC err capture noise
This series remove unnecessary GuC err capture noise. Alan Previn (1): drm/i915/guc: Remove unnecessary GuC err capture noise .../gpu/drm/i915/gt/uc/intel_guc_capture.c| 77 +-- 1 file changed, 2 insertions(+), 75 deletions(-) -- 2.25.1
[PATCH 3/3] drm/msm: stop storing the array of CRTCs in struct msm_drm_private
Handling the array of CRTC duplicate the struct msm_drm_private duplicates a list of CRTCs in the drm_device. Drop it and use the existing list for CRTC enumeration. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 2 +- drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c | 2 +- drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c | 2 +- drivers/gpu/drm/msm/msm_drv.c| 27 drivers/gpu/drm/msm/msm_drv.h| 3 +-- 5 files changed, 17 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 494978da7785..f89dcb903869 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -808,7 +808,7 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms) ret = PTR_ERR(crtc); return ret; } - priv->crtcs[priv->num_crtcs++] = crtc; + priv->num_crtcs++; } /* All CRTCs are compatible with all encoders */ diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c index b7aced272af9..375643a14198 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c @@ -335,7 +335,7 @@ static int modeset_init(struct mdp4_kms *mdp4_kms) goto fail; } - priv->crtcs[priv->num_crtcs++] = crtc; + priv->num_crtcs++; } /* diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c index 18cf0ff4da6c..35242e76de10 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c @@ -495,7 +495,7 @@ static int modeset_init(struct mdp5_kms *mdp5_kms) DRM_DEV_ERROR(dev->dev, "failed to construct crtc %d (%d)\n", i, ret); goto fail; } - priv->crtcs[priv->num_crtcs++] = crtc; + priv->num_crtcs++; } /* diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index d2fbe54fec4d..576d346cc860 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -98,7 +98,7 @@ static void msm_irq_uninstall(struct drm_device *dev) struct msm_vblank_work { struct work_struct work; - int crtc_id; + struct drm_crtc *crtc; bool enable; struct msm_drm_private *priv; }; @@ -111,15 +111,15 @@ static void vblank_ctrl_worker(struct work_struct *work) struct msm_kms *kms = priv->kms; if (vbl_work->enable) - kms->funcs->enable_vblank(kms, priv->crtcs[vbl_work->crtc_id]); + kms->funcs->enable_vblank(kms, vbl_work->crtc); else - kms->funcs->disable_vblank(kms, priv->crtcs[vbl_work->crtc_id]); + kms->funcs->disable_vblank(kms, vbl_work->crtc); kfree(vbl_work); } static int vblank_ctrl_queue_work(struct msm_drm_private *priv, - int crtc_id, bool enable) + struct drm_crtc *crtc, bool enable) { struct msm_vblank_work *vbl_work; @@ -129,7 +129,7 @@ static int vblank_ctrl_queue_work(struct msm_drm_private *priv, INIT_WORK(_work->work, vblank_ctrl_worker); - vbl_work->crtc_id = crtc_id; + vbl_work->crtc = crtc; vbl_work->enable = enable; vbl_work->priv = priv; @@ -303,6 +303,7 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv) struct msm_drm_private *priv = dev_get_drvdata(dev); struct drm_device *ddev; struct msm_kms *kms; + struct drm_crtc *crtc; int ret, i; if (drm_firmware_drivers_only()) @@ -376,12 +377,12 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv) ddev->mode_config.funcs = _config_funcs; ddev->mode_config.helper_private = _config_helper_funcs; - for (i = 0; i < priv->num_crtcs; i++) { + drm_for_each_crtc(crtc, ddev) { /* initialize event thread */ - priv->event_thread[i].crtc_id = priv->crtcs[i]->base.id; + priv->event_thread[i].crtc = crtc; priv->event_thread[i].dev = ddev; priv->event_thread[i].worker = kthread_create_worker(0, - "crtc_event:%d", priv->event_thread[i].crtc_id); + "crtc_event:%d", priv->event_thread[i].crtc->base.id); if (IS_ERR(priv->event_thread[i].worker)) { ret = PTR_ERR(priv->event_thread[i].worker); DRM_DEV_ERROR(dev, "failed to create crtc_event kthread\n"); @@ -517,25 +518,23 @@ static void msm_postclose(struct drm_device *dev, struct drm_file *file) int msm_crtc_enable_vblank(struct drm_crtc
[PATCH 2/3] drm/msm/mdp5: convert to drm_crtc_handle_vblank()
Stop using deprecated drm_handle_vblank(), use drm_crtc_handle_vblank() instead. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/mdp5/mdp5_irq.c | 9 - 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_irq.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_irq.c index d573ff29d5a4..18cc62f1e7ec 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_irq.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_irq.c @@ -85,8 +85,7 @@ static irqreturn_t mdp5_irq(int irq, void *arg) struct mdp_kms *mdp_kms = to_mdp_kms(kms); struct mdp5_kms *mdp5_kms = to_mdp5_kms(mdp_kms); struct drm_device *dev = mdp5_kms->dev; - struct msm_drm_private *priv = dev->dev_private; - unsigned int id; + struct drm_crtc *crtc; uint32_t status, enable; enable = mdp5_read(mdp5_kms, REG_MDP5_INTR_EN); @@ -97,9 +96,9 @@ static irqreturn_t mdp5_irq(int irq, void *arg) mdp_dispatch_irqs(mdp_kms, status); - for (id = 0; id < priv->num_crtcs; id++) - if (status & mdp5_crtc_vblank(priv->crtcs[id])) - drm_handle_vblank(dev, id); + drm_for_each_crtc(crtc, dev) + if (status & mdp5_crtc_vblank(crtc)) + drm_crtc_handle_vblank(crtc); return IRQ_HANDLED; } -- 2.35.1
[PATCH 1/3] drm/msm/mdp4: convert to drm_crtc_handle_vblank()
Stop using deprecated drm_handle_vblank(), use drm_crtc_handle_vblank() instead. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/mdp4/mdp4_irq.c | 9 - 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_irq.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_irq.c index 87675c162eea..62cc566756e8 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_irq.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_irq.c @@ -72,8 +72,7 @@ static irqreturn_t mdp4_irq(int irq, void *arg) struct mdp_kms *mdp_kms = to_mdp_kms(kms); struct mdp4_kms *mdp4_kms = to_mdp4_kms(mdp_kms); struct drm_device *dev = mdp4_kms->dev; - struct msm_drm_private *priv = dev->dev_private; - unsigned int id; + struct drm_crtc *crtc; uint32_t status, enable; enable = mdp4_read(mdp4_kms, REG_MDP4_INTR_ENABLE); @@ -84,9 +83,9 @@ static irqreturn_t mdp4_irq(int irq, void *arg) mdp_dispatch_irqs(mdp_kms, status); - for (id = 0; id < priv->num_crtcs; id++) - if (status & mdp4_crtc_vblank(priv->crtcs[id])) - drm_handle_vblank(dev, id); + drm_for_each_crtc(crtc, dev) + if (status & mdp4_crtc_vblank(crtc)) + drm_crtc_handle_vblank(crtc); return IRQ_HANDLED; } -- 2.35.1
[PATCH 2/2] drm/msm: push IRQ setup into individual drivers
Afther the commit f026e431cf86 ("drm/msm: Convert to Linux IRQ interfaces") converted MSM DRM driver to handle IRQs on it's own (rather than using the DRM IRQ mid-layer), there is little point in keeping irq wrapper in the msm_drv.c which just call into individual drivers. Push respective code into the mdp4/mdp5/dpu drivers and drop irq_preinstall/irq_postinstall/irq msm_kms funcs. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h | 13 +--- .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 28 - drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 6 +- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 7 +++ drivers/gpu/drm/msm/disp/mdp4/mdp4_irq.c | 30 - drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c | 4 +- drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.h | 4 +- drivers/gpu/drm/msm/disp/mdp5/mdp5_irq.c | 30 - drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c | 4 +- drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h | 4 +- drivers/gpu/drm/msm/msm_drv.c | 62 +++ drivers/gpu/drm/msm/msm_kms.h | 4 +- 12 files changed, 105 insertions(+), 91 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h index b5b6e7031fb9..c6938b1f1870 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h @@ -8,13 +8,6 @@ #include "dpu_kms.h" #include "dpu_hw_interrupts.h" -/** - * dpu_core_irq_preinstall - perform pre-installation of core IRQ handler - * @kms: MSM KMS handle - * @return:none - */ -void dpu_core_irq_preinstall(struct msm_kms *kms); - /** * dpu_core_irq_uninstall - uninstall core IRQ handler * @kms: MSM KMS handle @@ -23,11 +16,11 @@ void dpu_core_irq_preinstall(struct msm_kms *kms); void dpu_core_irq_uninstall(struct msm_kms *kms); /** - * dpu_core_irq - core IRQ handler + * dpu_core_irq_install - install core IRQ handler * @kms: MSM KMS handle - * @return:interrupt handling status + * @return:non-zero in case of an error */ -irqreturn_t dpu_core_irq(struct msm_kms *kms); +int dpu_core_irq_install(struct msm_kms *kms); /** * dpu_core_irq_read - IRQ helper function for reading IRQ status diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c index d6498e45dc2c..fa4f99034a08 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c @@ -164,8 +164,9 @@ static void dpu_core_irq_callback_handler(struct dpu_kms *dpu_kms, int irq_idx) dpu_kms->hw_intr->irq_tbl[irq_idx].cb(dpu_kms->hw_intr->irq_tbl[irq_idx].arg, irq_idx); } -irqreturn_t dpu_core_irq(struct msm_kms *kms) +static irqreturn_t dpu_irq(int irq, void *arg) { + struct msm_kms *kms = arg; struct dpu_kms *dpu_kms = to_dpu_kms(kms); struct dpu_hw_intr *intr = dpu_kms->hw_intr; int reg_idx; @@ -541,7 +542,7 @@ void dpu_debugfs_core_irq_init(struct dpu_kms *dpu_kms, } #endif -void dpu_core_irq_preinstall(struct msm_kms *kms) +static void dpu_core_irq_preinstall(struct msm_kms *kms) { struct dpu_kms *dpu_kms = to_dpu_kms(kms); int i; @@ -570,5 +571,28 @@ void dpu_core_irq_uninstall(struct msm_kms *kms) dpu_clear_irqs(dpu_kms); dpu_disable_all_irqs(dpu_kms); + if (kms->irq_requested) + free_irq(kms->irq, kms); pm_runtime_put_sync(_kms->pdev->dev); } + +int dpu_core_irq_install(struct msm_kms *kms) +{ + int ret; + + dpu_core_irq_preinstall(kms); + + ret = request_irq(kms->irq, dpu_irq, 0, "dpu", kms); + if (ret) + return ret; + + kms->irq_requested = true; + + ret = dpu_irq_postinstall(kms); + if (ret) { + free_irq(kms->irq, kms); + return ret; + } + + return 0; +} diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 2b9d931474e0..494978da7785 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -884,7 +884,7 @@ static void dpu_kms_destroy(struct msm_kms *kms) pm_runtime_disable(_kms->pdev->dev); } -static int dpu_irq_postinstall(struct msm_kms *kms) +int dpu_irq_postinstall(struct msm_kms *kms) { struct msm_drm_private *priv; struct dpu_kms *dpu_kms = to_dpu_kms(kms); @@ -960,10 +960,8 @@ static void dpu_kms_mdp_snapshot(struct msm_disp_state *disp_state, struct msm_k static const struct msm_kms_funcs kms_funcs = { .hw_init = dpu_kms_hw_init, - .irq_preinstall = dpu_core_irq_preinstall, - .irq_postinstall = dpu_irq_postinstall, + .irq_install = dpu_core_irq_install, .irq_uninstall = dpu_core_irq_uninstall, - .irq =
[PATCH 1/2] drm/msm: don't free the IRQ if it was not requested
As msm_drm_uninit() is called from the msm_drm_init() error path, additional care should be necessary as not to call the free_irq() for the IRQ that was not requested before (because an error occured earlier than the request_irq() call). This fixed the issue reported with the following backtrace: [8.571329] Trying to free already-free IRQ 187 [8.571339] WARNING: CPU: 0 PID: 76 at kernel/irq/manage.c:1895 free_irq+0x1e0/0x35c [8.588746] Modules linked in: pmic_glink pdr_interface fastrpc qrtr_smd snd_soc_hdmi_codec msm fsa4480 gpu_sched drm_dp_aux_bus qrtr i2c_qcom_geni crct10dif_ce qcom_stats qcom_q6v5_pas drm_display_helper gpi qcom_pil_info drm_kms_helper qcom_q6v5 qcom_sysmon qcom_common qcom_glink_smem qcom_rng mdt_loader qmi_helpers phy_qcom_qmp ufs_qcom typec qnoc_sm8350 socinfo rmtfs_mem fuse drm ipv6 [8.624154] CPU: 0 PID: 76 Comm: kworker/u16:2 Not tainted 5.18.0-rc5-next-20220506-00033-g6cee8cab6089-dirty #419 [8.624161] Hardware name: Qualcomm Technologies, Inc. SM8350 HDK (DT) [8.641496] Workqueue: events_unbound deferred_probe_work_func [8.647510] pstate: 604000c5 (nZCv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [8.654681] pc : free_irq+0x1e0/0x35c [8.658454] lr : free_irq+0x1e0/0x35c [8.662228] sp : 88ab3950 [8.665642] x29: 88ab3950 x28: x27: 16350f56a700 [8.672994] x26: 1635025df080 x25: 16350251badc x24: 16350251bb90 [8.680343] x23: x22: 00bb x21: 16350e8f9800 [8.687690] x20: 16350251ba00 x19: 16350cbd5880 x18: [8.695039] x17: x16: a2dd12179434 x15: a2dd1431d02d [8.702391] x14: x13: a2dd1431d028 x12: 662d79646165726c [8.709740] x11: a2dd13fd2438 x10: 000a x9 : 00bb [8.717111] x8 : a2dd13fd23f0 x7 : 88ab3750 x6 : f202 [8.724487] x5 : 16377e870a18 x4 : f202 x3 : 735a6ae1b000 [8.731851] x2 : x1 : x0 : 1635015f8000 [8.739217] Call trace: [8.741755] free_irq+0x1e0/0x35c [8.745198] msm_drm_uninit.isra.0+0x14c/0x294 [msm] [8.750548] msm_drm_bind+0x28c/0x5d0 [msm] [8.755081] try_to_bring_up_aggregate_device+0x164/0x1d0 [8.760657] __component_add+0xa0/0x170 [8.764626] component_add+0x14/0x20 [8.768337] dp_display_probe+0x2a4/0x464 [msm] [8.773242] platform_probe+0x68/0xe0 [8.777043] really_probe.part.0+0x9c/0x28c [8.781368] __driver_probe_device+0x98/0x144 [8.785871] driver_probe_device+0x40/0x140 [8.790191] __device_attach_driver+0xb4/0x120 [8.794788] bus_for_each_drv+0x78/0xd0 [8.798751] __device_attach+0xdc/0x184 [8.802713] device_initial_probe+0x14/0x20 [8.807031] bus_probe_device+0x9c/0xa4 [8.810991] deferred_probe_work_func+0x88/0xc0 [8.815667] process_one_work+0x1d0/0x320 [8.819809] worker_thread+0x14c/0x444 [8.823688] kthread+0x10c/0x110 [8.827036] ret_from_fork+0x10/0x20 Reported-by: Bjorn Andersson Fixes: f026e431cf86 ("drm/msm: Convert to Linux IRQ interfaces") Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/msm_drv.c | 7 ++- drivers/gpu/drm/msm/msm_kms.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 4a3dda23e3e0..44485363f37a 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -113,6 +113,8 @@ static int msm_irq_postinstall(struct drm_device *dev) static int msm_irq_install(struct drm_device *dev, unsigned int irq) { + struct msm_drm_private *priv = dev->dev_private; + struct msm_kms *kms = priv->kms; int ret; if (irq == IRQ_NOTCONNECTED) @@ -124,6 +126,8 @@ static int msm_irq_install(struct drm_device *dev, unsigned int irq) if (ret) return ret; + kms->irq_requested = true; + ret = msm_irq_postinstall(dev); if (ret) { free_irq(irq, dev); @@ -139,7 +143,8 @@ static void msm_irq_uninstall(struct drm_device *dev) struct msm_kms *kms = priv->kms; kms->funcs->irq_uninstall(kms); - free_irq(kms->irq, dev); + if (kms->irq_requested) + free_irq(kms->irq, dev); } struct msm_vblank_work { diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h index ab25fff271f9..f8ed7588928c 100644 --- a/drivers/gpu/drm/msm/msm_kms.h +++ b/drivers/gpu/drm/msm/msm_kms.h @@ -148,6 +148,7 @@ struct msm_kms { /* irq number to be passed on to msm_irq_install */ int irq; + bool irq_requested; /* mapper-id used to request GEM buffer mapped for scanout: */ struct msm_gem_address_space *aspace; -- 2.35.1
Re: [PATCH] drm/msm/dp: Always clear mask bits to disable interrupts at dp_ctrl_reset_irq_ctrl()
Quoting Kuogee Hsieh (2022-05-06 14:41:07) > dp_catalog_ctrl_reset() will software reset DP controller. But it will > not reset programmable registers to default value. DP driver still have > to clear mask bits to interrupt status registers to disable interrupts > after software reset of controller. This patch removes the enable flag > condition checking to always clear mask bits of interrupt status > registers to disable interrupts if enable flag is false. Another paragraph is needed which is that this (partially?) fixes the suspend path where we call dp_catalog_ctrl_reset() but the irq is still unmasked and can come in while we're suspending. This leads to bus hangs if the irq is handled after we power down the DP hardware because we run the irq handler and access a device register assuming that no irq could ever come in if we powered down the device. We don't know when the irq will be handled though, so it's possible the irq is pending from before we disable the irq in the hardware. Don't we need some irq synchronize to make sure it doesn't run? > > Fixes: ba0a422be723 ("drm/msm/dp: do not initialize phy until plugin > interrupt received") > Signed-off-by: Kuogee Hsieh > --- > drivers/gpu/drm/msm/dp/dp_ctrl.c | 9 +++-- > 1 file changed, 7 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c > b/drivers/gpu/drm/msm/dp/dp_ctrl.c > index 38026f2..cbf3399 100644 > --- a/drivers/gpu/drm/msm/dp/dp_ctrl.c > +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c > @@ -1379,8 +1379,13 @@ void dp_ctrl_reset_irq_ctrl(struct dp_ctrl *dp_ctrl, > bool enable) > > dp_catalog_ctrl_reset(ctrl->catalog); > > - if (enable) > - dp_catalog_ctrl_enable_irq(ctrl->catalog, enable); > + /* > +* all dp controller programmable registers will not > +* be reset to default value after DP_SW_RESET > +* therefore interrupt mask bits have to be updated > +* to enable/disable interrupts > +*/ > + dp_catalog_ctrl_enable_irq(ctrl->catalog, enable); > } > > void dp_ctrl_phy_init(struct dp_ctrl *dp_ctrl) > -- > The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, > a Linux Foundation Collaborative Project >
Re: [PATCH 5/5] drm/i915/sseu: Disassociate internal subslice mask representation from uapi
On Thu, Apr 28, 2022 at 01:18:42PM +0100, Tvrtko Ursulin wrote: > > Hi, > > On 28/04/2022 00:07, Matt Roper wrote: > > Rather than storing subslice masks internally as u8[] (inside the sseu > > structure) and u32 (everywhere else), let's move over to using an > > intel_sseu_ss_mask_t typedef compatible with the operations in > > linux/bitmap.h. We're soon going to start adding code for a new > > platform where subslice masks are spread across two 32-bit registers > > (requiring 64 bits to represent), and we expect future platforms will > > likely take this even farther, requiring bitmask storage larger than a > > simple u64 can hold. > > I won't have time to look into this in a detailed way for a few days. Until > then a couple questions comments only. > > First, out of curiousity, were you able to end up with less code after your > series? With my bitmap conversion I think actually ended up with couple KB > smaller text which was a good sign eliminating the internal layout > complications was a good approach. Yeah, looks like I did: $ size i915.ko.orig i915.ko textdata bss dec hex filename 3479050 1324986760 3618308 373604 i915.ko.orig 3476552 1324666760 3615778 372c22 i915.ko > > For your series I am not convinced by sseu->has_common_ss_eumask. Why the > duality, just to save a few u32 at runtime? With this flag, eu_mask is an array of GEN_MAX_HSW_SLICES * GEN_MAX_SS_PER_HSW_SLICE (i.e., 3*6 = 18). If we store the replicated EU masks, then we'll have 64 u16's on PVC (where we have a DSS mask spread across two registers) and 96 u16's on a future platform that spreads the mask across three fuse registers. 18 -> 96 (or possibly even more farther in the future). I think we've eliminated all of the stack allocations of sseu structures now, so it probably isn't as important as it used to be though; I can drop it if you think the size savings aren't worth the extra complexity. > > I am also not convinced with leaving the eu_mask and subslice_mask > being manually indexed with stride, calculcated by the driver. In my > approach I simply went with multi-dimensional arrays which I think > ends up with simpler code. So something like enum { u16 hsw[GEN_MAX_HSW_SLICES][GEN_MAX_SS_PER_HSW_SLICE]; u16 xehp[GEN_MAX_DSS]; } eu_mask; ? Or should we just skip the enum and live with allocating three times as much space as the largest Xe_HP platform needs? > > For all bitmap API call sites and *pb printk format sites, I suggest not > hard-coding the widths from SSEU defines by querying the type itsef via > wrappers. (See my BITMAP_BITS macro and helpers which wrap it for fields.) > > Ie instead: > > bitmap_shift_left(to_mask->b, to_mask->b, offset, I915_MAX_SS_FUSE_BITS); > > I suggest: > > bitmap_zero(slices.b, BITMAP_BITS(slices.b)); > > Also, all accesses to the bitmap type from outside intel_sse*.c|h should use > intel_sseu wrappers and not embed knowledge of the typedef (that it has an > member named .b etc). > > And finally I would also use the opportunity to clean up the pointless u8 > types for counts and such since I think they just result in worse code > generation. > > You can of course counter with what you did not like in my attempt. :) I know > I did not finish the wrappers and possibly made an overkill by converting the > slice mask to bitmap. These suggestions all make sense. I'll work on incorporating them into the next version. Matt > > Regards, > > Tvrtko > > Signed-off-by: Matt Roper > > --- > > drivers/gpu/drm/i915/gem/i915_gem_context.c | 4 +- > > drivers/gpu/drm/i915/gt/intel_engine_cs.c| 2 +- > > drivers/gpu/drm/i915/gt/intel_gt.c | 14 +- > > drivers/gpu/drm/i915/gt/intel_sseu.c | 197 +++ > > drivers/gpu/drm/i915/gt/intel_sseu.h | 48 ++--- > > drivers/gpu/drm/i915/gt/intel_sseu_debugfs.c | 28 +-- > > drivers/gpu/drm/i915/gt/intel_workarounds.c | 28 ++- > > drivers/gpu/drm/i915/i915_getparam.c | 2 +- > > drivers/gpu/drm/i915/i915_query.c| 8 +- > > 9 files changed, 183 insertions(+), 148 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c > > b/drivers/gpu/drm/i915/gem/i915_gem_context.c > > index ab4c5ab28e4d..ea012ee3a8de 100644 > > --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c > > @@ -1901,7 +1901,7 @@ i915_gem_user_to_context_sseu(struct intel_gt *gt, > > if (user->slice_mask & ~device->slice_mask) > > return -EINVAL; > > - if (user->subslice_mask & ~device->subslice_mask[0]) > > + if (user->subslice_mask & ~device->subslice_mask.b[0]) > > return -EINVAL; > > if (user->max_eus_per_subslice > device->max_eus_per_subslice) > > @@ -1915,7 +1915,7 @@ i915_gem_user_to_context_sseu(struct intel_gt *gt, > > /* Part specific restrictions. */ > >
Re: [PATCH 12/25] drm/msm/dpu: inline _dpu_plane_set_scanout
On 07/05/2022 02:33, Abhinav Kumar wrote: On 2/9/2022 9:25 AM, Dmitry Baryshkov wrote: In preparation to reworking dpu_plane_sspp_atomic_update() inline the _dpu_plane_set_scanout() function. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 41 ++- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index d029ce806039..3ce7dcc285e2 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -490,28 +490,6 @@ static void _dpu_plane_set_qos_remap(struct drm_plane *plane) dpu_vbif_set_qos_remap(dpu_kms, _params); } -static void _dpu_plane_set_scanout(struct drm_plane *plane, - struct dpu_plane_state *pstate, - struct dpu_hw_pipe_cfg *pipe_cfg, - struct drm_framebuffer *fb) -{ - struct dpu_plane *pdpu = to_dpu_plane(plane); - struct dpu_kms *kms = _dpu_plane_get_kms(>base); - struct msm_gem_address_space *aspace = kms->base.aspace; - int ret; - - ret = dpu_format_populate_layout(aspace, fb, _cfg->layout); - if (ret == -EAGAIN) - DPU_DEBUG_PLANE(pdpu, "not updating same src addrs\n"); - else if (ret) - DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret); - else if (pstate->pipe.sspp->ops.setup_sourceaddress) { - trace_dpu_plane_set_scanout(>pipe, - _cfg->layout); - pstate->pipe.sspp->ops.setup_sourceaddress(>pipe, pipe_cfg); - } -} - static void _dpu_plane_setup_scaler3(struct dpu_hw_pipe *pipe_hw, uint32_t src_w, uint32_t src_h, uint32_t dst_w, uint32_t dst_h, struct dpu_hw_scaler3_cfg *scale_cfg, @@ -1074,10 +1052,27 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane) const struct dpu_format *fmt = to_dpu_format(msm_framebuffer_format(fb)); struct dpu_hw_pipe_cfg pipe_cfg; + struct dpu_kms *kms = _dpu_plane_get_kms(>base); + struct msm_gem_address_space *aspace = kms->base.aspace; + bool update_src_addr = true; + int ret; memset(_cfg, 0, sizeof(struct dpu_hw_pipe_cfg)); - _dpu_plane_set_scanout(plane, pstate, _cfg, fb); + ret = dpu_format_populate_layout(aspace, fb, _cfg.layout); + if (ret == -EAGAIN) { + DPU_DEBUG_PLANE(pdpu, "not updating same src addrs\n"); + update_src_addr = false; + } else if (ret) { + DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret); + update_src_addr = false; + } + Do we need update_src_addr? It seems we can just do if (!ret && pipe->sspp->ops.setup_sourceaddress) { . . } Ack, let's do it this way + if (update_src_addr && + pipe->sspp->ops.setup_sourceaddress) { + trace_dpu_plane_set_scanout(pipe, _cfg.layout); + pipe->sspp->ops.setup_sourceaddress(pipe, _cfg); + } pstate->pending = true; -- With best wishes Dmitry
Re: [PATCH 12/25] drm/msm/dpu: inline _dpu_plane_set_scanout
On 2/9/2022 9:25 AM, Dmitry Baryshkov wrote: In preparation to reworking dpu_plane_sspp_atomic_update() inline the _dpu_plane_set_scanout() function. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 41 ++- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index d029ce806039..3ce7dcc285e2 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -490,28 +490,6 @@ static void _dpu_plane_set_qos_remap(struct drm_plane *plane) dpu_vbif_set_qos_remap(dpu_kms, _params); } -static void _dpu_plane_set_scanout(struct drm_plane *plane, - struct dpu_plane_state *pstate, - struct dpu_hw_pipe_cfg *pipe_cfg, - struct drm_framebuffer *fb) -{ - struct dpu_plane *pdpu = to_dpu_plane(plane); - struct dpu_kms *kms = _dpu_plane_get_kms(>base); - struct msm_gem_address_space *aspace = kms->base.aspace; - int ret; - - ret = dpu_format_populate_layout(aspace, fb, _cfg->layout); - if (ret == -EAGAIN) - DPU_DEBUG_PLANE(pdpu, "not updating same src addrs\n"); - else if (ret) - DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret); - else if (pstate->pipe.sspp->ops.setup_sourceaddress) { - trace_dpu_plane_set_scanout(>pipe, - _cfg->layout); - pstate->pipe.sspp->ops.setup_sourceaddress(>pipe, pipe_cfg); - } -} - static void _dpu_plane_setup_scaler3(struct dpu_hw_pipe *pipe_hw, uint32_t src_w, uint32_t src_h, uint32_t dst_w, uint32_t dst_h, struct dpu_hw_scaler3_cfg *scale_cfg, @@ -1074,10 +1052,27 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane) const struct dpu_format *fmt = to_dpu_format(msm_framebuffer_format(fb)); struct dpu_hw_pipe_cfg pipe_cfg; + struct dpu_kms *kms = _dpu_plane_get_kms(>base); + struct msm_gem_address_space *aspace = kms->base.aspace; + bool update_src_addr = true; + int ret; memset(_cfg, 0, sizeof(struct dpu_hw_pipe_cfg)); - _dpu_plane_set_scanout(plane, pstate, _cfg, fb); + ret = dpu_format_populate_layout(aspace, fb, _cfg.layout); + if (ret == -EAGAIN) { + DPU_DEBUG_PLANE(pdpu, "not updating same src addrs\n"); + update_src_addr = false; + } else if (ret) { + DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret); + update_src_addr = false; + } + Do we need update_src_addr? It seems we can just do if (!ret && pipe->sspp->ops.setup_sourceaddress) { . . } + if (update_src_addr && + pipe->sspp->ops.setup_sourceaddress) { + trace_dpu_plane_set_scanout(pipe, _cfg.layout); + pipe->sspp->ops.setup_sourceaddress(pipe, _cfg); + } pstate->pending = true;
Re: [PATCH v5 9/9] drm: vkms: Add support to the RGB565 format
Hi Pekka, On 4/27/22 04:55, Pekka Paalanen wrote: On Tue, 26 Apr 2022 21:53:19 -0300 Igor Torrente wrote: Hi Pekka, On 4/21/22 07:58, Pekka Paalanen wrote: On Mon, 4 Apr 2022 17:45:15 -0300 Igor Torrente wrote: Adds this common format to vkms. This commit also adds new helper macros to deal with fixed-point arithmetic. It was done to improve the precision of the conversion to ARGB16161616 since the "conversion ratio" is not an integer. V3: Adapt the handlers to the new format introduced in patch 7 V3. V5: Minor improvements Signed-off-by: Igor Torrente --- drivers/gpu/drm/vkms/vkms_formats.c | 70 +++ drivers/gpu/drm/vkms/vkms_plane.c | 6 ++- drivers/gpu/drm/vkms/vkms_writeback.c | 3 +- 3 files changed, 76 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/vkms/vkms_formats.c b/drivers/gpu/drm/vkms/vkms_formats.c index 8d913fa7dbde..4af8b295f31e 100644 --- a/drivers/gpu/drm/vkms/vkms_formats.c +++ b/drivers/gpu/drm/vkms/vkms_formats.c @@ -5,6 +5,23 @@ #include "vkms_formats.h" +/* The following macros help doing fixed point arithmetic. */ +/* + * With Fixed-Point scale 15 we have 17 and 15 bits of integer and fractional + * parts respectively. + * | 0.000 | + * 31 0 + */ +#define FIXED_SCALE 15 I think this would usually be called a "shift" since it's used in bit-shifts. Ok, I will rename this. + +#define INT_TO_FIXED(a) ((a) << FIXED_SCALE) +#define FIXED_MUL(a, b) ((s32)(((s64)(a) * (b)) >> FIXED_SCALE)) +#define FIXED_DIV(a, b) ((s32)(((s64)(a) << FIXED_SCALE) / (b))) A truncating div, ok. +/* This macro converts a fixed point number to int, and round half up it */ +#define FIXED_TO_INT_ROUND(a) (((a) + (1 << (FIXED_SCALE - 1))) >> FIXED_SCALE) Yes. +/* Convert divisor and dividend to Fixed-Point and performs the division */ +#define INT_TO_FIXED_DIV(a, b) (FIXED_DIV(INT_TO_FIXED(a), INT_TO_FIXED(b))) Ok, this is obvious to read, even though it's the same as FIXED_DIV() alone. Not sure the compiler would optimize that extra bit-shift away... If one wanted to, it would be possible to write type-safe functions for these so that fixed and integer could not be mixed up. Ok, I will move to a function. That's not all. If you want it type-safe, then you need something like struct vkms_fixed_point { s32 value; }; And use `struct vkms_fixed_point` (by value) everywhere where you pass a fixed point value, and never as a plain s32 type. Then it will be impossible to do incorrect arithmetic or conversions by accident on fixed point values. Is it worth it? I don't know, since it's limited into this one file. A simple 'typedef s32 vkms_fixed_point' does not work, because it does not prevent computing with vkms_fixed_point as if it was just a normal s32. Using a struct prevents that. ohhh. Got it! I wonder if the kernel doesn't already have something like this available in general... After some time searching I found `include/drm/drm_fixed.h`[1]. It seems fine. There are minor things to consider: 1. It doesn't have a `FIXED_TO_INT_ROUND` equivalent. 2. We can use `fixed20_12` for rgb565 but We have to use s64 for YUV formats or add a `sfixed20_12` with s32. In terms of consistency, do you think worth using this "library" given that we may need to use two distinct ways to represent the fixed point soonish? Or it's better to implement `sfixed20_12`? Or just continue with the current macros? [1] - https://elixir.bootlin.com/linux/latest/source/include/drm/drm_fixed.h + u16 r = FIXED_TO_INT_ROUND(FIXED_DIV(fp_r, fp_rb_ratio)); + u16 g = FIXED_TO_INT_ROUND(FIXED_DIV(fp_g, fp_g_ratio)); + u16 b = FIXED_TO_INT_ROUND(FIXED_DIV(fp_b, fp_rb_ratio)); + + *dst_pixels = cpu_to_le16(r << 11 | g << 5 | b); Looks good. You are using signed variables (int, s64, s32) when negative values should never occur. It doesn't seem wrong, just unexpected. I left the signal so I can reuse them in the YUV formats. Good point. The use of int in code vs. s32 in the macros is a bit inconsistent as well. Right. I think I will stick with s32 and s64 then. ... diff --git a/drivers/gpu/drm/vkms/vkms_writeback.c b/drivers/gpu/drm/vkms/vkms_writeback.c index cb63a5da9af1..98da7bee0f4b 100644 --- a/drivers/gpu/drm/vkms/vkms_writeback.c +++ b/drivers/gpu/drm/vkms/vkms_writeback.c @@ -16,7 +16,8 @@ static const u32 vkms_wb_formats[] = { DRM_FORMAT_XRGB, DRM_FORMAT_XRGB16161616, - DRM_FORMAT_ARGB16161616 + DRM_FORMAT_ARGB16161616, + DRM_FORMAT_RGB565 }; static const struct drm_connector_funcs vkms_wb_connector_funcs = { I wonder, would it be possible to add a unit test to make sure that get_plane_fmt_transform_function() or get_wb_fmt_transform_function() does not return NULL for any of the listed formats,
Re: [Freedreno] [PATCH 10/25] drm/msm/dpu: introduce struct dpu_sw_pipe
On 5/6/2022 3:29 PM, Dmitry Baryshkov wrote: On 07/05/2022 00:48, Abhinav Kumar wrote: On 5/6/2022 2:39 PM, Dmitry Baryshkov wrote: On 07/05/2022 00:30, Abhinav Kumar wrote: On 2/9/2022 9:25 AM, Dmitry Baryshkov wrote: Wrap SSPP and multirect index/mode into a single structure that represents software view on the pipe used. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 8 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 16 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 136 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 4 +- 4 files changed, 86 insertions(+), 78 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index ada7d5750536..751c64012058 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -441,14 +441,14 @@ static void _dpu_crtc_blend_setup_ctl(struct drm_crtc *crtc) pstate = to_dpu_plane_state(state); - sspp_idx = pstate->pipe_hw->idx; + sspp_idx = pstate->pipe.sspp->idx; set_bit(sspp_idx, fetch_active); stage_idx = zpos_cnt[pstate->stage]++; stage_cfg.stage[pstate->stage][stage_idx] = sspp_idx; stage_cfg.multirect_index[pstate->stage][stage_idx] = - pstate->multirect_index; + pstate->pipe.multirect_index; /* blend config update */ for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) @@ -1118,7 +1118,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc, pstates[cnt].dpu_pstate = to_dpu_plane_state(pstate); pstates[cnt].drm_pstate = pstate; pstates[cnt].stage = pstate->normalized_zpos; - pstates[cnt].pipe_id = to_dpu_plane_state(pstate)->pipe_hw->idx; + pstates[cnt].pipe_id = to_dpu_plane_state(pstate)->pipe.sspp->idx; if (pipe_staged[pstates[cnt].pipe_id]) { multirect_plane[multirect_count].r0 = @@ -1389,7 +1389,7 @@ static int _dpu_debugfs_status_show(struct seq_file *s, void *data) state->crtc_x, state->crtc_y, state->crtc_w, state->crtc_h); seq_printf(s, "\tmultirect: mode: %d index: %d\n", - pstate->multirect_mode, pstate->multirect_index); + pstate->pipe.multirect_mode, pstate->pipe.multirect_index); seq_puts(s, "\n"); } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h index 674f311f99b4..0af2bc6e5df8 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h @@ -159,15 +159,11 @@ struct dpu_hw_pixel_ext { * @src_rect: src ROI, caller takes into account the different operations * such as decimation, flip etc to program this field * @dest_rect: destination ROI. - * @index: index of the rectangle of SSPP - * @mode: parallel or time multiplex multirect mode */ struct dpu_hw_pipe_cfg { struct dpu_hw_fmt_layout layout; struct drm_rect src_rect; struct drm_rect dst_rect; - enum dpu_sspp_multirect_index index; - enum dpu_sspp_multirect_mode mode; }; /** @@ -218,6 +214,18 @@ struct dpu_hw_pipe_ts_cfg { u64 time; }; +/** + * struct dpu_sw_pipe - software pipe description + * @sspp: backing SSPP pipe + * @index: index of the rectangle of SSPP + * @mode: parallel or time multiplex multirect mode + */ +struct dpu_sw_pipe { + struct dpu_hw_pipe *sspp; + enum dpu_sspp_multirect_index multirect_index; + enum dpu_sspp_multirect_mode multirect_mode; +}; + /** * struct dpu_hw_sspp_ops - interface to the SSPP Hw driver functions * Caller must call the init function to get the pipe context for each pipe diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index d1f9b4bc10ac..51b5e8a3182b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -247,7 +247,7 @@ static int _dpu_plane_calc_fill_level(struct drm_plane *plane, ((src_width + 32) * fmt->bpp); } } else { - if (pstate->multirect_mode == DPU_SSPP_MULTIRECT_PARALLEL) { + if (pstate->pipe.multirect_mode == DPU_SSPP_MULTIRECT_PARALLEL) { total_fl = (fixed_buff_size / 2) * 2 / ((src_width + 32) * fmt->bpp); } else { @@ -331,7 +331,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane, fmt ? (char *)>base.pixel_format : NULL, pdpu->is_rt_pipe, total_fl, qos_lut); - pstate->pipe_hw->ops.setup_creq_lut(pstate->pipe_hw, qos_lut); + pstate->pipe.sspp->ops.setup_creq_lut(pstate->pipe.sspp, qos_lut); } /** @@ -383,7 +383,7 @@ static void _dpu_plane_set_danger_lut(struct drm_plane *plane, danger_lut,
Re: [PATCH v0.5 5/9] dt-bindings: phy: add binding for the i.MX8MP HDMI PHY
On Fri, 06 May 2022 20:10:30 +0200, Lucas Stach wrote: > Add a DT binding for the HDMI PHY found on the i.MX8MP SoC. > > Signed-off-by: Lucas Stach > --- > .../bindings/phy/fsl,imx8mp-hdmi-phy.yaml | 62 +++ > 1 file changed, 62 insertions(+) > create mode 100644 > Documentation/devicetree/bindings/phy/fsl,imx8mp-hdmi-phy.yaml > My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check' on your patch (DT_CHECKER_FLAGS is new in v5.13): yamllint warnings/errors: dtschema/dtc warnings/errors: Error: Documentation/devicetree/bindings/phy/fsl,imx8mp-hdmi-phy.example.dts:29.45-46 syntax error FATAL ERROR: Unable to parse input tree make[1]: *** [scripts/Makefile.lib:364: Documentation/devicetree/bindings/phy/fsl,imx8mp-hdmi-phy.example.dtb] Error 1 make[1]: *** Waiting for unfinished jobs make: *** [Makefile:1401: dt_binding_check] Error 2 doc reference errors (make refcheckdocs): See https://patchwork.ozlabs.org/patch/ This check can fail if there are any dependencies. The base for a patch series is generally the most recent rc1. If you already ran 'make dt_binding_check' and didn't see the above error(s), then make sure 'yamllint' is installed and dt-schema is up to date: pip3 install dtschema --upgrade Please check and re-submit.
Re: [PATCH v2 08/11] dt-bindings: display: convert PL110/PL111 to DT schema
On Fri, 06 May 2022 15:05:30 +0100, Andre Przywara wrote: > The Arm PL110 and PL111 are IP blocks that provide a display engine with > an LCD interface, being able to drive a variety of LC panels. > > Convert the binding over to DT schema, to the DTs can be automatically > checked. > This still contains the deprecated "arm,pl11x,tft-r0g0b0-pads" property, > because this is used by several DTs in the tree. > > Signed-off-by: Andre Przywara > --- > .../devicetree/bindings/display/arm,pl11x.txt | 110 --- > .../bindings/display/arm,pl11x.yaml | 174 ++ > 2 files changed, 174 insertions(+), 110 deletions(-) > delete mode 100644 Documentation/devicetree/bindings/display/arm,pl11x.txt > create mode 100644 Documentation/devicetree/bindings/display/arm,pl11x.yaml > Running 'make dtbs_check' with the schema in this patch gives the following warnings. Consider if they are expected or the schema is incorrect. These may not be new warnings. Note that it is not yet a requirement to have 0 warnings for dtbs_check. This will change in the future. Full log is available here: https://patchwork.ozlabs.org/patch/ clcd@1002: 'oneOf' conditional failed, one must be fixed: arch/arm/boot/dts/arm-realview-eb-11mp-bbrevd-ctrevb.dtb arch/arm/boot/dts/arm-realview-eb-11mp-bbrevd.dtb arch/arm/boot/dts/arm-realview-eb-11mp-ctrevb.dtb arch/arm/boot/dts/arm-realview-eb-11mp.dtb arch/arm/boot/dts/arm-realview-eb-a9mp-bbrevd.dtb arch/arm/boot/dts/arm-realview-eb-a9mp.dtb clcd@3104: 'interrupt-names' is a required property arch/arm/boot/dts/lpc3250-phy3250.dtb clcd@6000: 'clock-names' is a required property arch/arm/boot/dts/spear300-evb.dtb clcd@6000: 'clocks' is a required property arch/arm/boot/dts/spear300-evb.dtb clcd@6000: 'interrupt-names' is a required property arch/arm/boot/dts/spear300-evb.dtb clcd@6000: 'port' is a required property arch/arm/boot/dts/spear300-evb.dtb clcd@9000: 'clock-names' is a required property arch/arm/boot/dts/spear320-hmi.dtb clcd@9000: 'clocks' is a required property arch/arm/boot/dts/spear320-hmi.dtb clcd@9000: 'interrupt-names' is a required property arch/arm/boot/dts/spear320-hmi.dtb clcd@9000: 'port' is a required property arch/arm/boot/dts/spear320-hmi.dtb clcd@c000: 'interrupt-names' is a required property arch/arm/boot/dts/integratorcp.dtb clcd@c000: 'port@0' does not match any of the regexes: 'pinctrl-[0-9]+' arch/arm/boot/dts/integratorcp.dtb clcd@c000: 'port' is a required property arch/arm/boot/dts/integratorcp.dtb clcd@fc20: 'clock-names' is a required property arch/arm/boot/dts/spear600-evb.dtb clcd@fc20: 'clocks' is a required property arch/arm/boot/dts/spear600-evb.dtb clcd@fc20: 'interrupt-names' is a required property arch/arm/boot/dts/spear600-evb.dtb clcd@fc20: 'port' is a required property arch/arm/boot/dts/spear600-evb.dtb display@100: 'interrupt-names' is a required property arch/arm/boot/dts/integratorap-im-pd1.dtb display@100: 'port@0' does not match any of the regexes: 'pinctrl-[0-9]+' arch/arm/boot/dts/integratorap-im-pd1.dtb display@100: 'port' is a required property arch/arm/boot/dts/integratorap-im-pd1.dtb display@1012: 'interrupt-names' is a required property arch/arm/boot/dts/versatile-ab.dtb arch/arm/boot/dts/versatile-ab-ib2.dtb arch/arm/boot/dts/versatile-pb.dtb display@1012: 'port@0' does not match any of the regexes: 'pinctrl-[0-9]+' arch/arm/boot/dts/versatile-ab.dtb arch/arm/boot/dts/versatile-ab-ib2.dtb arch/arm/boot/dts/versatile-pb.dtb display@1012: 'port' is a required property arch/arm/boot/dts/versatile-ab.dtb arch/arm/boot/dts/versatile-ab-ib2.dtb arch/arm/boot/dts/versatile-pb.dtb lcd@C000: 'interrupt-names' is a required property arch/arm/boot/dts/nspire-clp.dtb arch/arm/boot/dts/nspire-cx.dtb arch/arm/boot/dts/nspire-tp.dtb lcd-controller@40008000: 'resets' does not match any of the regexes: 'pinctrl-[0-9]+' arch/arm/boot/dts/lpc4337-ciaa.dtb arch/arm/boot/dts/lpc4350-hitex-eval.dtb arch/arm/boot/dts/lpc4357-ea4357-devkit.dtb arch/arm/boot/dts/lpc4357-myd-lpc4357.dtb
Re: [PATCH v2 10/11] dt-bindings: display: convert Arm Mali-DP to DT schema
On Fri, 06 May 2022 15:05:32 +0100, Andre Przywara wrote: > The Arm Mali Display Processor (DP) 5xx/6xx is a series of IP that scans > out a framebuffer and hands the pixels over to a digital signal encoder. > It supports multiple layers, scaling and rotation. > > Convert the existing DT binding to DT schema. > > Signed-off-by: Andre Przywara > --- > .../bindings/display/arm,malidp.txt | 68 -- > .../bindings/display/arm,malidp.yaml | 116 ++ > 2 files changed, 116 insertions(+), 68 deletions(-) > delete mode 100644 Documentation/devicetree/bindings/display/arm,malidp.txt > create mode 100644 Documentation/devicetree/bindings/display/arm,malidp.yaml > Running 'make dtbs_check' with the schema in this patch gives the following warnings. Consider if they are expected or the schema is incorrect. These may not be new warnings. Note that it is not yet a requirement to have 0 warnings for dtbs_check. This will change in the future. Full log is available here: https://patchwork.ozlabs.org/patch/ display@f08: 'arm,malidp-arqos-value' does not match any of the regexes: 'pinctrl-[0-9]+' arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-kbox-a-230-ls.dtb arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28.dtb arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var1.dtb arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var2.dtb arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var3-ads2.dtb arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var4.dtb arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dtb arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dtb
Re: [PATCH v0.5 3/9] dt-bindings: display: imx: add binding for i.MX8MP HDMI PVI
On Fri, 06 May 2022 20:10:28 +0200, Lucas Stach wrote: > Add binding for the i.MX8MP HDMI parallel video interface block. > > Signed-off-by: Lucas Stach > --- > .../display/imx/fsl,imx8mp-hdmi-pvi.yaml | 83 +++ > 1 file changed, 83 insertions(+) > create mode 100644 > Documentation/devicetree/bindings/display/imx/fsl,imx8mp-hdmi-pvi.yaml > My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check' on your patch (DT_CHECKER_FLAGS is new in v5.13): yamllint warnings/errors: dtschema/dtc warnings/errors: Error: Documentation/devicetree/bindings/display/imx/fsl,imx8mp-hdmi-pvi.example.dts:26.45-46 syntax error FATAL ERROR: Unable to parse input tree make[1]: *** [scripts/Makefile.lib:364: Documentation/devicetree/bindings/display/imx/fsl,imx8mp-hdmi-pvi.example.dtb] Error 1 make[1]: *** Waiting for unfinished jobs make: *** [Makefile:1401: dt_binding_check] Error 2 doc reference errors (make refcheckdocs): See https://patchwork.ozlabs.org/patch/ This check can fail if there are any dependencies. The base for a patch series is generally the most recent rc1. If you already ran 'make dt_binding_check' and didn't see the above error(s), then make sure 'yamllint' is installed and dt-schema is up to date: pip3 install dtschema --upgrade Please check and re-submit.
Re: [PATCH v2 09/11] dt-bindings: display: convert Arm HDLCD to DT schema
On Fri, 06 May 2022 15:05:31 +0100, Andre Przywara wrote: > The Arm HDLCD is a display controller that scans out a framebuffer and > hands a signal to a digital encoder to generate a DVI or HDMI signal. > > Convert the existing DT binding to DT schema. > > Signed-off-by: Andre Przywara > --- > .../devicetree/bindings/display/arm,hdlcd.txt | 79 > .../bindings/display/arm,hdlcd.yaml | 89 +++ > 2 files changed, 89 insertions(+), 79 deletions(-) > delete mode 100644 Documentation/devicetree/bindings/display/arm,hdlcd.txt > create mode 100644 Documentation/devicetree/bindings/display/arm,hdlcd.yaml > Running 'make dtbs_check' with the schema in this patch gives the following warnings. Consider if they are expected or the schema is incorrect. These may not be new warnings. Note that it is not yet a requirement to have 0 warnings for dtbs_check. This will change in the future. Full log is available here: https://patchwork.ozlabs.org/patch/ hdlcd@2a11: 'port' is a required property arch/arm/boot/dts/vexpress-v2p-ca5s.dtb hdlcd@2b00: 'port' is a required property arch/arm/boot/dts/vexpress-v2p-ca15_a7.dtb arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dtb
Re: [PATCH v0.5 1/9] dt-bindings: display: imx: add binding for i.MX8MP HDMI TX
On Fri, 06 May 2022 20:10:26 +0200, Lucas Stach wrote: > The HDMI TX controller on the i.MX8MP SoC is a Synopsys designware IP > core with a little bit of SoC integration around it. > > Signed-off-by: Lucas Stach > --- > .../bindings/display/imx/fsl,imx8mp-hdmi.yaml | 73 +++ > 1 file changed, 73 insertions(+) > create mode 100644 > Documentation/devicetree/bindings/display/imx/fsl,imx8mp-hdmi.yaml > My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check' on your patch (DT_CHECKER_FLAGS is new in v5.13): yamllint warnings/errors: dtschema/dtc warnings/errors: Error: Documentation/devicetree/bindings/display/imx/fsl,imx8mp-hdmi.example.dts:36.45-46 syntax error FATAL ERROR: Unable to parse input tree make[1]: *** [scripts/Makefile.lib:364: Documentation/devicetree/bindings/display/imx/fsl,imx8mp-hdmi.example.dtb] Error 1 make[1]: *** Waiting for unfinished jobs make: *** [Makefile:1401: dt_binding_check] Error 2 doc reference errors (make refcheckdocs): See https://patchwork.ozlabs.org/patch/ This check can fail if there are any dependencies. The base for a patch series is generally the most recent rc1. If you already ran 'make dt_binding_check' and didn't see the above error(s), then make sure 'yamllint' is installed and dt-schema is up to date: pip3 install dtschema --upgrade Please check and re-submit.
Re: [Freedreno] [PATCH 10/25] drm/msm/dpu: introduce struct dpu_sw_pipe
On 07/05/2022 00:48, Abhinav Kumar wrote: On 5/6/2022 2:39 PM, Dmitry Baryshkov wrote: On 07/05/2022 00:30, Abhinav Kumar wrote: On 2/9/2022 9:25 AM, Dmitry Baryshkov wrote: Wrap SSPP and multirect index/mode into a single structure that represents software view on the pipe used. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 8 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 16 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 136 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 4 +- 4 files changed, 86 insertions(+), 78 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index ada7d5750536..751c64012058 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -441,14 +441,14 @@ static void _dpu_crtc_blend_setup_ctl(struct drm_crtc *crtc) pstate = to_dpu_plane_state(state); - sspp_idx = pstate->pipe_hw->idx; + sspp_idx = pstate->pipe.sspp->idx; set_bit(sspp_idx, fetch_active); stage_idx = zpos_cnt[pstate->stage]++; stage_cfg.stage[pstate->stage][stage_idx] = sspp_idx; stage_cfg.multirect_index[pstate->stage][stage_idx] = - pstate->multirect_index; + pstate->pipe.multirect_index; /* blend config update */ for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) @@ -1118,7 +1118,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc, pstates[cnt].dpu_pstate = to_dpu_plane_state(pstate); pstates[cnt].drm_pstate = pstate; pstates[cnt].stage = pstate->normalized_zpos; - pstates[cnt].pipe_id = to_dpu_plane_state(pstate)->pipe_hw->idx; + pstates[cnt].pipe_id = to_dpu_plane_state(pstate)->pipe.sspp->idx; if (pipe_staged[pstates[cnt].pipe_id]) { multirect_plane[multirect_count].r0 = @@ -1389,7 +1389,7 @@ static int _dpu_debugfs_status_show(struct seq_file *s, void *data) state->crtc_x, state->crtc_y, state->crtc_w, state->crtc_h); seq_printf(s, "\tmultirect: mode: %d index: %d\n", - pstate->multirect_mode, pstate->multirect_index); + pstate->pipe.multirect_mode, pstate->pipe.multirect_index); seq_puts(s, "\n"); } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h index 674f311f99b4..0af2bc6e5df8 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h @@ -159,15 +159,11 @@ struct dpu_hw_pixel_ext { * @src_rect: src ROI, caller takes into account the different operations * such as decimation, flip etc to program this field * @dest_rect: destination ROI. - * @index: index of the rectangle of SSPP - * @mode: parallel or time multiplex multirect mode */ struct dpu_hw_pipe_cfg { struct dpu_hw_fmt_layout layout; struct drm_rect src_rect; struct drm_rect dst_rect; - enum dpu_sspp_multirect_index index; - enum dpu_sspp_multirect_mode mode; }; /** @@ -218,6 +214,18 @@ struct dpu_hw_pipe_ts_cfg { u64 time; }; +/** + * struct dpu_sw_pipe - software pipe description + * @sspp: backing SSPP pipe + * @index: index of the rectangle of SSPP + * @mode: parallel or time multiplex multirect mode + */ +struct dpu_sw_pipe { + struct dpu_hw_pipe *sspp; + enum dpu_sspp_multirect_index multirect_index; + enum dpu_sspp_multirect_mode multirect_mode; +}; + /** * struct dpu_hw_sspp_ops - interface to the SSPP Hw driver functions * Caller must call the init function to get the pipe context for each pipe diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index d1f9b4bc10ac..51b5e8a3182b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -247,7 +247,7 @@ static int _dpu_plane_calc_fill_level(struct drm_plane *plane, ((src_width + 32) * fmt->bpp); } } else { - if (pstate->multirect_mode == DPU_SSPP_MULTIRECT_PARALLEL) { + if (pstate->pipe.multirect_mode == DPU_SSPP_MULTIRECT_PARALLEL) { total_fl = (fixed_buff_size / 2) * 2 / ((src_width + 32) * fmt->bpp); } else { @@ -331,7 +331,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane, fmt ? (char *)>base.pixel_format : NULL, pdpu->is_rt_pipe, total_fl, qos_lut); - pstate->pipe_hw->ops.setup_creq_lut(pstate->pipe_hw, qos_lut); + pstate->pipe.sspp->ops.setup_creq_lut(pstate->pipe.sspp, qos_lut); } /** @@ -383,7 +383,7 @@ static void _dpu_plane_set_danger_lut(struct drm_plane *plane, danger_lut, safe_lut); -
Re: [PATCH 11/25] drm/msm/dpu: use dpu_sw_pipe for dpu_hw_sspp callbacks
On 2/9/2022 9:25 AM, Dmitry Baryshkov wrote: Where feasible, use dpu_sw_pipe rather than a combo of dpu_hw_pipe and multirect_index/_mode arguments. Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 59 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 46 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 62 + drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h | 9 ++- 4 files changed, 77 insertions(+), 99 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c index 8714ee767346..d8120168f974 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c @@ -168,17 +168,16 @@ static int _sspp_subblk_offset(struct dpu_hw_pipe *ctx, return rc; } -static void dpu_hw_sspp_setup_multirect(struct dpu_hw_pipe *ctx, - enum dpu_sspp_multirect_index index, - enum dpu_sspp_multirect_mode mode) +static void dpu_hw_sspp_setup_multirect(struct dpu_sw_pipe *pipe) { + struct dpu_hw_pipe *ctx = pipe->sspp; u32 mode_mask; u32 idx; if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, )) return; - if (index == DPU_SSPP_RECT_SOLO) { + if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) { /** * if rect index is RECT_SOLO, we cannot expect a * virtual plane sharing the same SSPP id. So we go @@ -187,8 +186,8 @@ static void dpu_hw_sspp_setup_multirect(struct dpu_hw_pipe *ctx, mode_mask = 0; } else { mode_mask = DPU_REG_READ(>hw, SSPP_MULTIRECT_OPMODE + idx); - mode_mask |= index; - if (mode == DPU_SSPP_MULTIRECT_TIME_MX) + mode_mask |= pipe->multirect_index; + if (pipe->multirect_mode == DPU_SSPP_MULTIRECT_TIME_MX) mode_mask |= BIT(2); else mode_mask &= ~BIT(2); @@ -239,10 +238,10 @@ static void _sspp_setup_csc10_opmode(struct dpu_hw_pipe *ctx, /* * Setup source pixel format, flip, */ -static void dpu_hw_sspp_setup_format(struct dpu_hw_pipe *ctx, - const struct dpu_format *fmt, u32 flags, - enum dpu_sspp_multirect_index rect_mode) +static void dpu_hw_sspp_setup_format(struct dpu_sw_pipe *pipe, + const struct dpu_format *fmt, u32 flags) { + struct dpu_hw_pipe *ctx = pipe->sspp; struct dpu_hw_blk_reg_map *c; u32 chroma_samp, unpack, src_format; u32 opmode = 0; @@ -253,7 +252,8 @@ static void dpu_hw_sspp_setup_format(struct dpu_hw_pipe *ctx, if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, ) || !fmt) return; - if (rect_mode == DPU_SSPP_RECT_SOLO || rect_mode == DPU_SSPP_RECT_0) { + if (pipe->multirect_index == DPU_SSPP_RECT_SOLO || + pipe->multirect_index == DPU_SSPP_RECT_0) { op_mode_off = SSPP_SRC_OP_MODE; unpack_pat_off = SSPP_SRC_UNPACK_PATTERN; format_off = SSPP_SRC_FORMAT; @@ -443,10 +443,10 @@ static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_pipe *ctx) /* * dpu_hw_sspp_setup_rects() */ -static void dpu_hw_sspp_setup_rects(struct dpu_hw_pipe *ctx, - struct dpu_hw_pipe_cfg *cfg, - enum dpu_sspp_multirect_index rect_index) +static void dpu_hw_sspp_setup_rects(struct dpu_sw_pipe *pipe, + struct dpu_hw_pipe_cfg *cfg) { + struct dpu_hw_pipe *ctx = pipe->sspp; struct dpu_hw_blk_reg_map *c; u32 src_size, src_xy, dst_size, dst_xy, ystride0, ystride1; u32 src_size_off, src_xy_off, out_size_off, out_xy_off; @@ -457,7 +457,8 @@ static void dpu_hw_sspp_setup_rects(struct dpu_hw_pipe *ctx, c = >hw; - if (rect_index == DPU_SSPP_RECT_SOLO || rect_index == DPU_SSPP_RECT_0) { + if (pipe->multirect_index == DPU_SSPP_RECT_SOLO || + pipe->multirect_index == DPU_SSPP_RECT_0) { src_size_off = SSPP_SRC_SIZE; src_xy_off = SSPP_SRC_XY; out_size_off = SSPP_OUT_SIZE; @@ -478,7 +479,7 @@ static void dpu_hw_sspp_setup_rects(struct dpu_hw_pipe *ctx, dst_size = (drm_rect_height(>dst_rect) << 16) | drm_rect_width(>dst_rect); - if (rect_index == DPU_SSPP_RECT_SOLO) { + if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) { ystride0 = (cfg->layout.plane_pitch[0]) | (cfg->layout.plane_pitch[1] << 16); ystride1 = (cfg->layout.plane_pitch[2]) | @@ -487,7 +488,7 @@ static void dpu_hw_sspp_setup_rects(struct dpu_hw_pipe *ctx, ystride0 = DPU_REG_READ(c, SSPP_SRC_YSTRIDE0 + idx); ystride1 = DPU_REG_READ(c, SSPP_SRC_YSTRIDE1 + idx); - if (rect_index == DPU_SSPP_RECT_0) { + if
Re: [PATCH v2 1/3] drm/msm/adreno: Add A619 support
On 14/04/2022 21:44, Konrad Dybcio wrote: Add support for the Adreno 619 GPU, as found in Snapdragon 690 (SM6350), 480 (SM4350) and 750G (SM7225). Signed-off-by: Konrad Dybcio --- Changes in v2: - Don't reserve icache/dcache regions on legacy GMUs, as that is apparently not necessary and simply a downstream leftover. drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 11 ++-- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 70 +- drivers/gpu/drm/msm/adreno/a6xx_hfi.c | 66 +++- drivers/gpu/drm/msm/adreno/adreno_device.c | 14 + drivers/gpu/drm/msm/adreno/adreno_gpu.h| 13 +++- 5 files changed, 166 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index 3e325e2a2b1b..e8d4cca6cd46 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -527,6 +527,8 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu) pdc_in_aop = true; else if (adreno_is_a618(adreno_gpu) || adreno_is_a640_family(adreno_gpu)) pdc_address_offset = 0x30090; + else if (adreno_is_a619(adreno_gpu)) + pdc_address_offset = 0x300a0; else pdc_address_offset = 0x30080; @@ -601,7 +603,8 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu) pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_MSGID + 4, 0x10108); pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_ADDR + 4, 0x3); - if (adreno_is_a618(adreno_gpu) || adreno_is_a650_family(adreno_gpu)) + if (adreno_is_a618(adreno_gpu) || adreno_is_a619(adreno_gpu) || + adreno_is_a650_family(adreno_gpu)) pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_DATA + 4, 0x2); else pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_DATA + 4, 0x3); @@ -1537,7 +1540,7 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node) SZ_16M - SZ_16K, 0x04000, "icache"); if (ret) goto err_memory; - } else if (adreno_is_a640_family(adreno_gpu)) { + } else { ret = a6xx_gmu_memory_alloc(gmu, >icache, SZ_256K - SZ_16K, 0x04000, "icache"); if (ret) @@ -1547,9 +1550,9 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node) SZ_256K - SZ_16K, 0x44000, "dcache"); if (ret) goto err_memory; - } else { - BUG_ON(adreno_is_a660_family(adreno_gpu)); + } Is this chunk expected or not? I don't think you had intention to drop the BUG_ON. + if (adreno_is_a630(adreno_gpu) || adreno_is_a615_family(adreno_gpu)) { /* HFI v1, has sptprac */ gmu->legacy = true; diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 83c31b2ad865..ddeb04a77662 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -252,6 +252,74 @@ static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) a6xx_flush(gpu, ring); } +/* For a615 family (a615, a616, a618 and a619) */ +const struct adreno_reglist a615_hwcg[] = { + {REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x0222}, + {REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x0220}, + {REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x0080}, + {REG_A6XX_RBBM_CLOCK_HYST_SP0, 0xF3CF}, + {REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x0222}, + {REG_A6XX_RBBM_CLOCK_CNTL_TP1, 0x0222}, + {REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x}, + {REG_A6XX_RBBM_CLOCK_CNTL2_TP1, 0x}, + {REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x}, + {REG_A6XX_RBBM_CLOCK_CNTL3_TP1, 0x}, + {REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x0002}, + {REG_A6XX_RBBM_CLOCK_CNTL4_TP1, 0x0002}, + {REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x}, + {REG_A6XX_RBBM_CLOCK_HYST_TP1, 0x}, + {REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x}, + {REG_A6XX_RBBM_CLOCK_HYST2_TP1, 0x}, + {REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x}, + {REG_A6XX_RBBM_CLOCK_HYST3_TP1, 0x}, + {REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x0007}, + {REG_A6XX_RBBM_CLOCK_HYST4_TP1, 0x0007}, + {REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x}, + {REG_A6XX_RBBM_CLOCK_DELAY_TP1, 0x}, + {REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x}, + {REG_A6XX_RBBM_CLOCK_DELAY2_TP1, 0x}, + {REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x}, + {REG_A6XX_RBBM_CLOCK_DELAY3_TP1, 0x}, + {REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x0001}, + {REG_A6XX_RBBM_CLOCK_DELAY4_TP1, 0x0001}, + {REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x}, + {REG_A6XX_RBBM_CLOCK_CNTL2_UCHE, 0x}, + {REG_A6XX_RBBM_CLOCK_CNTL3_UCHE, 0x}, +
Re: [Freedreno] [PATCH 10/25] drm/msm/dpu: introduce struct dpu_sw_pipe
On 5/6/2022 2:39 PM, Dmitry Baryshkov wrote: On 07/05/2022 00:30, Abhinav Kumar wrote: On 2/9/2022 9:25 AM, Dmitry Baryshkov wrote: Wrap SSPP and multirect index/mode into a single structure that represents software view on the pipe used. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 8 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 16 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 136 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 4 +- 4 files changed, 86 insertions(+), 78 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index ada7d5750536..751c64012058 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -441,14 +441,14 @@ static void _dpu_crtc_blend_setup_ctl(struct drm_crtc *crtc) pstate = to_dpu_plane_state(state); - sspp_idx = pstate->pipe_hw->idx; + sspp_idx = pstate->pipe.sspp->idx; set_bit(sspp_idx, fetch_active); stage_idx = zpos_cnt[pstate->stage]++; stage_cfg.stage[pstate->stage][stage_idx] = sspp_idx; stage_cfg.multirect_index[pstate->stage][stage_idx] = - pstate->multirect_index; + pstate->pipe.multirect_index; /* blend config update */ for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) @@ -1118,7 +1118,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc, pstates[cnt].dpu_pstate = to_dpu_plane_state(pstate); pstates[cnt].drm_pstate = pstate; pstates[cnt].stage = pstate->normalized_zpos; - pstates[cnt].pipe_id = to_dpu_plane_state(pstate)->pipe_hw->idx; + pstates[cnt].pipe_id = to_dpu_plane_state(pstate)->pipe.sspp->idx; if (pipe_staged[pstates[cnt].pipe_id]) { multirect_plane[multirect_count].r0 = @@ -1389,7 +1389,7 @@ static int _dpu_debugfs_status_show(struct seq_file *s, void *data) state->crtc_x, state->crtc_y, state->crtc_w, state->crtc_h); seq_printf(s, "\tmultirect: mode: %d index: %d\n", - pstate->multirect_mode, pstate->multirect_index); + pstate->pipe.multirect_mode, pstate->pipe.multirect_index); seq_puts(s, "\n"); } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h index 674f311f99b4..0af2bc6e5df8 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h @@ -159,15 +159,11 @@ struct dpu_hw_pixel_ext { * @src_rect: src ROI, caller takes into account the different operations * such as decimation, flip etc to program this field * @dest_rect: destination ROI. - * @index: index of the rectangle of SSPP - * @mode: parallel or time multiplex multirect mode */ struct dpu_hw_pipe_cfg { struct dpu_hw_fmt_layout layout; struct drm_rect src_rect; struct drm_rect dst_rect; - enum dpu_sspp_multirect_index index; - enum dpu_sspp_multirect_mode mode; }; /** @@ -218,6 +214,18 @@ struct dpu_hw_pipe_ts_cfg { u64 time; }; +/** + * struct dpu_sw_pipe - software pipe description + * @sspp: backing SSPP pipe + * @index: index of the rectangle of SSPP + * @mode: parallel or time multiplex multirect mode + */ +struct dpu_sw_pipe { + struct dpu_hw_pipe *sspp; + enum dpu_sspp_multirect_index multirect_index; + enum dpu_sspp_multirect_mode multirect_mode; +}; + /** * struct dpu_hw_sspp_ops - interface to the SSPP Hw driver functions * Caller must call the init function to get the pipe context for each pipe diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index d1f9b4bc10ac..51b5e8a3182b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -247,7 +247,7 @@ static int _dpu_plane_calc_fill_level(struct drm_plane *plane, ((src_width + 32) * fmt->bpp); } } else { - if (pstate->multirect_mode == DPU_SSPP_MULTIRECT_PARALLEL) { + if (pstate->pipe.multirect_mode == DPU_SSPP_MULTIRECT_PARALLEL) { total_fl = (fixed_buff_size / 2) * 2 / ((src_width + 32) * fmt->bpp); } else { @@ -331,7 +331,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane, fmt ? (char *)>base.pixel_format : NULL, pdpu->is_rt_pipe, total_fl, qos_lut); - pstate->pipe_hw->ops.setup_creq_lut(pstate->pipe_hw, qos_lut); + pstate->pipe.sspp->ops.setup_creq_lut(pstate->pipe.sspp, qos_lut); } /** @@ -383,7 +383,7 @@ static void _dpu_plane_set_danger_lut(struct drm_plane *plane, danger_lut, safe_lut); - pstate->pipe_hw->ops.setup_danger_safe_lut(pstate->pipe_hw, +
[PATCH] drm/msm/dp: Always clear mask bits to disable interrupts at dp_ctrl_reset_irq_ctrl()
dp_catalog_ctrl_reset() will software reset DP controller. But it will not reset programmable registers to default value. DP driver still have to clear mask bits to interrupt status registers to disable interrupts after software reset of controller. This patch removes the enable flag condition checking to always clear mask bits of interrupt status registers to disable interrupts if enable flag is false. Fixes: ba0a422be723 ("drm/msm/dp: do not initialize phy until plugin interrupt received") Signed-off-by: Kuogee Hsieh --- drivers/gpu/drm/msm/dp/dp_ctrl.c | 9 +++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c index 38026f2..cbf3399 100644 --- a/drivers/gpu/drm/msm/dp/dp_ctrl.c +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c @@ -1379,8 +1379,13 @@ void dp_ctrl_reset_irq_ctrl(struct dp_ctrl *dp_ctrl, bool enable) dp_catalog_ctrl_reset(ctrl->catalog); - if (enable) - dp_catalog_ctrl_enable_irq(ctrl->catalog, enable); + /* +* all dp controller programmable registers will not +* be reset to default value after DP_SW_RESET +* therefore interrupt mask bits have to be updated +* to enable/disable interrupts +*/ + dp_catalog_ctrl_enable_irq(ctrl->catalog, enable); } void dp_ctrl_phy_init(struct dp_ctrl *dp_ctrl) -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
Re: [PATCH 10/25] drm/msm/dpu: introduce struct dpu_sw_pipe
On 07/05/2022 00:30, Abhinav Kumar wrote: On 2/9/2022 9:25 AM, Dmitry Baryshkov wrote: Wrap SSPP and multirect index/mode into a single structure that represents software view on the pipe used. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 8 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 16 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 136 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 4 +- 4 files changed, 86 insertions(+), 78 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index ada7d5750536..751c64012058 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -441,14 +441,14 @@ static void _dpu_crtc_blend_setup_ctl(struct drm_crtc *crtc) pstate = to_dpu_plane_state(state); - sspp_idx = pstate->pipe_hw->idx; + sspp_idx = pstate->pipe.sspp->idx; set_bit(sspp_idx, fetch_active); stage_idx = zpos_cnt[pstate->stage]++; stage_cfg.stage[pstate->stage][stage_idx] = sspp_idx; stage_cfg.multirect_index[pstate->stage][stage_idx] = - pstate->multirect_index; + pstate->pipe.multirect_index; /* blend config update */ for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) @@ -1118,7 +1118,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc, pstates[cnt].dpu_pstate = to_dpu_plane_state(pstate); pstates[cnt].drm_pstate = pstate; pstates[cnt].stage = pstate->normalized_zpos; - pstates[cnt].pipe_id = to_dpu_plane_state(pstate)->pipe_hw->idx; + pstates[cnt].pipe_id = to_dpu_plane_state(pstate)->pipe.sspp->idx; if (pipe_staged[pstates[cnt].pipe_id]) { multirect_plane[multirect_count].r0 = @@ -1389,7 +1389,7 @@ static int _dpu_debugfs_status_show(struct seq_file *s, void *data) state->crtc_x, state->crtc_y, state->crtc_w, state->crtc_h); seq_printf(s, "\tmultirect: mode: %d index: %d\n", - pstate->multirect_mode, pstate->multirect_index); + pstate->pipe.multirect_mode, pstate->pipe.multirect_index); seq_puts(s, "\n"); } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h index 674f311f99b4..0af2bc6e5df8 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h @@ -159,15 +159,11 @@ struct dpu_hw_pixel_ext { * @src_rect: src ROI, caller takes into account the different operations * such as decimation, flip etc to program this field * @dest_rect: destination ROI. - * @index: index of the rectangle of SSPP - * @mode: parallel or time multiplex multirect mode */ struct dpu_hw_pipe_cfg { struct dpu_hw_fmt_layout layout; struct drm_rect src_rect; struct drm_rect dst_rect; - enum dpu_sspp_multirect_index index; - enum dpu_sspp_multirect_mode mode; }; /** @@ -218,6 +214,18 @@ struct dpu_hw_pipe_ts_cfg { u64 time; }; +/** + * struct dpu_sw_pipe - software pipe description + * @sspp: backing SSPP pipe + * @index: index of the rectangle of SSPP + * @mode: parallel or time multiplex multirect mode + */ +struct dpu_sw_pipe { + struct dpu_hw_pipe *sspp; + enum dpu_sspp_multirect_index multirect_index; + enum dpu_sspp_multirect_mode multirect_mode; +}; + /** * struct dpu_hw_sspp_ops - interface to the SSPP Hw driver functions * Caller must call the init function to get the pipe context for each pipe diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index d1f9b4bc10ac..51b5e8a3182b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -247,7 +247,7 @@ static int _dpu_plane_calc_fill_level(struct drm_plane *plane, ((src_width + 32) * fmt->bpp); } } else { - if (pstate->multirect_mode == DPU_SSPP_MULTIRECT_PARALLEL) { + if (pstate->pipe.multirect_mode == DPU_SSPP_MULTIRECT_PARALLEL) { total_fl = (fixed_buff_size / 2) * 2 / ((src_width + 32) * fmt->bpp); } else { @@ -331,7 +331,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane, fmt ? (char *)>base.pixel_format : NULL, pdpu->is_rt_pipe, total_fl, qos_lut); - pstate->pipe_hw->ops.setup_creq_lut(pstate->pipe_hw, qos_lut); + pstate->pipe.sspp->ops.setup_creq_lut(pstate->pipe.sspp, qos_lut); } /** @@ -383,7 +383,7 @@ static void _dpu_plane_set_danger_lut(struct drm_plane *plane, danger_lut, safe_lut); - pstate->pipe_hw->ops.setup_danger_safe_lut(pstate->pipe_hw, + pstate->pipe.sspp->ops.setup_danger_safe_lut(pstate->pipe.sspp,
Re: [PATCH] drm/msm: return an error pointer in msm_gem_prime_get_sg_table()
On 05/05/2022 13:28, Dan Carpenter wrote: The msm_gem_prime_get_sg_table() needs to return error pointers on error. This is called from drm_gem_map_dma_buf() and returning a NULL will lead to a crash in that function. Fixes: ac45146733b0 ("drm/msm: fix msm_gem_prime_get_sg_table()") Signed-off-by: Dan Carpenter Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/msm_gem_prime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_gem_prime.c b/drivers/gpu/drm/msm/msm_gem_prime.c index e8f1b7a2ca9c..94ab705e9b8a 100644 --- a/drivers/gpu/drm/msm/msm_gem_prime.c +++ b/drivers/gpu/drm/msm/msm_gem_prime.c @@ -17,7 +17,7 @@ struct sg_table *msm_gem_prime_get_sg_table(struct drm_gem_object *obj) int npages = obj->size >> PAGE_SHIFT; if (WARN_ON(!msm_obj->pages)) /* should have already pinned! */ - return NULL; + return ERR_PTR(-ENOMEM); return drm_prime_pages_to_sg(obj->dev, msm_obj->pages, npages); } -- With best wishes Dmitry
Re: [PATCH] drm/nouveau: Fix a potential theorical leak in nouveau_get_backlight_name()
Sorry I totally missed this patch up until now, noticed it while going through unread emails today. This is: Reviewed-by: Lyude Paul FWIW, if there's something you need reviews on that hasn't gotten looked at after a few weeks feel free to poke the nouveau list/me. Anyway, I will go ahead and push this to drm-misc-fixes in a moment. Thanks! On Wed, 2022-02-09 at 07:03 +0100, Christophe JAILLET wrote: > If successful ida_simple_get() calls are not undone when needed, some > additional memory may be allocated and wasted. > > Here, an ID between 0 and MAX_INT is required. If this ID is >=100, it is > not taken into account and is wasted. It should be released. > > Instead of calling ida_simple_remove(), take advantage of the 'max' > parameter to require the ID not to be too big. Should it be too big, it > is not allocated and don't need to be freed. > > While at it, use ida_alloc_xxx()/ida_free() instead to > ida_simple_get()/ida_simple_remove(). > The latter is deprecated and more verbose. > > Fixes: db1a0ae21461 ("drm/nouveau/bl: Assign different names to interfaces") > Signed-off-by: Christophe JAILLET > --- > This patch is more a clean-up than a fix. > It is unlikely than >= 100 backlight devices will be registered, and the > over allocation would occur even much later when the underlying xarray is > full. > > I also think that the 'if (bl->id >= 0)' before the ida_simple_remove() > calls are useless. We don't store the id if a negative (i.e. error) is > returned by ida_simple_get(). > > Finally, having a '#define BL_MAX_MINORS 99' could be better than a > magic number in the code. > --- > drivers/gpu/drm/nouveau/nouveau_backlight.c | 8 > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c > b/drivers/gpu/drm/nouveau/nouveau_backlight.c > index ae2f2abc8f5a..ccd080ba30bf 100644 > --- a/drivers/gpu/drm/nouveau/nouveau_backlight.c > +++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c > @@ -46,8 +46,8 @@ static bool > nouveau_get_backlight_name(char backlight_name[BL_NAME_SIZE], > struct nouveau_backlight *bl) > { > - const int nb = ida_simple_get(_ida, 0, 0, GFP_KERNEL); > - if (nb < 0 || nb >= 100) > + const int nb = ida_alloc_max(_ida, 99, GFP_KERNEL); > + if (nb < 0) > return false; > if (nb > 0) > snprintf(backlight_name, BL_NAME_SIZE, "nv_backlight%d", > nb); > @@ -414,7 +414,7 @@ nouveau_backlight_init(struct drm_connector *connector) > nv_encoder, ops, ); > if (IS_ERR(bl->dev)) { > if (bl->id >= 0) > - ida_simple_remove(_ida, bl->id); > + ida_free(_ida, bl->id); > ret = PTR_ERR(bl->dev); > goto fail_alloc; > } > @@ -442,7 +442,7 @@ nouveau_backlight_fini(struct drm_connector *connector) > return; > > if (bl->id >= 0) > - ida_simple_remove(_ida, bl->id); > + ida_free(_ida, bl->id); > > backlight_device_unregister(bl->dev); > nv_conn->backlight = NULL; -- Cheers, Lyude Paul (she/her) Software Engineer at Red Hat
Re: [PATCH 10/25] drm/msm/dpu: introduce struct dpu_sw_pipe
On 2/9/2022 9:25 AM, Dmitry Baryshkov wrote: Wrap SSPP and multirect index/mode into a single structure that represents software view on the pipe used. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c| 8 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 16 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 136 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 4 +- 4 files changed, 86 insertions(+), 78 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index ada7d5750536..751c64012058 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -441,14 +441,14 @@ static void _dpu_crtc_blend_setup_ctl(struct drm_crtc *crtc) pstate = to_dpu_plane_state(state); - sspp_idx = pstate->pipe_hw->idx; + sspp_idx = pstate->pipe.sspp->idx; set_bit(sspp_idx, fetch_active); stage_idx = zpos_cnt[pstate->stage]++; stage_cfg.stage[pstate->stage][stage_idx] = sspp_idx; stage_cfg.multirect_index[pstate->stage][stage_idx] = - pstate->multirect_index; + pstate->pipe.multirect_index; /* blend config update */ for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) @@ -1118,7 +1118,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc, pstates[cnt].dpu_pstate = to_dpu_plane_state(pstate); pstates[cnt].drm_pstate = pstate; pstates[cnt].stage = pstate->normalized_zpos; - pstates[cnt].pipe_id = to_dpu_plane_state(pstate)->pipe_hw->idx; + pstates[cnt].pipe_id = to_dpu_plane_state(pstate)->pipe.sspp->idx; if (pipe_staged[pstates[cnt].pipe_id]) { multirect_plane[multirect_count].r0 = @@ -1389,7 +1389,7 @@ static int _dpu_debugfs_status_show(struct seq_file *s, void *data) state->crtc_x, state->crtc_y, state->crtc_w, state->crtc_h); seq_printf(s, "\tmultirect: mode: %d index: %d\n", - pstate->multirect_mode, pstate->multirect_index); + pstate->pipe.multirect_mode, pstate->pipe.multirect_index); seq_puts(s, "\n"); } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h index 674f311f99b4..0af2bc6e5df8 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h @@ -159,15 +159,11 @@ struct dpu_hw_pixel_ext { * @src_rect: src ROI, caller takes into account the different operations * such as decimation, flip etc to program this field * @dest_rect: destination ROI. - * @index: index of the rectangle of SSPP - * @mode: parallel or time multiplex multirect mode */ struct dpu_hw_pipe_cfg { struct dpu_hw_fmt_layout layout; struct drm_rect src_rect; struct drm_rect dst_rect; - enum dpu_sspp_multirect_index index; - enum dpu_sspp_multirect_mode mode; }; /** @@ -218,6 +214,18 @@ struct dpu_hw_pipe_ts_cfg { u64 time; }; +/** + * struct dpu_sw_pipe - software pipe description + * @sspp: backing SSPP pipe + * @index: index of the rectangle of SSPP + * @mode: parallel or time multiplex multirect mode + */ +struct dpu_sw_pipe { + struct dpu_hw_pipe *sspp; + enum dpu_sspp_multirect_index multirect_index; + enum dpu_sspp_multirect_mode multirect_mode; +}; + /** * struct dpu_hw_sspp_ops - interface to the SSPP Hw driver functions * Caller must call the init function to get the pipe context for each pipe diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index d1f9b4bc10ac..51b5e8a3182b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -247,7 +247,7 @@ static int _dpu_plane_calc_fill_level(struct drm_plane *plane, ((src_width + 32) * fmt->bpp); } } else { - if (pstate->multirect_mode == DPU_SSPP_MULTIRECT_PARALLEL) { + if (pstate->pipe.multirect_mode == DPU_SSPP_MULTIRECT_PARALLEL) { total_fl = (fixed_buff_size / 2) * 2 / ((src_width + 32) * fmt->bpp); } else { @@ -331,7 +331,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane, fmt ? (char *)>base.pixel_format : NULL, pdpu->is_rt_pipe, total_fl, qos_lut); - pstate->pipe_hw->ops.setup_creq_lut(pstate->pipe_hw, qos_lut); + pstate->pipe.sspp->ops.setup_creq_lut(pstate->pipe.sspp, qos_lut); } /** @@ -383,7 +383,7 @@ static
Re: [PATCH v3 2/2] drm/msm/mdp5: Return error code in mdp5_mixer_release when deadlock is detected
On 06/05/2022 00:40, Jessica Zhang wrote: There is a possibility for mdp5_get_global_state to return -EDEADLK when acquiring the modeset lock, but currently global_state in mdp5_mixer_release doesn't check for if an error is returned. To avoid a NULL dereference error, let's have mdp5_mixer_release check if an error is returned and propagate that error. Reported-by: Tomeu Vizoso Signed-off-by: Jessica Zhang Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c | 10 -- drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c | 15 +++ drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.h | 4 ++-- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c index b966cd69f99d..fe2922c8d21b 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c @@ -612,9 +612,15 @@ static int mdp5_crtc_setup_pipeline(struct drm_crtc *crtc, if (ret) return ret; - mdp5_mixer_release(new_crtc_state->state, old_mixer); + ret = mdp5_mixer_release(new_crtc_state->state, old_mixer); + if (ret) + return ret; + if (old_r_mixer) { - mdp5_mixer_release(new_crtc_state->state, old_r_mixer); + ret = mdp5_mixer_release(new_crtc_state->state, old_r_mixer); + if (ret) + return ret; + if (!need_right_mixer) pipeline->r_mixer = NULL; } diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c index 954db683ae44..2536def2a000 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c @@ -116,21 +116,28 @@ int mdp5_mixer_assign(struct drm_atomic_state *s, struct drm_crtc *crtc, return 0; } -void mdp5_mixer_release(struct drm_atomic_state *s, struct mdp5_hw_mixer *mixer) +int mdp5_mixer_release(struct drm_atomic_state *s, struct mdp5_hw_mixer *mixer) { struct mdp5_global_state *global_state = mdp5_get_global_state(s); - struct mdp5_hw_mixer_state *new_state = _state->hwmixer; + struct mdp5_hw_mixer_state *new_state; if (!mixer) - return; + return 0; + + if (IS_ERR(global_state)) + return PTR_ERR(global_state); + + new_state = _state->hwmixer; if (WARN_ON(!new_state->hwmixer_to_crtc[mixer->idx])) - return; + return -EINVAL; DBG("%s: release from crtc %s", mixer->name, new_state->hwmixer_to_crtc[mixer->idx]->name); new_state->hwmixer_to_crtc[mixer->idx] = NULL; + + return 0; } void mdp5_mixer_destroy(struct mdp5_hw_mixer *mixer) diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.h b/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.h index 43c9ba43ce18..545ee223b9d7 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.h +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.h @@ -30,7 +30,7 @@ void mdp5_mixer_destroy(struct mdp5_hw_mixer *lm); int mdp5_mixer_assign(struct drm_atomic_state *s, struct drm_crtc *crtc, uint32_t caps, struct mdp5_hw_mixer **mixer, struct mdp5_hw_mixer **r_mixer); -void mdp5_mixer_release(struct drm_atomic_state *s, - struct mdp5_hw_mixer *mixer); +int mdp5_mixer_release(struct drm_atomic_state *s, + struct mdp5_hw_mixer *mixer); #endif /* __MDP5_LM_H__ */ -- With best wishes Dmitry
Re: [PATCH v3 1/2] drm/msm/mdp5: Return error code in mdp5_pipe_release when deadlock is detected
On 06/05/2022 01:01, Rob Clark wrote: On Thu, May 5, 2022 at 2:41 PM Jessica Zhang wrote: mdp5_get_global_state runs the risk of hitting a -EDEADLK when acquiring the modeset lock, but currently mdp5_pipe_release doesn't check for if an error is returned. Because of this, there is a possibility of mdp5_pipe_release hitting a NULL dereference error. To avoid this, let's have mdp5_pipe_release check if mdp5_get_global_state returns an error and propogate that error. Changes since v1: - Separated declaration and initialization of *new_state to avoid compiler warning - Fixed some spelling mistakes in commit message Changes since v2: - Return 0 in case where hwpipe is NULL as this is considered normal behavior - Added 2nd patch in series to fix a similar NULL dereference issue in mdp5_mixer_release Reported-by: Tomeu Vizoso Signed-off-by: Jessica Zhang Fixes: 7907a0d77cb4 ("drm/msm/mdp5: Use the new private_obj state") Reviewed-by: Rob Clark Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c | 15 +++ drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.h | 2 +- drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c | 20 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c index ba6695963aa6..a4f5cb90f3e8 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c @@ -119,18 +119,23 @@ int mdp5_pipe_assign(struct drm_atomic_state *s, struct drm_plane *plane, return 0; } -void mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe) +int mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe) { struct msm_drm_private *priv = s->dev->dev_private; struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms)); struct mdp5_global_state *state = mdp5_get_global_state(s); - struct mdp5_hw_pipe_state *new_state = >hwpipe; + struct mdp5_hw_pipe_state *new_state; if (!hwpipe) - return; + return 0; + + if (IS_ERR(state)) + return PTR_ERR(state); + + new_state = >hwpipe; if (WARN_ON(!new_state->hwpipe_to_plane[hwpipe->idx])) - return; + return -EINVAL; DBG("%s: release from plane %s", hwpipe->name, new_state->hwpipe_to_plane[hwpipe->idx]->name); @@ -141,6 +146,8 @@ void mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe) } new_state->hwpipe_to_plane[hwpipe->idx] = NULL; + + return 0; } void mdp5_pipe_destroy(struct mdp5_hw_pipe *hwpipe) diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.h b/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.h index 9b26d0761bd4..cca67938cab2 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.h +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.h @@ -37,7 +37,7 @@ int mdp5_pipe_assign(struct drm_atomic_state *s, struct drm_plane *plane, uint32_t caps, uint32_t blkcfg, struct mdp5_hw_pipe **hwpipe, struct mdp5_hw_pipe **r_hwpipe); -void mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe); +int mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe); struct mdp5_hw_pipe *mdp5_pipe_init(enum mdp5_pipe pipe, uint32_t reg_offset, uint32_t caps); diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c index 228b22830970..979458482841 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c @@ -311,12 +311,24 @@ static int mdp5_plane_atomic_check_with_state(struct drm_crtc_state *crtc_state, mdp5_state->r_hwpipe = NULL; - mdp5_pipe_release(state->state, old_hwpipe); - mdp5_pipe_release(state->state, old_right_hwpipe); + ret = mdp5_pipe_release(state->state, old_hwpipe); + if (ret) + return ret; + + ret = mdp5_pipe_release(state->state, old_right_hwpipe); + if (ret) + return ret; + } } else { - mdp5_pipe_release(state->state, mdp5_state->hwpipe); - mdp5_pipe_release(state->state, mdp5_state->r_hwpipe); + ret = mdp5_pipe_release(state->state, mdp5_state->hwpipe); + if (ret) + return ret; + + ret = mdp5_pipe_release(state->state, mdp5_state->r_hwpipe); + if (ret) + return ret; + mdp5_state->hwpipe = mdp5_state->r_hwpipe = NULL; } -- 2.35.1 -- With best wishes Dmitry
Re: [PATCH v3 1/2] drm/msm/mdp5: Return error code in mdp5_pipe_release when deadlock is detected
On 06/05/2022 00:40, Jessica Zhang wrote: mdp5_get_global_state runs the risk of hitting a -EDEADLK when acquiring the modeset lock, but currently mdp5_pipe_release doesn't check for if an error is returned. Because of this, there is a possibility of mdp5_pipe_release hitting a NULL dereference error. To avoid this, let's have mdp5_pipe_release check if mdp5_get_global_state returns an error and propogate that error. Changes since v1: - Separated declaration and initialization of *new_state to avoid compiler warning - Fixed some spelling mistakes in commit message Changes since v2: - Return 0 in case where hwpipe is NULL as this is considered normal behavior - Added 2nd patch in series to fix a similar NULL dereference issue in mdp5_mixer_release Reported-by: Tomeu Vizoso Signed-off-by: Jessica Zhang Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c | 15 +++ drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.h | 2 +- drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c | 20 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c index ba6695963aa6..a4f5cb90f3e8 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c @@ -119,18 +119,23 @@ int mdp5_pipe_assign(struct drm_atomic_state *s, struct drm_plane *plane, return 0; } -void mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe) +int mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe) { struct msm_drm_private *priv = s->dev->dev_private; struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms)); struct mdp5_global_state *state = mdp5_get_global_state(s); - struct mdp5_hw_pipe_state *new_state = >hwpipe; + struct mdp5_hw_pipe_state *new_state; if (!hwpipe) - return; + return 0; + + if (IS_ERR(state)) + return PTR_ERR(state); + + new_state = >hwpipe; if (WARN_ON(!new_state->hwpipe_to_plane[hwpipe->idx])) - return; + return -EINVAL; DBG("%s: release from plane %s", hwpipe->name, new_state->hwpipe_to_plane[hwpipe->idx]->name); @@ -141,6 +146,8 @@ void mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe) } new_state->hwpipe_to_plane[hwpipe->idx] = NULL; + + return 0; } void mdp5_pipe_destroy(struct mdp5_hw_pipe *hwpipe) diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.h b/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.h index 9b26d0761bd4..cca67938cab2 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.h +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.h @@ -37,7 +37,7 @@ int mdp5_pipe_assign(struct drm_atomic_state *s, struct drm_plane *plane, uint32_t caps, uint32_t blkcfg, struct mdp5_hw_pipe **hwpipe, struct mdp5_hw_pipe **r_hwpipe); -void mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe); +int mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe); struct mdp5_hw_pipe *mdp5_pipe_init(enum mdp5_pipe pipe, uint32_t reg_offset, uint32_t caps); diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c index 228b22830970..979458482841 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c @@ -311,12 +311,24 @@ static int mdp5_plane_atomic_check_with_state(struct drm_crtc_state *crtc_state, mdp5_state->r_hwpipe = NULL; - mdp5_pipe_release(state->state, old_hwpipe); - mdp5_pipe_release(state->state, old_right_hwpipe); + ret = mdp5_pipe_release(state->state, old_hwpipe); + if (ret) + return ret; + + ret = mdp5_pipe_release(state->state, old_right_hwpipe); + if (ret) + return ret; + } } else { - mdp5_pipe_release(state->state, mdp5_state->hwpipe); - mdp5_pipe_release(state->state, mdp5_state->r_hwpipe); + ret = mdp5_pipe_release(state->state, mdp5_state->hwpipe); + if (ret) + return ret; + + ret = mdp5_pipe_release(state->state, mdp5_state->r_hwpipe); + if (ret) + return ret; + mdp5_state->hwpipe = mdp5_state->r_hwpipe = NULL; } -- With best wishes Dmitry
Re: [Freedreno] [PATCH v10 1/4] drm/msm/dp: Add eDP support via aux_bus
On 07/05/2022 00:17, Abhinav Kumar wrote: On 5/6/2022 2:05 PM, Dmitry Baryshkov wrote: On 07/05/2022 00:03, Abhinav Kumar wrote: On 5/6/2022 1:49 PM, Dmitry Baryshkov wrote: On 25/04/2022 14:44, Sankeerth Billakanti wrote: This patch adds support for generic eDP sink through aux_bus. The eDP/DP controller driver should support aux transactions originating from the panel-edp driver and hence should be initialized and ready. The panel bridge supporting the panel should be ready before the bridge connector is initialized. The generic panel probe needs the controller resources to be enabled to support the aux transactions originating from the panel probe. Signed-off-by: Sankeerth Billakanti Reviewed-by: Douglas Anderson Reviewed-by: Stephen Boyd An additional side effect from this patch. Previously missing panel would have caused the bind error. Now it is the dp_modeset_init error, which translates to kms_hw_init returning -517. I kind ask to move the next_bridge acquisition back to the dp_bind in one of the followup patches. This is true. But the end result would be same isnt it? When dp_display_bind() failed earlier, it would cause master bind failure too due to component model. Even now, it causes the same result? Yes, it helped us to uncover several error. But I'd still prefer to have EPROBE_DEFER being returned earlier rather than later. Alright, point noted to try moving this earlier. We will be following this up with rounds of cleanups to implement the suggestions given by you and Doug earlier. This point shall be noted too. Thanks a lot. --- Changes in v10: - modify the error handling condition - modify the kernel doc Changes in v9: - add comments for panel probe - modify the error handling checks Changes in v8: - handle corner cases - add comment for the bridge ops Changes in v7: - aux_bus is mandatory for eDP - connector type check modified to just check for eDP Changes in v6: - Remove initialization - Fix aux_bus node leak - Split the patches drivers/gpu/drm/msm/dp/dp_display.c | 72 ++--- drivers/gpu/drm/msm/dp/dp_display.h | 1 + drivers/gpu/drm/msm/dp/dp_drm.c | 21 --- drivers/gpu/drm/msm/dp/dp_parser.c | 23 ++-- drivers/gpu/drm/msm/dp/dp_parser.h | 14 +++- 5 files changed, 101 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index d7a19d6..f772d84 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "msm_drv.h" #include "msm_kms.h" @@ -259,14 +260,12 @@ static int dp_display_bind(struct device *dev, struct device *master, dp->dp_display.drm_dev = drm; priv->dp[dp->id] = >dp_display; - rc = dp->parser->parse(dp->parser, dp->dp_display.connector_type); + rc = dp->parser->parse(dp->parser); if (rc) { DRM_ERROR("device tree parsing failed\n"); goto end; } - dp->dp_display.next_bridge = dp->parser->next_bridge; - dp->aux->drm_dev = drm; rc = dp_aux_register(dp->aux); if (rc) { @@ -1319,6 +1318,8 @@ static int dp_display_probe(struct platform_device *pdev) dp->pdev = pdev; dp->name = "drm_dp"; dp->dp_display.connector_type = desc->connector_type; + dp->dp_display.is_edp = + (dp->dp_display.connector_type == DRM_MODE_CONNECTOR_eDP); rc = dp_init_sub_modules(dp); if (rc) { @@ -1508,7 +1509,8 @@ void msm_dp_irq_postinstall(struct msm_dp *dp_display) dp_hpd_event_setup(dp); - dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 100); + if (!dp_display->is_edp) + dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 100); } void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor) @@ -1530,6 +1532,64 @@ void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor) } } +static int dp_display_get_next_bridge(struct msm_dp *dp) +{ + int rc; + struct dp_display_private *dp_priv; + struct device_node *aux_bus; + struct device *dev; + + dp_priv = container_of(dp, struct dp_display_private, dp_display); + dev = _priv->pdev->dev; + aux_bus = of_get_child_by_name(dev->of_node, "aux-bus"); + + if (aux_bus && dp->is_edp) { + dp_display_host_init(dp_priv); + dp_catalog_ctrl_hpd_config(dp_priv->catalog); + dp_display_host_phy_init(dp_priv); + enable_irq(dp_priv->irq); + + /* + * The code below assumes that the panel will finish probing + * by the time devm_of_dp_aux_populate_ep_devices() returns. + * This isn't a great assumption since it will fail if the + * panel driver is probed asynchronously but is the best we + * can do without a bigger driver reorganization. + */ + rc =
Re: [Freedreno] [PATCH v10 1/4] drm/msm/dp: Add eDP support via aux_bus
On 5/6/2022 2:05 PM, Dmitry Baryshkov wrote: On 07/05/2022 00:03, Abhinav Kumar wrote: On 5/6/2022 1:49 PM, Dmitry Baryshkov wrote: On 25/04/2022 14:44, Sankeerth Billakanti wrote: This patch adds support for generic eDP sink through aux_bus. The eDP/DP controller driver should support aux transactions originating from the panel-edp driver and hence should be initialized and ready. The panel bridge supporting the panel should be ready before the bridge connector is initialized. The generic panel probe needs the controller resources to be enabled to support the aux transactions originating from the panel probe. Signed-off-by: Sankeerth Billakanti Reviewed-by: Douglas Anderson Reviewed-by: Stephen Boyd An additional side effect from this patch. Previously missing panel would have caused the bind error. Now it is the dp_modeset_init error, which translates to kms_hw_init returning -517. I kind ask to move the next_bridge acquisition back to the dp_bind in one of the followup patches. This is true. But the end result would be same isnt it? When dp_display_bind() failed earlier, it would cause master bind failure too due to component model. Even now, it causes the same result? Yes, it helped us to uncover several error. But I'd still prefer to have EPROBE_DEFER being returned earlier rather than later. Alright, point noted to try moving this earlier. We will be following this up with rounds of cleanups to implement the suggestions given by you and Doug earlier. This point shall be noted too. --- Changes in v10: - modify the error handling condition - modify the kernel doc Changes in v9: - add comments for panel probe - modify the error handling checks Changes in v8: - handle corner cases - add comment for the bridge ops Changes in v7: - aux_bus is mandatory for eDP - connector type check modified to just check for eDP Changes in v6: - Remove initialization - Fix aux_bus node leak - Split the patches drivers/gpu/drm/msm/dp/dp_display.c | 72 ++--- drivers/gpu/drm/msm/dp/dp_display.h | 1 + drivers/gpu/drm/msm/dp/dp_drm.c | 21 --- drivers/gpu/drm/msm/dp/dp_parser.c | 23 ++-- drivers/gpu/drm/msm/dp/dp_parser.h | 14 +++- 5 files changed, 101 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index d7a19d6..f772d84 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "msm_drv.h" #include "msm_kms.h" @@ -259,14 +260,12 @@ static int dp_display_bind(struct device *dev, struct device *master, dp->dp_display.drm_dev = drm; priv->dp[dp->id] = >dp_display; - rc = dp->parser->parse(dp->parser, dp->dp_display.connector_type); + rc = dp->parser->parse(dp->parser); if (rc) { DRM_ERROR("device tree parsing failed\n"); goto end; } - dp->dp_display.next_bridge = dp->parser->next_bridge; - dp->aux->drm_dev = drm; rc = dp_aux_register(dp->aux); if (rc) { @@ -1319,6 +1318,8 @@ static int dp_display_probe(struct platform_device *pdev) dp->pdev = pdev; dp->name = "drm_dp"; dp->dp_display.connector_type = desc->connector_type; + dp->dp_display.is_edp = + (dp->dp_display.connector_type == DRM_MODE_CONNECTOR_eDP); rc = dp_init_sub_modules(dp); if (rc) { @@ -1508,7 +1509,8 @@ void msm_dp_irq_postinstall(struct msm_dp *dp_display) dp_hpd_event_setup(dp); - dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 100); + if (!dp_display->is_edp) + dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 100); } void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor) @@ -1530,6 +1532,64 @@ void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor) } } +static int dp_display_get_next_bridge(struct msm_dp *dp) +{ + int rc; + struct dp_display_private *dp_priv; + struct device_node *aux_bus; + struct device *dev; + + dp_priv = container_of(dp, struct dp_display_private, dp_display); + dev = _priv->pdev->dev; + aux_bus = of_get_child_by_name(dev->of_node, "aux-bus"); + + if (aux_bus && dp->is_edp) { + dp_display_host_init(dp_priv); + dp_catalog_ctrl_hpd_config(dp_priv->catalog); + dp_display_host_phy_init(dp_priv); + enable_irq(dp_priv->irq); + + /* + * The code below assumes that the panel will finish probing + * by the time devm_of_dp_aux_populate_ep_devices() returns. + * This isn't a great assumption since it will fail if the + * panel driver is probed asynchronously but is the best we + * can do without a bigger driver reorganization. + */ + rc = devm_of_dp_aux_populate_ep_devices(dp_priv->aux); + of_node_put(aux_bus); + if
Re: [PATCH] drm/nouveau/tegra: Stop using iommu_present()
Whoops! Was going through my unread emails and noticed I somehow missed this patch last month. Reviewed-by: Lyude Paul I will push this to drm-misc-fixes in a little bit (assuming I don't find it there already) On Tue, 2022-04-05 at 15:21 +0100, Robin Murphy wrote: > Even if some IOMMU has registered itself on the platform "bus", that > doesn't necessarily mean it provides translation for the device we > care about. Replace iommu_present() with a more appropriate check. > > Signed-off-by: Robin Murphy > --- > drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c > b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c > index 992cc285f2fe..2ed528c065fa 100644 > --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c > +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c > @@ -123,7 +123,7 @@ nvkm_device_tegra_probe_iommu(struct nvkm_device_tegra > *tdev) > > mutex_init(>iommu.mutex); > > - if (iommu_present(_bus_type)) { > + if (device_iommu_mapped(dev)) { > tdev->iommu.domain = iommu_domain_alloc(_bus_type); > if (!tdev->iommu.domain) > goto error; -- Cheers, Lyude Paul (she/her) Software Engineer at Red Hat
Re: [PATCH v10 1/4] drm/msm/dp: Add eDP support via aux_bus
On 07/05/2022 00:03, Abhinav Kumar wrote: On 5/6/2022 1:49 PM, Dmitry Baryshkov wrote: On 25/04/2022 14:44, Sankeerth Billakanti wrote: This patch adds support for generic eDP sink through aux_bus. The eDP/DP controller driver should support aux transactions originating from the panel-edp driver and hence should be initialized and ready. The panel bridge supporting the panel should be ready before the bridge connector is initialized. The generic panel probe needs the controller resources to be enabled to support the aux transactions originating from the panel probe. Signed-off-by: Sankeerth Billakanti Reviewed-by: Douglas Anderson Reviewed-by: Stephen Boyd An additional side effect from this patch. Previously missing panel would have caused the bind error. Now it is the dp_modeset_init error, which translates to kms_hw_init returning -517. I kind ask to move the next_bridge acquisition back to the dp_bind in one of the followup patches. This is true. But the end result would be same isnt it? When dp_display_bind() failed earlier, it would cause master bind failure too due to component model. Even now, it causes the same result? Yes, it helped us to uncover several error. But I'd still prefer to have EPROBE_DEFER being returned earlier rather than later. --- Changes in v10: - modify the error handling condition - modify the kernel doc Changes in v9: - add comments for panel probe - modify the error handling checks Changes in v8: - handle corner cases - add comment for the bridge ops Changes in v7: - aux_bus is mandatory for eDP - connector type check modified to just check for eDP Changes in v6: - Remove initialization - Fix aux_bus node leak - Split the patches drivers/gpu/drm/msm/dp/dp_display.c | 72 ++--- drivers/gpu/drm/msm/dp/dp_display.h | 1 + drivers/gpu/drm/msm/dp/dp_drm.c | 21 --- drivers/gpu/drm/msm/dp/dp_parser.c | 23 ++-- drivers/gpu/drm/msm/dp/dp_parser.h | 14 +++- 5 files changed, 101 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index d7a19d6..f772d84 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "msm_drv.h" #include "msm_kms.h" @@ -259,14 +260,12 @@ static int dp_display_bind(struct device *dev, struct device *master, dp->dp_display.drm_dev = drm; priv->dp[dp->id] = >dp_display; - rc = dp->parser->parse(dp->parser, dp->dp_display.connector_type); + rc = dp->parser->parse(dp->parser); if (rc) { DRM_ERROR("device tree parsing failed\n"); goto end; } - dp->dp_display.next_bridge = dp->parser->next_bridge; - dp->aux->drm_dev = drm; rc = dp_aux_register(dp->aux); if (rc) { @@ -1319,6 +1318,8 @@ static int dp_display_probe(struct platform_device *pdev) dp->pdev = pdev; dp->name = "drm_dp"; dp->dp_display.connector_type = desc->connector_type; + dp->dp_display.is_edp = + (dp->dp_display.connector_type == DRM_MODE_CONNECTOR_eDP); rc = dp_init_sub_modules(dp); if (rc) { @@ -1508,7 +1509,8 @@ void msm_dp_irq_postinstall(struct msm_dp *dp_display) dp_hpd_event_setup(dp); - dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 100); + if (!dp_display->is_edp) + dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 100); } void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor) @@ -1530,6 +1532,64 @@ void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor) } } +static int dp_display_get_next_bridge(struct msm_dp *dp) +{ + int rc; + struct dp_display_private *dp_priv; + struct device_node *aux_bus; + struct device *dev; + + dp_priv = container_of(dp, struct dp_display_private, dp_display); + dev = _priv->pdev->dev; + aux_bus = of_get_child_by_name(dev->of_node, "aux-bus"); + + if (aux_bus && dp->is_edp) { + dp_display_host_init(dp_priv); + dp_catalog_ctrl_hpd_config(dp_priv->catalog); + dp_display_host_phy_init(dp_priv); + enable_irq(dp_priv->irq); + + /* + * The code below assumes that the panel will finish probing + * by the time devm_of_dp_aux_populate_ep_devices() returns. + * This isn't a great assumption since it will fail if the + * panel driver is probed asynchronously but is the best we + * can do without a bigger driver reorganization. + */ + rc = devm_of_dp_aux_populate_ep_devices(dp_priv->aux); + of_node_put(aux_bus); + if (rc) + goto error; + } else if (dp->is_edp) { + DRM_ERROR("eDP aux_bus not found\n"); + return -ENODEV; + } + + /* + * External bridges are mandatory for eDP interfaces: one has to + * provide at least an eDP
Re: [PATCH v10 1/4] drm/msm/dp: Add eDP support via aux_bus
On 5/6/2022 1:49 PM, Dmitry Baryshkov wrote: On 25/04/2022 14:44, Sankeerth Billakanti wrote: This patch adds support for generic eDP sink through aux_bus. The eDP/DP controller driver should support aux transactions originating from the panel-edp driver and hence should be initialized and ready. The panel bridge supporting the panel should be ready before the bridge connector is initialized. The generic panel probe needs the controller resources to be enabled to support the aux transactions originating from the panel probe. Signed-off-by: Sankeerth Billakanti Reviewed-by: Douglas Anderson Reviewed-by: Stephen Boyd An additional side effect from this patch. Previously missing panel would have caused the bind error. Now it is the dp_modeset_init error, which translates to kms_hw_init returning -517. I kind ask to move the next_bridge acquisition back to the dp_bind in one of the followup patches. This is true. But the end result would be same isnt it? When dp_display_bind() failed earlier, it would cause master bind failure too due to component model. Even now, it causes the same result? --- Changes in v10: - modify the error handling condition - modify the kernel doc Changes in v9: - add comments for panel probe - modify the error handling checks Changes in v8: - handle corner cases - add comment for the bridge ops Changes in v7: - aux_bus is mandatory for eDP - connector type check modified to just check for eDP Changes in v6: - Remove initialization - Fix aux_bus node leak - Split the patches drivers/gpu/drm/msm/dp/dp_display.c | 72 ++--- drivers/gpu/drm/msm/dp/dp_display.h | 1 + drivers/gpu/drm/msm/dp/dp_drm.c | 21 --- drivers/gpu/drm/msm/dp/dp_parser.c | 23 ++-- drivers/gpu/drm/msm/dp/dp_parser.h | 14 +++- 5 files changed, 101 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index d7a19d6..f772d84 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "msm_drv.h" #include "msm_kms.h" @@ -259,14 +260,12 @@ static int dp_display_bind(struct device *dev, struct device *master, dp->dp_display.drm_dev = drm; priv->dp[dp->id] = >dp_display; - rc = dp->parser->parse(dp->parser, dp->dp_display.connector_type); + rc = dp->parser->parse(dp->parser); if (rc) { DRM_ERROR("device tree parsing failed\n"); goto end; } - dp->dp_display.next_bridge = dp->parser->next_bridge; - dp->aux->drm_dev = drm; rc = dp_aux_register(dp->aux); if (rc) { @@ -1319,6 +1318,8 @@ static int dp_display_probe(struct platform_device *pdev) dp->pdev = pdev; dp->name = "drm_dp"; dp->dp_display.connector_type = desc->connector_type; + dp->dp_display.is_edp = + (dp->dp_display.connector_type == DRM_MODE_CONNECTOR_eDP); rc = dp_init_sub_modules(dp); if (rc) { @@ -1508,7 +1509,8 @@ void msm_dp_irq_postinstall(struct msm_dp *dp_display) dp_hpd_event_setup(dp); - dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 100); + if (!dp_display->is_edp) + dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 100); } void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor) @@ -1530,6 +1532,64 @@ void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor) } } +static int dp_display_get_next_bridge(struct msm_dp *dp) +{ + int rc; + struct dp_display_private *dp_priv; + struct device_node *aux_bus; + struct device *dev; + + dp_priv = container_of(dp, struct dp_display_private, dp_display); + dev = _priv->pdev->dev; + aux_bus = of_get_child_by_name(dev->of_node, "aux-bus"); + + if (aux_bus && dp->is_edp) { + dp_display_host_init(dp_priv); + dp_catalog_ctrl_hpd_config(dp_priv->catalog); + dp_display_host_phy_init(dp_priv); + enable_irq(dp_priv->irq); + + /* + * The code below assumes that the panel will finish probing + * by the time devm_of_dp_aux_populate_ep_devices() returns. + * This isn't a great assumption since it will fail if the + * panel driver is probed asynchronously but is the best we + * can do without a bigger driver reorganization. + */ + rc = devm_of_dp_aux_populate_ep_devices(dp_priv->aux); + of_node_put(aux_bus); + if (rc) + goto error; + } else if (dp->is_edp) { + DRM_ERROR("eDP aux_bus not found\n"); + return -ENODEV; + } + + /* + * External bridges are mandatory for eDP interfaces: one has to + * provide at least an eDP panel (which gets wrapped into panel-bridge). + * + * For DisplayPort interfaces external bridges are optional, so + * silently ignore an error if one is not present
Re: [PATCH v10 1/4] drm/msm/dp: Add eDP support via aux_bus
On 25/04/2022 14:44, Sankeerth Billakanti wrote: This patch adds support for generic eDP sink through aux_bus. The eDP/DP controller driver should support aux transactions originating from the panel-edp driver and hence should be initialized and ready. The panel bridge supporting the panel should be ready before the bridge connector is initialized. The generic panel probe needs the controller resources to be enabled to support the aux transactions originating from the panel probe. Signed-off-by: Sankeerth Billakanti Reviewed-by: Douglas Anderson Reviewed-by: Stephen Boyd An additional side effect from this patch. Previously missing panel would have caused the bind error. Now it is the dp_modeset_init error, which translates to kms_hw_init returning -517. I kind ask to move the next_bridge acquisition back to the dp_bind in one of the followup patches. --- Changes in v10: - modify the error handling condition - modify the kernel doc Changes in v9: - add comments for panel probe - modify the error handling checks Changes in v8: - handle corner cases - add comment for the bridge ops Changes in v7: - aux_bus is mandatory for eDP - connector type check modified to just check for eDP Changes in v6: - Remove initialization - Fix aux_bus node leak - Split the patches drivers/gpu/drm/msm/dp/dp_display.c | 72 ++--- drivers/gpu/drm/msm/dp/dp_display.h | 1 + drivers/gpu/drm/msm/dp/dp_drm.c | 21 --- drivers/gpu/drm/msm/dp/dp_parser.c | 23 ++-- drivers/gpu/drm/msm/dp/dp_parser.h | 14 +++- 5 files changed, 101 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index d7a19d6..f772d84 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "msm_drv.h" #include "msm_kms.h" @@ -259,14 +260,12 @@ static int dp_display_bind(struct device *dev, struct device *master, dp->dp_display.drm_dev = drm; priv->dp[dp->id] = >dp_display; - rc = dp->parser->parse(dp->parser, dp->dp_display.connector_type); + rc = dp->parser->parse(dp->parser); if (rc) { DRM_ERROR("device tree parsing failed\n"); goto end; } - dp->dp_display.next_bridge = dp->parser->next_bridge; - dp->aux->drm_dev = drm; rc = dp_aux_register(dp->aux); if (rc) { @@ -1319,6 +1318,8 @@ static int dp_display_probe(struct platform_device *pdev) dp->pdev = pdev; dp->name = "drm_dp"; dp->dp_display.connector_type = desc->connector_type; + dp->dp_display.is_edp = + (dp->dp_display.connector_type == DRM_MODE_CONNECTOR_eDP); rc = dp_init_sub_modules(dp); if (rc) { @@ -1508,7 +1509,8 @@ void msm_dp_irq_postinstall(struct msm_dp *dp_display) dp_hpd_event_setup(dp); - dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 100); + if (!dp_display->is_edp) + dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 100); } void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor) @@ -1530,6 +1532,64 @@ void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor) } } +static int dp_display_get_next_bridge(struct msm_dp *dp) +{ + int rc; + struct dp_display_private *dp_priv; + struct device_node *aux_bus; + struct device *dev; + + dp_priv = container_of(dp, struct dp_display_private, dp_display); + dev = _priv->pdev->dev; + aux_bus = of_get_child_by_name(dev->of_node, "aux-bus"); + + if (aux_bus && dp->is_edp) { + dp_display_host_init(dp_priv); + dp_catalog_ctrl_hpd_config(dp_priv->catalog); + dp_display_host_phy_init(dp_priv); + enable_irq(dp_priv->irq); + + /* +* The code below assumes that the panel will finish probing +* by the time devm_of_dp_aux_populate_ep_devices() returns. +* This isn't a great assumption since it will fail if the +* panel driver is probed asynchronously but is the best we +* can do without a bigger driver reorganization. +*/ + rc = devm_of_dp_aux_populate_ep_devices(dp_priv->aux); + of_node_put(aux_bus); + if (rc) + goto error; + } else if (dp->is_edp) { + DRM_ERROR("eDP aux_bus not found\n"); + return -ENODEV; + } + + /* +* External bridges are mandatory for eDP interfaces: one has to +* provide at least an eDP panel (which gets wrapped into panel-bridge). +* +* For DisplayPort interfaces external bridges are optional, so +* silently ignore an error if one is not present (-ENODEV). +
Re: [PATCH 09/25] drm/msm/dpu: dpu_crtc_blend_setup: split mixer and ctl logic
On 06/05/2022 21:56, Abhinav Kumar wrote: On 2/9/2022 9:25 AM, Dmitry Baryshkov wrote: The funcitons _dpu_crtc_blend_setup() and _dpu_crtc_blend_setup_mixer() have an intertwined mixture of CTL and LM-related code. Split these two functions into LM-specific and CTL-specific parts, making both code paths clean and observable. I do see the intention of this change, but there are two things to consider here. Let me know what you think of those: 1) Agreed that we are able to split it out but at what cost? We are repeating some of the loops such as a) for (i = 0; i < cstate->num_mixers; i++) { b) drm_atomic_crtc_for_each_plane( Maybe we should invert these loops, so that we'll through the planes and only then loop over the mixers. 2) The intertwining is "somewhat" logical here because we are programming the LMs for which we are staging the planes so it somewhat goes together I'll revisit this for v2. I'll move this towards the end of the series, so it would be more obvious if patch 25/25 is better with this change or w/o it. 3) dropping sspp idx from this trace removes some useful informatio of which sspp is staged to which stage of blend I can add this back to the dpu_crtc_blend_setup_ctl > trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane), > state, pstate, stage_idx, > - sspp_idx - SSPP_VIG0, > format->base.pixel_format, > fb ? fb->modifier : 0); Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 101 +- drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h | 10 +-- 2 files changed, 63 insertions(+), 48 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index e6c33022d560..ada7d5750536 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -336,27 +336,23 @@ static void _dpu_crtc_program_lm_output_roi(struct drm_crtc *crtc) } } -static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc, - struct dpu_crtc *dpu_crtc, struct dpu_crtc_mixer *mixer, - struct dpu_hw_stage_cfg *stage_cfg) +static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc) { + struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state); + struct dpu_crtc_mixer *mixer = cstate->mixers; struct drm_plane *plane; struct drm_framebuffer *fb; struct drm_plane_state *state; - struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state); struct dpu_plane_state *pstate = NULL; struct dpu_format *format; - struct dpu_hw_ctl *ctl = mixer->lm_ctl; - + int i; uint32_t stage_idx, lm_idx; - int zpos_cnt[DPU_STAGE_MAX + 1] = { 0 }; bool bg_alpha_enable = false; - DECLARE_BITMAP(fetch_active, SSPP_MAX); - memset(fetch_active, 0, sizeof(fetch_active)); - drm_atomic_crtc_for_each_plane(plane, crtc) { - enum dpu_sspp sspp_idx; + for (i = 0; i < cstate->num_mixers; i++) + mixer[i].mixer_op_mode = 0; + drm_atomic_crtc_for_each_plane(plane, crtc) { state = plane->state; if (!state) continue; @@ -364,14 +360,10 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc, pstate = to_dpu_plane_state(state); fb = state->fb; - sspp_idx = pstate->pipe_hw->idx; - set_bit(sspp_idx, fetch_active); - - DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n", + DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d fb %d\n", crtc->base.id, pstate->stage, plane->base.id, - sspp_idx - SSPP_VIG0, state->fb ? state->fb->base.id : -1); format = to_dpu_format(msm_framebuffer_format(pstate->base.fb)); @@ -379,15 +371,8 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc, if (pstate->stage == DPU_STAGE_BASE && format->alpha_enable) bg_alpha_enable = true; - stage_idx = zpos_cnt[pstate->stage]++; - stage_cfg->stage[pstate->stage][stage_idx] = - sspp_idx; - stage_cfg->multirect_index[pstate->stage][stage_idx] = - pstate->multirect_index; - trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane), state, pstate, stage_idx, - sspp_idx - SSPP_VIG0, format->base.pixel_format, fb ? fb->modifier : 0); @@ -396,8 +381,6 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc, _dpu_crtc_setup_blend_cfg(mixer + lm_idx, pstate, format); - mixer[lm_idx].lm_ctl->ops.update_pending_flush_sspp(mixer[lm_idx].lm_ctl, sspp_idx); - if (bg_alpha_enable && !format->alpha_enable) mixer[lm_idx].mixer_op_mode
Re: [PATCH 09/25] drm/msm/dpu: dpu_crtc_blend_setup: split mixer and ctl logic
On 2/9/2022 9:25 AM, Dmitry Baryshkov wrote: The funcitons _dpu_crtc_blend_setup() and _dpu_crtc_blend_setup_mixer() have an intertwined mixture of CTL and LM-related code. Split these two functions into LM-specific and CTL-specific parts, making both code paths clean and observable. I do see the intention of this change, but there are two things to consider here. Let me know what you think of those: 1) Agreed that we are able to split it out but at what cost? We are repeating some of the loops such as a) for (i = 0; i < cstate->num_mixers; i++) { b) drm_atomic_crtc_for_each_plane( 2) The intertwining is "somewhat" logical here because we are programming the LMs for which we are staging the planes so it somewhat goes together 3) dropping sspp idx from this trace removes some useful informatio of which sspp is staged to which stage of blend >trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane), > state, pstate, stage_idx, > - sspp_idx - SSPP_VIG0, > format->base.pixel_format, > fb ? fb->modifier : 0); Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 101 +- drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h | 10 +-- 2 files changed, 63 insertions(+), 48 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index e6c33022d560..ada7d5750536 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -336,27 +336,23 @@ static void _dpu_crtc_program_lm_output_roi(struct drm_crtc *crtc) } } -static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc, - struct dpu_crtc *dpu_crtc, struct dpu_crtc_mixer *mixer, - struct dpu_hw_stage_cfg *stage_cfg) +static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc) { + struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state); + struct dpu_crtc_mixer *mixer = cstate->mixers; struct drm_plane *plane; struct drm_framebuffer *fb; struct drm_plane_state *state; - struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state); struct dpu_plane_state *pstate = NULL; struct dpu_format *format; - struct dpu_hw_ctl *ctl = mixer->lm_ctl; - + int i; uint32_t stage_idx, lm_idx; - int zpos_cnt[DPU_STAGE_MAX + 1] = { 0 }; bool bg_alpha_enable = false; - DECLARE_BITMAP(fetch_active, SSPP_MAX); - memset(fetch_active, 0, sizeof(fetch_active)); - drm_atomic_crtc_for_each_plane(plane, crtc) { - enum dpu_sspp sspp_idx; + for (i = 0; i < cstate->num_mixers; i++) + mixer[i].mixer_op_mode = 0; + drm_atomic_crtc_for_each_plane(plane, crtc) { state = plane->state; if (!state) continue; @@ -364,14 +360,10 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc, pstate = to_dpu_plane_state(state); fb = state->fb; - sspp_idx = pstate->pipe_hw->idx; - set_bit(sspp_idx, fetch_active); - - DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n", + DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d fb %d\n", crtc->base.id, pstate->stage, plane->base.id, - sspp_idx - SSPP_VIG0, state->fb ? state->fb->base.id : -1); format = to_dpu_format(msm_framebuffer_format(pstate->base.fb)); @@ -379,15 +371,8 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc, if (pstate->stage == DPU_STAGE_BASE && format->alpha_enable) bg_alpha_enable = true; - stage_idx = zpos_cnt[pstate->stage]++; - stage_cfg->stage[pstate->stage][stage_idx] = - sspp_idx; - stage_cfg->multirect_index[pstate->stage][stage_idx] = - pstate->multirect_index; - trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane), state, pstate, stage_idx, - sspp_idx - SSPP_VIG0, format->base.pixel_format, fb ? fb->modifier : 0); @@ -396,8 +381,6 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc, _dpu_crtc_setup_blend_cfg(mixer + lm_idx, pstate, format); - mixer[lm_idx].lm_ctl->ops.update_pending_flush_sspp(mixer[lm_idx].lm_ctl, sspp_idx); - if (bg_alpha_enable &&
[PATCH v0.5 6/9] phy: freescale: add Samsung HDMI PHY
This adds the driver for the Samsung HDMI PHY found on the i.MX8MP SoC. Signed-off-by: Lucas Stach --- drivers/phy/freescale/Kconfig|6 + drivers/phy/freescale/Makefile |1 + drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 1078 ++ 3 files changed, 1085 insertions(+) create mode 100644 drivers/phy/freescale/phy-fsl-samsung-hdmi.c diff --git a/drivers/phy/freescale/Kconfig b/drivers/phy/freescale/Kconfig index f9c54cd02036..e88cc2212370 100644 --- a/drivers/phy/freescale/Kconfig +++ b/drivers/phy/freescale/Kconfig @@ -26,6 +26,12 @@ config PHY_FSL_IMX8M_PCIE Enable this to add support for the PCIE PHY as found on i.MX8M family of SOCs. +config PHY_FSL_SAMSUNG_HDMI_PHY + tristate "Samsung HDMI PHY support" + depends on OF && HAS_IOMEM + help + Enable this to add support for the Samsung HDMI PHY in i.MX8MP. + endif config PHY_FSL_LYNX_28G diff --git a/drivers/phy/freescale/Makefile b/drivers/phy/freescale/Makefile index 3518d5dbe8a7..46a26929376d 100644 --- a/drivers/phy/freescale/Makefile +++ b/drivers/phy/freescale/Makefile @@ -2,4 +2,5 @@ obj-$(CONFIG_PHY_FSL_IMX8MQ_USB) += phy-fsl-imx8mq-usb.o obj-$(CONFIG_PHY_MIXEL_MIPI_DPHY) += phy-fsl-imx8-mipi-dphy.o obj-$(CONFIG_PHY_FSL_IMX8M_PCIE) += phy-fsl-imx8m-pcie.o +obj-$(CONFIG_PHY_FSL_SAMSUNG_HDMI_PHY) += phy-fsl-samsung-hdmi.o obj-$(CONFIG_PHY_FSL_LYNX_28G) += phy-fsl-lynx-28g.o diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c new file mode 100644 index ..6d20a5ce44e6 --- /dev/null +++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c @@ -0,0 +1,1078 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2020 NXP + * Copyright 2022 Pengutronix, Lucas Stach + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define HDMI_TX_CONTROL0 0x200 +#define HDMI_TX_CONTROL_PHY_PWRDWNBIT(3) + +#define PHY_REG_33 0x84 +#define REG33_MODE_SET_DONE BIT(7) +#define REG33_FIX_DA BIT(1) + +#define PHY_REG_34 0x88 +#define REG34_PHY_READY BIT(7) +#define REG34_PLL_LOCKBIT(6) +#define REG34_PHY_CLK_READY BIT(5) + + +#define PHY_PLL_REGS_NUM 48 + +struct phy_config { + u32 clk_rate; + u8 regs[PHY_PLL_REGS_NUM]; +}; + +const struct phy_config phy_pll_cfg[] = { + { 2225, { + 0x00, 0xD1, 0x4B, 0xF1, 0x89, 0x88, 0x80, 0x40, + 0x4F, 0x30, 0x33, 0x65, 0x00, 0x15, 0x25, 0x80, + 0x6C, 0xF2, 0x67, 0x00, 0x10, 0x8F, 0x30, 0x32, + 0x60, 0x8F, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xE0, 0x83, 0x0F, 0x3E, 0xF8, 0x00, 0x00, + }, + }, { + 2375, { + 0x00, 0xD1, 0x50, 0xF1, 0x86, 0x85, 0x80, 0x40, + 0x4F, 0x30, 0x33, 0x65, 0x00, 0x03, 0x25, 0x80, + 0x6C, 0xF2, 0x67, 0x00, 0x10, 0x8F, 0x30, 0x32, + 0x60, 0x8F, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xE0, 0x83, 0x0F, 0x3E, 0xF8, 0x00, 0x00, + }, + },{ + 2400, { + 0x00, 0xD1, 0x50, 0xF0, 0x00, 0x00, 0x80, 0x00, + 0x4F, 0x30, 0x33, 0x65, 0x00, 0x01, 0x25, 0x80, + 0x6C, 0xF2, 0x67, 0x00, 0x10, 0x8F, 0x30, 0x32, + 0x60, 0x8F, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xE0, 0x83, 0x0F, 0x3E, 0xF8, 0x00, 0x00, + }, + },{ + 24024000, { + 0x00, 0xD1, 0x50, 0xF1, 0x99, 0x02, 0x80, 0x40, + 0x4F, 0x30, 0x33, 0x65, 0x00, 0x00, 0x25, 0x80, + 0x6C, 0xF2, 0x67, 0x00, 0x10, 0x8F, 0x30, 0x32, + 0x60, 0x8F, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xE0, 0x83, 0x0F, 0x3E, 0xF8, 0x00, 0x00, + }, + }, { + 25175000, { + 0x00, 0xD1, 0x54, 0xFC, 0xCC, 0x91, 0x80, 0x40, + 0x4F, 0x30, 0x33, 0x65, 0x00, 0xF5, 0x24, 0x80, + 0x6C, 0xF2, 0x67, 0x00, 0x10, 0x8F, 0x30, 0x32, + 0x60, 0x8F, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xE0, 0x83, 0x0F, 0x3E, 0xF8, 0x00, 0x00, + }, + }, { + 2520, { +
[PATCH v0.5 9/9] arm64: dts: imx8mp-evk: enable HDMI
Enable the DT nodes for HDMI TX and PHY and add the pinctrl for the few involved pins that are configurable. Signed-off-by: Lucas Stach --- arch/arm64/boot/dts/freescale/imx8mp-evk.dts | 19 +++ 1 file changed, 19 insertions(+) diff --git a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts index 4c3ac4214a2c..fdf851865ba9 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts @@ -197,6 +197,16 @@ ethphy1: ethernet-phy@1 { }; }; +_tx { + pinctrl-names = "default"; + pinctrl-0 = <_hdmi>; + status = "okay"; +}; + +_tx_phy { + status = "okay"; +}; + { clock-frequency = <40>; pinctrl-names = "default"; @@ -465,6 +475,15 @@ MX8MP_IOMUXC_NAND_READY_B__GPIO3_IO16 0x19 >; }; + pinctrl_hdmi: hdmigrp { + fsl,pins = < + MX8MP_IOMUXC_HDMI_DDC_SCL__HDMIMIX_HDMI_SCL 0x1c3 + MX8MP_IOMUXC_HDMI_DDC_SDA__HDMIMIX_HDMI_SDA 0x1c3 + MX8MP_IOMUXC_HDMI_HPD__HDMIMIX_HDMI_HPD 0x19 + MX8MP_IOMUXC_HDMI_CEC__HDMIMIX_HDMI_CEC 0x19 + >; + }; + pinctrl_i2c1: i2c1grp { fsl,pins = < MX8MP_IOMUXC_I2C1_SCL__I2C1_SCL 0x41c3 -- 2.30.2
[PATCH v0.5 4/9] drm/imx: add driver for HDMI TX Parallel Video Interface
This IP block is found in the HDMI subsystem of the i.MX8MP SoC. It has a full timing generator and can switch between different video sources. On the i.MX8MP however the only supported source is the LCDIF. The block just needs to be powered up and told about the polarity of the video sync signals to act in bypass mode. Signed-off-by: Lucas Stach --- drivers/gpu/drm/imx/bridge/Kconfig| 8 + drivers/gpu/drm/imx/bridge/Makefile | 1 + drivers/gpu/drm/imx/bridge/imx-hdmi-pvi.c | 201 ++ 3 files changed, 210 insertions(+) create mode 100644 drivers/gpu/drm/imx/bridge/imx-hdmi-pvi.c diff --git a/drivers/gpu/drm/imx/bridge/Kconfig b/drivers/gpu/drm/imx/bridge/Kconfig index d63a09ca63dd..1f74f73c790e 100644 --- a/drivers/gpu/drm/imx/bridge/Kconfig +++ b/drivers/gpu/drm/imx/bridge/Kconfig @@ -8,3 +8,11 @@ config DRM_IMX_DW_HDMI_BRIDGE help Enable support for the internal HDMI encoder on i.MX8MP SoC +config DRM_IMX_HDMI_PVI + tristate "i.MX8MP HDMI PVI bridge support" + depends on (ARCH_MXC && ARM64) || COMPILE_TEST + depends on DRM && OF + help + Enable support for the internal HDMI TX Parallel Video Interface + found on the i.MX8MP SoC. + diff --git a/drivers/gpu/drm/imx/bridge/Makefile b/drivers/gpu/drm/imx/bridge/Makefile index 1cfe9623c0d8..512ea98722b8 100644 --- a/drivers/gpu/drm/imx/bridge/Makefile +++ b/drivers/gpu/drm/imx/bridge/Makefile @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_DRM_IMX_DW_HDMI_BRIDGE) += imx-hdmi.o +obj-$(CONFIG_DRM_IMX_HDMI_PVI) += imx-hdmi-pvi.o diff --git a/drivers/gpu/drm/imx/bridge/imx-hdmi-pvi.c b/drivers/gpu/drm/imx/bridge/imx-hdmi-pvi.c new file mode 100644 index ..962779dc539e --- /dev/null +++ b/drivers/gpu/drm/imx/bridge/imx-hdmi-pvi.c @@ -0,0 +1,201 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/* + * Copyright (C) 2022 Pengutronix, Lucas Stach + */ + +#include +#include +#include +#include +#include +#include +#include + +#define HTX_PVI_CTL0x0 +#define PVI_CTL_OP_VSYNC_POL BIT(18) +#define PVI_CTL_OP_HSYNC_POL BIT(17) +#define PVI_CTL_OP_DE_POL BIT(16) +#define PVI_CTL_INP_VSYNC_POL BIT(14) +#define PVI_CTL_INP_HSYNC_POL BIT(13) +#define PVI_CTL_INP_DE_POLBIT(12) +#define PVI_CTL_INPUT_LCDIF BIT(2) +#define PVI_CTL_ENBIT(0) + +struct imx_hdmi_pvi { + struct drm_bridge bridge; + struct device *dev; + struct drm_bridge *next_bridge; + void __iomem*regs; +}; + +static inline struct imx_hdmi_pvi * +to_imx_hdmi_pvi(struct drm_bridge *bridge) +{ + return container_of(bridge, struct imx_hdmi_pvi, bridge); +} + +static int imx_hdmi_pvi_bridge_attach(struct drm_bridge *bridge, + enum drm_bridge_attach_flags flags) +{ + struct imx_hdmi_pvi *pvi = to_imx_hdmi_pvi(bridge); + + return drm_bridge_attach(bridge->encoder, pvi->next_bridge, bridge, flags); +} + +static void imx_hdmi_pvi_bridge_enable(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state) +{ + struct drm_atomic_state *state = bridge_state->base.state; + struct imx_hdmi_pvi *pvi = to_imx_hdmi_pvi(bridge); + struct drm_connector_state *conn_state; + const struct drm_display_mode *mode; + struct drm_crtc_state *crtc_state; + struct drm_connector *connector; + u32 bus_flags, val; + + connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder); + conn_state = drm_atomic_get_new_connector_state(state, connector); + crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc); + + if (WARN_ON(pm_runtime_resume_and_get(pvi->dev))) + return; + + mode = _state->adjusted_mode; + + val = PVI_CTL_INPUT_LCDIF; + + if (mode->flags & DRM_MODE_FLAG_PVSYNC) + val |= PVI_CTL_OP_VSYNC_POL | PVI_CTL_INP_VSYNC_POL; + + if (mode->flags & DRM_MODE_FLAG_PHSYNC) + val |= PVI_CTL_OP_HSYNC_POL | PVI_CTL_INP_HSYNC_POL; + + if (pvi->next_bridge->timings) + bus_flags = pvi->next_bridge->timings->input_bus_flags; + else if (bridge_state) + bus_flags = bridge_state->input_bus_cfg.flags; + + if (bus_flags & DRM_BUS_FLAG_DE_HIGH) + val |= PVI_CTL_OP_DE_POL | PVI_CTL_INP_DE_POL; + + writel(val, pvi->regs + HTX_PVI_CTL); + val |= PVI_CTL_EN; + writel(val, pvi->regs + HTX_PVI_CTL); +} + +static void imx_hdmi_pvi_bridge_disable(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state) +{ + struct imx_hdmi_pvi *pvi = to_imx_hdmi_pvi(bridge); + + writel(0x0, pvi->regs + HTX_PVI_CTL); + + pm_runtime_put(pvi->dev); +} + +static u32 *pvi_bridge_get_input_bus_fmts(struct drm_bridge *bridge, +
[PATCH v0.5 7/9] arm64: dts: imx8mp: add HDMI irqsteer
The HDMI irqsteer is a secondary interrupt controller within the HDMI subsystem that maps all HDMI peripheral IRQs into a single upstream IRQ line. Signed-off-by: Lucas Stach --- arch/arm64/boot/dts/freescale/imx8mp.dtsi | 13 + 1 file changed, 13 insertions(+) diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi index d33794bcdc15..6fcbfe9d59b8 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi @@ -,6 +,19 @@ hdmi_blk_ctrl: blk-ctrl@32fc { "hdmi-tx", "hdmi-tx-phy"; #power-domain-cells = <1>; }; + + irqsteer_hdmi: interrupt-controller@32fc2000 { + compatible = "fsl,imx-irqsteer"; + reg = <0x32fc2000 0x44>; + interrupts = ; + interrupt-controller; + #interrupt-cells = <1>; + fsl,channel = <1>; + fsl,num-irqs = <64>; + clocks = < IMX8MP_CLK_HDMI_APB>; + clock-names = "ipg"; + power-domains = <_blk_ctrl IMX8MP_HDMIBLK_PD_IRQSTEER>; + }; }; gpu3d: gpu@3800 { -- 2.30.2
[PATCH v0.5 8/9] arm64: dts: imx8mp: add HDMI display pipeline
This adds the DT nodes for all the peripherals that make up the HDMI display pipeline. Signed-off-by: Lucas Stach --- arch/arm64/boot/dts/freescale/imx8mp.dtsi | 81 +++ 1 file changed, 81 insertions(+) diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi index 6fcbfe9d59b8..47173ece95a5 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi @@ -1124,6 +1124,87 @@ irqsteer_hdmi: interrupt-controller@32fc2000 { clock-names = "ipg"; power-domains = <_blk_ctrl IMX8MP_HDMIBLK_PD_IRQSTEER>; }; + + hdmi_pvi: display-bridge@32fc4000 { + compatible = "fsl,imx8mp-hdmi-pvi"; + reg = <0x32fc4000 0x40>; + power-domains = <_blk_ctrl IMX8MP_HDMIBLK_PD_PVI>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + pvi_from_lcdif3: endpoint { + remote-endpoint = <_to_pvi>; + }; + }; + + port@1 { + reg = <1>; + pvi_to_hdmi_tx: endpoint { + remote-endpoint = <_tx_from_pvi>; + }; + }; + }; + }; + + lcdif3: display-controller@32fc6000 { + compatible = "fsl,imx8mp-lcdif"; + reg = <0x32fc6000 0x238>; + interrupts = <8 IRQ_TYPE_LEVEL_HIGH>; + interrupt-parent = <_hdmi>; + clocks = <_tx_phy>, +< IMX8MP_CLK_HDMI_APB>, +< IMX8MP_CLK_HDMI_ROOT>; + clock-names = "pix", "axi", "disp_axi"; + power-domains = <_blk_ctrl IMX8MP_HDMIBLK_PD_LCDIF>; + + port { + lcdif3_to_pvi: endpoint { + remote-endpoint = <_from_lcdif3>; + }; + }; + }; + + hdmi_tx: hdmi@32fd8000 { + compatible = "fsl,imx8mp-hdmi"; + reg = <0x32fd8000 0x7eff>; + interrupts = <0 IRQ_TYPE_LEVEL_HIGH>; + interrupt-parent = <_hdmi>; + clocks = < IMX8MP_CLK_HDMI_APB>, +< IMX8MP_CLK_HDMI_REF_266M>, +< IMX8MP_CLK_HDMI_FDCC_TST>, +< IMX8MP_CLK_32K>, +<_tx_phy>; + clock-names = "iahb", "isfr", "fdcc", "cec", "pix"; + assigned-clocks = < IMX8MP_CLK_HDMI_REF_266M>; + assigned-clock-parents = < IMX8MP_SYS_PLL1_266M>; + power-domains = <_blk_ctrl IMX8MP_HDMIBLK_PD_HDMI_TX>; + reg-io-width = <1>; + status = "disabled"; + + port { + hdmi_tx_from_pvi: endpoint { + remote-endpoint = <_to_hdmi_tx>; + }; + }; + }; + + hdmi_tx_phy: phy@32fdff00 { + compatible = "fsl,imx8mp-hdmi-phy"; + reg = <0x32fdff00 0x100>; + clocks = < IMX8MP_CLK_HDMI_APB>, +< IMX8MP_CLK_HDMI_24M>; + clock-names = "apb", "ref"; + assigned-clocks = < IMX8MP_CLK_HDMI_24M>; + assigned-clock-parents = < IMX8MP_CLK_24M>; + power-domains = <_blk_ctrl IMX8MP_HDMIBLK_PD_HDMI_TX_PHY>; + #clock-cells = <0>; + #phy-cells = <0>; + status
[PATCH v0.5 5/9] dt-bindings: phy: add binding for the i.MX8MP HDMI PHY
Add a DT binding for the HDMI PHY found on the i.MX8MP SoC. Signed-off-by: Lucas Stach --- .../bindings/phy/fsl,imx8mp-hdmi-phy.yaml | 62 +++ 1 file changed, 62 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/fsl,imx8mp-hdmi-phy.yaml diff --git a/Documentation/devicetree/bindings/phy/fsl,imx8mp-hdmi-phy.yaml b/Documentation/devicetree/bindings/phy/fsl,imx8mp-hdmi-phy.yaml new file mode 100644 index ..bc21c073e92a --- /dev/null +++ b/Documentation/devicetree/bindings/phy/fsl,imx8mp-hdmi-phy.yaml @@ -0,0 +1,62 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/phy/fsl,imx8mp-hdmi-phy.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Freescale i.MX8MP HDMI PHY binding + +maintainers: + - Lucas Stach + +properties: + compatible: +enum: + - fsl,imx8mp-hdmi-phy + + reg: +maxItems: 1 + + "#clock-cells": +const: 0 + + clocks: +minItems: 2 +maxItems: 2 + + clock-names: +items: + - const: apb + - const: ref + + "#phy-cells": +const: 0 + + power-domains: +maxItems: 1 + +required: + - compatible + - reg + - "#clock-cells" + - clocks + - clock-names + - power-domains + +additionalProperties: false + +examples: + - | +#include +#include + +phy@32fdff00 { +compatible = "fsl,imx8mp-hdmi-phy"; +reg = <0x32fdff00 0x100>; +clocks = < IMX8MP_CLK_HDMI_APB>, + < IMX8MP_CLK_HDMI_24M>; +clock-names = "apb", "ref"; +power-domains = <_blk_ctrl IMX8MP_HDMIBLK_PD_HDMI_TX_PHY>; +#clock-cells = <0>; +#phy-cells = <0>; +}; -- 2.30.2
[PATCH v0.5 3/9] dt-bindings: display: imx: add binding for i.MX8MP HDMI PVI
Add binding for the i.MX8MP HDMI parallel video interface block. Signed-off-by: Lucas Stach --- .../display/imx/fsl,imx8mp-hdmi-pvi.yaml | 83 +++ 1 file changed, 83 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8mp-hdmi-pvi.yaml diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8mp-hdmi-pvi.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8mp-hdmi-pvi.yaml new file mode 100644 index ..bf25d29c03ab --- /dev/null +++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8mp-hdmi-pvi.yaml @@ -0,0 +1,83 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/imx/fsl,imx8mp-hdmi-pvi.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Freescale i.MX8MP HDMI Parallel Video Interface + +maintainers: + - Lucas Stach + +description: | + The HDMI parallel video interface is timing and sync generator block in the + i.MX8MP SoC, that sits between the video source and the HDMI TX controller. + +properties: + compatible: +enum: + - fsl,imx8mp-hdmi-pvi + + reg: +maxItems: 1 + + power-domains: +maxItems: 1 + + ports: +$ref: /schemas/graph.yaml#/properties/ports +description: | + This device has two video ports. + +properties: + port@0: +$ref: /schemas/graph.yaml#/properties/port +description: Input from the LCDIF controller. + + port@1: +$ref: /schemas/graph.yaml#/properties/port +description: Output to the HDMI TX controller + +anyOf: + - required: + - port@0 + - required: + - port@1 + +required: + - compatible + - reg + - power-domains + - ports + +additionalProperties: false + +examples: + - | +#include +#include + +display-bridge@32fc4000 { +compatible = "fsl,imx8mp-hdmi-pvi"; +reg = <0x32fc4000 0x40>; +power-domains = <_blk_ctrl IMX8MP_HDMIBLK_PD_PVI>; + +ports { +#address-cells = <1>; +#size-cells = <0>; + +port@0 { +reg = <0>; +pvi_from_lcdif3: endpoint { +remote-endpoint = <_to_pvi>; +}; +}; + +port@1 { +reg = <1>; +pvi_to_hdmi_tx: endpoint { +remote-endpoint = <_tx_from_pvi>; +}; +}; +}; +}; -- 2.30.2
[PATCH v0.5 2/9] drm/imx: add bridge wrapper driver for i.MX8MP DWC HDMI
Add a simple wrapper driver for the DWC HDMI bridge driver that implements the few bits that are necessary to abstract the i.MX8MP SoC integration. Signed-off-by: Lucas Stach --- drivers/gpu/drm/imx/Kconfig | 1 + drivers/gpu/drm/imx/Makefile | 2 + drivers/gpu/drm/imx/bridge/Kconfig| 10 ++ drivers/gpu/drm/imx/bridge/Makefile | 3 + drivers/gpu/drm/imx/bridge/imx-hdmi.c | 141 ++ 5 files changed, 157 insertions(+) create mode 100644 drivers/gpu/drm/imx/bridge/Kconfig create mode 100644 drivers/gpu/drm/imx/bridge/Makefile create mode 100644 drivers/gpu/drm/imx/bridge/imx-hdmi.c diff --git a/drivers/gpu/drm/imx/Kconfig b/drivers/gpu/drm/imx/Kconfig index bb9738c7c825..88b054c095c6 100644 --- a/drivers/gpu/drm/imx/Kconfig +++ b/drivers/gpu/drm/imx/Kconfig @@ -42,3 +42,4 @@ config DRM_IMX_HDMI Choose this if you want to use HDMI on i.MX6. source "drivers/gpu/drm/imx/dcss/Kconfig" +source "drivers/gpu/drm/imx/bridge/Kconfig" diff --git a/drivers/gpu/drm/imx/Makefile b/drivers/gpu/drm/imx/Makefile index b644deffe948..861403d11af6 100644 --- a/drivers/gpu/drm/imx/Makefile +++ b/drivers/gpu/drm/imx/Makefile @@ -10,3 +10,5 @@ obj-$(CONFIG_DRM_IMX_LDB) += imx-ldb.o obj-$(CONFIG_DRM_IMX_HDMI) += dw_hdmi-imx.o obj-$(CONFIG_DRM_IMX_DCSS) += dcss/ + +obj-y += bridge/ diff --git a/drivers/gpu/drm/imx/bridge/Kconfig b/drivers/gpu/drm/imx/bridge/Kconfig new file mode 100644 index ..d63a09ca63dd --- /dev/null +++ b/drivers/gpu/drm/imx/bridge/Kconfig @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0 + +config DRM_IMX_DW_HDMI_BRIDGE + tristate "i.MX8MP HDMI bridge support" + depends on (ARCH_MXC && ARM64) || COMPILE_TEST + depends on DRM && OF + select DRM_DW_HDMI + help + Enable support for the internal HDMI encoder on i.MX8MP SoC + diff --git a/drivers/gpu/drm/imx/bridge/Makefile b/drivers/gpu/drm/imx/bridge/Makefile new file mode 100644 index ..1cfe9623c0d8 --- /dev/null +++ b/drivers/gpu/drm/imx/bridge/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_DRM_IMX_DW_HDMI_BRIDGE) += imx-hdmi.o diff --git a/drivers/gpu/drm/imx/bridge/imx-hdmi.c b/drivers/gpu/drm/imx/bridge/imx-hdmi.c new file mode 100644 index ..66089bc690c8 --- /dev/null +++ b/drivers/gpu/drm/imx/bridge/imx-hdmi.c @@ -0,0 +1,141 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/* + * Copyright (C) 2022 Pengutronix, Lucas Stach + */ + +#include +#include +#include +#include +#include +#include + +struct imx_hdmi { + struct dw_hdmi_plat_data plat_data; + struct dw_hdmi *dw_hdmi; + struct clk *pixclk; + struct clk *fdcc; +}; + +static enum drm_mode_status +imx8mp_hdmi_mode_valid(struct dw_hdmi *dw_hdmi, void *data, + const struct drm_display_info *info, + const struct drm_display_mode *mode) +{ + struct imx_hdmi *hdmi = (struct imx_hdmi *)data; + + if (mode->clock < 13500) + return MODE_CLOCK_LOW; + + if (mode->clock > 297000) + return MODE_CLOCK_HIGH; + + if (clk_round_rate(hdmi->pixclk, mode->clock * 1000) != + mode->clock * 1000) + return MODE_CLOCK_RANGE; + + /* We don't support double-clocked and Interlaced modes */ + if ((mode->flags & DRM_MODE_FLAG_DBLCLK) || + (mode->flags & DRM_MODE_FLAG_INTERLACE)) + return MODE_BAD; + + return MODE_OK; +} + +static int imx8mp_hdmi_phy_init(struct dw_hdmi *dw_hdmi, void *data, + const struct drm_display_info *display, + const struct drm_display_mode *mode) +{ + return 0; +} + +static void imx8mp_hdmi_phy_disable(struct dw_hdmi *dw_hdmi, void *data) +{ +} + +static const struct dw_hdmi_phy_ops imx8mp_hdmi_phy_ops = { + .init = imx8mp_hdmi_phy_init, + .disable= imx8mp_hdmi_phy_disable, + .read_hpd = dw_hdmi_phy_read_hpd, + .update_hpd = dw_hdmi_phy_update_hpd, + .setup_hpd = dw_hdmi_phy_setup_hpd, +}; + +static int imx_dw_hdmi_probe(struct platform_device *pdev) +{ + struct device *dev = >dev; + struct dw_hdmi_plat_data *plat_data; + struct imx_hdmi *hdmi; + int ret; + + hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL); + if (!hdmi) + return -ENOMEM; + + plat_data = >plat_data; + + hdmi->pixclk = devm_clk_get(dev, "pix"); + if (IS_ERR(hdmi->pixclk)) + return dev_err_probe(dev, PTR_ERR(hdmi->pixclk), +"Unable to get pixel clock\n"); + + hdmi->fdcc = devm_clk_get(dev, "fdcc"); + if (IS_ERR(hdmi->fdcc)) + return dev_err_probe(dev, PTR_ERR(hdmi->fdcc), +"Unable to get FDCC clock\n"); + + ret = clk_prepare_enable(hdmi->fdcc); + if (ret) +
[PATCH v0.5 1/9] dt-bindings: display: imx: add binding for i.MX8MP HDMI TX
The HDMI TX controller on the i.MX8MP SoC is a Synopsys designware IP core with a little bit of SoC integration around it. Signed-off-by: Lucas Stach --- .../bindings/display/imx/fsl,imx8mp-hdmi.yaml | 73 +++ 1 file changed, 73 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8mp-hdmi.yaml diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx8mp-hdmi.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx8mp-hdmi.yaml new file mode 100644 index ..bd9a2b135176 --- /dev/null +++ b/Documentation/devicetree/bindings/display/imx/fsl,imx8mp-hdmi.yaml @@ -0,0 +1,73 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/imx/fsl,imx8mp-hdmi.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Freescale i.MX8MP DWC HDMI TX Encoder + +maintainers: + - Lucas Stach + +description: | + The HDMI transmitter is a Synopsys DesignWare HDMI 2.0 TX controller IP. + +allOf: + - $ref: ../bridge/synopsys,dw-hdmi.yaml# + +properties: + compatible: +enum: + - fsl,imx8mp-hdmi + + reg: +maxItems: 1 + + reg-io-width: +const: 1 + + clocks: +maxItems: 5 + + clock-names: +items: + - {} + - {} + - const: cec + - const: pix + - const: fdcc + + interrupts: +maxItems: 1 + + power-domains: +maxItems: 1 + +required: + - compatible + - reg + - clocks + - clock-names + - interrupts + - power-domains + +additionalProperties: false + +examples: + - | +#include +#include +#include + +hdmi@32fd8000 { +compatible = "fsl,imx8mp-hdmi"; +reg = <0x32fd8000 0x7eff>; +interrupts = <0 IRQ_TYPE_LEVEL_HIGH>; +clocks = < IMX8MP_CLK_HDMI_APB>, + < IMX8MP_CLK_HDMI_REF_266M>, + < IMX8MP_CLK_32K>, + <_tx_phy>; +clock-names = "iahb", "isfr", "cec", "pix"; +power-domains = <_blk_ctrl IMX8MP_HDMIBLK_PD_HDMI_TX>; +reg-io-width = <1>; +}; -- 2.30.2
[PATCH v0.5 0/9] i.MX8MP HDMI support
Hi all, second round of the i.MX8MP HDMI work. Still not split up into proper parts for merging through the various trees this needs to go into, but should make it easy for people to test. I've worked in the feedback I got from the last round, including fixing the system hang that could happen when the drivers were built as modules. Series is based on linux-next/master, as there are some prerequisite patches in both the drm and imx tree already. The last patch from [1] and the patches from [2] need to be applied. Please note that this series expects the sync polarity from the LCDIF to be set according to the comments I made in [2]. Please test and provide feedback. Regards, Lucas [1] https://lore.kernel.org/all/20220406153402.1265474-1-l.st...@pengutronix.de/ [2] https://lore.kernel.org/all/20220322142853.125880-1-ma...@denx.de/ Lucas Stach (9): dt-bindings: display: imx: add binding for i.MX8MP HDMI TX drm/imx: add bridge wrapper driver for i.MX8MP DWC HDMI dt-bindings: display: imx: add binding for i.MX8MP HDMI PVI drm/imx: add driver for HDMI TX Parallel Video Interface dt-bindings: phy: add binding for the i.MX8MP HDMI PHY phy: freescale: add Samsung HDMI PHY arm64: dts: imx8mp: add HDMI irqsteer arm64: dts: imx8mp: add HDMI display pipeline arm64: dts: imx8mp-evk: enable HDMI .../display/imx/fsl,imx8mp-hdmi-pvi.yaml | 83 ++ .../bindings/display/imx/fsl,imx8mp-hdmi.yaml | 73 ++ .../bindings/phy/fsl,imx8mp-hdmi-phy.yaml | 62 + arch/arm64/boot/dts/freescale/imx8mp-evk.dts | 19 + arch/arm64/boot/dts/freescale/imx8mp.dtsi | 94 ++ drivers/gpu/drm/imx/Kconfig |1 + drivers/gpu/drm/imx/Makefile |2 + drivers/gpu/drm/imx/bridge/Kconfig| 18 + drivers/gpu/drm/imx/bridge/Makefile |4 + drivers/gpu/drm/imx/bridge/imx-hdmi-pvi.c | 201 +++ drivers/gpu/drm/imx/bridge/imx-hdmi.c | 141 +++ drivers/phy/freescale/Kconfig |6 + drivers/phy/freescale/Makefile|1 + drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 1078 + 14 files changed, 1783 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8mp-hdmi-pvi.yaml create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx8mp-hdmi.yaml create mode 100644 Documentation/devicetree/bindings/phy/fsl,imx8mp-hdmi-phy.yaml create mode 100644 drivers/gpu/drm/imx/bridge/Kconfig create mode 100644 drivers/gpu/drm/imx/bridge/Makefile create mode 100644 drivers/gpu/drm/imx/bridge/imx-hdmi-pvi.c create mode 100644 drivers/gpu/drm/imx/bridge/imx-hdmi.c create mode 100644 drivers/phy/freescale/phy-fsl-samsung-hdmi.c -- 2.30.2
Re: [PATCH 17/25] drm/edid: add drm_edid helper for drm_edid_to_sad()
On Fri, May 06, 2022 at 01:10:24PM +0300, Jani Nikula wrote: > +int drm_edid_to_sad(const struct edid *edid, struct cea_sad **sads) > +{ > + struct drm_edid drm_edid = { > + .edid = edid, > + .size = edid_size(edid), > + }; > + > + return _drm_edid_to_sad(_edid, sads); No need to check for NULL edid in these wrappers? > +} > EXPORT_SYMBOL(drm_edid_to_sad); > > /** > -- > 2.30.2 -- Ville Syrjälä Intel
Re: drm pull request (was Re: )
On Sat, 7 May 2022 at 02:50, Linus Torvalds wrote: > > On Thu, May 5, 2022 at 9:07 PM Dave Airlie wrote: > > > > pretty quiet week, one fbdev, msm, kconfig, and 2 amdgpu fixes, about > > what I'd expect for rc6. > > You're not getting the automated pr-tracker-bot response, because your > subject line was missing... > > Just a "how did that happen" together with a "here's the manual > response instead". I just forgot to type it in, I send the email from gmail manually pasting in the contents from the PR. Dave.
Re: [PATCH 02/25] drm/edid: convert drm_for_each_detailed_block() to edid iter
On Fri, May 06, 2022 at 01:10:09PM +0300, Jani Nikula wrote: > We have an iterator for this, use it. It does include the base block, > but its tag is 0 and will be skipped. > > Signed-off-by: Jani Nikula Reviewed-by: Ville Syrjälä > --- > drivers/gpu/drm/drm_edid.c | 8 +--- > 1 file changed, 5 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c > index efc1999b9573..dcef92c8887a 100644 > --- a/drivers/gpu/drm/drm_edid.c > +++ b/drivers/gpu/drm/drm_edid.c > @@ -2574,6 +2574,8 @@ vtb_for_each_detailed_block(const u8 *ext, detailed_cb > *cb, void *closure) > static void > drm_for_each_detailed_block(const struct edid *edid, detailed_cb *cb, void > *closure) > { > + struct drm_edid_iter edid_iter; > + const u8 *ext; > int i; > > if (edid == NULL) > @@ -2582,9 +2584,8 @@ drm_for_each_detailed_block(const struct edid *edid, > detailed_cb *cb, void *clos > for (i = 0; i < EDID_DETAILED_TIMINGS; i++) > cb(&(edid->detailed_timings[i]), closure); > > - for (i = 0; i < edid_extension_block_count(edid); i++) { > - const u8 *ext = edid_extension_block_data(edid, i); > - > + drm_edid_iter_begin(edid, _iter); > + drm_edid_iter_for_each(ext, _iter) { > switch (*ext) { > case CEA_EXT: > cea_for_each_detailed_block(ext, cb, closure); > @@ -2596,6 +2597,7 @@ drm_for_each_detailed_block(const struct edid *edid, > detailed_cb *cb, void *clos > break; > } > } > + drm_edid_iter_end(_iter); > } > > static void > -- > 2.30.2 -- Ville Syrjälä Intel
Re: [PATCH 01/25] drm/edid: use else-if in CTA extension parsing
On Fri, May 06, 2022 at 01:10:08PM +0300, Jani Nikula wrote: > Only one of the conditions can be true. > > Suggested-by: Ville Syrjälä > Signed-off-by: Jani Nikula Reviewed-by: Ville Syrjälä > --- > drivers/gpu/drm/drm_edid.c | 12 ++-- > 1 file changed, 6 insertions(+), 6 deletions(-) > > diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c > index 47d121e99201..efc1999b9573 100644 > --- a/drivers/gpu/drm/drm_edid.c > +++ b/drivers/gpu/drm/drm_edid.c > @@ -5473,16 +5473,16 @@ static void drm_parse_cea_ext(struct drm_connector > *connector, > > if (cea_db_is_hdmi_vsdb(db)) > drm_parse_hdmi_vsdb_video(connector, data); > - if (cea_db_is_hdmi_forum_vsdb(db) || > - cea_db_is_hdmi_forum_scdb(db)) > + else if (cea_db_is_hdmi_forum_vsdb(db) || > + cea_db_is_hdmi_forum_scdb(db)) > drm_parse_hdmi_forum_scds(connector, data); > - if (cea_db_is_microsoft_vsdb(db)) > + else if (cea_db_is_microsoft_vsdb(db)) > drm_parse_microsoft_vsdb(connector, data); > - if (cea_db_is_y420cmdb(db)) > + else if (cea_db_is_y420cmdb(db)) > drm_parse_y420cmdb_bitmap(connector, data); > - if (cea_db_is_vcdb(db)) > + else if (cea_db_is_vcdb(db)) > drm_parse_vcdb(connector, data); > - if (cea_db_is_hdmi_hdr_metadata_block(db)) > + else if (cea_db_is_hdmi_hdr_metadata_block(db)) > drm_parse_hdr_metadata_block(connector, data); > } > cea_db_iter_end(); > -- > 2.30.2 -- Ville Syrjälä Intel
Re: [PATCH v2 05/12] drm/i915/pvc: Remove additional 3D flags from PIPE_CONTROL
On Fri, May 06, 2022 at 10:23:41AM -0700, Lucas De Marchi wrote: > On Thu, May 05, 2022 at 02:38:05PM -0700, Matt Roper wrote: > > From: Stuart Summers > > > > Although we already strip 3D-specific flags from PIPE_CONTROL > > instructions when submitting to a compute engine, there are some > > additional flags that need to be removed when the platform as a whole > > lacks a 3D pipeline. Add those restrictions here. > > > > Bspec: 47112 > > Signed-off-by: Stuart Summers > > Signed-off-by: Matt Roper > > --- > > drivers/gpu/drm/i915/gt/gen8_engine_cs.c | 18 -- > > drivers/gpu/drm/i915/gt/intel_gpu_commands.h | 12 ++-- > > drivers/gpu/drm/i915/i915_drv.h | 2 ++ > > drivers/gpu/drm/i915/i915_pci.c | 3 ++- > > drivers/gpu/drm/i915/intel_device_info.h | 3 ++- > > 5 files changed, 28 insertions(+), 10 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c > > b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c > > index 3e13960615bd..11c72792573d 100644 > > --- a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c > > +++ b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c > > @@ -197,8 +197,10 @@ int gen12_emit_flush_rcs(struct i915_request *rq, u32 > > mode) > > > > flags |= PIPE_CONTROL_CS_STALL; > > > > - if (engine->class == COMPUTE_CLASS) > > - flags &= ~PIPE_CONTROL_3D_FLAGS; > > + if (LACKS_3D_PIPELINE(engine->i915)) > > + flags &= ~PIPE_CONTROL_3D_ARCH_FLAGS; > > + else if (engine->class == COMPUTE_CLASS) > > + flags &= ~PIPE_CONTROL_3D_ENGINE_FLAGS; > > > > cs = intel_ring_begin(rq, 6); > > if (IS_ERR(cs)) > > @@ -227,8 +229,10 @@ int gen12_emit_flush_rcs(struct i915_request *rq, u32 > > mode) > > > > flags |= PIPE_CONTROL_CS_STALL; > > > > - if (engine->class == COMPUTE_CLASS) > > - flags &= ~PIPE_CONTROL_3D_FLAGS; > > + if (LACKS_3D_PIPELINE(engine->i915)) > > + flags &= ~PIPE_CONTROL_3D_ARCH_FLAGS; > > + else if (engine->class == COMPUTE_CLASS) > > + flags &= ~PIPE_CONTROL_3D_ENGINE_FLAGS; > > > > if (!HAS_FLAT_CCS(rq->engine->i915)) > > count = 8 + 4; > > @@ -716,8 +720,10 @@ u32 *gen12_emit_fini_breadcrumb_rcs(struct > > i915_request *rq, u32 *cs) > > /* Wa_1409600907 */ > > flags |= PIPE_CONTROL_DEPTH_STALL; > > > > - if (rq->engine->class == COMPUTE_CLASS) > > - flags &= ~PIPE_CONTROL_3D_FLAGS; > > + if (LACKS_3D_PIPELINE(rq->engine->i915)) > > + flags &= ~PIPE_CONTROL_3D_ARCH_FLAGS; > > + else if (rq->engine->class == COMPUTE_CLASS) > > + flags &= ~PIPE_CONTROL_3D_ENGINE_FLAGS; > > > > cs = gen12_emit_ggtt_write_rcs(cs, > >rq->fence.seqno, > > diff --git a/drivers/gpu/drm/i915/gt/intel_gpu_commands.h > > b/drivers/gpu/drm/i915/gt/intel_gpu_commands.h > > index 556bca3be804..900755f4b787 100644 > > --- a/drivers/gpu/drm/i915/gt/intel_gpu_commands.h > > +++ b/drivers/gpu/drm/i915/gt/intel_gpu_commands.h > > @@ -288,8 +288,8 @@ > > #define PIPE_CONTROL_DEPTH_CACHE_FLUSH(1<<0) > > #define PIPE_CONTROL_GLOBAL_GTT (1<<2) /* in addr dword */ > > > > -/* 3D-related flags can't be set on compute engine */ > > -#define PIPE_CONTROL_3D_FLAGS (\ > > +/* 3D-related flags that can't be set on _engines_ that lack a 3D pipeline > > */ > > +#define PIPE_CONTROL_3D_ENGINE_FLAGS (\ > > PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH | \ > > PIPE_CONTROL_DEPTH_CACHE_FLUSH | \ > > PIPE_CONTROL_TILE_CACHE_FLUSH | \ > > @@ -300,6 +300,14 @@ > > PIPE_CONTROL_VF_CACHE_INVALIDATE | \ > > PIPE_CONTROL_GLOBAL_SNAPSHOT_RESET) > > > > +/* 3D-related flags that can't be set on _platforms_ that lack a 3D > > pipeline */ > > +#define PIPE_CONTROL_3D_ARCH_FLAGS ( \ > > names and comments here I think are confusing. In the code we do: > > if (LACKS_3D_PIPELINE(engine->i915)) > flags &= ~PIPE_CONTROL_3D_ARCH_FLAGS; > else if (engine->class == COMPUTE_CLASS) > flags &= ~PIPE_CONTROL_3D_ENGINE_FLAGS; > > coments give the _engines_ that lack a 3D pipeline doens't seem accurate > as bcs, vcs, vecs also lack a 3d pipeline. Maybe be explicit about the > flags being set on compute engine: PIPE_CONTROL_COMPUTE_ENGINE_FLAGS > > And LACKS_3D_PIPELINE... may be better to invert the condition to follow > the other macros: HAS_3D_PIPELINE. > > > + PIPE_CONTROL_3D_ENGINE_FLAGS | \ > > + PIPE_CONTROL_INDIRECT_STATE_DISABLE | \ > > + PIPE_CONTROL_FLUSH_ENABLE | \ > > + PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE | \ > > + PIPE_CONTROL_DC_FLUSH_ENABLE) > > + > > #define MI_MATH(x) MI_INSTR(0x1a, (x) - 1) > > #define
Re: [PATCH v2 05/12] drm/i915/pvc: Remove additional 3D flags from PIPE_CONTROL
On Thu, May 05, 2022 at 02:38:05PM -0700, Matt Roper wrote: From: Stuart Summers Although we already strip 3D-specific flags from PIPE_CONTROL instructions when submitting to a compute engine, there are some additional flags that need to be removed when the platform as a whole lacks a 3D pipeline. Add those restrictions here. Bspec: 47112 Signed-off-by: Stuart Summers Signed-off-by: Matt Roper --- drivers/gpu/drm/i915/gt/gen8_engine_cs.c | 18 -- drivers/gpu/drm/i915/gt/intel_gpu_commands.h | 12 ++-- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_pci.c | 3 ++- drivers/gpu/drm/i915/intel_device_info.h | 3 ++- 5 files changed, 28 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c index 3e13960615bd..11c72792573d 100644 --- a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c +++ b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c @@ -197,8 +197,10 @@ int gen12_emit_flush_rcs(struct i915_request *rq, u32 mode) flags |= PIPE_CONTROL_CS_STALL; - if (engine->class == COMPUTE_CLASS) - flags &= ~PIPE_CONTROL_3D_FLAGS; + if (LACKS_3D_PIPELINE(engine->i915)) + flags &= ~PIPE_CONTROL_3D_ARCH_FLAGS; + else if (engine->class == COMPUTE_CLASS) + flags &= ~PIPE_CONTROL_3D_ENGINE_FLAGS; cs = intel_ring_begin(rq, 6); if (IS_ERR(cs)) @@ -227,8 +229,10 @@ int gen12_emit_flush_rcs(struct i915_request *rq, u32 mode) flags |= PIPE_CONTROL_CS_STALL; - if (engine->class == COMPUTE_CLASS) - flags &= ~PIPE_CONTROL_3D_FLAGS; + if (LACKS_3D_PIPELINE(engine->i915)) + flags &= ~PIPE_CONTROL_3D_ARCH_FLAGS; + else if (engine->class == COMPUTE_CLASS) + flags &= ~PIPE_CONTROL_3D_ENGINE_FLAGS; if (!HAS_FLAT_CCS(rq->engine->i915)) count = 8 + 4; @@ -716,8 +720,10 @@ u32 *gen12_emit_fini_breadcrumb_rcs(struct i915_request *rq, u32 *cs) /* Wa_1409600907 */ flags |= PIPE_CONTROL_DEPTH_STALL; - if (rq->engine->class == COMPUTE_CLASS) - flags &= ~PIPE_CONTROL_3D_FLAGS; + if (LACKS_3D_PIPELINE(rq->engine->i915)) + flags &= ~PIPE_CONTROL_3D_ARCH_FLAGS; + else if (rq->engine->class == COMPUTE_CLASS) + flags &= ~PIPE_CONTROL_3D_ENGINE_FLAGS; cs = gen12_emit_ggtt_write_rcs(cs, rq->fence.seqno, diff --git a/drivers/gpu/drm/i915/gt/intel_gpu_commands.h b/drivers/gpu/drm/i915/gt/intel_gpu_commands.h index 556bca3be804..900755f4b787 100644 --- a/drivers/gpu/drm/i915/gt/intel_gpu_commands.h +++ b/drivers/gpu/drm/i915/gt/intel_gpu_commands.h @@ -288,8 +288,8 @@ #define PIPE_CONTROL_DEPTH_CACHE_FLUSH(1<<0) #define PIPE_CONTROL_GLOBAL_GTT (1<<2) /* in addr dword */ -/* 3D-related flags can't be set on compute engine */ -#define PIPE_CONTROL_3D_FLAGS (\ +/* 3D-related flags that can't be set on _engines_ that lack a 3D pipeline */ +#define PIPE_CONTROL_3D_ENGINE_FLAGS (\ PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH | \ PIPE_CONTROL_DEPTH_CACHE_FLUSH | \ PIPE_CONTROL_TILE_CACHE_FLUSH | \ @@ -300,6 +300,14 @@ PIPE_CONTROL_VF_CACHE_INVALIDATE | \ PIPE_CONTROL_GLOBAL_SNAPSHOT_RESET) +/* 3D-related flags that can't be set on _platforms_ that lack a 3D pipeline */ +#define PIPE_CONTROL_3D_ARCH_FLAGS ( \ names and comments here I think are confusing. In the code we do: if (LACKS_3D_PIPELINE(engine->i915)) flags &= ~PIPE_CONTROL_3D_ARCH_FLAGS; else if (engine->class == COMPUTE_CLASS) flags &= ~PIPE_CONTROL_3D_ENGINE_FLAGS; coments give the _engines_ that lack a 3D pipeline doens't seem accurate as bcs, vcs, vecs also lack a 3d pipeline. Maybe be explicit about the flags being set on compute engine: PIPE_CONTROL_COMPUTE_ENGINE_FLAGS And LACKS_3D_PIPELINE... may be better to invert the condition to follow the other macros: HAS_3D_PIPELINE. + PIPE_CONTROL_3D_ENGINE_FLAGS | \ + PIPE_CONTROL_INDIRECT_STATE_DISABLE | \ + PIPE_CONTROL_FLUSH_ENABLE | \ + PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE | \ + PIPE_CONTROL_DC_FLUSH_ENABLE) + #define MI_MATH(x) MI_INSTR(0x1a, (x) - 1) #define MI_MATH_INSTR(opcode, op1, op2) ((opcode) << 20 | (op1) << 10 | (op2)) /* Opcodes for MI_MATH_INSTR */ diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index b389674b5210..1e153cefc92e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1403,6 +1403,8 @@
Re: [Intel-gfx] [PATCH v2 03/12] drm/i915/pvc: Define MOCS table for PVC
On Thu, May 05, 2022 at 02:38:03PM -0700, Matt Roper wrote: From: Ayaz A Siddiqui v2 (MattR): - Clarify comment above RING_CMD_CCTL programming. - Remove bspec reference from field definition. (Lucas) - Add WARN if we try to use a (presumably uninitialized) wb_index of 0. On most platforms 0 is an invalid MOCS entry and even on the ones where it isn't, it isn't the right setting for wb_index. (Lucas) Bspec: 45101, 72161 Cc: Lucas De Marchi Signed-off-by: Ayaz A Siddiqui Signed-off-by: Fei Yang Signed-off-by: Matt Roper --- drivers/gpu/drm/i915/gt/intel_gt_types.h| 1 + drivers/gpu/drm/i915/gt/intel_mocs.c| 24 - drivers/gpu/drm/i915/gt/intel_workarounds.c | 30 - drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_pci.c | 3 ++- drivers/gpu/drm/i915/intel_device_info.h| 1 + 6 files changed, 53 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_gt_types.h b/drivers/gpu/drm/i915/gt/intel_gt_types.h index b06611c1d4ad..7853ea194ea6 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_types.h +++ b/drivers/gpu/drm/i915/gt/intel_gt_types.h @@ -221,6 +221,7 @@ struct intel_gt { struct { u8 uc_index; + u8 wb_index; /* Only for platforms listed in Bspec: 72161 */ doesn't correspond to changelog other than that, Reviewed-by: Lucas De Marchi Lucas De Marchi } mocs; struct intel_pxp pxp; diff --git a/drivers/gpu/drm/i915/gt/intel_mocs.c b/drivers/gpu/drm/i915/gt/intel_mocs.c index c4c37585ae8c..c6ebe2781076 100644 --- a/drivers/gpu/drm/i915/gt/intel_mocs.c +++ b/drivers/gpu/drm/i915/gt/intel_mocs.c @@ -23,6 +23,7 @@ struct drm_i915_mocs_table { unsigned int n_entries; const struct drm_i915_mocs_entry *table; u8 uc_index; + u8 wb_index; /* Only used on HAS_L3_CCS_READ() platforms */ u8 unused_entries_index; }; @@ -47,6 +48,7 @@ struct drm_i915_mocs_table { /* Helper defines */ #define GEN9_NUM_MOCS_ENTRIES 64 /* 63-64 are reserved, but configured. */ +#define PVC_NUM_MOCS_ENTRIES 3 /* (e)LLC caching options */ /* @@ -394,6 +396,17 @@ static const struct drm_i915_mocs_entry dg2_mocs_table_g10_ax[] = { MOCS_ENTRY(3, 0, L3_3_WB | L3_LKUP(1)), }; +static const struct drm_i915_mocs_entry pvc_mocs_table[] = { + /* Error */ + MOCS_ENTRY(0, 0, L3_3_WB), + + /* UC */ + MOCS_ENTRY(1, 0, L3_1_UC), + + /* WB */ + MOCS_ENTRY(2, 0, L3_3_WB), +}; + enum { HAS_GLOBAL_MOCS = BIT(0), HAS_ENGINE_MOCS = BIT(1), @@ -423,7 +436,14 @@ static unsigned int get_mocs_settings(const struct drm_i915_private *i915, memset(table, 0, sizeof(struct drm_i915_mocs_table)); table->unused_entries_index = I915_MOCS_PTE; - if (IS_DG2(i915)) { + if (IS_PONTEVECCHIO(i915)) { + table->size = ARRAY_SIZE(pvc_mocs_table); + table->table = pvc_mocs_table; + table->n_entries = PVC_NUM_MOCS_ENTRIES; + table->uc_index = 1; + table->wb_index = 2; + table->unused_entries_index = 2; + } else if (IS_DG2(i915)) { if (IS_DG2_GRAPHICS_STEP(i915, G10, STEP_A0, STEP_B0)) { table->size = ARRAY_SIZE(dg2_mocs_table_g10_ax); table->table = dg2_mocs_table_g10_ax; @@ -622,6 +642,8 @@ void intel_set_mocs_index(struct intel_gt *gt) get_mocs_settings(gt->i915, ); gt->mocs.uc_index = table.uc_index; + if (HAS_L3_CCS_READ(gt->i915)) + gt->mocs.wb_index = table.wb_index; } void intel_mocs_init(struct intel_gt *gt) diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c b/drivers/gpu/drm/i915/gt/intel_workarounds.c index a05c4b99b3fb..756807c4b405 100644 --- a/drivers/gpu/drm/i915/gt/intel_workarounds.c +++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c @@ -1994,19 +1994,37 @@ void intel_engine_apply_whitelist(struct intel_engine_cs *engine) static void engine_fake_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal) { - u8 mocs; + u8 mocs_w, mocs_r; /* -* RING_CMD_CCTL are need to be programed to un-cached -* for memory writes and reads outputted by Command -* Streamers on Gen12 onward platforms. +* RING_CMD_CCTL specifies the default MOCS entry that will be used +* by the command streamer when executing commands that don't have +* a way to explicitly specify a MOCS setting. The default should +* usually reference whichever MOCS entry corresponds to uncached +* behavior, although use of a WB cached entry is recommended by the +* spec in certain circumstances on specific platforms. */ if (GRAPHICS_VER(engine->i915) >= 12) { - mocs = engine->gt->mocs.uc_index; + mocs_r = engine->gt->mocs.uc_index; + mocs_w =
Re: [PATCH] fbdev: efifb: Fix a use-after-free due early fb_info cleanup
On 06.05.2022 15:22, Javier Martinez Canillas wrote: Commit d258d00fb9c7 ("fbdev: efifb: Cleanup fb_info in .fb_destroy rather than .remove") attempted to fix a use-after-free error due driver freeing the fb_info in the .remove handler instead of doing it in .fb_destroy. But ironically that change introduced yet another use-after-free since the fb_info was still used after the free. This should fix for good by freeing the fb_info at the end of the handler. Fixes: d258d00fb9c7 ("fbdev: efifb: Cleanup fb_info in .fb_destroy rather than .remove") Reported-by: Ville Syrjälä Reported-by: Andrzej Hajda Signed-off-by: Javier Martinez Canillas --- Reviewed-by: Andrzej Hajda Regards Andrzej drivers/video/fbdev/efifb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c index cfa3dc0b4eee..b3d5f884c544 100644 --- a/drivers/video/fbdev/efifb.c +++ b/drivers/video/fbdev/efifb.c @@ -259,12 +259,12 @@ static void efifb_destroy(struct fb_info *info) memunmap(info->screen_base); } - framebuffer_release(info); - if (request_mem_succeeded) release_mem_region(info->apertures->ranges[0].base, info->apertures->ranges[0].size); fb_dealloc_cmap(>cmap); + + framebuffer_release(info); } static const struct fb_ops efifb_ops = {
drm pull request (was Re: )
On Thu, May 5, 2022 at 9:07 PM Dave Airlie wrote: > > pretty quiet week, one fbdev, msm, kconfig, and 2 amdgpu fixes, about > what I'd expect for rc6. You're not getting the automated pr-tracker-bot response, because your subject line was missing... Just a "how did that happen" together with a "here's the manual response instead". Linus
Re: [Intel-gfx] [PATCH] drm/i915/guc/slpc: Use non-blocking H2G for waitboost
On 5/6/2022 00:18, Tvrtko Ursulin wrote: On 05/05/2022 19:36, John Harrison wrote: On 5/5/2022 10:21, Belgaumkar, Vinay wrote: On 5/5/2022 5:13 AM, Tvrtko Ursulin wrote: On 05/05/2022 06:40, Vinay Belgaumkar wrote: SLPC min/max frequency updates require H2G calls. We are seeing timeouts when GuC channel is backed up and it is unable to respond in a timely fashion causing warnings and affecting CI. Is it the "Unable to force min freq" error? Do you have a link to the GitLab issue to add to commit message? We don't have a specific error for this one, but have seen similar issues with other H2G which are blocking. This is seen when waitboosting happens during a stress test. this patch updates the waitboost path to use a non-blocking H2G call instead, which returns as soon as the message is successfully transmitted. AFAIU with this approach, when CT channel is congested, you instead achieve silent dropping of the waitboost request, right? We are hoping it makes it, but just not waiting for it to complete. We are not 'hoping it makes it'. We know for a fact that it will make it. We just don't know when. The issue is not about whether the waitboost request itself gets dropped/lost it is about the ack that comes back. The GuC will process the message and it will send an ack. It's just a question of whether the i915 driver has given up waiting for it yet. And if it has, then you get the initial 'timed out waiting for ack' followed by a later 'got unexpected ack' message. Whereas, if we make the call asynchronous, there is no ack. i915 doesn't bother waiting and it won't get surprised later. Also, note that this is only an issue when GuC itself is backed up. Normally that requires the creation/destruction of large numbers of contexts in rapid succession (context management is about the slowest thing we do with GuC). Some of the IGTs and selftests do that with thousands of contexts all at once. Those are generally where we see this kind of problem. It would be highly unlikely (but not impossible) to hit it in real world usage. Goto -> The general design philosophy of H2G messages is that asynchronous mode should be used for everything if at all possible. It is fire and forget and will all get processed in the order sent (same as batch buffer execution, really). Synchronous messages should only be used when an ack/status is absolutely required. E.g. start of day initialisation or things like TLB invalidation where we need to know that a cache has been cleared/flushed before updating memory from the CPU. John. It sounds like a potentially important feedback from the field to lose so easily. How about you added drm_notice to the worker when it fails? Or simply a "one line patch" to replace i915_probe_error (!?) with drm_notice and keep the blocking behavior. (I have no idea what is the typical time to drain the CT buffer, and so to decide whether waiting or dropping makes more sense for effectiveness of waitboosting.) Or since the congestion /should not/ happen in production, then the argument is why complicate with more code, in which case going with one line patch is an easy way forward? Here. Where I did hint I understood the "should not happen in production angle". So statement is GuC is congested in processing requests, but the h2g buffer is not congested so no chance intel_guc_send_nb() will fail with no space in that buffer? Sounds a bit un-intuitive. That's two different things. The problem of no space in the H2G buffer is the same whether the call is sent blocking or non-blocking. The wait-for-space version is intel_guc_send_busy_loop() rather than intel_guc_send_nb(). NB: _busy_loop is a wrapper around _nb, so the wait-for-space version is also non-blocking ;). If a non-looping version is used (blocking or otherwise) it will return -EBUSY if there is no space. So both the original SLPC call and this non-blocking version will still get an immediate EBUSY return code if the H2G channel is backed up completely. Whether the code should be handling EBUSY or not is another matter. Vinay, does anything higher up do a loop on EBUSY? If not, maybe it should be using the _busy_loop() call instead? The blocking vs non-blocking is about waiting for a response if the command is successfully sent. The blocking case will sit and spin for a reply, the non-blocking assumes success and expects an asynchronous error report on failure. The assumption being that the call can't fail unless something is already broken - i915 sending invalid data to GuC for example. And thus any failure is in the BUG_ON category rather than the try again with a different approach and/or try again later category. This is the point of the change. We are currently getting timeout errors when the H2G channel has space so the command can be sent, but the channel already contains a lot of slow operations. The command has been sent and will be processed
[GIT PULL] drm/tegra: Changes for v5.19-rc1
Hi Dave, Daniel, The following changes since commit 3123109284176b1532874591f7c81f3837bbdc17: Linux 5.18-rc1 (2022-04-03 14:08:21 -0700) are available in the Git repository at: https://gitlab.freedesktop.org/drm/tegra.git tags/drm/tegra/for-5.19-rc1 for you to fetch changes up to cb7e1abc2c73633e1eefa168ab2dad6e838899c9: drm/tegra: gem: Do not try to dereference ERR_PTR() (2022-05-06 15:52:49 +0200) Thanks, Thierry drm/tegra: Changes for v5.19-rc1 Only a few fixes this time, and some debuggability improvements. Arnd Bergmann (1): drm/tegra: vic: Fix unused-function warnings Jon Hunter (1): gpu: host1x: Show all allocated syncpts via debugfs Randy Dunlap (1): gpu: host1x: Fix a kernel-doc warning Thierry Reding (2): gpu: host1x: Do not use mapping cache for job submissions drm/tegra: gem: Do not try to dereference ERR_PTR() drivers/gpu/drm/tegra/gem.c | 1 + drivers/gpu/drm/tegra/vic.c | 5 ++--- drivers/gpu/host1x/debug.c | 11 +++ drivers/gpu/host1x/job.c| 4 ++-- include/linux/host1x.h | 6 ++ 5 files changed, 18 insertions(+), 9 deletions(-)
Re: [RFC PATCH] drm/edid: drm_add_modes_noedid() should set lowest resolution as preferred
Hi Jani On 5/6/2022 4:16 AM, Jani Nikula wrote: On Thu, 05 May 2022, Doug Anderson wrote: Ville, On Tue, Apr 26, 2022 at 1:21 PM Douglas Anderson wrote: If we're unable to read the EDID for a display because it's corrupt / bogus / invalid then we'll add a set of standard modes for the display. When userspace looks at these modes it doesn't really have a good concept for which mode to pick and it'll likely pick the highest resolution one by default. That's probably not ideal because the modes were purely guesses on the part of the Linux kernel. Let's instead set 640x480 as the "preferred" mode when we have no EDID. Signed-off-by: Douglas Anderson --- drivers/gpu/drm/drm_edid.c | 9 + 1 file changed, 9 insertions(+) Someone suggested that you might have an opinion on this patch and another one I posted recently [1]. Do you have any thoughts on it? Just to be clear: I'm hoping to land _both_ this patch and [1]. If you don't have an opinion, that's OK too. [1] https://lore.kernel.org/r/20220426114627.2.I4ac7f55aa446699f8c200a23c10463256f6f439f@changeid There are a number of drivers with combos: drm_add_modes_noedid() drm_set_preferred_mode() which I think would be affected by the change. Perhaps you should just call drm_set_preferred_mode() in your referenced patch? So it seems like many drivers handle the !edid case within their respective get_modes() call which probably is because they know the max capability of their connector and because they know which mode should be set as preferred. But at the same time, perhaps the code below which handles the count == 0 case should be changed like below to make sure we are within the max_width/height of the connector (to handle the first condition)? diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index 682359512996..6eb89d90777b 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -517,7 +517,8 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, if (count == 0 && (connector->status == connector_status_connected || connector->status == connector_status_unknown)) - count = drm_add_modes_noedid(connector, 1024, 768); + count = drm_add_modes_noedid(connector, connector->dev->mode_config.max_width, + connector->dev->mode_config.max_height); count += drm_helper_probe_add_cmdline_mode(connector); if (count == 0) goto prune; Alternatively, perhaps drm_set_preferred_mode() should erase the previous preferred mode(s) if it finds a matching new preferred mode. But still yes, even if we change it like above perhaps for other non-DP cases its still better to allow individual drivers to pick their preferred modes. If we call drm_set_preferred_mode() in the referenced patch, it will not address the no EDID cases because the patch comes into picture when there was a EDID with some modes but not with 640x480. So i think the second proposal is a good one. It will cover existing users of drm_set_preferred_mode() as typically its called after drm_add_modes_noedid() which means the existing users want to "override" their preferred mode. BR, Jani.
Re: [Intel-gfx] [PATCH] drm/i915/guc/slpc: Use non-blocking H2G for waitboost
On 5/6/2022 12:18 AM, Tvrtko Ursulin wrote: On 05/05/2022 19:36, John Harrison wrote: On 5/5/2022 10:21, Belgaumkar, Vinay wrote: On 5/5/2022 5:13 AM, Tvrtko Ursulin wrote: On 05/05/2022 06:40, Vinay Belgaumkar wrote: SLPC min/max frequency updates require H2G calls. We are seeing timeouts when GuC channel is backed up and it is unable to respond in a timely fashion causing warnings and affecting CI. Is it the "Unable to force min freq" error? Do you have a link to the GitLab issue to add to commit message? We don't have a specific error for this one, but have seen similar issues with other H2G which are blocking. This is seen when waitboosting happens during a stress test. this patch updates the waitboost path to use a non-blocking H2G call instead, which returns as soon as the message is successfully transmitted. AFAIU with this approach, when CT channel is congested, you instead achieve silent dropping of the waitboost request, right? We are hoping it makes it, but just not waiting for it to complete. We are not 'hoping it makes it'. We know for a fact that it will make it. We just don't know when. The issue is not about whether the waitboost request itself gets dropped/lost it is about the ack that comes back. The GuC will process the message and it will send an ack. It's just a question of whether the i915 driver has given up waiting for it yet. And if it has, then you get the initial 'timed out waiting for ack' followed by a later 'got unexpected ack' message. Whereas, if we make the call asynchronous, there is no ack. i915 doesn't bother waiting and it won't get surprised later. Also, note that this is only an issue when GuC itself is backed up. Normally that requires the creation/destruction of large numbers of contexts in rapid succession (context management is about the slowest thing we do with GuC). Some of the IGTs and selftests do that with thousands of contexts all at once. Those are generally where we see this kind of problem. It would be highly unlikely (but not impossible) to hit it in real world usage. Goto -> The general design philosophy of H2G messages is that asynchronous mode should be used for everything if at all possible. It is fire and forget and will all get processed in the order sent (same as batch buffer execution, really). Synchronous messages should only be used when an ack/status is absolutely required. E.g. start of day initialisation or things like TLB invalidation where we need to know that a cache has been cleared/flushed before updating memory from the CPU. John. It sounds like a potentially important feedback from the field to lose so easily. How about you added drm_notice to the worker when it fails? Or simply a "one line patch" to replace i915_probe_error (!?) with drm_notice and keep the blocking behavior. (I have no idea what is the typical time to drain the CT buffer, and so to decide whether waiting or dropping makes more sense for effectiveness of waitboosting.) Or since the congestion /should not/ happen in production, then the argument is why complicate with more code, in which case going with one line patch is an easy way forward? Here. Where I did hint I understood the "should not happen in production angle". So statement is GuC is congested in processing requests, but the h2g buffer is not congested so no chance intel_guc_send_nb() will fail with no space in that buffer? Sounds a bit un-intuitive. Anyway, it sounds okay to me to use the non-blocking, but I would like to see some logging if the unexpected does happen. Hence I was suggesting the option of adding drm_notice logging if the send fails from the worker. (Because I think other callers would already propagate the error, like sysfs.) err = slpc_force_min_freq(slpc, slpc->boost_freq); if (!err) slpc->num_boosts++; else drm_notice(... "Failed to send waitboost request (%d)", err); Ok, makes sense. Will send out another rev with this change. Thanks, Vinay. Something like that. Regards, Tvrtko Even if we soften the blow here, the actual timeout error occurs in the intel_guc_ct.c code, so we cannot hide that error anyways. Making this call non-blocking will achieve both things. Thanks, Vinay. Regards, Tvrtko Signed-off-by: Vinay Belgaumkar --- drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c | 38 - 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c index 1db833da42df..c852f73cf521 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c @@ -98,6 +98,30 @@ static u32 slpc_get_state(struct intel_guc_slpc *slpc) return data->header.global_state; } +static int guc_action_slpc_set_param_nb(struct intel_guc *guc, u8 id, u32 value) +{ + u32 request[] = { + GUC_ACTION_HOST2GUC_PC_SLPC_REQUEST,
Re: [PATCH] drm/amdkfd: Return true/false (not 1/0) from bool functions
On Thu, May 5, 2022 at 10:05 PM Haowen Bai wrote: > > Return boolean values ("true" or "false") instead of 1 or 0 from bool > functions. > > Signed-off-by: Haowen Bai Thanks, I just applied the same fix from someone else. Alex > --- > drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c > b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c > index c3919aaa76e6..1431f0961769 100644 > --- a/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c > +++ b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c > @@ -241,14 +241,14 @@ static bool event_interrupt_isr_v11(struct kfd_dev *dev, > if (/*!KFD_IRQ_IS_FENCE(client_id, source_id) &&*/ > (vmid < dev->vm_info.first_vmid_kfd || > vmid > dev->vm_info.last_vmid_kfd)) > - return 0; > + return false; > > pasid = SOC15_PASID_FROM_IH_ENTRY(ih_ring_entry); > context_id0 = SOC15_CONTEXT_ID0_FROM_IH_ENTRY(ih_ring_entry); > > if ((source_id == SOC15_INTSRC_CP_END_OF_PIPE) && > (context_id0 & AMDGPU_FENCE_MES_QUEUE_FLAG)) > - return 0; > + return false; > > pr_debug("client id 0x%x, source id %d, vmid %d, pasid 0x%x. raw > data:\n", > client_id, source_id, vmid, pasid); > @@ -258,7 +258,7 @@ static bool event_interrupt_isr_v11(struct kfd_dev *dev, > > /* If there is no valid PASID, it's likely a bug */ > if (WARN_ONCE(pasid == 0, "Bug: No PASID in KFD interrupt")) > - return 0; > + return false; > > /* Interrupt types we care about: various signals and faults. > * They will be forwarded to a work queue (see below). > -- > 2.7.4 >
Re: [PATCH -next 2/2] drm/amdkfd: Return true/false (not 1/0) from bool functions
Applied. Thanks! On Fri, May 6, 2022 at 12:04 PM Alex Deucher wrote: > > Series is: > Reviewed-by: Alex Deucher > > On Thu, May 5, 2022 at 7:28 PM Yang Li wrote: > > > > Return boolean values ("true" or "false") instead of 1 or 0 from bool > > functions. This fixes the following warnings from coccicheck: > > > > ./drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c:244:9-10: WARNING: > > return of 0/1 in function 'event_interrupt_isr_v11' with return type > > bool > > > > Reported-by: Abaci Robot > > Signed-off-by: Yang Li > > --- > > drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c | 6 +++--- > > 1 file changed, 3 insertions(+), 3 deletions(-) > > > > diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c > > b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c > > index c3919aaa76e6..1431f0961769 100644 > > --- a/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c > > +++ b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c > > @@ -241,14 +241,14 @@ static bool event_interrupt_isr_v11(struct kfd_dev > > *dev, > > if (/*!KFD_IRQ_IS_FENCE(client_id, source_id) &&*/ > > (vmid < dev->vm_info.first_vmid_kfd || > > vmid > dev->vm_info.last_vmid_kfd)) > > - return 0; > > + return false; > > > > pasid = SOC15_PASID_FROM_IH_ENTRY(ih_ring_entry); > > context_id0 = SOC15_CONTEXT_ID0_FROM_IH_ENTRY(ih_ring_entry); > > > > if ((source_id == SOC15_INTSRC_CP_END_OF_PIPE) && > > (context_id0 & AMDGPU_FENCE_MES_QUEUE_FLAG)) > > - return 0; > > + return false; > > > > pr_debug("client id 0x%x, source id %d, vmid %d, pasid 0x%x. raw > > data:\n", > > client_id, source_id, vmid, pasid); > > @@ -258,7 +258,7 @@ static bool event_interrupt_isr_v11(struct kfd_dev *dev, > > > > /* If there is no valid PASID, it's likely a bug */ > > if (WARN_ONCE(pasid == 0, "Bug: No PASID in KFD interrupt")) > > - return 0; > > + return false; > > > > /* Interrupt types we care about: various signals and faults. > > * They will be forwarded to a work queue (see below). > > -- > > 2.20.1.7.g153144c > >
Re: [PATCH -next 2/2] drm/amdkfd: Return true/false (not 1/0) from bool functions
Series is: Reviewed-by: Alex Deucher On Thu, May 5, 2022 at 7:28 PM Yang Li wrote: > > Return boolean values ("true" or "false") instead of 1 or 0 from bool > functions. This fixes the following warnings from coccicheck: > > ./drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c:244:9-10: WARNING: > return of 0/1 in function 'event_interrupt_isr_v11' with return type > bool > > Reported-by: Abaci Robot > Signed-off-by: Yang Li > --- > drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c > b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c > index c3919aaa76e6..1431f0961769 100644 > --- a/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c > +++ b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c > @@ -241,14 +241,14 @@ static bool event_interrupt_isr_v11(struct kfd_dev *dev, > if (/*!KFD_IRQ_IS_FENCE(client_id, source_id) &&*/ > (vmid < dev->vm_info.first_vmid_kfd || > vmid > dev->vm_info.last_vmid_kfd)) > - return 0; > + return false; > > pasid = SOC15_PASID_FROM_IH_ENTRY(ih_ring_entry); > context_id0 = SOC15_CONTEXT_ID0_FROM_IH_ENTRY(ih_ring_entry); > > if ((source_id == SOC15_INTSRC_CP_END_OF_PIPE) && > (context_id0 & AMDGPU_FENCE_MES_QUEUE_FLAG)) > - return 0; > + return false; > > pr_debug("client id 0x%x, source id %d, vmid %d, pasid 0x%x. raw > data:\n", > client_id, source_id, vmid, pasid); > @@ -258,7 +258,7 @@ static bool event_interrupt_isr_v11(struct kfd_dev *dev, > > /* If there is no valid PASID, it's likely a bug */ > if (WARN_ONCE(pasid == 0, "Bug: No PASID in KFD interrupt")) > - return 0; > + return false; > > /* Interrupt types we care about: various signals and faults. > * They will be forwarded to a work queue (see below). > -- > 2.20.1.7.g153144c >
Re: [PATCH v2 -next] drm/display: Fix build error without CONFIG_OF
On 5/6/2022 5:32 AM, YueHaibing wrote: While CONFIG_OF is n but COMPILE_TEST is y, we got this: WARNING: unmet direct dependencies detected for DRM_DP_AUX_BUS Depends on [n]: HAS_IOMEM [=y] && DRM [=y] && OF [=n] Selected by [y]: - DRM_MSM [=y] && HAS_IOMEM [=y] && DRM [=y] && (ARCH_QCOM || SOC_IMX5 || COMPILE_TEST [=y]) && COMMON_CLK [=y] && IOMMU_SUPPORT [=y] && (QCOM_OCMEM [=n] || QCOM_OCMEM [=n]=n) && (QCOM_LLCC [=y] || QCOM_LLCC [=y]=n) && (QCOM_COMMAND_DB [=n] || QCOM_COMMAND_DB [=n]=n) Make DRM_DP_AUX_BUS depends on OF || COMPILE_TEST to fix this warning. Fixes: f5d01644921b ("drm/msm: select DRM_DP_AUX_BUS for the AUX bus support") Signed-off-by: YueHaibing Reviewed-by: Abhinav Kumar --- v2: fix this in DRM_DP_AUX_BUS dependencies --- drivers/gpu/drm/display/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/display/Kconfig b/drivers/gpu/drm/display/Kconfig index 1b6e6af37546..09712b88a5b8 100644 --- a/drivers/gpu/drm/display/Kconfig +++ b/drivers/gpu/drm/display/Kconfig @@ -3,7 +3,7 @@ config DRM_DP_AUX_BUS tristate depends on DRM - depends on OF + depends on OF || COMPILE_TEST config DRM_DISPLAY_HELPER tristate
Re: [Intel-gfx] [PATCH] fbdev: efifb: Fix a use-after-free due early fb_info cleanup
Hi Javier, On Fri, May 06, 2022 at 03:22:25PM +0200, Javier Martinez Canillas wrote: > Commit d258d00fb9c7 ("fbdev: efifb: Cleanup fb_info in .fb_destroy rather > than .remove") attempted to fix a use-after-free error due driver freeing > the fb_info in the .remove handler instead of doing it in .fb_destroy. > > But ironically that change introduced yet another use-after-free since the > fb_info was still used after the free. > > This should fix for good by freeing the fb_info at the end of the handler. > > Fixes: d258d00fb9c7 ("fbdev: efifb: Cleanup fb_info in .fb_destroy rather > than .remove") > Reported-by: Ville Syrjälä > Reported-by: Andrzej Hajda > Signed-off-by: Javier Martinez Canillas Reviewed-by: Andi Shyti Andi
Re: [Intel-gfx] [PATCH v2] drm/i915/guc: Support programming the EU priority in the GuC descriptor
On 5/6/2022 12:51 AM, Tvrtko Ursulin wrote: On 05/05/2022 19:56, John Harrison wrote: On 5/4/2022 16:46, Daniele Ceraolo Spurio wrote: From: Matthew Brost In GuC submission mode the EU priority must be updated by the GuC rather than the driver as the GuC owns the programming of the context descriptor. Given that the GuC code uses the GuC priorities, we can't use a generic function using i915 priorities for both execlists and GuC submission. The existing function has therefore been pushed to the execlists back-end while a new one has been added for GuC. v2: correctly use the GuC prio. Cc: John Harrison Cc: Matt Roper Signed-off-by: Matthew Brost Signed-off-by: Aravind Iddamsetty Signed-off-by: Daniele Ceraolo Spurio Reviewed-by: John Harrison I've asked for this already - since this seems a fix relevant for DG2, but now that it has been merged without a Fixes: tag, it will not get picked up for 5.19 by the scripts. Maybe I can cherry pick it manually in a few weeks, or maybe you guys can send it to stable manually once 5.19 is released, please make a reminder item if you think 5.19 should have it. I didn't add the tag because DG2 still requires force_probe. If sending fixes for DG2 is ok, I'll make a reminder and I'll send it manually later. Thanks, Daniele Regards, Tvrtko --- .../drm/i915/gt/intel_execlists_submission.c | 12 +- drivers/gpu/drm/i915/gt/intel_lrc.h | 10 - .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 22 +++ 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c index 86f7a9ac1c394..2b0266cab66b9 100644 --- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c +++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c @@ -661,6 +661,16 @@ static inline void execlists_schedule_out(struct i915_request *rq) i915_request_put(rq); } +static u32 map_i915_prio_to_lrc_desc_prio(int prio) +{ + if (prio > I915_PRIORITY_NORMAL) + return GEN12_CTX_PRIORITY_HIGH; + else if (prio < I915_PRIORITY_NORMAL) + return GEN12_CTX_PRIORITY_LOW; + else + return GEN12_CTX_PRIORITY_NORMAL; +} + static u64 execlists_update_context(struct i915_request *rq) { struct intel_context *ce = rq->context; @@ -669,7 +679,7 @@ static u64 execlists_update_context(struct i915_request *rq) desc = ce->lrc.desc; if (rq->engine->flags & I915_ENGINE_HAS_EU_PRIORITY) - desc |= lrc_desc_priority(rq_prio(rq)); + desc |= map_i915_prio_to_lrc_desc_prio(rq_prio(rq)); /* * WaIdleLiteRestore:bdw,skl diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.h b/drivers/gpu/drm/i915/gt/intel_lrc.h index 31be734010db3..a390f0813c8b6 100644 --- a/drivers/gpu/drm/i915/gt/intel_lrc.h +++ b/drivers/gpu/drm/i915/gt/intel_lrc.h @@ -111,16 +111,6 @@ enum { #define XEHP_SW_COUNTER_SHIFT 58 #define XEHP_SW_COUNTER_WIDTH 6 -static inline u32 lrc_desc_priority(int prio) -{ - if (prio > I915_PRIORITY_NORMAL) - return GEN12_CTX_PRIORITY_HIGH; - else if (prio < I915_PRIORITY_NORMAL) - return GEN12_CTX_PRIORITY_LOW; - else - return GEN12_CTX_PRIORITY_NORMAL; -} - static inline void lrc_runtime_start(struct intel_context *ce) { struct intel_context_stats *stats = >stats; diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c index 75291e9846c50..8bf8b6d588d43 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c @@ -2394,6 +2394,26 @@ static int guc_context_policy_init(struct intel_context *ce, bool loop) return ret; } +static u32 map_guc_prio_to_lrc_desc_prio(u8 prio) +{ + /* + * this matches the mapping we do in map_i915_prio_to_guc_prio() + * (e.g. prio < I915_PRIORITY_NORMAL maps to GUC_CLIENT_PRIORITY_NORMAL) + */ + switch (prio) { + default: + MISSING_CASE(prio); + fallthrough; + case GUC_CLIENT_PRIORITY_KMD_NORMAL: + return GEN12_CTX_PRIORITY_NORMAL; + case GUC_CLIENT_PRIORITY_NORMAL: + return GEN12_CTX_PRIORITY_LOW; + case GUC_CLIENT_PRIORITY_HIGH: + case GUC_CLIENT_PRIORITY_KMD_HIGH: + return GEN12_CTX_PRIORITY_HIGH; + } +} + static void prepare_context_registration_info(struct intel_context *ce, struct guc_ctxt_registration_info *info) { @@ -2420,6 +2440,8 @@ static void prepare_context_registration_info(struct intel_context *ce, */ info->hwlrca_lo = lower_32_bits(ce->lrc.lrca); info->hwlrca_hi = upper_32_bits(ce->lrc.lrca); + if (engine->flags & I915_ENGINE_HAS_EU_PRIORITY) + info->hwlrca_lo |= map_guc_prio_to_lrc_desc_prio(ce->guc_state.prio); info->flags = CONTEXT_REGISTRATION_FLAG_KMD; /*
Re: [Intel-gfx] [PATCH v7 6/7] drm/i915/gt: Create per-tile RPS sysfs interfaces
Hi Jani, On Fri, May 06, 2022 at 02:53:50PM +0300, Jani Nikula wrote: > On Sat, 19 Mar 2022, Andi Shyti wrote: > > +#define INTEL_GT_RPS_SYSFS_ATTR(_name, _mode, _show, _store) \ > > + struct device_attribute dev_attr_gt_##_name = __ATTR(gt_##_name, _mode, > > _show, _store); \ > > + struct device_attribute dev_attr_rps_##_name = __ATTR(rps_##_name, > > _mode, _show, _store) > > Consider this macro... > > > + > > +#define INTEL_GT_RPS_SYSFS_ATTR_RO(_name) \ > > + INTEL_GT_RPS_SYSFS_ATTR(_name, 0444, _name##_show, NULL) > > +#define INTEL_GT_RPS_SYSFS_ATTR_RW(_name) \ > > + INTEL_GT_RPS_SYSFS_ATTR(_name, 0644, _name##_show, > > _name##_store) > > + > > +static INTEL_GT_RPS_SYSFS_ATTR_RO(act_freq_mhz); > > +static INTEL_GT_RPS_SYSFS_ATTR_RO(cur_freq_mhz); > > +static INTEL_GT_RPS_SYSFS_ATTR_RW(boost_freq_mhz); > > +static INTEL_GT_RPS_SYSFS_ATTR_RO(RP0_freq_mhz); > > +static INTEL_GT_RPS_SYSFS_ATTR_RO(RP1_freq_mhz); > > +static INTEL_GT_RPS_SYSFS_ATTR_RO(RPn_freq_mhz); > > +static INTEL_GT_RPS_SYSFS_ATTR_RW(max_freq_mhz); > > +static INTEL_GT_RPS_SYSFS_ATTR_RW(min_freq_mhz); > > ...and the static keyword here. > > All of the dev_attr_rps_* attributes become non-static, as the static > only applies to the dev_attr_gt_* attributes: right! Missed that! Thanks, will send the fix. Thanks, Andi > CHECK drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c > drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c:468:8: warning: symbol > 'dev_attr_rps_act_freq_mhz' was not declared. Should it be static? > drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c:469:8: warning: symbol > 'dev_attr_rps_cur_freq_mhz' was not declared. Should it be static? > drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c:470:8: warning: symbol > 'dev_attr_rps_boost_freq_mhz' was not declared. Should it be static? > drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c:471:8: warning: symbol > 'dev_attr_rps_RP0_freq_mhz' was not declared. Should it be static? > drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c:472:8: warning: symbol > 'dev_attr_rps_RP1_freq_mhz' was not declared. Should it be static? > drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c:473:8: warning: symbol > 'dev_attr_rps_RPn_freq_mhz' was not declared. Should it be static? > drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c:474:8: warning: symbol > 'dev_attr_rps_max_freq_mhz' was not declared. Should it be static? > drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c:475:8: warning: symbol > 'dev_attr_rps_min_freq_mhz' was not declared. Should it be static? > > BR, > Jani. > > > -- > Jani Nikula, Intel Open Source Graphics Center
Re: [Intel-gfx] [PATCH 07/11] drm/i915/pvc: Engines definitions for new copy engines
On Fri, May 06, 2022 at 08:21:46AM +0100, Tvrtko Ursulin wrote: > > On 05/05/2022 21:59, Matt Roper wrote: > > On Tue, May 03, 2022 at 09:05:43AM +0100, Tvrtko Ursulin wrote: > > > > > > On 02/05/2022 17:34, Matt Roper wrote: > > > > This patch adds the basic definitions needed to support > > > > new copy engines. Also updating the cmd_info to accommodate > > > > new engines, as the engine id's of legacy engines have been > > > > changed. > > > > > > > > Original-author: CQ Tang > > > > Signed-off-by: Matt Roper > > > > --- > > > >drivers/gpu/drm/i915/gt/intel_engine_cs.c| 56 > > > > > > > >drivers/gpu/drm/i915/gt/intel_engine_types.h | 10 +++- > > > >drivers/gpu/drm/i915/gt/intel_gt_regs.h | 8 +++ > > > >drivers/gpu/drm/i915/gvt/cmd_parser.c| 2 +- > > > >drivers/gpu/drm/i915/i915_reg.h | 8 +++ > > > >5 files changed, 82 insertions(+), 2 deletions(-) > > > > > > > > diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c > > > > b/drivers/gpu/drm/i915/gt/intel_engine_cs.c > > > > index 14c6ddbbfde8..4532c3ea9ace 100644 > > > > --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c > > > > +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c > > > > @@ -71,6 +71,62 @@ static const struct engine_info intel_engines[] = { > > > > { .graphics_ver = 6, .base = BLT_RING_BASE } > > > > }, > > > > }, > > > > + [BCS1] = { > > > > + .class = COPY_ENGINE_CLASS, > > > > + .instance = 1, > > > > + .mmio_bases = { > > > > + { .graphics_ver = 12, .base = > > > > XEHPC_BCS1_RING_BASE } > > > > + }, > > > > + }, > > > > + [BCS2] = { > > > > + .class = COPY_ENGINE_CLASS, > > > > + .instance = 2, > > > > + .mmio_bases = { > > > > + { .graphics_ver = 12, .base = > > > > XEHPC_BCS2_RING_BASE } > > > > + }, > > > > + }, > > > > + [BCS3] = { > > > > + .class = COPY_ENGINE_CLASS, > > > > + .instance = 3, > > > > + .mmio_bases = { > > > > + { .graphics_ver = 12, .base = > > > > XEHPC_BCS3_RING_BASE } > > > > + }, > > > > + }, > > > > + [BCS4] = { > > > > + .class = COPY_ENGINE_CLASS, > > > > + .instance = 4, > > > > + .mmio_bases = { > > > > + { .graphics_ver = 12, .base = > > > > XEHPC_BCS4_RING_BASE } > > > > + }, > > > > + }, > > > > + [BCS5] = { > > > > + .class = COPY_ENGINE_CLASS, > > > > + .instance = 5, > > > > + .mmio_bases = { > > > > + { .graphics_ver = 12, .base = > > > > XEHPC_BCS5_RING_BASE } > > > > + }, > > > > + }, > > > > + [BCS6] = { > > > > + .class = COPY_ENGINE_CLASS, > > > > + .instance = 6, > > > > + .mmio_bases = { > > > > + { .graphics_ver = 12, .base = > > > > XEHPC_BCS6_RING_BASE } > > > > + }, > > > > + }, > > > > + [BCS7] = { > > > > + .class = COPY_ENGINE_CLASS, > > > > + .instance = 7, > > > > + .mmio_bases = { > > > > + { .graphics_ver = 12, .base = > > > > XEHPC_BCS7_RING_BASE } > > > > + }, > > > > + }, > > > > + [BCS8] = { > > > > + .class = COPY_ENGINE_CLASS, > > > > + .instance = 8, > > > > + .mmio_bases = { > > > > + { .graphics_ver = 12, .base = > > > > XEHPC_BCS8_RING_BASE } > > > > + }, > > > > + }, > > > > [VCS0] = { > > > > .class = VIDEO_DECODE_CLASS, > > > > .instance = 0, > > > > diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h > > > > b/drivers/gpu/drm/i915/gt/intel_engine_types.h > > > > index 298f2cc7a879..356c15cdccf0 100644 > > > > --- a/drivers/gpu/drm/i915/gt/intel_engine_types.h > > > > +++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h > > > > @@ -35,7 +35,7 @@ > > > >#define OTHER_CLASS 4 > > > >#define COMPUTE_CLASS5 > > > >#define MAX_ENGINE_CLASS 5 > > > > -#define MAX_ENGINE_INSTANCE7 > > > > +#define MAX_ENGINE_INSTANCE8 > > > >#define I915_MAX_SLICES 3 > > > >#define I915_MAX_SUBSLICES 8 > > > > @@ -107,6 +107,14 @@ struct i915_ctx_workarounds { > > > >enum intel_engine_id { > > > > RCS0 = 0, > > > > BCS0, > > > > + BCS1, > > > > + BCS2, > > > > + BCS3, > > > > + BCS4, > > > > + BCS5, > > > > + BCS6, > > > > + BCS7, > > > > + BCS8, > > > > > > _BCS(n) macro will not be required? > > > > > > > VCS0, > > > > VCS1, > > > > VCS2, > > > >
Re: [PATCH v3 4/5] drm/gud: Map framebuffer BOs with drm_gem_fb_vmap()
Hi Am 06.05.22 um 16:01 schrieb Noralf Trønnes: Hi Thomas, I'm getting this on Ubuntu 22.04: [0.00] Linux version 5.15.0-27-generic (buildd@ubuntu) (gcc (Ubuntu 11.2.0-19ubuntu1) 11.2.0, GNU ld (GNU Binutils for Ubuntu) 2.38) #28-Ubuntu SMP Thu Apr 14 04:55:28 UTC 2022 (Ubuntu 5.15.0-27.28-generic 5.15.30) [4.830866] usb 2-3.1: new high-speed USB device number 4 using xhci_hcd [4.935546] usb 2-3.1: New USB device found, idVendor=1d50, idProduct=614d, bcdDevice= 1.00 [4.935553] usb 2-3.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 [4.935556] usb 2-3.1: Product: Raspberry Pi 4 Display Gadget [4.935558] usb 2-3.1: Manufacturer: Raspberry Pi [4.935560] usb 2-3.1: SerialNumber: 10003b40d6c6 [7.497361] [drm] Initialized gud 1.0.0 20200422 for 2-3.1:1.0 on minor 0 [7.573048] gud 2-3.1:1.0: [drm] fb1: guddrmfb frame buffer device [9.199402] [9.199411] UBSAN: invalid-load in /build/linux-HMZHpV/linux-5.15.0/include/linux/dma-buf-map.h:224:9 [9.199416] load of value 226 is not a valid value for type '_Bool' [9.199420] CPU: 0 PID: 113 Comm: kworker/0:2 Not tainted 5.15.0-27-generic #28-Ubuntu [9.199424] Hardware name: Hewlett-Packard HP EliteBook 820 G1/1991, BIOS L71 Ver. 01.44 04/12/2018 [9.199427] Workqueue: events_long gud_flush_work [gud] [9.199440] Call Trace: [9.199443] [9.199447] show_stack+0x52/0x58 [9.199456] dump_stack_lvl+0x4a/0x5f [9.199464] dump_stack+0x10/0x12 [9.199468] ubsan_epilogue+0x9/0x45 [9.199473] __ubsan_handle_load_invalid_value.cold+0x44/0x49 [9.199478] drm_gem_fb_vmap.cold+0x10/0x3d [drm_kms_helper] [9.199519] gud_prep_flush+0xaa/0x410 [gud] [9.199525] ? check_preempt_curr+0x5d/0x70 [9.199533] ? update_load_avg+0x82/0x620 [9.199540] ? set_next_entity+0xb7/0x200 [9.199545] gud_flush_work+0x1e0/0x430 [gud] [9.199551] ? psi_task_switch+0x1e7/0x220 [9.199557] process_one_work+0x22b/0x3d0 [9.199564] worker_thread+0x53/0x410 [9.199570] ? process_one_work+0x3d0/0x3d0 [9.199575] kthread+0x12a/0x150 [9.199579] ? set_kthread_struct+0x50/0x50 [9.199584] ret_from_fork+0x22/0x30 [9.199593] [9.199595] [9.199598] [9.199600] UBSAN: invalid-load in /build/linux-HMZHpV/linux-5.15.0/include/linux/dma-buf-map.h:194:9 [9.199604] load of value 226 is not a valid value for type '_Bool' [9.199606] CPU: 0 PID: 113 Comm: kworker/0:2 Not tainted 5.15.0-27-generic #28-Ubuntu [9.199610] Hardware name: Hewlett-Packard HP EliteBook 820 G1/1991, BIOS L71 Ver. 01.44 04/12/2018 [9.199612] Workqueue: events_long gud_flush_work [gud] [9.199618] Call Trace: [9.199619] [9.199621] show_stack+0x52/0x58 [9.199627] dump_stack_lvl+0x4a/0x5f [9.199633] dump_stack+0x10/0x12 [9.199637] ubsan_epilogue+0x9/0x45 [9.199641] __ubsan_handle_load_invalid_value.cold+0x44/0x49 [9.199646] drm_gem_fb_vmap.cold+0x24/0x3d [drm_kms_helper] [9.199675] gud_prep_flush+0xaa/0x410 [gud] [9.199682] ? check_preempt_curr+0x5d/0x70 [9.199688] ? update_load_avg+0x82/0x620 [9.199693] ? update_load_avg+0x82/0x620 [9.199697] gud_flush_work+0x1e0/0x430 [gud] [9.199702] ? psi_task_switch+0x1e7/0x220 [9.199706] process_one_work+0x22b/0x3d0 [9.199713] worker_thread+0x53/0x410 [9.199718] ? process_one_work+0x3d0/0x3d0 [9.199723] kthread+0x12a/0x150 [9.199728] ? set_kthread_struct+0x50/0x50 [9.199732] ret_from_fork+0x22/0x30 [9.199741] [9.199743] It's the "if (map->is_iomem)" statement in dma_buf_map_clear() and dma_buf_map_is_null() that triggers this. I tried 5.18.0-rc5 and the problem is still present. UBSAN entries in the config: CONFIG_ARCH_HAS_UBSAN_SANITIZE_ALL=y CONFIG_UBSAN=y # CONFIG_UBSAN_TRAP is not set CONFIG_CC_HAS_UBSAN_BOUNDS=y CONFIG_UBSAN_BOUNDS=y CONFIG_UBSAN_ONLY_BOUNDS=y CONFIG_UBSAN_SHIFT=y # CONFIG_UBSAN_DIV_ZERO is not set CONFIG_UBSAN_BOOL=y CONFIG_UBSAN_ENUM=y # CONFIG_UBSAN_ALIGNMENT is not set CONFIG_UBSAN_SANITIZE_ALL=y # CONFIG_TEST_UBSAN is not set Continuing further down. Den 30.07.2021 20.35, skrev Thomas Zimmermann: Abstract the framebuffer details by mapping its BOs with a call to drm_gem_fb_vmap(). Unmap with drm_gem_fb_vunmap(). The call to drm_gem_fb_vmap() ensures that all BOs are mapped correctly. Gud still only supports single-plane formats. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Noralf Trønnes Acked-by: Sam Ravnborg --- drivers/gpu/drm/gud/gud_pipe.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git
Re: [PATCH 1/5] dma-buf: cleanup dma_fence_unwrap selftest v2
I had to send this out once more. This time with the right mail addresses and a much simplified patch #3. Christian. Am 06.05.22 um 16:10 schrieb Christian König: The selftests, fix the error handling, remove unused functions and stop leaking memory in failed tests. v2: fix the memory leak correctly. Signed-off-by: Christian König --- drivers/dma-buf/st-dma-fence-unwrap.c | 48 +++ 1 file changed, 19 insertions(+), 29 deletions(-) diff --git a/drivers/dma-buf/st-dma-fence-unwrap.c b/drivers/dma-buf/st-dma-fence-unwrap.c index 039f016b57be..e20c5a7dcfe4 100644 --- a/drivers/dma-buf/st-dma-fence-unwrap.c +++ b/drivers/dma-buf/st-dma-fence-unwrap.c @@ -4,27 +4,19 @@ * Copyright (C) 2022 Advanced Micro Devices, Inc. */ +#include +#include +#include #include -#if 0 -#include -#include -#include -#include -#include -#include -#include -#endif #include "selftest.h" #define CHAIN_SZ (4 << 10) -static inline struct mock_fence { +struct mock_fence { struct dma_fence base; spinlock_t lock; -} *to_mock_fence(struct dma_fence *f) { - return container_of(f, struct mock_fence, base); -} +}; static const char *mock_name(struct dma_fence *f) { @@ -45,7 +37,8 @@ static struct dma_fence *mock_fence(void) return NULL; spin_lock_init(>lock); - dma_fence_init(>base, _ops, >lock, 0, 0); + dma_fence_init(>base, _ops, >lock, + dma_fence_context_alloc(1), 1); return >base; } @@ -59,7 +52,7 @@ static struct dma_fence *mock_array(unsigned int num_fences, ...) fences = kcalloc(num_fences, sizeof(*fences), GFP_KERNEL); if (!fences) - return NULL; + goto error_put; va_start(valist, num_fences); for (i = 0; i < num_fences; ++i) @@ -70,13 +63,17 @@ static struct dma_fence *mock_array(unsigned int num_fences, ...) dma_fence_context_alloc(1), 1, false); if (!array) - goto cleanup; + goto error_free; return >base; -cleanup: - for (i = 0; i < num_fences; ++i) - dma_fence_put(fences[i]); +error_free: kfree(fences); + +error_put: + va_start(valist, num_fences); + for (i = 0; i < num_fences; ++i) + dma_fence_put(va_arg(valist, typeof(*fences))); + va_end(valist); return NULL; } @@ -113,7 +110,6 @@ static int sanitycheck(void *arg) if (!chain) return -ENOMEM; - dma_fence_signal(f); dma_fence_put(chain); return err; } @@ -154,10 +150,8 @@ static int unwrap_array(void *arg) err = -EINVAL; } - dma_fence_signal(f1); - dma_fence_signal(f2); dma_fence_put(array); - return 0; + return err; } static int unwrap_chain(void *arg) @@ -196,10 +190,8 @@ static int unwrap_chain(void *arg) err = -EINVAL; } - dma_fence_signal(f1); - dma_fence_signal(f2); dma_fence_put(chain); - return 0; + return err; } static int unwrap_chain_array(void *arg) @@ -242,10 +234,8 @@ static int unwrap_chain_array(void *arg) err = -EINVAL; } - dma_fence_signal(f1); - dma_fence_signal(f2); dma_fence_put(chain); - return 0; + return err; } int dma_fence_unwrap(void)
[PATCH 5/5] drm: use dma_fence_unwrap_merge() in drm_syncobj
The unwrap merge function is now intended for this use case. Signed-off-by: Christian König Reviewed-by: Daniel Vetter --- drivers/gpu/drm/drm_syncobj.c | 57 +-- 1 file changed, 7 insertions(+), 50 deletions(-) diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 7e48dcd1bee4..bbad9e4696e7 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -184,6 +184,7 @@ */ #include +#include #include #include #include @@ -853,57 +854,12 @@ drm_syncobj_fd_to_handle_ioctl(struct drm_device *dev, void *data, >handle); } - -/* - * Try to flatten a dma_fence_chain into a dma_fence_array so that it can be - * added as timeline fence to a chain again. - */ -static int drm_syncobj_flatten_chain(struct dma_fence **f) -{ - struct dma_fence_chain *chain = to_dma_fence_chain(*f); - struct dma_fence *tmp, **fences; - struct dma_fence_array *array; - unsigned int count; - - if (!chain) - return 0; - - count = 0; - dma_fence_chain_for_each(tmp, >base) - ++count; - - fences = kmalloc_array(count, sizeof(*fences), GFP_KERNEL); - if (!fences) - return -ENOMEM; - - count = 0; - dma_fence_chain_for_each(tmp, >base) - fences[count++] = dma_fence_get(tmp); - - array = dma_fence_array_create(count, fences, - dma_fence_context_alloc(1), - 1, false); - if (!array) - goto free_fences; - - dma_fence_put(*f); - *f = >base; - return 0; - -free_fences: - while (count--) - dma_fence_put(fences[count]); - - kfree(fences); - return -ENOMEM; -} - static int drm_syncobj_transfer_to_timeline(struct drm_file *file_private, struct drm_syncobj_transfer *args) { struct drm_syncobj *timeline_syncobj = NULL; + struct dma_fence *fence, *tmp; struct dma_fence_chain *chain; - struct dma_fence *fence; int ret; timeline_syncobj = drm_syncobj_find(file_private, args->dst_handle); @@ -912,13 +868,14 @@ static int drm_syncobj_transfer_to_timeline(struct drm_file *file_private, } ret = drm_syncobj_find_fence(file_private, args->src_handle, args->src_point, args->flags, -); +); if (ret) goto err_put_timeline; - ret = drm_syncobj_flatten_chain(); - if (ret) - goto err_free_fence; + fence = dma_fence_unwrap_merge(tmp); + dma_fence_put(tmp); + if (!fence) + goto err_put_timeline; chain = dma_fence_chain_alloc(); if (!chain) { -- 2.25.1
[PATCH 3/5] dma-buf: return only unsignaled fences in dma_fence_unwrap_for_each v3
dma_fence_chain containers cleanup signaled fences automatically, so filter those out from arrays as well. v2: fix missing walk over the array v3: massively simplify the patch and actually update the description. Signed-off-by: Christian König --- include/linux/dma-fence-unwrap.h | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/linux/dma-fence-unwrap.h b/include/linux/dma-fence-unwrap.h index e7c219da4ed7..a4d342fef8e0 100644 --- a/include/linux/dma-fence-unwrap.h +++ b/include/linux/dma-fence-unwrap.h @@ -43,9 +43,13 @@ struct dma_fence *dma_fence_unwrap_next(struct dma_fence_unwrap *cursor); * Unwrap dma_fence_chain and dma_fence_array containers and deep dive into all * potential fences in them. If @head is just a normal fence only that one is * returned. + * + * Note that signalled fences are opportunistically filtered out, which + * means the iteration is potentially over no fence at all. */ #define dma_fence_unwrap_for_each(fence, cursor, head) \ for (fence = dma_fence_unwrap_first(head, cursor); fence; \ -fence = dma_fence_unwrap_next(cursor)) +fence = dma_fence_unwrap_next(cursor)) \ + if (!dma_fence_is_signaled(fence)) #endif -- 2.25.1
[PATCH 2/5] dma-buf: cleanup dma_fence_unwrap implementation
Move the code from the inline functions into exported functions. Signed-off-by: Christian König Acked-by: Daniel Vetter --- drivers/dma-buf/Makefile | 2 +- drivers/dma-buf/dma-fence-unwrap.c | 59 ++ include/linux/dma-fence-unwrap.h | 52 ++ 3 files changed, 64 insertions(+), 49 deletions(-) create mode 100644 drivers/dma-buf/dma-fence-unwrap.c diff --git a/drivers/dma-buf/Makefile b/drivers/dma-buf/Makefile index 4c9eb53ba3f8..70ec901edf2c 100644 --- a/drivers/dma-buf/Makefile +++ b/drivers/dma-buf/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only obj-y := dma-buf.o dma-fence.o dma-fence-array.o dma-fence-chain.o \ -dma-resv.o +dma-fence-unwrap.o dma-resv.o obj-$(CONFIG_DMABUF_HEAPS) += dma-heap.o obj-$(CONFIG_DMABUF_HEAPS) += heaps/ obj-$(CONFIG_SYNC_FILE)+= sync_file.o diff --git a/drivers/dma-buf/dma-fence-unwrap.c b/drivers/dma-buf/dma-fence-unwrap.c new file mode 100644 index ..711be125428c --- /dev/null +++ b/drivers/dma-buf/dma-fence-unwrap.c @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * dma-fence-util: misc functions for dma_fence objects + * + * Copyright (C) 2022 Advanced Micro Devices, Inc. + * Authors: + * Christian König + */ + +#include +#include +#include +#include + +/* Internal helper to start new array iteration, don't use directly */ +static struct dma_fence * +__dma_fence_unwrap_array(struct dma_fence_unwrap *cursor) +{ + cursor->array = dma_fence_chain_contained(cursor->chain); + cursor->index = 0; + return dma_fence_array_first(cursor->array); +} + +/** + * dma_fence_unwrap_first - return the first fence from fence containers + * @head: the entrypoint into the containers + * @cursor: current position inside the containers + * + * Unwraps potential dma_fence_chain/dma_fence_array containers and return the + * first fence. + */ +struct dma_fence *dma_fence_unwrap_first(struct dma_fence *head, +struct dma_fence_unwrap *cursor) +{ + cursor->chain = dma_fence_get(head); + return __dma_fence_unwrap_array(cursor); +} +EXPORT_SYMBOL_GPL(dma_fence_unwrap_first); + +/** + * dma_fence_unwrap_next - return the next fence from a fence containers + * @cursor: current position inside the containers + * + * Continue unwrapping the dma_fence_chain/dma_fence_array containers and return + * the next fence from them. + */ +struct dma_fence *dma_fence_unwrap_next(struct dma_fence_unwrap *cursor) +{ + struct dma_fence *tmp; + + ++cursor->index; + tmp = dma_fence_array_next(cursor->array, cursor->index); + if (tmp) + return tmp; + + cursor->chain = dma_fence_chain_walk(cursor->chain); + return __dma_fence_unwrap_array(cursor); +} +EXPORT_SYMBOL_GPL(dma_fence_unwrap_next); diff --git a/include/linux/dma-fence-unwrap.h b/include/linux/dma-fence-unwrap.h index 77e335a1bcac..e7c219da4ed7 100644 --- a/include/linux/dma-fence-unwrap.h +++ b/include/linux/dma-fence-unwrap.h @@ -1,7 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * fence-chain: chain fences together in a timeline - * * Copyright (C) 2022 Advanced Micro Devices, Inc. * Authors: * Christian König @@ -10,8 +8,7 @@ #ifndef __LINUX_DMA_FENCE_UNWRAP_H #define __LINUX_DMA_FENCE_UNWRAP_H -#include -#include +struct dma_fence; /** * struct dma_fence_unwrap - cursor into the container structure @@ -33,50 +30,9 @@ struct dma_fence_unwrap { unsigned int index; }; -/* Internal helper to start new array iteration, don't use directly */ -static inline struct dma_fence * -__dma_fence_unwrap_array(struct dma_fence_unwrap * cursor) -{ - cursor->array = dma_fence_chain_contained(cursor->chain); - cursor->index = 0; - return dma_fence_array_first(cursor->array); -} - -/** - * dma_fence_unwrap_first - return the first fence from fence containers - * @head: the entrypoint into the containers - * @cursor: current position inside the containers - * - * Unwraps potential dma_fence_chain/dma_fence_array containers and return the - * first fence. - */ -static inline struct dma_fence * -dma_fence_unwrap_first(struct dma_fence *head, struct dma_fence_unwrap *cursor) -{ - cursor->chain = dma_fence_get(head); - return __dma_fence_unwrap_array(cursor); -} - -/** - * dma_fence_unwrap_next - return the next fence from a fence containers - * @cursor: current position inside the containers - * - * Continue unwrapping the dma_fence_chain/dma_fence_array containers and return - * the next fence from them. - */ -static inline struct dma_fence * -dma_fence_unwrap_next(struct dma_fence_unwrap *cursor) -{ - struct dma_fence *tmp; - - ++cursor->index; - tmp = dma_fence_array_next(cursor->array, cursor->index); - if (tmp) - return tmp; - - cursor->chain =
[PATCH 4/5] dma-buf: generalize dma_fence unwrap & merging v2
Introduce a dma_fence_unwrap_merge() macro which allows to unwrap fences which potentially can be containers as well and then merge them back together into a flat dma_fence_array. v2: rename the function, add some more comments about how the wrapper is used, move filtering of signaled fences into the unwrap iterator, add complex selftest which covers more cases. Signed-off-by: Christian König Reviewed-by: Daniel Vetter --- drivers/dma-buf/dma-fence-unwrap.c| 99 + drivers/dma-buf/st-dma-fence-unwrap.c | 109 +++ drivers/dma-buf/sync_file.c | 119 ++ include/linux/dma-fence-unwrap.h | 24 ++ 4 files changed, 238 insertions(+), 113 deletions(-) diff --git a/drivers/dma-buf/dma-fence-unwrap.c b/drivers/dma-buf/dma-fence-unwrap.c index 711be125428c..0e51547bbabd 100644 --- a/drivers/dma-buf/dma-fence-unwrap.c +++ b/drivers/dma-buf/dma-fence-unwrap.c @@ -11,6 +11,7 @@ #include #include #include +#include /* Internal helper to start new array iteration, don't use directly */ static struct dma_fence * @@ -57,3 +58,101 @@ struct dma_fence *dma_fence_unwrap_next(struct dma_fence_unwrap *cursor) return __dma_fence_unwrap_array(cursor); } EXPORT_SYMBOL_GPL(dma_fence_unwrap_next); + +/* Implementation for the dma_fence_merge() marco, don't use directly */ +struct dma_fence *__dma_fence_unwrap_merge(unsigned int num_fences, + struct dma_fence **fences, + struct dma_fence_unwrap *iter) +{ + struct dma_fence_array *result; + struct dma_fence *tmp, **array; + unsigned int i; + size_t count; + + count = 0; + for (i = 0; i < num_fences; ++i) { + dma_fence_unwrap_for_each(tmp, [i], fences[i]) + ++count; + } + + if (count == 0) + return dma_fence_get_stub(); + + array = kmalloc_array(count, sizeof(*array), GFP_KERNEL); + if (!array) + return NULL; + + /* +* This trashes the input fence array and uses it as position for the +* following merge loop. This works because the dma_fence_merge() +* wrapper macro is creating this temporary array on the stack together +* with the iterators. +*/ + for (i = 0; i < num_fences; ++i) + fences[i] = dma_fence_unwrap_first(fences[i], [i]); + + count = 0; + do { + unsigned int sel; + +restart: + tmp = NULL; + for (i = 0; i < num_fences; ++i) { + struct dma_fence *next = fences[i]; + + if (!next) + continue; + + /* +* We can't guarantee that inpute fences are ordered by +* context, but it is still quite likely when this +* function is used multiple times. So attempt to order +* the fences by context as we pass over them and merge +* fences with the same context. +*/ + if (!tmp || tmp->context > next->context) { + tmp = next; + sel = i; + + } else if (tmp->context < next->context) { + continue; + + } else if (dma_fence_is_later(tmp, next)) { + fences[i] = dma_fence_unwrap_next([i]); + goto restart; + } else { + fences[sel] = dma_fence_unwrap_next([sel]); + goto restart; + } + } + + if (tmp) { + array[count++] = dma_fence_get(tmp); + fences[sel] = dma_fence_unwrap_next([sel]); + } + } while (tmp); + + if (count == 0) { + tmp = dma_fence_get_stub(); + goto return_tmp; + } + + if (count == 1) { + tmp = array[0]; + goto return_tmp; + } + + result = dma_fence_array_create(count, array, + dma_fence_context_alloc(1), + 1, false); + if (!result) { + tmp = NULL; + goto return_tmp; + } + return >base; + +return_tmp: + kfree(array); + return tmp; +} +EXPORT_SYMBOL_GPL(__dma_fence_unwrap_merge); diff --git a/drivers/dma-buf/st-dma-fence-unwrap.c b/drivers/dma-buf/st-dma-fence-unwrap.c index e20c5a7dcfe4..4105d5ea8dde 100644 --- a/drivers/dma-buf/st-dma-fence-unwrap.c +++ b/drivers/dma-buf/st-dma-fence-unwrap.c @@ -238,6 +238,113 @@ static int unwrap_chain_array(void *arg) return err; } +static int
[PATCH 1/5] dma-buf: cleanup dma_fence_unwrap selftest v2
The selftests, fix the error handling, remove unused functions and stop leaking memory in failed tests. v2: fix the memory leak correctly. Signed-off-by: Christian König --- drivers/dma-buf/st-dma-fence-unwrap.c | 48 +++ 1 file changed, 19 insertions(+), 29 deletions(-) diff --git a/drivers/dma-buf/st-dma-fence-unwrap.c b/drivers/dma-buf/st-dma-fence-unwrap.c index 039f016b57be..e20c5a7dcfe4 100644 --- a/drivers/dma-buf/st-dma-fence-unwrap.c +++ b/drivers/dma-buf/st-dma-fence-unwrap.c @@ -4,27 +4,19 @@ * Copyright (C) 2022 Advanced Micro Devices, Inc. */ +#include +#include +#include #include -#if 0 -#include -#include -#include -#include -#include -#include -#include -#endif #include "selftest.h" #define CHAIN_SZ (4 << 10) -static inline struct mock_fence { +struct mock_fence { struct dma_fence base; spinlock_t lock; -} *to_mock_fence(struct dma_fence *f) { - return container_of(f, struct mock_fence, base); -} +}; static const char *mock_name(struct dma_fence *f) { @@ -45,7 +37,8 @@ static struct dma_fence *mock_fence(void) return NULL; spin_lock_init(>lock); - dma_fence_init(>base, _ops, >lock, 0, 0); + dma_fence_init(>base, _ops, >lock, + dma_fence_context_alloc(1), 1); return >base; } @@ -59,7 +52,7 @@ static struct dma_fence *mock_array(unsigned int num_fences, ...) fences = kcalloc(num_fences, sizeof(*fences), GFP_KERNEL); if (!fences) - return NULL; + goto error_put; va_start(valist, num_fences); for (i = 0; i < num_fences; ++i) @@ -70,13 +63,17 @@ static struct dma_fence *mock_array(unsigned int num_fences, ...) dma_fence_context_alloc(1), 1, false); if (!array) - goto cleanup; + goto error_free; return >base; -cleanup: - for (i = 0; i < num_fences; ++i) - dma_fence_put(fences[i]); +error_free: kfree(fences); + +error_put: + va_start(valist, num_fences); + for (i = 0; i < num_fences; ++i) + dma_fence_put(va_arg(valist, typeof(*fences))); + va_end(valist); return NULL; } @@ -113,7 +110,6 @@ static int sanitycheck(void *arg) if (!chain) return -ENOMEM; - dma_fence_signal(f); dma_fence_put(chain); return err; } @@ -154,10 +150,8 @@ static int unwrap_array(void *arg) err = -EINVAL; } - dma_fence_signal(f1); - dma_fence_signal(f2); dma_fence_put(array); - return 0; + return err; } static int unwrap_chain(void *arg) @@ -196,10 +190,8 @@ static int unwrap_chain(void *arg) err = -EINVAL; } - dma_fence_signal(f1); - dma_fence_signal(f2); dma_fence_put(chain); - return 0; + return err; } static int unwrap_chain_array(void *arg) @@ -242,10 +234,8 @@ static int unwrap_chain_array(void *arg) err = -EINVAL; } - dma_fence_signal(f1); - dma_fence_signal(f2); dma_fence_put(chain); - return 0; + return err; } int dma_fence_unwrap(void) -- 2.25.1
[PATCH v2 10/11] dt-bindings: display: convert Arm Mali-DP to DT schema
The Arm Mali Display Processor (DP) 5xx/6xx is a series of IP that scans out a framebuffer and hands the pixels over to a digital signal encoder. It supports multiple layers, scaling and rotation. Convert the existing DT binding to DT schema. Signed-off-by: Andre Przywara --- .../bindings/display/arm,malidp.txt | 68 -- .../bindings/display/arm,malidp.yaml | 116 ++ 2 files changed, 116 insertions(+), 68 deletions(-) delete mode 100644 Documentation/devicetree/bindings/display/arm,malidp.txt create mode 100644 Documentation/devicetree/bindings/display/arm,malidp.yaml diff --git a/Documentation/devicetree/bindings/display/arm,malidp.txt b/Documentation/devicetree/bindings/display/arm,malidp.txt deleted file mode 100644 index 7a97a2b48c2a2..0 --- a/Documentation/devicetree/bindings/display/arm,malidp.txt +++ /dev/null @@ -1,68 +0,0 @@ -ARM Mali-DP - -The following bindings apply to a family of Display Processors sold as -licensable IP by ARM Ltd. The bindings describe the Mali DP500, DP550 and -DP650 processors that offer multiple composition layers, support for -rotation and scaling output. - -Required properties: - - compatible: should be one of - "arm,mali-dp500" - "arm,mali-dp550" - "arm,mali-dp650" -depending on the particular implementation present in the hardware - - reg: Physical base address and size of the block of registers used by -the processor. - - interrupts: Interrupt list, as defined in ../interrupt-controller/interrupts.txt, -interrupt client nodes. - - interrupt-names: name of the engine inside the processor that will -use the corresponding interrupt. Should be one of "DE" or "SE". - - clocks: A list of phandle + clock-specifier pairs, one for each entry -in 'clock-names' - - clock-names: A list of clock names. It should contain: - - "pclk": for the APB interface clock - - "aclk": for the AXI interface clock - - "mclk": for the main processor clock - - "pxlclk": for the pixel clock feeding the output PLL of the processor. - - arm,malidp-output-port-lines: Array of u8 values describing the number -of output lines per channel (R, G and B). - -Required sub-nodes: - - port: The Mali DP connection to an encoder input port. The connection -is modelled using the OF graph bindings specified in -Documentation/devicetree/bindings/graph.txt - -Optional properties: - - memory-region: phandle to a node describing memory (see -Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt) -to be used for the framebuffer; if not present, the framebuffer may -be located anywhere in memory. - - arm,malidp-arqos-high-level: integer of u32 value describing the ARQoS -levels of DP500's QoS signaling. - - -Example: - -/ { - ... - - dp0: malidp@6f20 { - compatible = "arm,mali-dp650"; - reg = <0 0x6f20 0 0x2>; - memory-region = <_reserved>; - interrupts = <0 168 IRQ_TYPE_LEVEL_HIGH>, -<0 168 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "DE", "SE"; - clocks = <>, <>, <>, <>; - clock-names = "pxlclk", "mclk", "aclk", "pclk"; - arm,malidp-output-port-lines = /bits/ 8 <8 8 8>; - arm,malidp-arqos-high-level = <0xd000d000>; - port { - dp0_output: endpoint { - remote-endpoint = <_2_input>; - }; - }; - }; - - ... -}; diff --git a/Documentation/devicetree/bindings/display/arm,malidp.yaml b/Documentation/devicetree/bindings/display/arm,malidp.yaml new file mode 100644 index 0..ea7b7100548bf --- /dev/null +++ b/Documentation/devicetree/bindings/display/arm,malidp.yaml @@ -0,0 +1,116 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/arm,malidp.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Arm Mali Display Processor (Mali-DP) binding + +maintainers: + - Liviu Dudau + - Andre Przywara + +description: + The following bindings apply to a family of Display Processors sold as + licensable IP by ARM Ltd. The bindings describe the Mali DP500, DP550 and + DP650 processors that offer multiple composition layers, support for + rotation and scaling output. + +properties: + compatible: +enum: + - arm,mali-dp500 + - arm,mali-dp550 + - arm,mali-dp650 + + reg: +maxItems: 1 + + interrupts: +items: + - description: + The interrupt used by the Display Engine (DE). Can be shared with + the interrupt for the Scaling Engine (SE), but it will have to be + listed individually. + - description: + The interrupt used by the Scaling Engine (SE). Can be shared with + the interrupt for the Display
[PATCH v2 11/11] dt-bindings: display: convert Arm Komeda to DT schema
The Arm Komeda (aka Mali-D71) is a display controller that scans out a framebuffer and hands a signal to a digital encoder to generate a DVI or HDMI signal. It supports up to two pipelines, each frame can be composed of up to four layers. Convert the existing DT binding to DT schema. Signed-off-by: Andre Przywara --- .../bindings/display/arm,komeda.txt | 78 --- .../bindings/display/arm,komeda.yaml | 130 ++ 2 files changed, 130 insertions(+), 78 deletions(-) delete mode 100644 Documentation/devicetree/bindings/display/arm,komeda.txt create mode 100644 Documentation/devicetree/bindings/display/arm,komeda.yaml diff --git a/Documentation/devicetree/bindings/display/arm,komeda.txt b/Documentation/devicetree/bindings/display/arm,komeda.txt deleted file mode 100644 index 8513695ee47fe..0 --- a/Documentation/devicetree/bindings/display/arm,komeda.txt +++ /dev/null @@ -1,78 +0,0 @@ -Device Tree bindings for Arm Komeda display driver - -Required properties: -- compatible: Should be "arm,mali-d71" -- reg: Physical base address and length of the registers in the system -- interrupts: the interrupt line number of the device in the system -- clocks: A list of phandle + clock-specifier pairs, one for each entry -in 'clock-names' -- clock-names: A list of clock names. It should contain: - - "aclk": for the main processor clock -- #address-cells: Must be 1 -- #size-cells: Must be 0 -- iommus: configure the stream id to IOMMU, Must be configured if want to -enable iommu in display. for how to configure this node please reference -devicetree/bindings/iommu/arm,smmu-v3.txt, -devicetree/bindings/iommu/iommu.txt - -Required properties for sub-node: pipeline@nq -Each device contains one or two pipeline sub-nodes (at least one), each -pipeline node should provide properties: -- reg: Zero-indexed identifier for the pipeline -- clocks: A list of phandle + clock-specifier pairs, one for each entry -in 'clock-names' -- clock-names: should contain: - - "pxclk": pixel clock - -- port: each pipeline connect to an encoder input port. The connection is -modeled using the OF graph bindings specified in -Documentation/devicetree/bindings/graph.txt - -Optional properties: - - memory-region: phandle to a node describing memory (see -Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt) -to be used for the framebuffer; if not present, the framebuffer may -be located anywhere in memory. - -Example: -/ { - ... - - dp0: display@c0 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "arm,mali-d71"; - reg = <0xc0 0x2>; - interrupts = <0 168 4>; - clocks = <_aclk>; - clock-names = "aclk"; - iommus = < 0>, < 1>, < 2>, < 3>, - < 4>, < 5>, < 6>, < 7>, - < 8>, < 9>; - - dp0_pipe0: pipeline@0 { - clocks = <>; - clock-names = "pxclk"; - reg = <0>; - - port { - dp0_pipe0_out: endpoint { - remote-endpoint = <_dvi0_in>; - }; - }; - }; - - dp0_pipe1: pipeline@1 { - clocks = <>; - clock-names = "pxclk"; - reg = <1>; - - port { - dp0_pipe1_out: endpoint { - remote-endpoint = <_dvi1_in>; - }; - }; - }; - }; - ... -}; diff --git a/Documentation/devicetree/bindings/display/arm,komeda.yaml b/Documentation/devicetree/bindings/display/arm,komeda.yaml new file mode 100644 index 0..9f4aade97f10a --- /dev/null +++ b/Documentation/devicetree/bindings/display/arm,komeda.yaml @@ -0,0 +1,130 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/arm,komeda.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Arm Komeda display processor + +maintainers: + - Liviu Dudau + - Andre Przywara + +description: + The Arm Mali D71 display processor supports up to two displays with up + to a 4K resolution each. Each pipeline can be composed of up to four + layers. It is typically connected to a digital display connector like HDMI. + +properties: + compatible: +oneOf: + - items: + - const: arm,mali-d32 + - const: arm,mali-d71 + - const: arm,mali-d71 + + reg: +maxItems: 1 + + interrupts: +maxItems: 1 + + clock-names: +const: aclk + + clocks: +maxItems: 1 +description: The main DPU processor clock + + "#address-cells": +
[PATCH v2 09/11] dt-bindings: display: convert Arm HDLCD to DT schema
The Arm HDLCD is a display controller that scans out a framebuffer and hands a signal to a digital encoder to generate a DVI or HDMI signal. Convert the existing DT binding to DT schema. Signed-off-by: Andre Przywara --- .../devicetree/bindings/display/arm,hdlcd.txt | 79 .../bindings/display/arm,hdlcd.yaml | 89 +++ 2 files changed, 89 insertions(+), 79 deletions(-) delete mode 100644 Documentation/devicetree/bindings/display/arm,hdlcd.txt create mode 100644 Documentation/devicetree/bindings/display/arm,hdlcd.yaml diff --git a/Documentation/devicetree/bindings/display/arm,hdlcd.txt b/Documentation/devicetree/bindings/display/arm,hdlcd.txt deleted file mode 100644 index 78bc24296f3e4..0 --- a/Documentation/devicetree/bindings/display/arm,hdlcd.txt +++ /dev/null @@ -1,79 +0,0 @@ -ARM HDLCD - -This is a display controller found on several development platforms produced -by ARM Ltd and in more modern of its' Fast Models. The HDLCD is an RGB -streamer that reads the data from a framebuffer and sends it to a single -digital encoder (DVI or HDMI). - -Required properties: - - compatible: "arm,hdlcd" - - reg: Physical base address and length of the controller's registers. - - interrupts: One interrupt used by the display controller to notify the -interrupt controller when any of the interrupt sources programmed in -the interrupt mask register have activated. - - clocks: A list of phandle + clock-specifier pairs, one for each -entry in 'clock-names'. - - clock-names: A list of clock names. For HDLCD it should contain: - - "pxlclk" for the clock feeding the output PLL of the controller. - -Required sub-nodes: - - port: The HDLCD connection to an encoder chip. The connection is modeled -using the OF graph bindings specified in -Documentation/devicetree/bindings/graph.txt. - -Optional properties: - - memory-region: phandle to a node describing memory (see -Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt) to be -used for the framebuffer; if not present, the framebuffer may be located -anywhere in memory. - - -Example: - -/ { - ... - - hdlcd@2b00 { - compatible = "arm,hdlcd"; - reg = <0 0x2b00 0 0x1000>; - interrupts = ; - clocks = <>; - clock-names = "pxlclk"; - port { - hdlcd_output: endpoint@0 { - remote-endpoint = <_enc_input>; - }; - }; - }; - - /* HDMI encoder on I2C bus */ - i2c@7ffa { - - hdmi-transmitter@70 { - compatible = "."; - reg = <0x70>; - port@0 { - hdmi_enc_input: endpoint { - remote-endpoint = <_output>; - }; - - hdmi_enc_output: endpoint { - remote-endpoint = <_1_port>; - }; - }; - }; - - }; - - hdmi1: connector@1 { - compatible = "hdmi-connector"; - type = "a"; - port { - hdmi_1_port: endpoint { - remote-endpoint = <_enc_output>; - }; - }; - }; - - ... -}; diff --git a/Documentation/devicetree/bindings/display/arm,hdlcd.yaml b/Documentation/devicetree/bindings/display/arm,hdlcd.yaml new file mode 100644 index 0..a2670258c48d3 --- /dev/null +++ b/Documentation/devicetree/bindings/display/arm,hdlcd.yaml @@ -0,0 +1,89 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/arm,hdlcd.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Arm HDLCD display controller binding + +maintainers: + - Liviu Dudau + - Andre Przywara + +description: + The Arm HDLCD is a display controller found on several development platforms + produced by ARM Ltd and in more modern of its Fast Models. The HDLCD is an + RGB streamer that reads the data from a framebuffer and sends it to a single + digital encoder (DVI or HDMI). + +properties: + compatible: +const: arm,hdlcd + + reg: +maxItems: 1 + + interrupts: +maxItems: 1 + + clock-names: +const: pxlclk + + clocks: +maxItems: 1 +description: The input reference for the pixel clock. + + memory-region: +maxItems: 1 +description: + Phandle to a node describing memory to be used for the framebuffer. + If not present, the framebuffer may be located anywhere in memory. + + iommus: +maxItems: 1 + + port: +$ref: /schemas/graph.yaml#/properties/port +unevaluatedProperties: false +description: +
[PATCH v2 08/11] dt-bindings: display: convert PL110/PL111 to DT schema
The Arm PL110 and PL111 are IP blocks that provide a display engine with an LCD interface, being able to drive a variety of LC panels. Convert the binding over to DT schema, to the DTs can be automatically checked. This still contains the deprecated "arm,pl11x,tft-r0g0b0-pads" property, because this is used by several DTs in the tree. Signed-off-by: Andre Przywara --- .../devicetree/bindings/display/arm,pl11x.txt | 110 --- .../bindings/display/arm,pl11x.yaml | 174 ++ 2 files changed, 174 insertions(+), 110 deletions(-) delete mode 100644 Documentation/devicetree/bindings/display/arm,pl11x.txt create mode 100644 Documentation/devicetree/bindings/display/arm,pl11x.yaml diff --git a/Documentation/devicetree/bindings/display/arm,pl11x.txt b/Documentation/devicetree/bindings/display/arm,pl11x.txt deleted file mode 100644 index 3f977e72a2005..0 --- a/Documentation/devicetree/bindings/display/arm,pl11x.txt +++ /dev/null @@ -1,110 +0,0 @@ -* ARM PrimeCell Color LCD Controller PL110/PL111 - -See also Documentation/devicetree/bindings/arm/primecell.yaml - -Required properties: - -- compatible: must be one of: - "arm,pl110", "arm,primecell" - "arm,pl111", "arm,primecell" - -- reg: base address and size of the control registers block - -- interrupt-names: either the single entry "combined" representing a - combined interrupt output (CLCDINTR), or the four entries - "mbe", "vcomp", "lnbu", "fuf" representing the individual - CLCDMBEINTR, CLCDVCOMPINTR, CLCDLNBUINTR, CLCDFUFINTR interrupts - -- interrupts: contains an interrupt specifier for each entry in - interrupt-names - -- clock-names: should contain "clcdclk" and "apb_pclk" - -- clocks: contains phandle and clock specifier pairs for the entries - in the clock-names property. See - Documentation/devicetree/bindings/clock/clock-bindings.txt - -Optional properties: - -- memory-region: phandle to a node describing memory (see - Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt) - to be used for the framebuffer; if not present, the framebuffer - may be located anywhere in the memory - -- max-memory-bandwidth: maximum bandwidth in bytes per second that the - cell's memory interface can handle; if not present, the memory - interface is fast enough to handle all possible video modes - -Required sub-nodes: - -- port: describes LCD panel signals, following the common binding - for video transmitter interfaces; see - Documentation/devicetree/bindings/media/video-interfaces.txt - -Deprecated properties: - The port's endbpoint subnode had this, now deprecated property - in the past. Drivers should be able to survive without it: - - - arm,pl11x,tft-r0g0b0-pads: an array of three 32-bit values, - defining the way CLD pads are wired up; first value - contains index of the "CLD" external pin (pad) used - as R0 (first bit of the red component), second value - index of the pad used as G0, third value index of the - pad used as B0, see also "LCD panel signal multiplexing - details" paragraphs in the PL110/PL111 Technical - Reference Manuals; this implicitly defines available - color modes, for example: - - PL111 TFT 4:4:4 panel: - arm,pl11x,tft-r0g0b0-pads = <4 15 20>; - - PL110 TFT (1:)5:5:5 panel: - arm,pl11x,tft-r0g0b0-pads = <1 7 13>; - - PL111 TFT (1:)5:5:5 panel: - arm,pl11x,tft-r0g0b0-pads = <3 11 19>; - - PL111 TFT 5:6:5 panel: - arm,pl11x,tft-r0g0b0-pads = <3 10 19>; - - PL110 and PL111 TFT 8:8:8 panel: - arm,pl11x,tft-r0g0b0-pads = <0 8 16>; - - PL110 and PL111 TFT 8:8:8 panel, R & B components swapped: - arm,pl11x,tft-r0g0b0-pads = <16 8 0>; - - -Example: - - clcd@1002 { - compatible = "arm,pl111", "arm,primecell"; - reg = <0x1002 0x1000>; - interrupt-names = "combined"; - interrupts = <0 44 4>; - clocks = <>, <>; - clock-names = "clcdclk", "apb_pclk"; - max-memory-bandwidth = <94371840>; /* Bps, 1024x768@60 16bpp */ - - port { - clcd_pads: endpoint { - remote-endpoint = <_panel>; - }; - }; - - }; - - panel { - compatible = "panel-dpi"; - - port { - clcd_panel: endpoint { - remote-endpoint = <_pads>; - }; - }; - - panel-timing { - clock-frequency = <25175000>; - hactive =
Re: [PATCH v3 4/5] drm/gud: Map framebuffer BOs with drm_gem_fb_vmap()
Hi Thomas, I'm getting this on Ubuntu 22.04: [0.00] Linux version 5.15.0-27-generic (buildd@ubuntu) (gcc (Ubuntu 11.2.0-19ubuntu1) 11.2.0, GNU ld (GNU Binutils for Ubuntu) 2.38) #28-Ubuntu SMP Thu Apr 14 04:55:28 UTC 2022 (Ubuntu 5.15.0-27.28-generic 5.15.30) [4.830866] usb 2-3.1: new high-speed USB device number 4 using xhci_hcd [4.935546] usb 2-3.1: New USB device found, idVendor=1d50, idProduct=614d, bcdDevice= 1.00 [4.935553] usb 2-3.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 [4.935556] usb 2-3.1: Product: Raspberry Pi 4 Display Gadget [4.935558] usb 2-3.1: Manufacturer: Raspberry Pi [4.935560] usb 2-3.1: SerialNumber: 10003b40d6c6 [7.497361] [drm] Initialized gud 1.0.0 20200422 for 2-3.1:1.0 on minor 0 [7.573048] gud 2-3.1:1.0: [drm] fb1: guddrmfb frame buffer device [9.199402] [9.199411] UBSAN: invalid-load in /build/linux-HMZHpV/linux-5.15.0/include/linux/dma-buf-map.h:224:9 [9.199416] load of value 226 is not a valid value for type '_Bool' [9.199420] CPU: 0 PID: 113 Comm: kworker/0:2 Not tainted 5.15.0-27-generic #28-Ubuntu [9.199424] Hardware name: Hewlett-Packard HP EliteBook 820 G1/1991, BIOS L71 Ver. 01.44 04/12/2018 [9.199427] Workqueue: events_long gud_flush_work [gud] [9.199440] Call Trace: [9.199443] [9.199447] show_stack+0x52/0x58 [9.199456] dump_stack_lvl+0x4a/0x5f [9.199464] dump_stack+0x10/0x12 [9.199468] ubsan_epilogue+0x9/0x45 [9.199473] __ubsan_handle_load_invalid_value.cold+0x44/0x49 [9.199478] drm_gem_fb_vmap.cold+0x10/0x3d [drm_kms_helper] [9.199519] gud_prep_flush+0xaa/0x410 [gud] [9.199525] ? check_preempt_curr+0x5d/0x70 [9.199533] ? update_load_avg+0x82/0x620 [9.199540] ? set_next_entity+0xb7/0x200 [9.199545] gud_flush_work+0x1e0/0x430 [gud] [9.199551] ? psi_task_switch+0x1e7/0x220 [9.199557] process_one_work+0x22b/0x3d0 [9.199564] worker_thread+0x53/0x410 [9.199570] ? process_one_work+0x3d0/0x3d0 [9.199575] kthread+0x12a/0x150 [9.199579] ? set_kthread_struct+0x50/0x50 [9.199584] ret_from_fork+0x22/0x30 [9.199593] [9.199595] [9.199598] [9.199600] UBSAN: invalid-load in /build/linux-HMZHpV/linux-5.15.0/include/linux/dma-buf-map.h:194:9 [9.199604] load of value 226 is not a valid value for type '_Bool' [9.199606] CPU: 0 PID: 113 Comm: kworker/0:2 Not tainted 5.15.0-27-generic #28-Ubuntu [9.199610] Hardware name: Hewlett-Packard HP EliteBook 820 G1/1991, BIOS L71 Ver. 01.44 04/12/2018 [9.199612] Workqueue: events_long gud_flush_work [gud] [9.199618] Call Trace: [9.199619] [9.199621] show_stack+0x52/0x58 [9.199627] dump_stack_lvl+0x4a/0x5f [9.199633] dump_stack+0x10/0x12 [9.199637] ubsan_epilogue+0x9/0x45 [9.199641] __ubsan_handle_load_invalid_value.cold+0x44/0x49 [9.199646] drm_gem_fb_vmap.cold+0x24/0x3d [drm_kms_helper] [9.199675] gud_prep_flush+0xaa/0x410 [gud] [9.199682] ? check_preempt_curr+0x5d/0x70 [9.199688] ? update_load_avg+0x82/0x620 [9.199693] ? update_load_avg+0x82/0x620 [9.199697] gud_flush_work+0x1e0/0x430 [gud] [9.199702] ? psi_task_switch+0x1e7/0x220 [9.199706] process_one_work+0x22b/0x3d0 [9.199713] worker_thread+0x53/0x410 [9.199718] ? process_one_work+0x3d0/0x3d0 [9.199723] kthread+0x12a/0x150 [9.199728] ? set_kthread_struct+0x50/0x50 [9.199732] ret_from_fork+0x22/0x30 [9.199741] [9.199743] It's the "if (map->is_iomem)" statement in dma_buf_map_clear() and dma_buf_map_is_null() that triggers this. I tried 5.18.0-rc5 and the problem is still present. UBSAN entries in the config: CONFIG_ARCH_HAS_UBSAN_SANITIZE_ALL=y CONFIG_UBSAN=y # CONFIG_UBSAN_TRAP is not set CONFIG_CC_HAS_UBSAN_BOUNDS=y CONFIG_UBSAN_BOUNDS=y CONFIG_UBSAN_ONLY_BOUNDS=y CONFIG_UBSAN_SHIFT=y # CONFIG_UBSAN_DIV_ZERO is not set CONFIG_UBSAN_BOOL=y CONFIG_UBSAN_ENUM=y # CONFIG_UBSAN_ALIGNMENT is not set CONFIG_UBSAN_SANITIZE_ALL=y # CONFIG_TEST_UBSAN is not set Continuing further down. Den 30.07.2021 20.35, skrev Thomas Zimmermann: > Abstract the framebuffer details by mapping its BOs with a call > to drm_gem_fb_vmap(). Unmap with drm_gem_fb_vunmap(). > > The call to drm_gem_fb_vmap() ensures that all BOs are mapped > correctly. Gud still only supports single-plane formats. > > No functional changes. > > Signed-off-by: Thomas Zimmermann > Acked-by: Noralf Trønnes > Acked-by: Sam Ravnborg > --- > drivers/gpu/drm/gud/gud_pipe.c | 10 +- > 1 file changed, 5 insertions(+), 5 deletions(-) > > diff --git
[PATCH] drm/tegra: gem: Do not try to dereference ERR_PTR()
From: Thierry Reding When mapping the DMA-BUF attachment fails, map->sgt will be an ERR_PTR- encoded error code and the cleanup code would try to free that memory, which obviously would fail. Zero out that pointer after extracting the error code when this happens so that kfree() can do the right thing. Reported-by: kernel test robot Reported-by: Dan Carpenter Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/gem.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c index 0063403ab5e1..7c7dd84e6db8 100644 --- a/drivers/gpu/drm/tegra/gem.c +++ b/drivers/gpu/drm/tegra/gem.c @@ -88,6 +88,7 @@ static struct host1x_bo_mapping *tegra_bo_pin(struct device *dev, struct host1x_ if (IS_ERR(map->sgt)) { dma_buf_detach(buf, map->attach); err = PTR_ERR(map->sgt); + map->sgt = NULL; goto free; } -- 2.35.1
Re: [PATCH] fbdev: efifb: Fix a use-after-free due early fb_info cleanup
Am 06.05.22 um 15:22 schrieb Javier Martinez Canillas: Commit d258d00fb9c7 ("fbdev: efifb: Cleanup fb_info in .fb_destroy rather than .remove") attempted to fix a use-after-free error due driver freeing the fb_info in the .remove handler instead of doing it in .fb_destroy. But ironically that change introduced yet another use-after-free since the fb_info was still used after the free. This should fix for good by freeing the fb_info at the end of the handler. Fixes: d258d00fb9c7 ("fbdev: efifb: Cleanup fb_info in .fb_destroy rather than .remove") Reported-by: Ville Syrjälä Reported-by: Andrzej Hajda Signed-off-by: Javier Martinez Canillas Reviewed-by: Thomas Zimmermann --- drivers/video/fbdev/efifb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c index cfa3dc0b4eee..b3d5f884c544 100644 --- a/drivers/video/fbdev/efifb.c +++ b/drivers/video/fbdev/efifb.c @@ -259,12 +259,12 @@ static void efifb_destroy(struct fb_info *info) memunmap(info->screen_base); } - framebuffer_release(info); - if (request_mem_succeeded) release_mem_region(info->apertures->ranges[0].base, info->apertures->ranges[0].size); fb_dealloc_cmap(>cmap); + + framebuffer_release(info); } static const struct fb_ops efifb_ops = { -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Ivo Totev OpenPGP_signature Description: OpenPGP digital signature
RE: [PATCH 1/2] dt-bindings: msm/dp: List supplies in the bindings
>> >> Our internal power grid documents list the regulators as >> >> VDD_A_*_1P2 and VDD_A_*_0P9 for all the platforms. >> > >> >Do your internal power grid documents indicate what these supplies >> >are powering? The question is if these supplies power any of the >> >logic inside the eDP controller or if they only supply power to the >> >analog circuits in the eDP phy. If it's the eDP phy only then the >> >regulator usage in the eDP driver should be removed. I would suspect >> >this is the case because the controller is probably all digital logic >> >and runs at the typical 1.8V that the rest of the SoC uses. >> >Similarly, these are voltage references which sound like a PLL reference >voltage. >> > >> >Please clarify this further. >> > >> >> For the DP driver using the usb-dp combo phy, there were cases where >> the usb driver was turning off the phy and pll regulators whenever usb-dp >concurrent mode need not be supported. >> This caused phy and pll to be powered down causing aux transaction failures >and display blankouts. >> From then on, it became a practice for the controller driver to vote for the >phy and pll regulators also. >> > >That sounds like USB-DP combo phy driver had improper regulator power >management where aux transactions from DP didn't keep the power on to >the phy. Where does the power physically go? If the power isn't physically >going to the DP controller it shouldn't be controlled from the DP controller >driver. If the aux bus needs the DP phy enabled, the DP controller driver >should enable the phy power (via phy_power_on()?). Yes, it was limitation earlier when we did not have proper interface to interact with the combo phy. In this case, the power from the regulators go to the combo phy. Now that there is an interface for the controller to interact with the combo phy, the proposal to drop the phy regulator voting from the controller driver seems reasonable to me. The phy_power_on() is used for getting the phy out of low power state or getting it ready for data transfer. The controller driver needs to enable the phy power via the phy_init() before any interaction with the sink like the aux transactions or before sending the data. The controller can disable the regulators via the phy_exit() call. Thank you, Sankeerth
[PATCH] fbdev: efifb: Fix a use-after-free due early fb_info cleanup
Commit d258d00fb9c7 ("fbdev: efifb: Cleanup fb_info in .fb_destroy rather than .remove") attempted to fix a use-after-free error due driver freeing the fb_info in the .remove handler instead of doing it in .fb_destroy. But ironically that change introduced yet another use-after-free since the fb_info was still used after the free. This should fix for good by freeing the fb_info at the end of the handler. Fixes: d258d00fb9c7 ("fbdev: efifb: Cleanup fb_info in .fb_destroy rather than .remove") Reported-by: Ville Syrjälä Reported-by: Andrzej Hajda Signed-off-by: Javier Martinez Canillas --- drivers/video/fbdev/efifb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c index cfa3dc0b4eee..b3d5f884c544 100644 --- a/drivers/video/fbdev/efifb.c +++ b/drivers/video/fbdev/efifb.c @@ -259,12 +259,12 @@ static void efifb_destroy(struct fb_info *info) memunmap(info->screen_base); } - framebuffer_release(info); - if (request_mem_succeeded) release_mem_region(info->apertures->ranges[0].base, info->apertures->ranges[0].size); fb_dealloc_cmap(>cmap); + + framebuffer_release(info); } static const struct fb_ops efifb_ops = { -- 2.35.1
Re: [PATCH v3 3/4] fbdev: efifb: Cleanup fb_info in .fb_destroy rather than .remove
Hello Andrzej, On 5/6/22 15:07, Andrzej Hajda wrote: > On 06.05.2022 00:05, Javier Martinez Canillas wrote: [snip] >> + >> +framebuffer_release(info); >> + >> if (request_mem_succeeded) >> release_mem_region(info->apertures->ranges[0].base, >> info->apertures->ranges[0].size); > > You are releasing info, then you are using it. > > I suspect it is responsible for multiple failures of Intel CI [1]. > Yes, it is :( sorry about the mess. Ville already reported this to me. I'll post a patch in a minute. I wonder how this didn't happen before since .remove() happens before .fb_destroy() AFAIU... -- Best regards, Javier Martinez Canillas Linux Engineering Red Hat
Re: [BUG] Warning and NULL-ptr dereference in amdgpu driver with 5.18
+ some display folks On Fri, May 6, 2022 at 6:19 AM Jörg Rödel wrote: > > Hi, > > since recently I started to experience warnings and NULL-ptr > dereferences in the amdgpu driver with kernel 5.18-rc5+. Earlier > 5.18-based kernels might be affected as well, but I havn't seen this > with 5.17. > > The kernel was built from the iommu-next branch, based on 5.18-rc5. > > The messages start with some PCIe error being reported: > > [20389.984993] pcieport :00:03.1: AER: Multiple Corrected error received: > :0a:00.0 > [20389.985005] amdgpu :0a:00.0: PCIe Bus Error: severity=Corrected, > type=Data Link Layer, (Receiver ID) > [20389.985007] amdgpu :0a:00.0: device [1002:6995] error > status/mask=00c0/2000 > [20389.985010] amdgpu :0a:00.0:[ 6] BadTLP > [20389.985013] amdgpu :0a:00.0:[ 7] BadDLLP > > Directly followed by a waring: > > [81829.087101] [ cut here ] > [81829.087105] WARNING: CPU: 4 PID: 644 at > drivers/gpu/drm/amd/amdgpu/../display/dc/clk_mgr/dce110/dce110_clk_mgr.c:140 > dce110_fill_display_configs+0x4a/0x150 [amdgpu] > [81829.087461] Modules linked in: snd_seq_dummy(E) snd_hrtimer(E) snd_seq(E) > rfcomm(E) af_packet(E) ocrdma(E) ib_uverbs(E) ib_core(E) nft_fib_inet(E) > nft_fib_ipv4(E) nft_fib_ipv6(E) nft_fib(E) nft_reject_inet(E) > nf_reject_ipv4(E) nf_reject_ipv6(E) nft_reject(E) nft_ct(E) nft_chain_nat(E) > nf_tables(E) ebtable_nat(E) ebtable_broute(E) ip6table_nat(E) > ip6table_mangle(E) ip6table_raw(E) ip6table_security(E) iptable_nat(E) > nf_nat(E) nf_conntrack(E) nf_defrag_ipv6(E) nf_defrag_ipv4(E) > iptable_mangle(E) iptable_raw(E) iptable_security(E) ip_set(E) nfnetlink(E) > ebtable_filter(E) ebtables(E) ip6table_filter(E) ip6_tables(E) > iptable_filter(E) bpfilter(E) cmac(E) algif_hash(E) algif_skcipher(E) > af_alg(E) bnep(E) dmi_sysfs(E) intel_rapl_msr(E) intel_rapl_common(E) > snd_hda_codec_realtek(E) eeepc_wmi(E) btusb(E) asus_wmi(E) kvm_amd(E) > btrtl(E) snd_hda_codec_generic(E) nls_iso8859_1(E) battery(E) uvcvideo(E) > sparse_keymap(E) ledtrig_audio(E) btbcm(E) video(E) wmi_bmof(E) > [81829.087502] platform_profile(E) mxm_wmi(E) snd_hda_codec_hdmi(E) > nls_cp437(E) videobuf2_vmalloc(E) btintel(E) asus_wmi_sensors(E) btmtk(E) > vfat(E) snd_hda_intel(E) videobuf2_memops(E) videobuf2_v4l2(E) > snd_intel_dspcfg(E) bluetooth(E) kvm(E) videobuf2_common(E) fat(E) > snd_usb_audio(E) snd_virtuoso(E) irqbypass(E) snd_usbmidi_lib(E) > snd_hda_codec(E) snd_oxygen_lib(E) videodev(E) snd_hwdep(E) > snd_mpu401_uart(E) mc(E) snd_hda_core(E) ecdh_generic(E) snd_rawmidi(E) > snd_pcm(E) snd_seq_device(E) rfkill(E) pcspkr(E) i2c_piix4(E) efi_pstore(E) > k10temp(E) snd_timer(E) ext4(E) igb(E) snd(E) dca(E) soundcore(E) mbcache(E) > be2net(E) jbd2(E) wmi(E) gpio_amdpt(E) gpio_generic(E) tiny_power_button(E) > button(E) acpi_cpufreq(E) fuse(E) configfs(E) ip_tables(E) x_tables(E) xfs(E) > libcrc32c(E) dm_crypt(E) essiv(E) authenc(E) trusted(E) asn1_encoder(E) > tee(E) hid_logitech_hidpp(E) hid_logitech_dj(E) hid_generic(E) usbhid(E) > sr_mod(E) cdrom(E) uas(E) usb_storage(E) amdgpu(E) > [81829.087551] drm_ttm_helper(E) ttm(E) iommu_v2(E) gpu_sched(E) > i2c_algo_bit(E) crct10dif_pclmul(E) drm_dp_helper(E) crc32_pclmul(E) > crc32c_intel(E) drm_kms_helper(E) syscopyarea(E) sysfillrect(E) sysimgblt(E) > fb_sys_fops(E) drm(E) xhci_pci(E) cec(E) ghash_clmulni_intel(E) > xhci_pci_renesas(E) aesni_intel(E) crypto_simd(E) cryptd(E) sp5100_tco(E) > xhci_hcd(E) ccp(E) rc_core(E) nvme(E) usbcore(E) nvme_core(E) sg(E) > br_netfilter(E) bridge(E) stp(E) llc(E) dm_multipath(E) dm_mod(E) > scsi_dh_rdac(E) scsi_dh_emc(E) scsi_dh_alua(E) ledtrig_timer(E) msr(E) > efivarfs(E) > [81829.087581] CPU: 4 PID: 644 Comm: kworker/4:1H Tainted: GE > 5.18.0-rc5-iommu-next+ #1 4d1b12f73ec264927e45e8f2e5d1c0c8e280bc7d > [81829.087585] Hardware name: System manufacturer System Product Name/PRIME > X470-PRO, BIOS 5406 11/13/2019 > [81829.087588] Workqueue: events_highpri dm_irq_work_func [amdgpu] > [81829.087928] RIP: 0010:dce110_fill_display_configs+0x4a/0x150 [amdgpu] > [81829.088274] Code: 31 ff 4d 8d 98 f0 01 00 00 49 8b 0c f8 4c 89 da 31 c0 48 > 39 0a 0f 84 e4 00 00 00 83 c0 01 48 81 c2 10 08 00 00 83 f8 06 75 e8 <0f> 0b > 31 c0 80 b9 48 03 00 00 00 0f 85 a9 00 00 00 48 8b 50 08 8b > [81829.088277] RSP: 0018:b891810c3be0 EFLAGS: 00010246 > [81829.088280] RAX: 0006 RBX: 9719a6b6 RCX: > 971d08e07800 > [81829.088282] RDX: 9719a6b63250 RSI: 9719a6b72980 RDI: > 0001 > [81829.088284] RBP: 971a812f R08: 9719a6b6 R09: > > [81829.088286] R10: 9719a6b72980 R11: 9719a6b601f0 R12: > 9719a6b72980 > [81829.088287] R13: 9719a6b6 R14: 0006 R15: > 3258 > [81829.088289] FS: () GS:97285eb0() > knlGS: > [81829.088291] CS: 0010 DS: ES: CR0:
Re: [PATCH v3 3/4] fbdev: efifb: Cleanup fb_info in .fb_destroy rather than .remove
On 06.05.2022 00:05, Javier Martinez Canillas wrote: The driver is calling framebuffer_release() in its .remove callback, but this will cause the struct fb_info to be freed too early. Since it could be that a reference is still hold to it if user-space opened the fbdev. This would lead to a use-after-free error if the framebuffer device was unregistered but later a user-space process tries to close the fbdev fd. To prevent this, move the framebuffer_release() call to fb_ops.fb_destroy instead of doing it in the driver's .remove callback. Strictly speaking, the code flow in the driver is still wrong because all the hardware cleanupd (i.e: iounmap) should be done in .remove while the software cleanup (i.e: releasing the framebuffer) should be done in the .fb_destroy handler. But this at least makes to match the behavior before commit 27599aacbaef ("fbdev: Hot-unplug firmware fb devices on forced removal"). Fixes: 27599aacbaef ("fbdev: Hot-unplug firmware fb devices on forced removal") Suggested-by: Daniel Vetter Signed-off-by: Javier Martinez Canillas Reviewed-by: Thomas Zimmermann Reviewed-by: Daniel Vetter --- (no changes since v1) drivers/video/fbdev/efifb.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c index ea42ba6445b2..cfa3dc0b4eee 100644 --- a/drivers/video/fbdev/efifb.c +++ b/drivers/video/fbdev/efifb.c @@ -243,6 +243,10 @@ static void efifb_show_boot_graphics(struct fb_info *info) static inline void efifb_show_boot_graphics(struct fb_info *info) {} #endif +/* + * fb_ops.fb_destroy is called by the last put_fb_info() call at the end + * of unregister_framebuffer() or fb_release(). Do any cleanup here. + */ static void efifb_destroy(struct fb_info *info) { if (efifb_pci_dev) @@ -254,6 +258,9 @@ static void efifb_destroy(struct fb_info *info) else memunmap(info->screen_base); } + + framebuffer_release(info); + if (request_mem_succeeded) release_mem_region(info->apertures->ranges[0].base, info->apertures->ranges[0].size); You are releasing info, then you are using it. I suspect it is responsible for multiple failures of Intel CI [1]. [1]: http://gfx-ci.fi.intel.com/tree/drm-tip/CI_DRM_11615/fi-adl-ddr5/boot0.txt Regards Andrzej @@ -620,9 +627,9 @@ static int efifb_remove(struct platform_device *pdev) { struct fb_info *info = platform_get_drvdata(pdev); + /* efifb_destroy takes care of info cleanup */ unregister_framebuffer(info); sysfs_remove_groups(>dev.kobj, efifb_groups); - framebuffer_release(info); return 0; }
Re: [PATCH v2 -next] drm/display: Fix build error without CONFIG_OF
On 06/05/2022 15:32, YueHaibing wrote: While CONFIG_OF is n but COMPILE_TEST is y, we got this: WARNING: unmet direct dependencies detected for DRM_DP_AUX_BUS Depends on [n]: HAS_IOMEM [=y] && DRM [=y] && OF [=n] Selected by [y]: - DRM_MSM [=y] && HAS_IOMEM [=y] && DRM [=y] && (ARCH_QCOM || SOC_IMX5 || COMPILE_TEST [=y]) && COMMON_CLK [=y] && IOMMU_SUPPORT [=y] && (QCOM_OCMEM [=n] || QCOM_OCMEM [=n]=n) && (QCOM_LLCC [=y] || QCOM_LLCC [=y]=n) && (QCOM_COMMAND_DB [=n] || QCOM_COMMAND_DB [=n]=n) Make DRM_DP_AUX_BUS depends on OF || COMPILE_TEST to fix this warning. Fixes: f5d01644921b ("drm/msm: select DRM_DP_AUX_BUS for the AUX bus support") Signed-off-by: YueHaibing Reviewed-by: Dmitry Baryshkov --- v2: fix this in DRM_DP_AUX_BUS dependencies --- drivers/gpu/drm/display/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/display/Kconfig b/drivers/gpu/drm/display/Kconfig index 1b6e6af37546..09712b88a5b8 100644 --- a/drivers/gpu/drm/display/Kconfig +++ b/drivers/gpu/drm/display/Kconfig @@ -3,7 +3,7 @@ config DRM_DP_AUX_BUS tristate depends on DRM - depends on OF + depends on OF || COMPILE_TEST config DRM_DISPLAY_HELPER tristate -- With best wishes Dmitry
Re: (subset) [PATCH 1/2] [RFC] regmap: Add bulk read/write callbacks into regmap_config
On Fri, May 06, 2022 at 01:55:57AM +0200, Marek Vasut wrote: > On 5/5/22 23:08, Mark Brown wrote: > > I did go through it and didn't spot > > any issues so it seemed like the testing coverage would be useful here. > > Are there specific things you're worried about that you'd like feedback > > on? > Plumbing on core code is worrying. Yeah, that's a big part of why I want things in testing. With something like this a lot of it is being aware of all the random corner cases out there. signature.asc Description: PGP signature
Re: (subset) [PATCH 1/2] [RFC] regmap: Add bulk read/write callbacks into regmap_config
On Fri, May 06, 2022 at 01:58:18PM +0300, Jani Nikula wrote: > Hey Mark, sorry for hijacking the thread a bit. regmap.h seems to have > comprehensive API documentation, but there's very little in terms of > higher level documentation that I could find. Is there any? Not outside of the source. I did a presentation at ELC-E ages ago which you can probably find but I'm not sure how much it would add. > I've been toying with the idea of adding a regmap based interface for > accessing Display Port DPCD registers, with caching, and regmap seems > like it's got the kitchen sink but I find it a bit difficult to > navigate... The bus code is generally very thin so you shouldn't need to worry about what the core is up to much if you just want to support some bus. If this is a bus that has registers at hardware level then looking at something like regmap-sdw.c should be helpful, for something that's just a bit stream at the bus level then something like regmap-i3c.c is a simple example. signature.asc Description: PGP signature
Re: [PATCH] dt-bindings: display: bridge: ldb: Fill in reg property
On Wed, 4 May 2022 at 17:06, Rob Herring wrote: > > On Wed, 04 May 2022 03:26:01 +0200, Marek Vasut wrote: > > Add missing reg and reg-names properties for both 'LDB_CTRL' > > and 'LVDS_CTRL' registers. > > > > Fixes: 463db5c2ed4ae ("drm: bridge: ldb: Implement simple Freescale i.MX8MP > > LDB bridge") > > Signed-off-by: Marek Vasut > > Cc: Laurent Pinchart > > Cc: Lucas Stach > > Cc: Maxime Ripard > > Cc: Peng Fan > > Cc: Rob Herring > > Cc: Robby Cai > > Cc: Robert Foss > > Cc: Sam Ravnborg > > Cc: Thomas Zimmermann > > Cc: devicet...@vger.kernel.org > > To: dri-devel@lists.freedesktop.org > > --- > > .../bindings/display/bridge/fsl,ldb.yaml | 16 +++- > > 1 file changed, 15 insertions(+), 1 deletion(-) > > > > Reviewed-by: Rob Herring Applied to drm-misc-next
[PATCH 3/3] drm/panel: introduce ebbg,ft8719 panel
Add DRM panel driver for EBBG FT8719 6.18" 2246x1080 DSI video mode panel, which can be found on some Xiaomi Poco F1 phones. The panel's backlight is managed through QCOM WLED driver. Signed-off-by: Joel Selvaraj --- MAINTAINERS | 7 + drivers/gpu/drm/panel/Kconfig | 11 + drivers/gpu/drm/panel/Makefile| 1 + drivers/gpu/drm/panel/panel-ebbg-ft8719.c | 362 ++ 4 files changed, 381 insertions(+) create mode 100644 drivers/gpu/drm/panel/panel-ebbg-ft8719.c diff --git a/MAINTAINERS b/MAINTAINERS index cd0f68d4a34a..dfd2c53aea00 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6018,6 +6018,13 @@ S: Maintained F: Documentation/devicetree/bindings/display/bridge/chipone,icn6211.yaml F: drivers/gpu/drm/bridge/chipone-icn6211.c +DRM DRIVER FOR EBBG FT8719 PANEL +M: Joel Selvaraj +S: Maintained +T: git git://anongit.freedesktop.org/drm/drm-misc +F: Documentation/devicetree/bindings/display/panel/ebbg,ft8719.yaml +F: drivers/gpu/drm/panel/panel-ebbg-ft8719.c + DRM DRIVER FOR FARADAY TVE200 TV ENCODER M: Linus Walleij S: Maintained diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index 9989a316fe88..77176df2e2ec 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -114,6 +114,17 @@ config DRM_PANEL_EDP that it can be automatically turned off when the panel goes into a low power state. +config DRM_PANEL_EBBG_FT8719 + tristate "EBBG FT8719 panel driver" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + Say Y here if you want to enable support for the EBBG FT8719 + video mode panel. Mainly found on Xiaomi Poco F1 mobile phone. + The panel has a resolution of 1080x2246. It provides a MIPI DSI + interface to the host. + config DRM_PANEL_ELIDA_KD35T133 tristate "Elida KD35T133 panel driver" depends on OF diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index d99fbbce49d1..47cc20c1a770 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_DRM_PANEL_DSI_CM) += panel-dsi-cm.o obj-$(CONFIG_DRM_PANEL_LVDS) += panel-lvds.o obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o obj-$(CONFIG_DRM_PANEL_EDP) += panel-edp.o +obj-$(CONFIG_DRM_PANEL_EBBG_FT8719) += panel-ebbg-ft8719.o obj-$(CONFIG_DRM_PANEL_ELIDA_KD35T133) += panel-elida-kd35t133.o obj-$(CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02) += panel-feixin-k101-im2ba02.o obj-$(CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D) += panel-feiyang-fy07024di26a30d.o diff --git a/drivers/gpu/drm/panel/panel-ebbg-ft8719.c b/drivers/gpu/drm/panel/panel-ebbg-ft8719.c new file mode 100644 index ..abd54c4b0c23 --- /dev/null +++ b/drivers/gpu/drm/panel/panel-ebbg-ft8719.c @@ -0,0 +1,362 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2022 Joel Selvaraj + * Generated with linux-mdss-dsi-panel-driver-generator from vendor device tree: + * Copyright (c) 2013, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +static const char * const regulator_names[] = { + "vddio", + "vddpos", + "vddneg", +}; + +static const unsigned long regulator_enable_loads[] = { + 62000, + 10, + 10 +}; + +struct ebbg_ft8719 { + struct drm_panel panel; + struct mipi_dsi_device *dsi; + + struct regulator_bulk_data supplies[ARRAY_SIZE(regulator_names)]; + + struct gpio_desc *reset_gpio; + bool prepared; +}; + +static inline +struct ebbg_ft8719 *to_ebbg_ft8719(struct drm_panel *panel) +{ + return container_of(panel, struct ebbg_ft8719, panel); +} + +#define dsi_generic_write_seq(dsi, seq...) do { \ + static const u8 d[] = { seq }; \ + int ret;\ + ret = mipi_dsi_generic_write(dsi, d, ARRAY_SIZE(d));\ + if (ret < 0)\ + return ret; \ + } while (0) + +#define dsi_dcs_write_seq(dsi, seq...) do {\ + static const u8 d[] = { seq }; \ + int ret;\ + ret = mipi_dsi_dcs_write_buffer(dsi, d, ARRAY_SIZE(d)); \ + if (ret < 0)\ + return ret; \ + } while (0) + +static void ebbg_ft8719_reset(struct ebbg_ft8719 *ctx) +{ + gpiod_set_value_cansleep(ctx->reset_gpio, 0); + usleep_range(4000, 5000); +
[PATCH 2/3] dt-bindings: display: Add bindings for EBBG FT8719
Add bindings for the EBBG FT8719 6.18" 2246x1080 DSI video mode panel, which can be found on some Xiaomi Poco F1 phones. The backlight is managed through the QCOM WLED driver. Signed-off-by: Joel Selvaraj --- .../bindings/display/panel/ebbg,ft8719.yaml | 78 +++ 1 file changed, 78 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/ebbg,ft8719.yaml diff --git a/Documentation/devicetree/bindings/display/panel/ebbg,ft8719.yaml b/Documentation/devicetree/bindings/display/panel/ebbg,ft8719.yaml new file mode 100644 index ..fac6c9692c55 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/ebbg,ft8719.yaml @@ -0,0 +1,78 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/ebbg,ft8719.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: EBBG FT8719 MIPI-DSI LCD panel + +maintainers: + - Joel Selvaraj + +description: | + The FT8719 panel from EBBG is a FHD+ LCD display panel with a resolution + of 1080x2246. It is a video mode DSI panel. The backlight is managed + through the QCOM WLED driver. + +allOf: + - $ref: panel-common.yaml# + +properties: + compatible: +const: ebbg,ft8719 + + reg: +description: DSI virtual channel of the peripheral + + reset-gpios: +description: phandle of gpio for reset line + + vddio-supply: +description: phandle of the Power IC supply regulator + + vddpos-supply: +description: phandle of the positive boost supply regulator + + vddneg-supply: +description: phandle of the negative boost supply regulator + + backlight: true + port: true + +required: + - compatible + - reg + - vddio-supply + - vddpos-supply + - vddneg-supply + - reset-gpios + - port + +unevaluatedProperties: false + +examples: + - |+ +#include +dsi0 { + #address-cells = <1>; + #size-cells = <0>; + + panel@0 { +compatible = "ebbg,ft8719"; +reg = <0>; + +vddio-supply = <_l14a_1p88>; +vddpos-supply = <>; +vddneg-supply = <>; + +reset-gpios = < 6 GPIO_ACTIVE_LOW>; + +backlight = <_wled>; + +port { + ebbg_ft8719_in_0: endpoint { +remote-endpoint = <_out>; + }; +}; + }; +}; -- 2.35.1
[PATCH 1/3] dt-bindings: vendor-prefixes: Add prefix for EBBG
Add a prefix for EBBG. They manufacture displays which are used in some Xiaomi phones, but I could not find much details about the company. Signed-off-by: Joel Selvaraj --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 80e80fa53f8a..effd1cb995cf 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -337,6 +337,8 @@ patternProperties: description: Embedded Artists AB "^ebang,.*": description: Zhejiang Ebang Communication Co., Ltd + "^ebbg,.*": +description: EBBG "^ebs-systart,.*": description: EBS-SYSTART GmbH "^ebv,.*": -- 2.35.1
[PATCH 0/3] Introduce EBBG FT8719 DRM panel driver
Add bindings and DRM panel driver for EBBG FT8719 6.18" 2246x1080 DSI video mode panel, which can be found on some Xiaomi Poco F1 phones. The panel's backlight is managed through QCOM WLED driver. The driver is built using linux-mdss-dsi-panel-driver-generator[1], and additionally support for handling regulators and linking external backlight is added. [1] https://github.com/msm8916-mainline/linux-mdss-dsi-panel-driver-generator Joel Selvaraj (3): dt-bindings: vendor-prefixes: Add prefix for EBBG dt-bindings: display: Add bindings for EBBG FT8719 drm/panel: introduce ebbg,ft8719 panel .../bindings/display/panel/ebbg,ft8719.yaml | 78 .../devicetree/bindings/vendor-prefixes.yaml | 2 + MAINTAINERS | 7 + drivers/gpu/drm/panel/Kconfig | 11 + drivers/gpu/drm/panel/Makefile| 1 + drivers/gpu/drm/panel/panel-ebbg-ft8719.c | 362 ++ 6 files changed, 461 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/ebbg,ft8719.yaml create mode 100644 drivers/gpu/drm/panel/panel-ebbg-ft8719.c -- 2.35.1
Re: [Intel-gfx] [PATCH v7 6/7] drm/i915/gt: Create per-tile RPS sysfs interfaces
On Sat, 19 Mar 2022, Andi Shyti wrote: > +#define INTEL_GT_RPS_SYSFS_ATTR(_name, _mode, _show, _store) \ > + struct device_attribute dev_attr_gt_##_name = __ATTR(gt_##_name, _mode, > _show, _store); \ > + struct device_attribute dev_attr_rps_##_name = __ATTR(rps_##_name, > _mode, _show, _store) Consider this macro... > + > +#define INTEL_GT_RPS_SYSFS_ATTR_RO(_name)\ > + INTEL_GT_RPS_SYSFS_ATTR(_name, 0444, _name##_show, NULL) > +#define INTEL_GT_RPS_SYSFS_ATTR_RW(_name)\ > + INTEL_GT_RPS_SYSFS_ATTR(_name, 0644, _name##_show, > _name##_store) > + > +static INTEL_GT_RPS_SYSFS_ATTR_RO(act_freq_mhz); > +static INTEL_GT_RPS_SYSFS_ATTR_RO(cur_freq_mhz); > +static INTEL_GT_RPS_SYSFS_ATTR_RW(boost_freq_mhz); > +static INTEL_GT_RPS_SYSFS_ATTR_RO(RP0_freq_mhz); > +static INTEL_GT_RPS_SYSFS_ATTR_RO(RP1_freq_mhz); > +static INTEL_GT_RPS_SYSFS_ATTR_RO(RPn_freq_mhz); > +static INTEL_GT_RPS_SYSFS_ATTR_RW(max_freq_mhz); > +static INTEL_GT_RPS_SYSFS_ATTR_RW(min_freq_mhz); ...and the static keyword here. All of the dev_attr_rps_* attributes become non-static, as the static only applies to the dev_attr_gt_* attributes: CHECK drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c:468:8: warning: symbol 'dev_attr_rps_act_freq_mhz' was not declared. Should it be static? drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c:469:8: warning: symbol 'dev_attr_rps_cur_freq_mhz' was not declared. Should it be static? drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c:470:8: warning: symbol 'dev_attr_rps_boost_freq_mhz' was not declared. Should it be static? drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c:471:8: warning: symbol 'dev_attr_rps_RP0_freq_mhz' was not declared. Should it be static? drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c:472:8: warning: symbol 'dev_attr_rps_RP1_freq_mhz' was not declared. Should it be static? drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c:473:8: warning: symbol 'dev_attr_rps_RPn_freq_mhz' was not declared. Should it be static? drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c:474:8: warning: symbol 'dev_attr_rps_max_freq_mhz' was not declared. Should it be static? drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c:475:8: warning: symbol 'dev_attr_rps_min_freq_mhz' was not declared. Should it be static? BR, Jani. -- Jani Nikula, Intel Open Source Graphics Center
amdgpu sparse warnings (was: Re: ✗ Fi.CI.SPARSE: warning for drm/edid: introduce struct drm_edid)
Hey, do you ever run sparse on your driver? Whenever our CI ends up recompiling amdgpu, there's quite the spew. See below. You're not alone, but, sorry to say, the _Static_assert() from amdgv_sriovmsg.h has been pretty obnoxious for quite some time now. First, I don't think you should be using _Static_assert() directly; there's an in-kernel static_assert() wrapper. However, it's the #pragma pack(push, 1) and #pragma pack(pop) pair that sparse does not understand, leaves the structs unpacked, and leads to warnings. BR, Jani. On Fri, 06 May 2022, Patchwork wrote: > == Series Details == > > Series: drm/edid: introduce struct drm_edid > URL : https://patchwork.freedesktop.org/series/103665/ > State : warning > > == Summary == > > Error: dim sparse failed > Sparse version: v0.6.2 > Fast mode used, each commit won't be checked separately. > - > +./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: > static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB" > +./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: > static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB" > +./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: > static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB" > +./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: > static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB" > +./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: > static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB" > +./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: > static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB" > +./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: > static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB" > +./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: > static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB" > +./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: > static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB" > +./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: > static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB" > +./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: > static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB" > +./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: > static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB" > +./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: > static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB" > +./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: > static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB" > +./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: > static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB" > +./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: > static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB" > +./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: > static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB" > +./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: > static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB" > +./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: > static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB" > +./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: > static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB" > +./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: > static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB" > +./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: > static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB" > +./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: > static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB" > +./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: > static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB" > +./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: > static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB" > +./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: > static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB" > +./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: > static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB" > +./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: > static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB" > +./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:314:49: error: > static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB" >