Re: [PATCH 37/39] drm: renesas: shmobile: Remove internal CRTC state tracking
Hi Geert, Thank you for the patch. On Thu, Jun 22, 2023 at 11:21:49AM +0200, Geert Uytterhoeven wrote: > Now the suspend/resume methods no longer need to look at internal driver > state, the dpms and started fields in the shmob_drm_crtc structure can > be removed, as well as the shmob_drm_crtc_dpms() wrapper. > > Signed-off-by: Geert Uytterhoeven > --- > .../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 35 --- > .../gpu/drm/renesas/shmobile/shmob_drm_crtc.h | 3 -- > 2 files changed, 6 insertions(+), 32 deletions(-) > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > index b11bb666de3bac46..f2332bb0fbbd51a1 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > @@ -196,9 +196,6 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc > *scrtc) > u32 value; > int ret; > > - if (scrtc->started) > - return; > - > ret = pm_runtime_resume_and_get(dev); > if (ret) > return; > @@ -252,8 +249,6 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc > *scrtc) > > /* Turn vertical blank interrupt reporting back on. */ > drm_crtc_vblank_on(crtc); > - > - scrtc->started = true; > } > > /* > - > @@ -314,9 +309,6 @@ static void shmob_drm_crtc_stop(struct shmob_drm_crtc > *scrtc) > struct drm_crtc *crtc = &scrtc->base; > struct shmob_drm_device *sdev = to_shmob_device(crtc->dev); > > - if (!scrtc->started) > - return; > - > /* >* Disable vertical blank interrupt reporting. We first need to wait >* for page flip completion before stopping the CRTC as userspace > @@ -335,8 +327,6 @@ static void shmob_drm_crtc_stop(struct shmob_drm_crtc > *scrtc) > shmob_drm_clk_off(sdev); > > pm_runtime_put(sdev->dev); > - > - scrtc->started = false; > } > > static inline struct shmob_drm_crtc *to_shmob_crtc(struct drm_crtc *crtc) > @@ -344,21 +334,6 @@ static inline struct shmob_drm_crtc > *to_shmob_crtc(struct drm_crtc *crtc) > return container_of(crtc, struct shmob_drm_crtc, base); > } > > -static void shmob_drm_crtc_dpms(struct drm_crtc *crtc, int mode) > -{ > - struct shmob_drm_crtc *scrtc = to_shmob_crtc(crtc); > - > - if (scrtc->dpms == mode) > - return; > - > - if (mode == DRM_MODE_DPMS_ON) > - shmob_drm_crtc_start(scrtc); > - else > - shmob_drm_crtc_stop(scrtc); > - > - scrtc->dpms = mode; > -} > - > static void shmob_drm_crtc_atomic_flush(struct drm_crtc *crtc, > struct drm_atomic_state *state) > { > @@ -378,13 +353,17 @@ static void shmob_drm_crtc_atomic_flush(struct drm_crtc > *crtc, > static void shmob_drm_crtc_atomic_enable(struct drm_crtc *crtc, >struct drm_atomic_state *state) > { > - shmob_drm_crtc_dpms(crtc, DRM_MODE_DPMS_ON); > + struct shmob_drm_crtc *scrtc = to_shmob_crtc(crtc); > + > + shmob_drm_crtc_start(scrtc); If this function isn't called from any other location anymore, you may want to inline it. > } > > static void shmob_drm_crtc_atomic_disable(struct drm_crtc *crtc, > struct drm_atomic_state *state) > { > - shmob_drm_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); > + struct shmob_drm_crtc *scrtc = to_shmob_crtc(crtc); > + > + shmob_drm_crtc_stop(scrtc); Same here. Reviewed-by: Laurent Pinchart > } > > static const struct drm_crtc_helper_funcs crtc_helper_funcs = { > @@ -476,8 +455,6 @@ int shmob_drm_crtc_create(struct shmob_drm_device *sdev) > > init_waitqueue_head(&sdev->crtc.flip_wait); > > - sdev->crtc.dpms = DRM_MODE_DPMS_OFF; > - > primary = shmob_drm_plane_create(sdev, 0); > if (IS_ERR(primary)) > return PTR_ERR(primary); > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h > index 37380c815f1f5a08..89a0746f9a35807d 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h > @@ -27,9 +27,6 @@ struct shmob_drm_crtc { > > struct drm_pending_vblank_event *event; > wait_queue_head_t flip_wait; > - int dpms; > - > - bool started; > }; > > struct shmob_drm_connector { -- Regards, Laurent Pinchart
Re: [PATCH 36/39] drm: renesas: shmobile: Use suspend/resume helpers
Hi Geert, Thank you for the patch. On Thu, Jun 22, 2023 at 11:21:48AM +0200, Geert Uytterhoeven wrote: > Replace the custom suspend/resume handling by calls into > drm_mode_config_helper_{suspend,resume}(). > > Signed-off-by: Geert Uytterhoeven Reviewed-by: Laurent Pinchart > --- > drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 13 - > drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h | 2 -- > drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 13 +++-- > 3 files changed, 3 insertions(+), 25 deletions(-) > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > index cf7152d64424e720..b11bb666de3bac46 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > @@ -339,19 +339,6 @@ static void shmob_drm_crtc_stop(struct shmob_drm_crtc > *scrtc) > scrtc->started = false; > } > > -void shmob_drm_crtc_suspend(struct shmob_drm_crtc *scrtc) > -{ > - shmob_drm_crtc_stop(scrtc); > -} > - > -void shmob_drm_crtc_resume(struct shmob_drm_crtc *scrtc) > -{ > - if (scrtc->dpms != DRM_MODE_DPMS_ON) > - return; > - > - shmob_drm_crtc_start(scrtc); > -} > - > static inline struct shmob_drm_crtc *to_shmob_crtc(struct drm_crtc *crtc) > { > return container_of(crtc, struct shmob_drm_crtc, base); > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h > index fe41e42d6cc55275..37380c815f1f5a08 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h > @@ -40,8 +40,6 @@ struct shmob_drm_connector { > > int shmob_drm_crtc_create(struct shmob_drm_device *sdev); > void shmob_drm_crtc_finish_page_flip(struct shmob_drm_crtc *scrtc); > -void shmob_drm_crtc_suspend(struct shmob_drm_crtc *scrtc); > -void shmob_drm_crtc_resume(struct shmob_drm_crtc *scrtc); > > int shmob_drm_encoder_create(struct shmob_drm_device *sdev); > int shmob_drm_connector_create(struct shmob_drm_device *sdev, > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > index 9107f84224602683..c43f408d6b1fcc5b 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > @@ -20,6 +20,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -115,22 +116,14 @@ static int shmob_drm_pm_suspend(struct device *dev) > { > struct shmob_drm_device *sdev = dev_get_drvdata(dev); > > - drm_kms_helper_poll_disable(&sdev->ddev); > - shmob_drm_crtc_suspend(&sdev->crtc); > - > - return 0; > + return drm_mode_config_helper_suspend(&sdev->ddev); > } > > static int shmob_drm_pm_resume(struct device *dev) > { > struct shmob_drm_device *sdev = dev_get_drvdata(dev); > > - drm_modeset_lock_all(&sdev->ddev); > - shmob_drm_crtc_resume(&sdev->crtc); > - drm_modeset_unlock_all(&sdev->ddev); > - > - drm_kms_helper_poll_enable(&sdev->ddev); > - return 0; > + return drm_mode_config_helper_resume(&sdev->ddev); > } > > static DEFINE_SIMPLE_DEV_PM_OPS(shmob_drm_pm_ops, -- Regards, Laurent Pinchart
Re: [PATCH 33/39] drm: renesas: shmobile: Cleanup encoder
Hi Geert, Thank you for the patch. On Thu, Jun 22, 2023 at 11:21:45AM +0200, Geert Uytterhoeven wrote: > Most unused callbacks can be NULL pointers these days. > Drop a bunch of empty encoder callbacks. > > Signed-off-by: Geert Uytterhoeven Reviewed-by: Laurent Pinchart > --- > .../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 26 --- > 1 file changed, 26 deletions(-) > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > index b184019d8b1ed89c..ef327da39bca415a 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > @@ -586,11 +586,6 @@ int shmob_drm_crtc_create(struct shmob_drm_device *sdev) > * Encoder > */ > > -static void shmob_drm_encoder_dpms(struct drm_encoder *encoder, int mode) > -{ > - /* No-op, everything is handled in the CRTC code. */ > -} > - > static bool shmob_drm_encoder_mode_fixup(struct drm_encoder *encoder, >const struct drm_display_mode *mode, >struct drm_display_mode *adjusted_mode) > @@ -613,29 +608,8 @@ static bool shmob_drm_encoder_mode_fixup(struct > drm_encoder *encoder, > return true; > } > > -static void shmob_drm_encoder_mode_prepare(struct drm_encoder *encoder) > -{ > - /* No-op, everything is handled in the CRTC code. */ > -} > - > -static void shmob_drm_encoder_mode_set(struct drm_encoder *encoder, > -struct drm_display_mode *mode, > -struct drm_display_mode *adjusted_mode) > -{ > - /* No-op, everything is handled in the CRTC code. */ > -} > - > -static void shmob_drm_encoder_mode_commit(struct drm_encoder *encoder) > -{ > - /* No-op, everything is handled in the CRTC code. */ > -} > - > static const struct drm_encoder_helper_funcs encoder_helper_funcs = { > - .dpms = shmob_drm_encoder_dpms, > .mode_fixup = shmob_drm_encoder_mode_fixup, > - .prepare = shmob_drm_encoder_mode_prepare, > - .commit = shmob_drm_encoder_mode_commit, > - .mode_set = shmob_drm_encoder_mode_set, > }; > > int shmob_drm_encoder_create(struct shmob_drm_device *sdev) -- Regards, Laurent Pinchart
Re: [PATCH 32/39] drm: renesas: shmobile: Shutdown the display on remove
Hi Geert, Thank you for the patch. On Thu, Jun 22, 2023 at 11:21:44AM +0200, Geert Uytterhoeven wrote: > When the device is unbound from the driver, the display may be active. > Make sure it gets shut down. > > Signed-off-by: Geert Uytterhoeven > --- > drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > index a29c0c1093725b6e..636f1888b815579b 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > @@ -16,6 +16,7 @@ > #include > #include > > +#include > #include > #include > #include > @@ -145,6 +146,7 @@ static int shmob_drm_remove(struct platform_device *pdev) > struct drm_device *ddev = &sdev->ddev; > > drm_dev_unregister(ddev); > + drm_helper_force_disable_all(ddev); I assume this will be turned into drm_atomic_helper_shutdown() later. Reviewed-by: Laurent Pinchart > drm_kms_helper_poll_fini(ddev); > return 0; > } -- Regards, Laurent Pinchart
Re: [PATCH 31/39] drm: renesas: shmobile: Turn vblank on/off when enabling/disabling CRTC
Hi Geert, Thank you for the patch. On Thu, Jun 22, 2023 at 11:21:43AM +0200, Geert Uytterhoeven wrote: > The DRM core vblank handling mechanism requires drivers to forcefully > turn vblank reporting off when disabling the CRTC, and to restore the > vblank reporting status when enabling the CRTC. > Implement this using the drm_crtc_vblank_{on,off}() helpers. > > Note that drm_crtc_vblank_off() must be called at startup to synchronize > the state of the vblank core code with the hardware, which is initially > disabled. This is performed at CRTC creation time, requiring vertical > blank initialization to be moved before creating CRTCs. > > Signed-off-by: Geert Uytterhoeven Reviewed-by: Laurent Pinchart > --- > drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 10 +- > drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 12 ++-- > 2 files changed, 15 insertions(+), 7 deletions(-) > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > index d2a0ac5f9368c11c..b184019d8b1ed89c 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > @@ -267,6 +267,9 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc > *scrtc) > > shmob_drm_crtc_start_stop(scrtc, true); > > + /* Turn vertical blank interrupt reporting back on. */ > + drm_crtc_vblank_on(crtc); > + > scrtc->started = true; > } > > @@ -332,10 +335,12 @@ static void shmob_drm_crtc_stop(struct shmob_drm_crtc > *scrtc) > return; > > /* > - * Wait for page flip completion before stopping the CRTC as userspace > + * Disable vertical blank interrupt reporting. We first need to wait > + * for page flip completion before stopping the CRTC as userspace >* expects page flips to eventually complete. >*/ > shmob_drm_crtc_wait_page_flip(scrtc); > + drm_crtc_vblank_off(crtc); > > /* Stop the LCDC. */ > shmob_drm_crtc_start_stop(scrtc, false); > @@ -571,6 +576,9 @@ int shmob_drm_crtc_create(struct shmob_drm_device *sdev) > > drm_crtc_helper_add(crtc, &crtc_helper_funcs); > > + /* Start with vertical blank interrupt reporting disabled. */ > + drm_crtc_vblank_off(crtc); > + > return 0; > } > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > index 6eaf2c5a104f451a..a29c0c1093725b6e 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > @@ -189,17 +189,17 @@ static int shmob_drm_probe(struct platform_device *pdev) > if (ret < 0) > return ret; > > - ret = shmob_drm_modeset_init(sdev); > - if (ret < 0) > - return dev_err_probe(&pdev->dev, ret, > - "failed to initialize mode setting\n"); > - > ret = drm_vblank_init(ddev, 1); > if (ret < 0) { > dev_err(&pdev->dev, "failed to initialize vblank\n"); > - goto err_modeset_cleanup; > + return ret; > } > > + ret = shmob_drm_modeset_init(sdev); > + if (ret < 0) > + return dev_err_probe(&pdev->dev, ret, > + "failed to initialize mode setting\n"); > + > ret = platform_get_irq(pdev, 0); > if (ret < 0) > goto err_modeset_cleanup; -- Regards, Laurent Pinchart
Re: [PATCH 30/39] drm: renesas: shmobile: Wait for page flip when turning CRTC off
Hi Geert, Thank you for the patch. On Thu, Jun 22, 2023 at 11:21:42AM +0200, Geert Uytterhoeven wrote: > Turning a CRTC off will prevent a queued page flip from ever completing, > potentially confusing userspace. Wait for queued page flips to complete > before turning the CRTC off to avoid this. > > Signed-off-by: Geert Uytterhoeven Given that you're duplicating the rcar-du page flip handling code, I have a feeling core helpers would be handy. It's not a blocker for this series though, so Reviewed-by: Laurent Pinchart > --- > .../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 37 +++ > .../gpu/drm/renesas/shmobile/shmob_drm_crtc.h | 3 ++ > 2 files changed, 40 insertions(+) > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > index 1d7fcf64bf2aab80..d2a0ac5f9368c11c 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > @@ -285,11 +285,40 @@ void shmob_drm_crtc_finish_page_flip(struct > shmob_drm_crtc *scrtc) > scrtc->event = NULL; > if (event) { > drm_crtc_send_vblank_event(&scrtc->base, event); > + wake_up(&scrtc->flip_wait); > drm_crtc_vblank_put(&scrtc->base); > } > spin_unlock_irqrestore(&dev->event_lock, flags); > } > > +static bool shmob_drm_crtc_page_flip_pending(struct shmob_drm_crtc *scrtc) > +{ > + struct drm_device *dev = scrtc->base.dev; > + unsigned long flags; > + bool pending; > + > + spin_lock_irqsave(&dev->event_lock, flags); > + pending = scrtc->event != NULL; > + spin_unlock_irqrestore(&dev->event_lock, flags); > + > + return pending; > +} > + > +static void shmob_drm_crtc_wait_page_flip(struct shmob_drm_crtc *scrtc) > +{ > + struct drm_crtc *crtc = &scrtc->base; > + struct shmob_drm_device *sdev = to_shmob_device(crtc->dev); > + > + if (wait_event_timeout(scrtc->flip_wait, > +!shmob_drm_crtc_page_flip_pending(scrtc), > +msecs_to_jiffies(50))) > + return; > + > + dev_warn(sdev->dev, "page flip timeout\n"); > + > + shmob_drm_crtc_finish_page_flip(scrtc); > +} > + > /* > - > * CRTC Functions > */ > @@ -302,6 +331,12 @@ static void shmob_drm_crtc_stop(struct shmob_drm_crtc > *scrtc) > if (!scrtc->started) > return; > > + /* > + * Wait for page flip completion before stopping the CRTC as userspace > + * expects page flips to eventually complete. > + */ > + shmob_drm_crtc_wait_page_flip(scrtc); > + > /* Stop the LCDC. */ > shmob_drm_crtc_start_stop(scrtc, false); > > @@ -515,6 +550,8 @@ int shmob_drm_crtc_create(struct shmob_drm_device *sdev) > unsigned int i; > int ret; > > + init_waitqueue_head(&sdev->crtc.flip_wait); > + > sdev->crtc.dpms = DRM_MODE_DPMS_OFF; > > primary = shmob_drm_plane_create(sdev, 0); > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h > index 2c6d7541427581a6..b9863e026e8a9b83 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h > @@ -14,6 +14,8 @@ > #include > #include > > +#include > + > #include > > struct drm_pending_vblank_event; > @@ -24,6 +26,7 @@ struct shmob_drm_crtc { > struct drm_crtc base; > > struct drm_pending_vblank_event *event; > + wait_queue_head_t flip_wait; > int dpms; > > const struct shmob_drm_format_info *format; -- Regards, Laurent Pinchart
Re: [PATCH 29/39] drm: renesas: shmobile: Move shmob_drm_crtc_finish_page_flip()
Hi Geert, Thank you for the patch. On Thu, Jun 22, 2023 at 11:21:41AM +0200, Geert Uytterhoeven wrote: > Move the shmob_drm_crtc_finish_page_flip() function up, to avoid having > to move it during the modification in the next change. > > Signed-off-by: Geert Uytterhoeven Reviewed-by: Laurent Pinchart > --- > .../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 40 +++ > 1 file changed, 24 insertions(+), 16 deletions(-) > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > index 2c0ca802d36026f4..1d7fcf64bf2aab80 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > @@ -270,6 +270,30 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc > *scrtc) > scrtc->started = true; > } > > +/* > - > + * Page Flip > + */ > + > +void shmob_drm_crtc_finish_page_flip(struct shmob_drm_crtc *scrtc) > +{ > + struct drm_pending_vblank_event *event; > + struct drm_device *dev = scrtc->base.dev; > + unsigned long flags; > + > + spin_lock_irqsave(&dev->event_lock, flags); > + event = scrtc->event; > + scrtc->event = NULL; > + if (event) { > + drm_crtc_send_vblank_event(&scrtc->base, event); > + drm_crtc_vblank_put(&scrtc->base); > + } > + spin_unlock_irqrestore(&dev->event_lock, flags); > +} > + > +/* > - > + * CRTC Functions > + */ > + > static void shmob_drm_crtc_stop(struct shmob_drm_crtc *scrtc) > { > struct drm_crtc *crtc = &scrtc->base; > @@ -412,22 +436,6 @@ static const struct drm_crtc_helper_funcs > crtc_helper_funcs = { > .mode_set_base = shmob_drm_crtc_mode_set_base, > }; > > -void shmob_drm_crtc_finish_page_flip(struct shmob_drm_crtc *scrtc) > -{ > - struct drm_pending_vblank_event *event; > - struct drm_device *dev = scrtc->base.dev; > - unsigned long flags; > - > - spin_lock_irqsave(&dev->event_lock, flags); > - event = scrtc->event; > - scrtc->event = NULL; > - if (event) { > - drm_crtc_send_vblank_event(&scrtc->base, event); > - drm_crtc_vblank_put(&scrtc->base); > - } > - spin_unlock_irqrestore(&dev->event_lock, flags); > -} > - > static int shmob_drm_crtc_page_flip(struct drm_crtc *crtc, > struct drm_framebuffer *fb, > struct drm_pending_vblank_event *event, -- Regards, Laurent Pinchart
Re: [PATCH 28/39] drm: renesas: shmobile: Use drm_crtc_handle_vblank()
Hi Geert, Thank you for the patch. On Thu, Jun 22, 2023 at 11:21:40AM +0200, Geert Uytterhoeven wrote: > Replace the call to the legacy drm_handle_vblank() function with a call > to the new drm_crtc_handle_vblank() helper. > > Signed-off-by: Geert Uytterhoeven Reviewed-by: Laurent Pinchart > --- > drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > index c98e2bdd888c3274..6eaf2c5a104f451a 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > @@ -86,7 +86,7 @@ static irqreturn_t shmob_drm_irq(int irq, void *arg) > spin_unlock_irqrestore(&sdev->irq_lock, flags); > > if (status & LDINTR_VES) { > - drm_handle_vblank(dev, 0); > + drm_crtc_handle_vblank(&sdev->crtc.base); > shmob_drm_crtc_finish_page_flip(&sdev->crtc); > } > -- Regards, Laurent Pinchart
Re: [PATCH 27/39] drm: renesas: shmobile: Rename shmob_drm_plane.plane
Hi Geert, Thank you for the patch. On Thu, Jun 22, 2023 at 11:21:39AM +0200, Geert Uytterhoeven wrote: > Rename the "plane" member of the shmob_drm_plane subclass structure to > "base", to improve readability. > > Signed-off-by: Geert Uytterhoeven Reviewed-by: Laurent Pinchart > --- > drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c | 10 +- > 1 file changed, 5 insertions(+), 5 deletions(-) > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c > index 63886015baaebfc0..e300e5c0de70a9b1 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c > @@ -20,7 +20,7 @@ > #include "shmob_drm_regs.h" > > struct shmob_drm_plane { > - struct drm_plane plane; > + struct drm_plane base; > unsigned int index; > unsigned int alpha; > > @@ -37,7 +37,7 @@ struct shmob_drm_plane { > > static inline struct shmob_drm_plane *to_shmob_plane(struct drm_plane *plane) > { > - return container_of(plane, struct shmob_drm_plane, plane); > + return container_of(plane, struct shmob_drm_plane, base); > } > > static void shmob_drm_plane_compute_base(struct shmob_drm_plane *splane, > @@ -64,7 +64,7 @@ static void shmob_drm_plane_compute_base(struct > shmob_drm_plane *splane, > static void __shmob_drm_plane_setup(struct shmob_drm_plane *splane, > struct drm_framebuffer *fb) > { > - struct shmob_drm_device *sdev = to_shmob_device(splane->plane.dev); > + struct shmob_drm_device *sdev = to_shmob_device(splane->base.dev); > unsigned int ovl_idx = splane->index - 1; > u32 format; > > @@ -221,7 +221,7 @@ struct drm_plane *shmob_drm_plane_create(struct > shmob_drm_device *sdev, > } > > splane = drmm_universal_plane_alloc(&sdev->ddev, > - struct shmob_drm_plane, plane, 1, > + struct shmob_drm_plane, base, 1, > funcs, formats, > ARRAY_SIZE(formats), NULL, type, > NULL); > @@ -231,5 +231,5 @@ struct drm_plane *shmob_drm_plane_create(struct > shmob_drm_device *sdev, > splane->index = index; > splane->alpha = 255; > > - return &splane->plane; > + return &splane->base; > } -- Regards, Laurent Pinchart
Re: [PATCH 26/39] drm: renesas: shmobile: Rename shmob_drm_connector.connector
Hi Geert, Thank you for the patch. On Thu, Jun 22, 2023 at 11:21:38AM +0200, Geert Uytterhoeven wrote: > Rename the "connector" member of the shmob_drm_connector subclass > structure to "base", to improve readability. > > Signed-off-by: Geert Uytterhoeven Reviewed-by: Laurent Pinchart > --- > drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 4 ++-- > drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h | 2 +- > 2 files changed, 3 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > index 3f0b71253ed929c9..2c0ca802d36026f4 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > @@ -608,7 +608,7 @@ int shmob_drm_encoder_create(struct shmob_drm_device > *sdev) > > static inline struct shmob_drm_connector *to_shmob_connector(struct > drm_connector *connector) > { > - return container_of(connector, struct shmob_drm_connector, connector); > + return container_of(connector, struct shmob_drm_connector, base); > } > > static int shmob_drm_connector_get_modes(struct drm_connector *connector) > @@ -669,7 +669,7 @@ shmob_drm_connector_init(struct shmob_drm_device *sdev, > if (!scon) > return ERR_PTR(-ENOMEM); > > - connector = &scon->connector; > + connector = &scon->base; > info = &connector->display_info; > info->width_mm = sdev->pdata->panel.width_mm; > info->height_mm = sdev->pdata->panel.height_mm; > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h > index 79cce0a0ada4cfce..2c6d7541427581a6 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h > @@ -33,7 +33,7 @@ struct shmob_drm_crtc { > }; > > struct shmob_drm_connector { > - struct drm_connector connector; > + struct drm_connector base; > struct drm_encoder *encoder; > const struct videomode *mode; > }; -- Regards, Laurent Pinchart
Re: [PATCH 25/39] drm: renesas: shmobile: Rename shmob_drm_crtc.crtc
Hi Geert, Thank you for the patch. On Thu, Jun 22, 2023 at 11:21:37AM +0200, Geert Uytterhoeven wrote: > Rename the "crtc" member of the shmob_drm_crtc subclass structure to > "base", to improve readability. I'm not sure that's more readable to me, but I don't mind :-) Reviewed-by: Laurent Pinchart > Signed-off-by: Geert Uytterhoeven > --- > .../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 26 +-- > .../gpu/drm/renesas/shmobile/shmob_drm_crtc.h | 2 +- > 2 files changed, 14 insertions(+), 14 deletions(-) > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > index 3f6af12f45988124..3f0b71253ed929c9 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > @@ -64,7 +64,7 @@ static void shmob_drm_clk_off(struct shmob_drm_device *sdev) > > static void shmob_drm_crtc_setup_geometry(struct shmob_drm_crtc *scrtc) > { > - struct drm_crtc *crtc = &scrtc->crtc; > + struct drm_crtc *crtc = &scrtc->base; > struct shmob_drm_device *sdev = to_shmob_device(crtc->dev); > const struct drm_display_info *info = &sdev->connector->display_info; > const struct drm_display_mode *mode = &crtc->mode; > @@ -152,7 +152,7 @@ static void shmob_drm_crtc_setup_geometry(struct > shmob_drm_crtc *scrtc) > > static void shmob_drm_crtc_start_stop(struct shmob_drm_crtc *scrtc, bool > start) > { > - struct shmob_drm_device *sdev = to_shmob_device(scrtc->crtc.dev); > + struct shmob_drm_device *sdev = to_shmob_device(scrtc->base.dev); > u32 value; > > value = lcdc_read(sdev, LDCNT2R); > @@ -185,7 +185,7 @@ static void shmob_drm_crtc_start_stop(struct > shmob_drm_crtc *scrtc, bool start) > */ > static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc) > { > - struct drm_crtc *crtc = &scrtc->crtc; > + struct drm_crtc *crtc = &scrtc->base; > struct shmob_drm_device *sdev = to_shmob_device(crtc->dev); > const struct shmob_drm_interface_data *idata = &sdev->pdata->iface; > const struct shmob_drm_format_info *format; > @@ -272,7 +272,7 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc > *scrtc) > > static void shmob_drm_crtc_stop(struct shmob_drm_crtc *scrtc) > { > - struct drm_crtc *crtc = &scrtc->crtc; > + struct drm_crtc *crtc = &scrtc->base; > struct shmob_drm_device *sdev = to_shmob_device(crtc->dev); > > if (!scrtc->started) > @@ -308,7 +308,7 @@ void shmob_drm_crtc_resume(struct shmob_drm_crtc *scrtc) > static void shmob_drm_crtc_compute_base(struct shmob_drm_crtc *scrtc, > int x, int y) > { > - struct drm_crtc *crtc = &scrtc->crtc; > + struct drm_crtc *crtc = &scrtc->base; > struct drm_framebuffer *fb = crtc->primary->fb; > struct drm_gem_dma_object *gem; > unsigned int bpp; > @@ -329,7 +329,7 @@ static void shmob_drm_crtc_compute_base(struct > shmob_drm_crtc *scrtc, > > static void shmob_drm_crtc_update_base(struct shmob_drm_crtc *scrtc) > { > - struct drm_crtc *crtc = &scrtc->crtc; > + struct drm_crtc *crtc = &scrtc->base; > struct shmob_drm_device *sdev = to_shmob_device(crtc->dev); > > shmob_drm_crtc_compute_base(scrtc, crtc->x, crtc->y); > @@ -343,7 +343,7 @@ static void shmob_drm_crtc_update_base(struct > shmob_drm_crtc *scrtc) > > static inline struct shmob_drm_crtc *to_shmob_crtc(struct drm_crtc *crtc) > { > - return container_of(crtc, struct shmob_drm_crtc, crtc); > + return container_of(crtc, struct shmob_drm_crtc, base); > } > > static void shmob_drm_crtc_dpms(struct drm_crtc *crtc, int mode) > @@ -415,15 +415,15 @@ static const struct drm_crtc_helper_funcs > crtc_helper_funcs = { > void shmob_drm_crtc_finish_page_flip(struct shmob_drm_crtc *scrtc) > { > struct drm_pending_vblank_event *event; > - struct drm_device *dev = scrtc->crtc.dev; > + struct drm_device *dev = scrtc->base.dev; > unsigned long flags; > > spin_lock_irqsave(&dev->event_lock, flags); > event = scrtc->event; > scrtc->event = NULL; > if (event) { > - drm_crtc_send_vblank_event(&scrtc->crtc, event); > - drm_crtc_vblank_put(&scrtc->crtc); > + drm_crtc_send_vblank_event(&scrtc->base, event); > + drm_crtc_vblank_put(&scrtc->base); > } > spin_unlock_irqrestore(&dev->event_lock, flags); > } > @@ -435,7 +435,7 @@ static int shmob_drm_crtc_page_flip(struct drm_crtc *crtc, > struct drm_modeset_acquire_ctx *ctx) > { > struct shmob_drm_crtc *scrtc = to_shmob_crtc(crtc); > - struct drm_device *dev = scrtc->crtc.dev; > + struct drm_device *dev = scrtc->base.dev; > unsigned long flags; > > spin_lock_irqsave(&dev->event_lock, flags); > @@ -450,7 +450,7 @@ static int shmob_drm_crtc_page_flip(struct drm_crtc *crtc, >
Re: [PATCH 24/39] drm: renesas: shmobile: Unify plane allocation
Hi Geert, Thank you for the patch. On Thu, Jun 22, 2023 at 11:21:36AM +0200, Geert Uytterhoeven wrote: > Unify primary and overlay plane allocation: > - Enhance shmob_drm_plane_create() so it can be used to create the > primary plane, too, > - Move overlay plane creation next to primary plane creation. > > As overlay plane index zero now means the primary plane, this requires > shifting all overlay plane indices by one. Do you use index zero to identify the primary plane just for shmob_drm_plane_create(), or somewhere else too ? If it's just to create the plane, you could instead pass the plane type to the function. > Signed-off-by: Geert Uytterhoeven > --- > Perhaps it would be better to not use dynamic allocation, but store > "struct drm_plane primary" and "struct shmob_drm_plane planes[5]" in > struct drm_shmob_device instead, like is done for the crtc and encoder? > --- > .../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 39 ++-- > .../gpu/drm/renesas/shmobile/shmob_drm_drv.c | 9 -- > .../drm/renesas/shmobile/shmob_drm_plane.c| 96 +++ > .../drm/renesas/shmobile/shmob_drm_plane.h| 3 +- > 4 files changed, 70 insertions(+), 77 deletions(-) > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > index 28a70536693f7788..3f6af12f45988124 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > @@ -19,7 +19,6 @@ > #include > #include > #include > -#include > #include > #include > #include > @@ -501,47 +500,29 @@ static const struct drm_crtc_funcs crtc_funcs = { > .disable_vblank = shmob_drm_disable_vblank, > }; > > -static const uint32_t modeset_formats[] = { > - DRM_FORMAT_RGB565, > - DRM_FORMAT_RGB888, > - DRM_FORMAT_ARGB, > - DRM_FORMAT_XRGB, > - DRM_FORMAT_NV12, > - DRM_FORMAT_NV21, > - DRM_FORMAT_NV16, > - DRM_FORMAT_NV61, > - DRM_FORMAT_NV24, > - DRM_FORMAT_NV42, > -}; > - > -static const struct drm_plane_funcs primary_plane_funcs = { > - DRM_PLANE_NON_ATOMIC_FUNCS, > -}; > - > int shmob_drm_crtc_create(struct shmob_drm_device *sdev) > { > struct drm_crtc *crtc = &sdev->crtc.crtc; > - struct drm_plane *primary; > + struct drm_plane *primary, *plane; > + unsigned int i; > int ret; > > sdev->crtc.dpms = DRM_MODE_DPMS_OFF; > > - primary = __drm_universal_plane_alloc(&sdev->ddev, sizeof(*primary), 0, > - 0, &primary_plane_funcs, > - modeset_formats, > - ARRAY_SIZE(modeset_formats), > - NULL, DRM_PLANE_TYPE_PRIMARY, > - NULL); > + primary = shmob_drm_plane_create(sdev, 0); > if (IS_ERR(primary)) > return PTR_ERR(primary); > > + for (i = 1; i < 5; ++i) { > + plane = shmob_drm_plane_create(sdev, i); > + if (IS_ERR(plane)) > + return PTR_ERR(plane); > + } > + > ret = drm_crtc_init_with_planes(&sdev->ddev, crtc, primary, NULL, > &crtc_funcs, NULL); > - if (ret < 0) { > - drm_plane_cleanup(primary); > - kfree(primary); > + if (ret < 0) > return ret; > - } > > drm_crtc_helper_add(crtc, &crtc_helper_funcs); > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > index c15ebbe74cac501f..c98e2bdd888c3274 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > @@ -154,7 +154,6 @@ static int shmob_drm_probe(struct platform_device *pdev) > struct shmob_drm_platform_data *pdata = pdev->dev.platform_data; > struct shmob_drm_device *sdev; > struct drm_device *ddev; > - unsigned int i; > int ret; > > if (pdata == NULL) { > @@ -195,14 +194,6 @@ static int shmob_drm_probe(struct platform_device *pdev) > return dev_err_probe(&pdev->dev, ret, >"failed to initialize mode setting\n"); > > - for (i = 0; i < 4; ++i) { > - ret = shmob_drm_plane_create(sdev, i); > - if (ret < 0) { > - dev_err(&pdev->dev, "failed to create plane %u\n", i); > - goto err_modeset_cleanup; > - } > - } > - > ret = drm_vblank_init(ddev, 1); > if (ret < 0) { > dev_err(&pdev->dev, "failed to initialize vblank\n"); > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c > index c58b9dca34736342..63886015baaebfc0 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c > +++ b/drivers/g
Re: [PATCH V4 1/8] drivers/acpi: Add support for Wifi band RF mitigations
On 6/23/2023 11:28 AM, Rafael J. Wysocki wrote: On Fri, Jun 23, 2023 at 5:57 PM Limonciello, Mario wrote: On 6/23/2023 9:52 AM, Rafael J. Wysocki wrote: On Wed, Jun 21, 2023 at 7:47 AM Evan Quan wrote: From: Mario Limonciello Due to electrical and mechanical constraints in certain platform designs there may be likely interference of relatively high-powered harmonics of the (G-)DDR memory clocks with local radio module frequency bands used by Wifi 6/6e/7. To mitigate this, AMD has introduced an ACPI based mechanism that devices can use to notify active use of particular frequencies so that devices can make relative internal adjustments as necessary to avoid this resonance. In order for a device to support this, the expected flow for device driver or subsystems: Drivers/subsystems contributing frequencies: 1) During probe, check `wbrf_supported_producer` to see if WBRF supported The prefix should be acpi_wbrf_ or acpi_amd_wbrf_ even, so it is clear that this uses ACPI and is AMD-specific. I guess if we end up with an intermediary library approach wbrf_supported_producer makes sense and that could call acpi_wbrf_*. But with no intermediate library your suggestion makes sense. I would prefer not to make it acpi_amd as there is no reason that this exact same problem couldn't happen on an Wifi 6e + Intel SOC + AMD dGPU design too and OEMs could use the same mitigation mechanism as Wifi6e + AMD SOC + AMD dGPU too. The mitigation mechanism might be the same, but the AML interface very well may be different. Right. I suppose right now we should keep it prefixed as "amd", and if it later is promoted as a standard it can be renamed. My point is that this particular interface is AMD-specific ATM and I'm not aware of any plans to make it "standard" in some way. Yeah; this implementation is currently AMD specific AML, but I expect the exact same AML would be delivered to OEMs using the dGPUs. Also if the given interface is specified somewhere, it would be good to have a pointer to that place. It's a code first implementation. I'm discussing with the owners when they will release it. Whether or not there needs to be an intermediate library wrapped around this is a different matter. IMO individual drivers should not be expected to use this interface directly, as that would add to boilerplate code and overall bloat. The thing is the ACPI method is not a platform method. It's a function of the device (_DSM). The reason for having acpi_wbrf.c in the first place is to avoid the boilerplate of the _DSM implementation across multiple drivers. Also whoever uses it, would first need to check if the device in question has an ACPI companion. Which comes back to Andrew's point. Either we: Have a generic wbrf_ helper that takes struct *device and internally checks if there is an ACPI companion and support. or Do the check for support in mac80211 + applicable drivers and only call the AMD WBRF ACPI method in those drivers in those cases.
Re: [PATCH 23/39] drm: renesas: shmobile: Move interface handling to connector setup
Hi Geert, Thank you for the patch. On Thu, Jun 22, 2023 at 11:21:35AM +0200, Geert Uytterhoeven wrote: > Move legacy interface handling to the connector setup code. > Set up bus_flags and bus_formats in display_info according to the > bus format and panel information from platform data, to make it more > similar with DT-based connector/bridge/panel setup. > This will allows us to use the same LCD interface setup code for both s/allows/allow/ > legacy and DT-based systems. > > Signed-off-by: Geert Uytterhoeven > --- > .../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 123 +++--- > .../gpu/drm/renesas/shmobile/shmob_drm_drv.c | 49 --- > .../gpu/drm/renesas/shmobile/shmob_drm_drv.h | 3 +- > 3 files changed, 109 insertions(+), 66 deletions(-) > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > index 5328910ebe09c832..28a70536693f7788 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > @@ -8,6 +8,7 @@ > */ > > #include > +#include > #include > > #include > @@ -66,15 +67,65 @@ static void shmob_drm_crtc_setup_geometry(struct > shmob_drm_crtc *scrtc) > { > struct drm_crtc *crtc = &scrtc->crtc; > struct shmob_drm_device *sdev = to_shmob_device(crtc->dev); > - enum display_flags dpy_flags = sdev->connector.mode->flags; > + const struct drm_display_info *info = &sdev->connector->display_info; > const struct drm_display_mode *mode = &crtc->mode; > u32 value; > > - value = sdev->ldmt1r > - | ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? 0 : LDMT1R_VPOL) > - | ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? 0 : LDMT1R_HPOL) > - | ((dpy_flags & DISPLAY_FLAGS_PIXDATA_POSEDGE) ? LDMT1R_DWPOL : 0) > - | ((dpy_flags & DISPLAY_FLAGS_DE_LOW) ? LDMT1R_DIPOL : 0); > + if (!info->num_bus_formats || !info->bus_formats) { > + dev_warn(sdev->dev, "No bus format reported, using RGB888\n"); > + value = LDMT1R_MIFTYP_RGB24; > + } else { > + switch (info->bus_formats[0]) { > + case MEDIA_BUS_FMT_RGB888_3X8: > + value = LDMT1R_MIFTYP_RGB8; > + break; > + > + case MEDIA_BUS_FMT_RGB666_2X9_BE: > + value = LDMT1R_MIFTYP_RGB9; > + break; > + > + case MEDIA_BUS_FMT_RGB888_2X12_BE: > + value = LDMT1R_MIFTYP_RGB12A; > + break; > + > + case MEDIA_BUS_FMT_RGB444_1X12: > + value = LDMT1R_MIFTYP_RGB12B; > + break; > + > + case MEDIA_BUS_FMT_RGB565_1X16: > + value = LDMT1R_MIFTYP_RGB16; > + break; > + > + case MEDIA_BUS_FMT_RGB666_1X18: > + value = LDMT1R_MIFTYP_RGB18; > + break; > + > + case MEDIA_BUS_FMT_RGB888_1X24: > + value = LDMT1R_MIFTYP_RGB24; > + break; > + > + case MEDIA_BUS_FMT_UYVY8_1X16: > + value = LDMT1R_MIFTYP_YCBCR; > + break; > + > + default: > + dev_warn(sdev->dev, > + "unsupported bus format 0x%x, using RGB888\n", > + info->bus_formats[0]); > + value = LDMT1R_MIFTYP_RGB24; > + break; > + } It's a bit annoying to lose the ability to validate the bus format at probe time. Can it be kept. I'm also OK with restoring it later in the series if it gets in the way of the conversion, in which case a mention in the commit message would be nice. > + } > + > + if (info->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE) > + value |= LDMT1R_DWPOL; > + if (info->bus_flags & DRM_BUS_FLAG_DE_LOW) > + value |= LDMT1R_DIPOL; > + > + if (mode->flags & DRM_MODE_FLAG_NVSYNC) > + value |= LDMT1R_VPOL; > + if (mode->flags & DRM_MODE_FLAG_NHSYNC) > + value |= LDMT1R_HPOL; > > lcdc_write(sdev, LDMT1R, value); > > @@ -512,7 +563,7 @@ static bool shmob_drm_encoder_mode_fixup(struct > drm_encoder *encoder, > { > struct drm_device *dev = encoder->dev; > struct shmob_drm_device *sdev = to_shmob_device(dev); > - struct drm_connector *connector = &sdev->connector.connector; > + struct drm_connector *connector = sdev->connector; > const struct drm_display_mode *panel_mode; > > if (list_empty(&connector->modes)) { > @@ -614,6 +665,8 @@ static void shmob_drm_connector_destroy(struct > drm_connector *connector) > { > drm_connector_unregister(connector); > drm_connector_cleanup(connector); > + > + kfree(connector); > } > > static const struct drm_connector_funcs connector_funcs = { > @@ -622,26
Re: [PATCH V4 1/8] drivers/acpi: Add support for Wifi band RF mitigations
On Wed, Jun 21, 2023 at 7:47 AM Evan Quan wrote: > > From: Mario Limonciello > > Due to electrical and mechanical constraints in certain platform designs > there may be likely interference of relatively high-powered harmonics of > the (G-)DDR memory clocks with local radio module frequency bands used > by Wifi 6/6e/7. > > To mitigate this, AMD has introduced an ACPI based mechanism that > devices can use to notify active use of particular frequencies so > that devices can make relative internal adjustments as necessary > to avoid this resonance. > > In order for a device to support this, the expected flow for device > driver or subsystems: > > Drivers/subsystems contributing frequencies: > > 1) During probe, check `wbrf_supported_producer` to see if WBRF supported >for the device. > 2) If adding frequencies, then call `wbrf_add_exclusion` with the >start and end ranges of the frequencies. > 3) If removing frequencies, then call `wbrf_remove_exclusion` with >start and end ranges of the frequencies. > > Drivers/subsystems responding to frequencies: > > 1) During probe, check `wbrf_supported_consumer` to see if WBRF is supported >for the device. > 2) Call the `wbrf_retrieve_exclusions` to retrieve the current >exclusions on receiving an ACPI notification for a new frequency >change. > > Signed-off-by: Mario Limonciello > Co-developed-by: Evan Quan > Signed-off-by: Evan Quan > -- > v1->v2: > - move those wlan specific implementations to net/mac80211(Mario) > --- > drivers/acpi/Kconfig | 7 ++ > drivers/acpi/Makefile| 2 + > drivers/acpi/acpi_wbrf.c | 215 +++ > include/linux/wbrf.h | 55 ++ > 4 files changed, 279 insertions(+) > create mode 100644 drivers/acpi/acpi_wbrf.c > create mode 100644 include/linux/wbrf.h > > diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig > index ccbeab9500ec..0276c1487fa2 100644 > --- a/drivers/acpi/Kconfig > +++ b/drivers/acpi/Kconfig > @@ -611,3 +611,10 @@ config X86_PM_TIMER > > You should nearly always say Y here because many modern > systems require this timer. > + > +config ACPI_WBRF > + bool "ACPI Wifi band RF mitigation mechanism" > + help > + Wifi band RF mitigation mechanism allows multiple drivers from > + different domains to notify the frequencies in use so that hardware > + can be reconfigured to avoid harmonic conflicts. > diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile > index feb36c0b9446..14863b0c619f 100644 > --- a/drivers/acpi/Makefile > +++ b/drivers/acpi/Makefile > @@ -131,3 +131,5 @@ obj-y += dptf/ > obj-$(CONFIG_ARM64)+= arm64/ > > obj-$(CONFIG_ACPI_VIOT)+= viot.o > + > +obj-$(CONFIG_ACPI_WBRF)+= acpi_wbrf.o > diff --git a/drivers/acpi/acpi_wbrf.c b/drivers/acpi/acpi_wbrf.c > new file mode 100644 > index ..8c275998ac29 > --- /dev/null > +++ b/drivers/acpi/acpi_wbrf.c > @@ -0,0 +1,215 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * AMD Wifi Band Exclusion Interface Where is the AML interface for this defined and how does it work? > + * Copyright (C) 2023 Advanced Micro Devices > + * > + */ > + > +#include > + > +/* functions */ > +#define WBRF_RECORD0x1 > +#define WBRF_RETRIEVE 0x2 > + > +/* record actions */ > +#define WBRF_RECORD_ADD0x0 > +#define WBRF_RECORD_REMOVE 0x1 > + > +#define WBRF_REVISION 0x1 > + > +static const guid_t wifi_acpi_dsm_guid = > + GUID_INIT(0x7b7656cf, 0xdc3d, 0x4c1c, > + 0x83, 0xe9, 0x66, 0xe7, 0x21, 0xde, 0x30, 0x70); > + > +static int wbrf_dsm(struct acpi_device *adev, u8 fn, > + union acpi_object *argv4, > + union acpi_object **out) > +{ > + union acpi_object *obj; > + int rc; > + > + obj = acpi_evaluate_dsm(adev->handle, &wifi_acpi_dsm_guid, > + WBRF_REVISION, fn, argv4); > + if (!obj) > + return -ENXIO; > + > + switch (obj->type) { > + case ACPI_TYPE_BUFFER: > + if (!*out) { > + rc = -EINVAL; > + break; I'm not sure why you want to return an error in this case. Did you really mean !out? > + } > + *out = obj; > + return 0; > + > + case ACPI_TYPE_INTEGER: > + rc = obj->integer.value ? -EINVAL : 0; > + break; An empty line here, please, as you added one after the return statement above. > + default: > + rc = -EOPNOTSUPP; > + } > + ACPI_FREE(obj); > + > + return rc; How does the caller know whether or not they need to free the out object after calling this function? > +} > + > +static int wbrf_record(struct acpi_device *adev, uint8_t action, > + struct wbrf_ranges_in *in) > +{ > + uni
Re: [PATCH v1 0/2] udmabuf: Add back support for mapping hugetlb pages
On Fri, Jun 23, 2023 at 12:35:45PM -0400, Peter Xu wrote: > It seems the previous concern on using gup was majorly fork(), if this is it: > > https://patchwork.freedesktop.org/patch/210992/?series=39879&rev=2#comment_414213 Fork and GUP have been fixed since that comment anyhow there is no longer a problem using GUP and fork together. > Could it also be guarded by just making sure the pages are MAP_SHARED when > creating the udmabuf, if fork() is a requirement of the feature? Also a resaonable thing to do > For instance, what if the userapp just punchs a hole in the shmem/hugetlbfs > file after creating the udmabuf (I see that F_SEAL_SHRINK is required, but > at least not F_SEAL_WRITE with current impl), and fault a new page into the > page cache? It becomes incoherent just like all other GUP users if userspace explicitly manipulates the VMAs. It is no different to what happens with VFIO, qemu should treat this memory the same as it does for VFIO memory. Jason
Re: [PATCH v1 0/2] udmabuf: Add back support for mapping hugetlb pages
On Fri, Jun 23, 2023 at 06:13:02AM +, Kasireddy, Vivek wrote: > Hi David, > > > > The first patch ensures that the mappings needed for handling mmap > > > operation would be managed by using the pfn instead of struct page. > > > The second patch restores support for mapping hugetlb pages where > > > subpages of a hugepage are not directly used anymore (main reason > > > for revert) and instead the hugetlb pages and the relevant offsets > > > are used to populate the scatterlist for dma-buf export and for > > > mmap operation. > > > > > > Testcase: default_hugepagesz=2M hugepagesz=2M hugepages=2500 > > options > > > were passed to the Host kernel and Qemu was launched with these > > > relevant options: qemu-system-x86_64 -m 4096m > > > -device virtio-gpu-pci,max_outputs=1,blob=true,xres=1920,yres=1080 > > > -display gtk,gl=on > > > -object memory-backend-memfd,hugetlb=on,id=mem1,size=4096M > > > -machine memory-backend=mem1 > > > > > > Replacing -display gtk,gl=on with -display gtk,gl=off above would > > > exercise the mmap handler. > > > > > > > While I think the VM_PFNMAP approach is much better and should fix that > > issue at hand, I thought more about missing memlock support and realized > > that we might have to fix something else. SO I'm going to raise the > > issue here. > > > > I think udmabuf chose the wrong interface to do what it's doing, that > > makes it harder to fix it eventually. > > > > Instead of accepting a range in a memfd, it should just have accepted a > > user space address range and then used > > pin_user_pages(FOLL_WRITE|FOLL_LONGTERM) to longterm-pin the pages > > "officially". > Udmabuf indeed started off by using user space address range and GUP but > the dma-buf subsystem maintainer had concerns with that approach in v2. > It also had support for mlock in that version. Here is v2 and the relevant > conversation: > https://patchwork.freedesktop.org/patch/210992/?series=39879&rev=2 > > > > > So what's the issue? Udma effectively pins pages longterm ("possibly > > forever") simply by grabbing a reference on them. These pages might > > easily reside in ZONE_MOVABLE or in MIGRATE_CMA pageblocks. > > > > So what udmabuf does is break memory hotunplug and CMA, because it > > turns > > pages that have to remain movable unmovable. > > > > In the pin_user_pages(FOLL_LONGTERM) case we make sure to migrate > > these > > pages. See mm/gup.c:check_and_migrate_movable_pages() and especially > > folio_is_longterm_pinnable(). We'd probably have to implement something > > similar for udmabuf, where we detect such unpinnable pages and migrate > > them. > The pages udmabuf pins are only those associated with Guest (GPU > driver/virtio-gpu) > resources (or buffers allocated and pinned from shmem via drm GEM). Some > resources are short-lived, and some are long-lived and whenever a resource > gets destroyed, the pages are unpinned. And, not all resources have their > pages > pinned. The resource that is pinned for the longest duration is the FB and > that's > because it is updated every ~16ms (assuming 1920x1080@60) by the Guest > GPU driver. We can certainly pin/unpin the FB after it is accessed on the Host > as a workaround, but I guess that may not be very efficient given the amount > of churn it would create. > > Also, as far as migration or S3/S4 is concerned, my understanding is that all > the Guest resources are destroyed and recreated again. So, wouldn't something > similar happen during memory hotunplug? > > > > > > > For example, pairing udmabuf with vfio (which pins pages using > > pin_user_pages(FOLL_LONGTERM)) in QEMU will most probably not work in > > all cases: if udmabuf longterm pinned the pages "the wrong way", vfio > > will fail to migrate them during FOLL_LONGTERM and consequently fail > > pin_user_pages(). As long as udmabuf holds a reference on these pages, > > that will never succeed. > Dma-buf rules (for exporters) indicate that the pages only need to be pinned > during the map_attachment phase (and until unmap attachment happens). > In other words, only when the sg_table is created by udmabuf. I guess one > option would be to not hold any references during UDMABUF_CREATE and > only grab references to the pages (as and when it gets used) during this step. > Would this help? IIUC the refcount is needed, otherwise I don't see what to protect the page from being freed and even reused elsewhere before map_attachment(). It seems the previous concern on using gup was majorly fork(), if this is it: https://patchwork.freedesktop.org/patch/210992/?series=39879&rev=2#comment_414213 Could it also be guarded by just making sure the pages are MAP_SHARED when creating the udmabuf, if fork() is a requirement of the feature? I had a feeling that the userspace still needs to always do the right thing to make it work, even using pure PFN mappings. For instance, what if the userapp just punchs a hole in the shmem/hugetlbfs file after creating the udmabuf (I see that
Re: [PATCH V4 1/8] drivers/acpi: Add support for Wifi band RF mitigations
On Fri, Jun 23, 2023 at 5:57 PM Limonciello, Mario wrote: > > > On 6/23/2023 9:52 AM, Rafael J. Wysocki wrote: > > On Wed, Jun 21, 2023 at 7:47 AM Evan Quan wrote: > >> From: Mario Limonciello > >> > >> Due to electrical and mechanical constraints in certain platform designs > >> there may be likely interference of relatively high-powered harmonics of > >> the (G-)DDR memory clocks with local radio module frequency bands used > >> by Wifi 6/6e/7. > >> > >> To mitigate this, AMD has introduced an ACPI based mechanism that > >> devices can use to notify active use of particular frequencies so > >> that devices can make relative internal adjustments as necessary > >> to avoid this resonance. > >> > >> In order for a device to support this, the expected flow for device > >> driver or subsystems: > >> > >> Drivers/subsystems contributing frequencies: > >> > >> 1) During probe, check `wbrf_supported_producer` to see if WBRF supported > > The prefix should be acpi_wbrf_ or acpi_amd_wbrf_ even, so it is clear > > that this uses ACPI and is AMD-specific. > > I guess if we end up with an intermediary library approach > wbrf_supported_producer makes sense and that could call acpi_wbrf_*. > > But with no intermediate library your suggestion makes sense. > > I would prefer not to make it acpi_amd as there is no reason that > this exact same problem couldn't happen on an > Wifi 6e + Intel SOC + AMD dGPU design too and OEMs could use the > same mitigation mechanism as Wifi6e + AMD SOC + AMD dGPU too. The mitigation mechanism might be the same, but the AML interface very well may be different. My point is that this particular interface is AMD-specific ATM and I'm not aware of any plans to make it "standard" in some way. Also if the given interface is specified somewhere, it would be good to have a pointer to that place. > > > > Whether or not there needs to be an intermediate library wrapped > > around this is a different matter. IMO individual drivers should not be expected to use this interface directly, as that would add to boilerplate code and overall bloat. Also whoever uses it, would first need to check if the device in question has an ACPI companion.
Re: [PATCH v3 9/9] drm/mediatek: dp: Add support for embedded DisplayPort aux-bus
On Tue, Apr 04, 2023 at 12:48:00PM +0200, AngeloGioacchino Del Regno wrote: > For the eDP case we can support using aux-bus on MediaTek DP: this > gives us the possibility to declare our panel as generic "panel-edp" > which will automatically configure the timings and available modes > via the EDID that we read from it. > > To do this, move the panel parsing at the end of the probe function > so that the hardware is initialized beforehand and also initialize > the DPTX AUX block and power both on as, when we populate the > aux-bus, the panel driver will trigger an EDID read to perform > panel detection. > > Last but not least, since now the AUX transfers can happen in the > separated aux-bus, it was necessary to add an exclusion for the > cable_plugged_in check in `mtk_dp_aux_transfer()` and the easiest > way to do this is to simply ignore checking that when the bridge > type is eDP. > > Signed-off-by: AngeloGioacchino Del Regno > > --- > drivers/gpu/drm/mediatek/mtk_dp.c | 61 ++- > 1 file changed, 51 insertions(+), 10 deletions(-) > > diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c > b/drivers/gpu/drm/mediatek/mtk_dp.c > index a67143c22024..8109f5b4392b 100644 > --- a/drivers/gpu/drm/mediatek/mtk_dp.c > +++ b/drivers/gpu/drm/mediatek/mtk_dp.c [..] > @@ -2571,6 +2585,33 @@ static int mtk_dp_probe(struct platform_device *pdev) > mtk_dp->need_debounce = true; > timer_setup(&mtk_dp->debounce_timer, mtk_dp_debounce_timer, 0); > > + if (mtk_dp->bridge.type == DRM_MODE_CONNECTOR_eDP) { > + /* Initialize, reset and poweron the DPTX AUX block */ > + mtk_dp_initialize_aux_settings(mtk_dp); > + mtk_dp_power_enable(mtk_dp); > + > + /* Power on the panel to allow EDID read from aux-bus */ > + mtk_dp_aux_panel_poweron(mtk_dp, true); > + > + ret = devm_of_dp_aux_populate_bus(&mtk_dp->aux, NULL); > + > + /* If the panel is present, detection is done: power off! */ > + mtk_dp_aux_panel_poweron(mtk_dp, false); > + mtk_dp_power_disable(mtk_dp); > + > + /* We ignore -ENODEV error, as the panel may not be on aux-bus > */ > + if (ret && ret != -ENODEV) > + return ret; > + > + /* > + * Here we don't ignore any error, as if there's no panel to > + * link, eDP is not configured correctly and will be unusable. > + */ > + ret = mtk_dp_edp_link_panel(&mtk_dp->aux); This call might return EDEFER_PROBE if the panel hasn't probed yet. That's a problem, because during this probe you register a device for the dp-phy, so you'll be retriggering defer probes every time you probe until the panel probes. But if this driver was builtin and the panel a module, then this loop will go on forever. You should make use of the done_probing callback in devm_of_dp_aux_populate_bus() and do the panel linking there. This way you can exit successfully from this probe and avoid the loop. I had to do the same thing for anx7625.c [1]. Thanks, Nícolas [1] https://lore.kernel.org/all/20230518193902.891121-1-nfrapr...@collabora.com/
Re: [PATCH V4 1/8] drivers/acpi: Add support for Wifi band RF mitigations
On 6/23/2023 9:52 AM, Rafael J. Wysocki wrote: On Wed, Jun 21, 2023 at 7:47 AM Evan Quan wrote: From: Mario Limonciello Due to electrical and mechanical constraints in certain platform designs there may be likely interference of relatively high-powered harmonics of the (G-)DDR memory clocks with local radio module frequency bands used by Wifi 6/6e/7. To mitigate this, AMD has introduced an ACPI based mechanism that devices can use to notify active use of particular frequencies so that devices can make relative internal adjustments as necessary to avoid this resonance. In order for a device to support this, the expected flow for device driver or subsystems: Drivers/subsystems contributing frequencies: 1) During probe, check `wbrf_supported_producer` to see if WBRF supported The prefix should be acpi_wbrf_ or acpi_amd_wbrf_ even, so it is clear that this uses ACPI and is AMD-specific. I guess if we end up with an intermediary library approach wbrf_supported_producer makes sense and that could call acpi_wbrf_*. But with no intermediate library your suggestion makes sense. I would prefer not to make it acpi_amd as there is no reason that this exact same problem couldn't happen on an Wifi 6e + Intel SOC + AMD dGPU design too and OEMs could use the same mitigation mechanism as Wifi6e + AMD SOC + AMD dGPU too. Whether or not there needs to be an intermediate library wrapped around this is a different matter.
Re: [PATCH 22/39] drm: renesas: shmobile: Use media bus formats in platform data
Hi Geert, Thank you for the patch. On Thu, Jun 22, 2023 at 11:21:34AM +0200, Geert Uytterhoeven wrote: > Replace the custom shmob_drm_interface enumeration values with standard > media bus formats. This simplifies driver handling of bus formats and > prepares for DT support. > > Signed-off-by: Geert Uytterhoeven Reviewed-by: Laurent Pinchart > --- > .../gpu/drm/renesas/shmobile/shmob_drm_drv.c | 52 +-- > include/linux/platform_data/shmob_drm.h | 13 + > 2 files changed, 38 insertions(+), 27 deletions(-) > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > index 1a1d66c6e817e227..e5be0ae99bd970be 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > @@ -9,6 +9,7 @@ > > #include > #include > +#include > #include > #include > #include > @@ -34,24 +35,45 @@ > > static int shmob_drm_init_interface(struct shmob_drm_device *sdev) > { > - static const u32 ldmt1r[] = { > - [SHMOB_DRM_IFACE_RGB8] = LDMT1R_MIFTYP_RGB8, > - [SHMOB_DRM_IFACE_RGB9] = LDMT1R_MIFTYP_RGB9, > - [SHMOB_DRM_IFACE_RGB12A] = LDMT1R_MIFTYP_RGB12A, > - [SHMOB_DRM_IFACE_RGB12B] = LDMT1R_MIFTYP_RGB12B, > - [SHMOB_DRM_IFACE_RGB16] = LDMT1R_MIFTYP_RGB16, > - [SHMOB_DRM_IFACE_RGB18] = LDMT1R_MIFTYP_RGB18, > - [SHMOB_DRM_IFACE_RGB24] = LDMT1R_MIFTYP_RGB24, > - [SHMOB_DRM_IFACE_YUV422] = LDMT1R_MIFTYP_YCBCR, > - }; > - > - if (sdev->pdata->iface.interface >= ARRAY_SIZE(ldmt1r)) { > - dev_err(sdev->dev, "invalid interface type %u\n", > - sdev->pdata->iface.interface); > + switch (sdev->pdata->iface.bus_fmt) { > + case MEDIA_BUS_FMT_RGB888_3X8: > + sdev->ldmt1r = LDMT1R_MIFTYP_RGB8; > + break; > + > + case MEDIA_BUS_FMT_RGB666_2X9_BE: > + sdev->ldmt1r = LDMT1R_MIFTYP_RGB9; > + break; > + > + case MEDIA_BUS_FMT_RGB888_2X12_BE: > + sdev->ldmt1r = LDMT1R_MIFTYP_RGB12A; > + break; > + > + case MEDIA_BUS_FMT_RGB444_1X12: > + sdev->ldmt1r = LDMT1R_MIFTYP_RGB12B; > + break; > + > + case MEDIA_BUS_FMT_RGB565_1X16: > + sdev->ldmt1r = LDMT1R_MIFTYP_RGB16; > + break; > + > + case MEDIA_BUS_FMT_RGB666_1X18: > + sdev->ldmt1r = LDMT1R_MIFTYP_RGB18; > + break; > + > + case MEDIA_BUS_FMT_RGB888_1X24: > + sdev->ldmt1r = LDMT1R_MIFTYP_RGB24; > + break; > + > + case MEDIA_BUS_FMT_UYVY8_1X16: > + sdev->ldmt1r = LDMT1R_MIFTYP_YCBCR; > + break; > + > + default: > + dev_err(sdev->dev, "invalid bus format 0x%x\n", > + sdev->pdata->iface.bus_fmt); > return -EINVAL; > } > > - sdev->ldmt1r = ldmt1r[sdev->pdata->iface.interface]; > return 0; > } > > diff --git a/include/linux/platform_data/shmob_drm.h > b/include/linux/platform_data/shmob_drm.h > index f3cb19ff9f818aca..5047e66f0a6823ba 100644 > --- a/include/linux/platform_data/shmob_drm.h > +++ b/include/linux/platform_data/shmob_drm.h > @@ -18,17 +18,6 @@ enum shmob_drm_clk_source { > SHMOB_DRM_CLK_EXTERNAL, > }; > > -enum shmob_drm_interface { > - SHMOB_DRM_IFACE_RGB8, /* 24bpp, 8:8:8 */ > - SHMOB_DRM_IFACE_RGB9, /* 18bpp, 9:9 */ > - SHMOB_DRM_IFACE_RGB12A, /* 24bpp, 12:12 */ > - SHMOB_DRM_IFACE_RGB12B, /* 12bpp */ > - SHMOB_DRM_IFACE_RGB16, /* 16bpp */ > - SHMOB_DRM_IFACE_RGB18, /* 18bpp */ > - SHMOB_DRM_IFACE_RGB24, /* 24bpp */ > - SHMOB_DRM_IFACE_YUV422, /* 16bpp */ > -}; > - > struct shmob_drm_panel_data { > unsigned int width_mm; /* Panel width in mm */ > unsigned int height_mm; /* Panel height in mm */ > @@ -36,7 +25,7 @@ struct shmob_drm_panel_data { > }; > > struct shmob_drm_interface_data { > - enum shmob_drm_interface interface; > + unsigned int bus_fmt; /* MEDIA_BUS_FMT_RGB888_* */ > unsigned int clk_div; > }; > -- Regards, Laurent Pinchart
Re: [PATCH 21/39] drm: renesas: shmobile: Use struct videomode in platform data
Hi Geert, Thank you for the patch. On Thu, Jun 22, 2023 at 11:21:33AM +0200, Geert Uytterhoeven wrote: > From: Laurent Pinchart > > Replace the drm_mode_modeinfo field with videomode that includes more > signal polarity flags. This simplifies driver handling of panel modes > and prepares for DT support. > > Signed-off-by: Laurent Pinchart > [geert: Simplify] > Signed-off-by: Geert Uytterhoeven Reviewed-by: Laurent Pinchart > --- > Changes compared to Laurent's original: > - Rebase, > - Fix build, > - Remove unneeded {width,height}_mm intermediaries from > shmob_drm_connector, > - Replace embedded videomode by a const pointer to pdata. > --- > .../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 35 --- > .../gpu/drm/renesas/shmobile/shmob_drm_crtc.h | 3 ++ > include/linux/platform_data/shmob_drm.h | 11 ++ > 3 files changed, 19 insertions(+), 30 deletions(-) > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > index 291b3a5014c24f08..5328910ebe09c832 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > @@ -23,6 +23,8 @@ > #include > #include > > +#include > + > #include "shmob_drm_crtc.h" > #include "shmob_drm_drv.h" > #include "shmob_drm_kms.h" > @@ -64,18 +66,16 @@ static void shmob_drm_crtc_setup_geometry(struct > shmob_drm_crtc *scrtc) > { > struct drm_crtc *crtc = &scrtc->crtc; > struct shmob_drm_device *sdev = to_shmob_device(crtc->dev); > - const struct shmob_drm_interface_data *idata = &sdev->pdata->iface; > + enum display_flags dpy_flags = sdev->connector.mode->flags; > const struct drm_display_mode *mode = &crtc->mode; > u32 value; > > value = sdev->ldmt1r > | ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? 0 : LDMT1R_VPOL) > | ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? 0 : LDMT1R_HPOL) > - | ((idata->flags & SHMOB_DRM_IFACE_FL_DWPOL) ? LDMT1R_DWPOL : 0) > - | ((idata->flags & SHMOB_DRM_IFACE_FL_DIPOL) ? LDMT1R_DIPOL : 0) > - | ((idata->flags & SHMOB_DRM_IFACE_FL_DAPOL) ? LDMT1R_DAPOL : 0) > - | ((idata->flags & SHMOB_DRM_IFACE_FL_HSCNT) ? LDMT1R_HSCNT : 0) > - | ((idata->flags & SHMOB_DRM_IFACE_FL_DWCNT) ? LDMT1R_DWCNT : 0); > + | ((dpy_flags & DISPLAY_FLAGS_PIXDATA_POSEDGE) ? LDMT1R_DWPOL : 0) > + | ((dpy_flags & DISPLAY_FLAGS_DE_LOW) ? LDMT1R_DIPOL : 0); > + > lcdc_write(sdev, LDMT1R, value); > > value = ((mode->hdisplay / 8) << 16)/* HDCN */ > @@ -581,7 +581,7 @@ static inline struct shmob_drm_connector > *to_shmob_connector(struct drm_connecto > > static int shmob_drm_connector_get_modes(struct drm_connector *connector) > { > - struct shmob_drm_device *sdev = to_shmob_device(connector->dev); > + struct shmob_drm_connector *scon = to_shmob_connector(connector); > struct drm_display_mode *mode; > > mode = drm_mode_create(connector->dev); > @@ -589,18 +589,9 @@ static int shmob_drm_connector_get_modes(struct > drm_connector *connector) > return 0; > > mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; > - mode->clock = sdev->pdata->panel.mode.clock; > - mode->hdisplay = sdev->pdata->panel.mode.hdisplay; > - mode->hsync_start = sdev->pdata->panel.mode.hsync_start; > - mode->hsync_end = sdev->pdata->panel.mode.hsync_end; > - mode->htotal = sdev->pdata->panel.mode.htotal; > - mode->vdisplay = sdev->pdata->panel.mode.vdisplay; > - mode->vsync_start = sdev->pdata->panel.mode.vsync_start; > - mode->vsync_end = sdev->pdata->panel.mode.vsync_end; > - mode->vtotal = sdev->pdata->panel.mode.vtotal; > - mode->flags = sdev->pdata->panel.mode.flags; > - > - drm_mode_set_name(mode); > + > + drm_display_mode_from_videomode(scon->mode, mode); > + > drm_mode_probed_add(connector, mode); > > return 1; > @@ -634,10 +625,12 @@ static const struct drm_connector_funcs connector_funcs > = { > int shmob_drm_connector_create(struct shmob_drm_device *sdev, > struct drm_encoder *encoder) > { > - struct drm_connector *connector = &sdev->connector.connector; > + struct shmob_drm_connector *scon = &sdev->connector; > + struct drm_connector *connector = &scon->connector; > int ret; > > - sdev->connector.encoder = encoder; > + scon->encoder = encoder; > + scon->mode = &sdev->pdata->panel.mode; > > connector->display_info.width_mm = sdev->pdata->panel.width_mm; > connector->display_info.height_mm = sdev->pdata->panel.height_mm; > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h > index bce6926269453b77..f507eaf912e16a22 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h > +++ b/drivers/gpu/drm/re
Re: [PATCH 20/39] drm: renesas: shmobile: Replace .dev_private with container_of()
Hi Geert, Thank you for the patch. On Thu, Jun 22, 2023 at 11:21:32AM +0200, Geert Uytterhoeven wrote: > Now that drm_device is embedded in shmob_drm_device, we can use > a container_of()-based helper to get the shmob_drm_device pointer from > the drm_device, instead of using the deprecated drm_device.dev_private > field. > > While at it, restore reverse Xmas tree ordering of local variable > declarations. > > Signed-off-by: Geert Uytterhoeven Reviewed-by: Laurent Pinchart > --- > .../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 20 +-- > .../gpu/drm/renesas/shmobile/shmob_drm_drv.c | 4 +--- > .../gpu/drm/renesas/shmobile/shmob_drm_drv.h | 5 + > .../drm/renesas/shmobile/shmob_drm_plane.c| 6 +++--- > 4 files changed, 19 insertions(+), 16 deletions(-) > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > index 40948b56017ff2df..291b3a5014c24f08 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > @@ -63,7 +63,7 @@ static void shmob_drm_clk_off(struct shmob_drm_device *sdev) > static void shmob_drm_crtc_setup_geometry(struct shmob_drm_crtc *scrtc) > { > struct drm_crtc *crtc = &scrtc->crtc; > - struct shmob_drm_device *sdev = crtc->dev->dev_private; > + struct shmob_drm_device *sdev = to_shmob_device(crtc->dev); > const struct shmob_drm_interface_data *idata = &sdev->pdata->iface; > const struct drm_display_mode *mode = &crtc->mode; > u32 value; > @@ -102,7 +102,7 @@ static void shmob_drm_crtc_setup_geometry(struct > shmob_drm_crtc *scrtc) > > static void shmob_drm_crtc_start_stop(struct shmob_drm_crtc *scrtc, bool > start) > { > - struct shmob_drm_device *sdev = scrtc->crtc.dev->dev_private; > + struct shmob_drm_device *sdev = to_shmob_device(scrtc->crtc.dev); > u32 value; > > value = lcdc_read(sdev, LDCNT2R); > @@ -136,7 +136,7 @@ static void shmob_drm_crtc_start_stop(struct > shmob_drm_crtc *scrtc, bool start) > static void shmob_drm_crtc_start(struct shmob_drm_crtc *scrtc) > { > struct drm_crtc *crtc = &scrtc->crtc; > - struct shmob_drm_device *sdev = crtc->dev->dev_private; > + struct shmob_drm_device *sdev = to_shmob_device(crtc->dev); > const struct shmob_drm_interface_data *idata = &sdev->pdata->iface; > const struct shmob_drm_format_info *format; > struct drm_device *dev = &sdev->ddev; > @@ -223,7 +223,7 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc > *scrtc) > static void shmob_drm_crtc_stop(struct shmob_drm_crtc *scrtc) > { > struct drm_crtc *crtc = &scrtc->crtc; > - struct shmob_drm_device *sdev = crtc->dev->dev_private; > + struct shmob_drm_device *sdev = to_shmob_device(crtc->dev); > > if (!scrtc->started) > return; > @@ -280,7 +280,7 @@ static void shmob_drm_crtc_compute_base(struct > shmob_drm_crtc *scrtc, > static void shmob_drm_crtc_update_base(struct shmob_drm_crtc *scrtc) > { > struct drm_crtc *crtc = &scrtc->crtc; > - struct shmob_drm_device *sdev = crtc->dev->dev_private; > + struct shmob_drm_device *sdev = to_shmob_device(crtc->dev); > > shmob_drm_crtc_compute_base(scrtc, crtc->x, crtc->y); > > @@ -322,8 +322,8 @@ static int shmob_drm_crtc_mode_set(struct drm_crtc *crtc, > int x, int y, > struct drm_framebuffer *old_fb) > { > + struct shmob_drm_device *sdev = to_shmob_device(crtc->dev); > struct shmob_drm_crtc *scrtc = to_shmob_crtc(crtc); > - struct shmob_drm_device *sdev = crtc->dev->dev_private; > const struct shmob_drm_format_info *format; > > format = shmob_drm_format_info(crtc->primary->fb->format->format); > @@ -428,7 +428,7 @@ static void shmob_drm_crtc_enable_vblank(struct > shmob_drm_device *sdev, > > static int shmob_drm_enable_vblank(struct drm_crtc *crtc) > { > - struct shmob_drm_device *sdev = crtc->dev->dev_private; > + struct shmob_drm_device *sdev = to_shmob_device(crtc->dev); > > shmob_drm_crtc_enable_vblank(sdev, true); > > @@ -437,7 +437,7 @@ static int shmob_drm_enable_vblank(struct drm_crtc *crtc) > > static void shmob_drm_disable_vblank(struct drm_crtc *crtc) > { > - struct shmob_drm_device *sdev = crtc->dev->dev_private; > + struct shmob_drm_device *sdev = to_shmob_device(crtc->dev); > > shmob_drm_crtc_enable_vblank(sdev, false); > } > @@ -511,7 +511,7 @@ static bool shmob_drm_encoder_mode_fixup(struct > drm_encoder *encoder, >struct drm_display_mode *adjusted_mode) > { > struct drm_device *dev = encoder->dev; > - struct shmob_drm_device *sdev = dev->dev_private; > + struct shmob_drm_device *sdev = to_shmob_device(dev); > struct drm_connector *connector = &sdev->connector.connector; > const struct drm_display
Re: [PATCH 19/39] drm: renesas: shmobile: Convert container helpers to static inline functions
Hi Geert, Thank you for the patch. On Thu, Jun 22, 2023 at 11:21:31AM +0200, Geert Uytterhoeven wrote: > Replace to conversion helper macros using container_of() by static > inline functions, to improve type-safety. > > Signed-off-by: Geert Uytterhoeven Reviewed-by: Laurent Pinchart > --- > drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 11 --- > drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c | 5 - > 2 files changed, 12 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > index 26611440f7a12715..40948b56017ff2df 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > @@ -291,7 +291,10 @@ static void shmob_drm_crtc_update_base(struct > shmob_drm_crtc *scrtc) > lcdc_write(sdev, LDRCNTR, lcdc_read(sdev, LDRCNTR) ^ LDRCNTR_MRS); > } > > -#define to_shmob_crtc(c) container_of(c, struct shmob_drm_crtc, crtc) > +static inline struct shmob_drm_crtc *to_shmob_crtc(struct drm_crtc *crtc) > +{ > + return container_of(crtc, struct shmob_drm_crtc, crtc); > +} > > static void shmob_drm_crtc_dpms(struct drm_crtc *crtc, int mode) > { > @@ -571,8 +574,10 @@ int shmob_drm_encoder_create(struct shmob_drm_device > *sdev) > * Connector > */ > > -#define to_shmob_connector(c) \ > - container_of(c, struct shmob_drm_connector, connector) > +static inline struct shmob_drm_connector *to_shmob_connector(struct > drm_connector *connector) > +{ > + return container_of(connector, struct shmob_drm_connector, connector); > +} > > static int shmob_drm_connector_get_modes(struct drm_connector *connector) > { > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c > index 17e66a018689f648..258288c80756bf16 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c > @@ -34,7 +34,10 @@ struct shmob_drm_plane { > unsigned int crtc_h; > }; > > -#define to_shmob_plane(p)container_of(p, struct shmob_drm_plane, plane) > +static inline struct shmob_drm_plane *to_shmob_plane(struct drm_plane *plane) > +{ > + return container_of(plane, struct shmob_drm_plane, plane); > +} > > static void shmob_drm_plane_compute_base(struct shmob_drm_plane *splane, >struct drm_framebuffer *fb, -- Regards, Laurent Pinchart
Re: [PATCH 2/3] drm/i915/gt: Fix context workarounds with non-masked regs
On Thu, Jun 22, 2023 at 04:37:21PM -0700, Kenneth Graunke wrote: On Thursday, June 22, 2023 11:27:30 AM PDT Lucas De Marchi wrote: Most of the context workarounds tweak masked registers, but not all. For masked registers, when writing the value it's sufficient to just write the wa->set_bits since that will take care of both the clr and set bits as well as not overwriting other bits. However there are some workarounds, the registers are non-masked. Up until now the driver was simply emitting a MI_LOAD_REGISTER_IMM with the set_bits to program the register via the GPU in the WA bb. This has the side effect of overwriting the content of the register outside of bits that should be set and also doesn't handle the bits that should be cleared. Kenneth reported that on DG2, mesa was seeing a weird behavior due to the kernel programming of L3SQCREG5 in dg2_ctx_gt_tuning_init(). With the GPU idle, that register could be read via intel_reg as 0x00e001ff, but during a 3D workload it would change to 0x007f. So the programming of that tuning was affecting more than the bits in L3_PWM_TIMER_INIT_VAL_MASK. Matt Roper noticed the lack of rmw for the context workarounds due to the use of MI_LOAD_REGISTER_IMM. So, for registers that are not masked, read its value via mmio, modify and then set it in the buffer to be written by the GPU. This should take care in a simple way of programming just the bits required by the tuning/workaround. If in future there are registers that involved that can't be read by the CPU, a more complex approach may be required like a) issuing additional instructions to read and modify; or b) scan the golden context and patch it in place before saving it; or something else. But for now this should suffice. Scanning the context workarounds for all platforms, these are the impacted ones with the respective registers mtl: DRAW_WATERMARK mtl/dg2: XEHP_L3SQCREG5, XEHP_FF_MODE2 gen12: GEN12_FF_MODE2 Speaking of GEN12_FF_MODE2...there's a big scary comment above that workaround write which says that register "will return the wrong value when read." I think with this patch, we'll start doing a RMW cycle for the register, which could mix in some of this "wrong value". The comment mentions that the intention is to write the whole register, as the default value is 0 for all fields. Good point. That also means we don't need to backport this patch to stable kernel to any gen12, since overwritting the other bits is actually the intended behavior. Maybe what we want to do is change gen12_ctx_gt_tuning_init to do wa_write(wal, GEN12_FF_MODE2, FF_MODE2_TDS_TIMER_128); so it has a clear mask of ~0 instead of FF_MODE2_TDS_TIMER_MASK, and In order to ignore read back when verifying, we would still need to use wa_add(), but changing the mask. We don't have a wa_write() that ends up with { .clr = ~0, .read_mask = 0 }. wa_add(wal, GEN12_FF_MODE2, ~0, FF_MODE2_TDS_TIMER_128, 0, false); then in this patch update your condition below from + if (wa->masked_reg || wa->set == U32_MAX) { to + if (wa->masked_reg || wa->set == U32_MAX || wa->clear == U32_MAX) { yeah... and maybe also warn if wa->read is 0, which means it's one of the registers we can't/shouldn't read from the CPU. because if we're clearing all bits then we don't care about doing a read-modify-write either. thanks Lucas De Marchi --Ken
Re: [PATCH 18/39] drm: renesas: shmobile: Embed drm_device in shmob_drm_device
Hi Geert, Thank you for the patch. On Thu, Jun 22, 2023 at 11:21:30AM +0200, Geert Uytterhoeven wrote: > Embedding drm_device in shmob_drm_device allows us to use the DRM > managed API to allocate both structures in one go, simplifying error > handling. > > Signed-off-by: Geert Uytterhoeven Reviewed-by: Laurent Pinchart > --- > .../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 12 +++--- > .../gpu/drm/renesas/shmobile/shmob_drm_drv.c | 41 +++ > .../gpu/drm/renesas/shmobile/shmob_drm_drv.h | 2 +- > .../gpu/drm/renesas/shmobile/shmob_drm_kms.c | 16 > .../drm/renesas/shmobile/shmob_drm_plane.c| 8 ++-- > 5 files changed, 34 insertions(+), 45 deletions(-) > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > index bcdebbc9f8a7e299..26611440f7a12715 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > @@ -139,7 +139,7 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc > *scrtc) > struct shmob_drm_device *sdev = crtc->dev->dev_private; > const struct shmob_drm_interface_data *idata = &sdev->pdata->iface; > const struct shmob_drm_format_info *format; > - struct drm_device *dev = sdev->ddev; > + struct drm_device *dev = &sdev->ddev; > struct drm_plane *plane; > u32 value; > int ret; > @@ -472,7 +472,7 @@ int shmob_drm_crtc_create(struct shmob_drm_device *sdev) > > sdev->crtc.dpms = DRM_MODE_DPMS_OFF; > > - primary = __drm_universal_plane_alloc(sdev->ddev, sizeof(*primary), 0, > + primary = __drm_universal_plane_alloc(&sdev->ddev, sizeof(*primary), 0, > 0, &primary_plane_funcs, > modeset_formats, > ARRAY_SIZE(modeset_formats), > @@ -481,7 +481,7 @@ int shmob_drm_crtc_create(struct shmob_drm_device *sdev) > if (IS_ERR(primary)) > return PTR_ERR(primary); > > - ret = drm_crtc_init_with_planes(sdev->ddev, crtc, primary, NULL, > + ret = drm_crtc_init_with_planes(&sdev->ddev, crtc, primary, NULL, > &crtc_funcs, NULL); > if (ret < 0) { > drm_plane_cleanup(primary); > @@ -557,7 +557,7 @@ int shmob_drm_encoder_create(struct shmob_drm_device > *sdev) > > encoder->possible_crtcs = 1; > > - ret = drm_simple_encoder_init(sdev->ddev, encoder, > + ret = drm_simple_encoder_init(&sdev->ddev, encoder, > DRM_MODE_ENCODER_DPI); > if (ret < 0) > return ret; > @@ -637,7 +637,7 @@ int shmob_drm_connector_create(struct shmob_drm_device > *sdev, > connector->display_info.width_mm = sdev->pdata->panel.width_mm; > connector->display_info.height_mm = sdev->pdata->panel.height_mm; > > - ret = drm_connector_init(sdev->ddev, connector, &connector_funcs, > + ret = drm_connector_init(&sdev->ddev, connector, &connector_funcs, >DRM_MODE_CONNECTOR_DPI); > if (ret < 0) > return ret; > @@ -650,7 +650,7 @@ int shmob_drm_connector_create(struct shmob_drm_device > *sdev, > > drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); > drm_object_property_set_value(&connector->base, > - sdev->ddev->mode_config.dpms_property, DRM_MODE_DPMS_OFF); > + sdev->ddev.mode_config.dpms_property, DRM_MODE_DPMS_OFF); > > return 0; > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > index ece9aedde9b662d4..2b77af3a8c97ef8c 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > @@ -137,7 +137,7 @@ static int shmob_drm_pm_suspend(struct device *dev) > { > struct shmob_drm_device *sdev = dev_get_drvdata(dev); > > - drm_kms_helper_poll_disable(sdev->ddev); > + drm_kms_helper_poll_disable(&sdev->ddev); > shmob_drm_crtc_suspend(&sdev->crtc); > > return 0; > @@ -147,11 +147,11 @@ static int shmob_drm_pm_resume(struct device *dev) > { > struct shmob_drm_device *sdev = dev_get_drvdata(dev); > > - drm_modeset_lock_all(sdev->ddev); > + drm_modeset_lock_all(&sdev->ddev); > shmob_drm_crtc_resume(&sdev->crtc); > - drm_modeset_unlock_all(sdev->ddev); > + drm_modeset_unlock_all(&sdev->ddev); > > - drm_kms_helper_poll_enable(sdev->ddev); > + drm_kms_helper_poll_enable(&sdev->ddev); > return 0; > } > > @@ -165,12 +165,10 @@ static DEFINE_SIMPLE_DEV_PM_OPS(shmob_drm_pm_ops, > static int shmob_drm_remove(struct platform_device *pdev) > { > struct shmob_drm_device *sdev = platform_get_drvdata(pdev); > - struct drm_device *ddev = sdev->ddev; > + struct drm_device *ddev = &sdev->ddev; > > drm
Re: [PATCH 17/39] drm: renesas: shmobile: Use drmm_universal_plane_alloc()
Hi Geert, Thank you for the patch. On Thu, Jun 22, 2023 at 11:21:29AM +0200, Geert Uytterhoeven wrote: > According to the comments for drm_universal_plane_init(), the plane > structure should not be allocated with devm_kzalloc(). > > Fix lifetime issues by using drmm_universal_plane_alloc() instead. > > Signed-off-by: Geert Uytterhoeven > --- > Plane (and connector) structures are still allocated with devm_kzalloc() > in several other drivers... > --- > .../drm/renesas/shmobile/shmob_drm_plane.c| 24 ++- > 1 file changed, 7 insertions(+), 17 deletions(-) > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c > index 0b2ab153e9ae76df..1fb68b5fe915b8dc 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c > @@ -176,16 +176,9 @@ static int shmob_drm_plane_disable(struct drm_plane > *plane, > return 0; > } > > -static void shmob_drm_plane_destroy(struct drm_plane *plane) > -{ > - drm_plane_force_disable(plane); > - drm_plane_cleanup(plane); drm_plane_cleanup() will still be called from drmm_universal_plane_alloc_release(), but drm_plane_force_disable() won't. Is this an issue ? This should be documented in the commit message. > -} > - > static const struct drm_plane_funcs shmob_drm_plane_funcs = { > .update_plane = shmob_drm_plane_update, > .disable_plane = shmob_drm_plane_disable, > - .destroy = shmob_drm_plane_destroy, > }; > > static const uint32_t formats[] = { > @@ -204,19 +197,16 @@ static const uint32_t formats[] = { > int shmob_drm_plane_create(struct shmob_drm_device *sdev, unsigned int index) > { > struct shmob_drm_plane *splane; > - int ret; > > - splane = devm_kzalloc(sdev->dev, sizeof(*splane), GFP_KERNEL); > - if (splane == NULL) > - return -ENOMEM; > + splane = drmm_universal_plane_alloc(sdev->ddev, struct shmob_drm_plane, > + plane, 1, &shmob_drm_plane_funcs, > + formats, ARRAY_SIZE(formats), NULL, > + DRM_PLANE_TYPE_OVERLAY, NULL); > + if (IS_ERR(splane)) > + return PTR_ERR(splane); > > splane->index = index; > splane->alpha = 255; > > - ret = drm_universal_plane_init(sdev->ddev, &splane->plane, 1, > -&shmob_drm_plane_funcs, > -formats, ARRAY_SIZE(formats), NULL, > -DRM_PLANE_TYPE_OVERLAY, NULL); > - > - return ret; > + return 0; > } -- Regards, Laurent Pinchart
Re: [PATCH 16/39] drm: renesas: shmobile: Convert to use devm_request_irq()
Hi Geert, Thank you for the patch. On Thu, Jun 22, 2023 at 11:21:28AM +0200, Geert Uytterhoeven wrote: > Convert to managed IRQ handling, to simplify cleanup. > > Signed-off-by: Geert Uytterhoeven Reviewed-by: Laurent Pinchart > --- > drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 9 +++-- > 1 file changed, 3 insertions(+), 6 deletions(-) > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > index 50fca18282c5cb5e..ece9aedde9b662d4 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > @@ -169,7 +169,6 @@ static int shmob_drm_remove(struct platform_device *pdev) > > drm_dev_unregister(ddev); > drm_kms_helper_poll_fini(ddev); > - free_irq(sdev->irq, ddev); > drm_dev_put(ddev); > > return 0; > @@ -252,8 +251,8 @@ static int shmob_drm_probe(struct platform_device *pdev) > goto err_modeset_cleanup; > sdev->irq = ret; > > - ret = request_irq(sdev->irq, shmob_drm_irq, 0, ddev->driver->name, > - ddev); > + ret = devm_request_irq(&pdev->dev, sdev->irq, shmob_drm_irq, 0, > +ddev->driver->name, ddev); > if (ret < 0) { > dev_err(&pdev->dev, "failed to install IRQ handler\n"); > goto err_modeset_cleanup; > @@ -265,14 +264,12 @@ static int shmob_drm_probe(struct platform_device *pdev) >*/ > ret = drm_dev_register(ddev, 0); > if (ret < 0) > - goto err_irq_uninstall; > + goto err_modeset_cleanup; > > drm_fbdev_generic_setup(ddev, 16); > > return 0; > > -err_irq_uninstall: > - free_irq(sdev->irq, ddev); > err_modeset_cleanup: > drm_kms_helper_poll_fini(ddev); > err_free_drm_dev: -- Regards, Laurent Pinchart
Re: [PATCH 15/39] drm: renesas: shmobile: Improve error handling
Hi Geert, Thank you for the patch. On Thu, Jun 22, 2023 at 11:21:27AM +0200, Geert Uytterhoeven wrote: > Prepare for DT conversion, where panel probe can be deferred, by > streamlining error propagation and handling: > - Use dev_err_probe() to avoid printing error messages in case of > probe deferral, > - Propagate errors where needed. > > Signed-off-by: Geert Uytterhoeven Reviewed-by: Laurent Pinchart > --- > drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 3 ++- > drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c | 14 +++--- > 2 files changed, 13 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > index 9aa9800899976a23..50fca18282c5cb5e 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > @@ -228,7 +228,8 @@ static int shmob_drm_probe(struct platform_device *pdev) > > ret = shmob_drm_modeset_init(sdev); > if (ret < 0) { > - dev_err(&pdev->dev, "failed to initialize mode setting\n"); > + dev_err_probe(&pdev->dev, ret, > + "failed to initialize mode setting\n"); > goto err_free_drm_dev; > } > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c > index 3051318ddc7999bc..1a62e7f8a8a9e6df 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c > @@ -157,9 +157,17 @@ int shmob_drm_modeset_init(struct shmob_drm_device *sdev) > if (ret) > return ret; > > - shmob_drm_crtc_create(sdev); > - shmob_drm_encoder_create(sdev); > - shmob_drm_connector_create(sdev, &sdev->encoder); > + ret = shmob_drm_crtc_create(sdev); > + if (ret < 0) > + return ret; > + > + ret = shmob_drm_encoder_create(sdev); > + if (ret < 0) > + return ret; > + > + ret = shmob_drm_connector_create(sdev, &sdev->encoder); > + if (ret < 0) > + return ret; > > drm_kms_helper_poll_init(sdev->ddev); > -- Regards, Laurent Pinchart
Re: [PATCH 11/39] drm: renesas: shmobile: Remove backlight support
Hi Geert, Thank you for the patch. On Thu, Jun 22, 2023 at 11:21:23AM +0200, Geert Uytterhoeven wrote: > From: Laurent Pinchart > > Backlight support should be implemented by panels, not by the LCDC > driver. As the feature is currently unused anyway, remove it. > > Signed-off-by: Laurent Pinchart > [geert: Cleanups] > Signed-off-by: Geert Uytterhoeven Reviewed-by: Laurent Pinchart > --- > Changes compared to Laurent's original: > - Rebase, > - Remove unused variable ‘scon’, > - Remove now unused to_shmob_encoder() macro, > - Remove now empty shmob_drm_encoder wrapper. > --- > drivers/gpu/drm/renesas/shmobile/Makefile | 3 +- > .../renesas/shmobile/shmob_drm_backlight.c| 82 --- > .../renesas/shmobile/shmob_drm_backlight.h| 19 - > .../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 33 +--- > .../gpu/drm/renesas/shmobile/shmob_drm_crtc.h | 8 -- > .../gpu/drm/renesas/shmobile/shmob_drm_drv.h | 2 +- > .../gpu/drm/renesas/shmobile/shmob_drm_kms.c | 2 +- > include/linux/platform_data/shmob_drm.h | 8 -- > 8 files changed, 7 insertions(+), 150 deletions(-) > delete mode 100644 drivers/gpu/drm/renesas/shmobile/shmob_drm_backlight.c > delete mode 100644 drivers/gpu/drm/renesas/shmobile/shmob_drm_backlight.h > > diff --git a/drivers/gpu/drm/renesas/shmobile/Makefile > b/drivers/gpu/drm/renesas/shmobile/Makefile > index 861edafed8562c87..2679555d61a70207 100644 > --- a/drivers/gpu/drm/renesas/shmobile/Makefile > +++ b/drivers/gpu/drm/renesas/shmobile/Makefile > @@ -1,6 +1,5 @@ > # SPDX-License-Identifier: GPL-2.0 > -shmob-drm-y := shmob_drm_backlight.o \ > -shmob_drm_crtc.o \ > +shmob-drm-y := shmob_drm_crtc.o \ > shmob_drm_drv.o \ > shmob_drm_kms.o \ > shmob_drm_plane.o > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_backlight.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_backlight.c > deleted file mode 100644 > index 794573badfe86076.. > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_backlight.c > +++ /dev/null > @@ -1,82 +0,0 @@ > -// SPDX-License-Identifier: GPL-2.0+ > -/* > - * shmob_drm_backlight.c -- SH Mobile DRM Backlight > - * > - * Copyright (C) 2012 Renesas Electronics Corporation > - * > - * Laurent Pinchart (laurent.pinch...@ideasonboard.com) > - */ > - > -#include > - > -#include "shmob_drm_backlight.h" > -#include "shmob_drm_crtc.h" > -#include "shmob_drm_drv.h" > - > -static int shmob_drm_backlight_update(struct backlight_device *bdev) > -{ > - struct shmob_drm_connector *scon = bl_get_data(bdev); > - struct shmob_drm_device *sdev = scon->connector.dev->dev_private; > - const struct shmob_drm_backlight_data *bdata = &sdev->pdata->backlight; > - int brightness = backlight_get_brightness(bdev); > - > - return bdata->set_brightness(brightness); > -} > - > -static int shmob_drm_backlight_get_brightness(struct backlight_device *bdev) > -{ > - struct shmob_drm_connector *scon = bl_get_data(bdev); > - struct shmob_drm_device *sdev = scon->connector.dev->dev_private; > - const struct shmob_drm_backlight_data *bdata = &sdev->pdata->backlight; > - > - return bdata->get_brightness(); > -} > - > -static const struct backlight_ops shmob_drm_backlight_ops = { > - .options= BL_CORE_SUSPENDRESUME, > - .update_status = shmob_drm_backlight_update, > - .get_brightness = shmob_drm_backlight_get_brightness, > -}; > - > -void shmob_drm_backlight_dpms(struct shmob_drm_connector *scon, int mode) > -{ > - if (scon->backlight == NULL) > - return; > - > - scon->backlight->props.power = mode == DRM_MODE_DPMS_ON > - ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN; > - backlight_update_status(scon->backlight); > -} > - > -int shmob_drm_backlight_init(struct shmob_drm_connector *scon) > -{ > - struct shmob_drm_device *sdev = scon->connector.dev->dev_private; > - const struct shmob_drm_backlight_data *bdata = &sdev->pdata->backlight; > - struct drm_connector *connector = &scon->connector; > - struct drm_device *dev = connector->dev; > - struct backlight_device *backlight; > - > - if (!bdata->max_brightness) > - return 0; > - > - backlight = backlight_device_register(bdata->name, dev->dev, scon, > - &shmob_drm_backlight_ops, NULL); > - if (IS_ERR(backlight)) { > - dev_err(dev->dev, "unable to register backlight device: %ld\n", > - PTR_ERR(backlight)); > - return PTR_ERR(backlight); > - } > - > - backlight->props.max_brightness = bdata->max_brightness; > - backlight->props.brightness = bdata->max_brightness; > - backlight->props.power = FB_BLANK_POWERDOWN; > - backlight_update_status(backlight); > - > - scon->backlight = backlight; > - return 0; > -} > - > -void shmob_drm_backlight_exit(struct shmob_drm_connector *s
[PATCH] drm/tests: Fix swapped test parameter names
The "YVU420 DRM_MODE_FB_MODIFIERS set without modifier" test hadn't DRM_MODE_FB_MODIFIERS set, so that it was in fact testing another case, while the "YVU420 Normal sizes" test in turn was with DRM_MODE_FB_MODIFIERS set and without modifiers, what should be the case tested by the former, which also in turn fit in what "YVU320 Normal sizes" should be, meaning that they were swapped. Signed-off-by: Carlos Eduardo Gallo Filho --- drivers/gpu/drm/tests/drm_framebuffer_test.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/tests/drm_framebuffer_test.c b/drivers/gpu/drm/tests/drm_framebuffer_test.c index df235b7fdaa5..f759d9f3b76e 100644 --- a/drivers/gpu/drm/tests/drm_framebuffer_test.c +++ b/drivers/gpu/drm/tests/drm_framebuffer_test.c @@ -178,13 +178,13 @@ static const struct drm_framebuffer_test drm_framebuffer_create_cases[] = { .handles = { 1, 1, 1 }, .pitches = { 600, 600, 600 }, } }, -{ .buffer_created = 1, .name = "YVU420 Normal sizes", +{ .buffer_created = 1, .name = "YVU420 DRM_MODE_FB_MODIFIERS set without modifier", .cmd = { .width = 600, .height = 600, .pixel_format = DRM_FORMAT_YVU420, .handles = { 1, 1, 1 }, .flags = DRM_MODE_FB_MODIFIERS, .pitches = { 600, 300, 300 }, } }, -{ .buffer_created = 1, .name = "YVU420 DRM_MODE_FB_MODIFIERS set without modifier", +{ .buffer_created = 1, .name = "YVU420 Normal sizes", .cmd = { .width = 600, .height = 600, .pixel_format = DRM_FORMAT_YVU420, .handles = { 1, 1, 1 }, .pitches = { 600, 300, 300 }, } -- 2.39.3
Re: [PATCH drm-next v5 03/14] drm: manager to keep track of GPUs VA mappings
Am 23.06.23 um 15:55 schrieb Danilo Krummrich: [SNIP] How do you efficiently find only the mappings of a BO in one VM? Actually, I think this case should even be more efficient than with a BO having a list of GPUVAs (or mappings): *than with a BO having a list of VMs: Having a list of GPUVAs per GEM, each GPUVA has a pointer to it's VM. Hence, you'd only need to iterate the list of mappings for a given BO and check the mappings VM pointer. Yeah, and that is extremely time consuming if you have tons of mappings in different VMs. Having a list of VMs per BO, you'd have to iterate the whole VM to find the mappings having a pointer to the given BO, right? No, you don't seem to understand what I'm suggesting. Currently you have a list of mappings attached to the BO, so when you need to make sure that a specific BO is up to date in a specific VM you either need to iterate over the VM or the BO. Neither of that is a good idea. What you need is a representation of the data used for each BO+VM combination. In other words another indirection which allows you to handle all the mappings of a BO inside a VM at once. Ok, after having a quick look at amdgpu, I can see what you mean. The missing piece for me was that the BO+VM abstraction itself keeps a list of mappings for this specific BO and VM. Just to make it obvious for other people following the discussion, let me quickly sketch up how this approach would look like for the GPUVA manager: 1. We would need a new structure to represent the BO+VM combination, something like: struct drm_gpuva_mgr_gem { struct drm_gpuva_manager *mgr; struct drm_gem_object *obj; struct list_head gpuva_list; }; with a less horrible name, hopefully. 2. Create an instance of struct drm_gpuva_mgr_gem once a GEM becomes associated with a GPUVA manager (VM) and attach it to the GEMs, as by now, "gpuva" list. In amdgpu, for example, this seems to be the case once a GEM object is opened, since there is one VM per file_priv. However, for other drivers this could be different, hence drivers would need to take care about this. Yes, exactly that. 3. Attach GPUVAs to the new gpuva_list of the corresponding instance of struct drm_gpuva_mgr_gem. 4. Drivers would need to clean up the instance of struct drm_gpuva_mgr_gem, once the GEM is not associated with the GPUVA manager anymore. As pointed out by Christian, this would optimize the "get all mappings backed by a specific BO from a given VM" use case. The question for me is, do other drivers than amdgpu commonly need this? I have no idea. And what does amdgpu need this for? Maybe amdgpu does something we're not doing (yet)? Basically when we do a CS we need to make sure that the VM used by this CS is up to date. For this we walk over the relocation list of BOs and check the status of each BO+VM structure. This is done because we don't want to update all VMs at the same time, but rather just those who needs the update. Christian - I know you didn't ask for "do it the way amdgpu does", instead you voted for keeping it entirely driver specific. But I think everyone is pretty close and I'm still optimistic that we could just generalize this. Well, you should *not* necessarily do it like amdgpu does! Basically the implementation in amdgpu was driven by requirements, e.g. we need that, let's do it like this. It's perfectly possible that other requirements (e.g. focus on Vulkan) lead to a completely different implementation. It's just that ideally I would like to have an implementation where I can apply at least the basics to amdgpu as well. Regards, Christian. - Danilo I'd think that a single VM potentially has more mapping entries than a single BO was mapped in multiple VMs. Another case to consider is the case I originally had in mind choosing this relationship: finding all mappings for a given BO, which I guess all drivers need to do in order to invalidate mappings on BO eviction. Having a list of VMs per BO, wouldn't you need to iterate all of the VMs entirely? No, see how amdgpu works. Regards, Christian.
Re: [PATCH 06/39] drm: renesas: shmobile: Add support for Runtime PM
On Fri, Jun 23, 2023 at 05:22:45PM +0200, Geert Uytterhoeven wrote: > On Fri, Jun 23, 2023 at 5:11 PM Laurent Pinchart wrote: > > On Fri, Jun 23, 2023 at 06:07:44PM +0300, Laurent Pinchart wrote: > > > On Thu, Jun 22, 2023 at 11:21:18AM +0200, Geert Uytterhoeven wrote: > > > > The SH-Mobile LCD Controller is part of a PM Domain on all relevant SoCs > > > > (clock domain on all, power domain on some). Hence it may not be > > > > sufficient to manage the LCDC module clock explicitly (e.g. if the > > > > selected clock source differs from SHMOB_DRM_CLK_BUS). > > > > > > > > Fix this by using Runtime PM instead. > > > > > > > > Signed-off-by: Geert Uytterhoeven > > > > --- > > > > drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 11 ++- > > > > drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 5 + > > > > 2 files changed, 15 insertions(+), 1 deletion(-) > > > > > > > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > > > > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > > > > index fbfd906844da490c..84dbf35025d7be63 100644 > > > > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > > > > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > > > > @@ -9,6 +9,7 @@ > > > > > > > > #include > > > > #include > > > > +#include > > > > > > > > #include > > > > #include > > > > @@ -170,10 +171,16 @@ static void shmob_drm_crtc_start(struct > > > > shmob_drm_crtc *scrtc) > > > > if (WARN_ON(format == NULL)) > > > > return; > > > > > > > > + ret = pm_runtime_resume_and_get(sdev->dev); > > > > + if (ret) > > > > + return; > > > > + > > > > /* Enable clocks before accessing the hardware. */ > > > > ret = shmob_drm_clk_on(sdev); > > > > > > This would be best located in the runtime PM resume handler. Same for > > > disabling clocks in the runtime PM suspend handler. > > > > The driver should then depend on CONFIG_PM. There's no indirect > > dependency through CONFIG_DRM as far as I can tell, but there's one > > through ARCH_SHMOBILE. This then got me puzzled, as ARCH_SHMOBILE is > > defined in arch/sh/Kconfig, and this driver depends on ARM. Am I missing > > something ? > > Vommit 4bd65789ba847f39 ("drm: shmobile: Make DRM_SHMOBILE visible on > Renesas SoC platforms") in drm-next: > > - depends on DRM && ARM > - depends on ARCH_SHMOBILE || COMPILE_TEST > + depends on DRM > + depends on ARCH_RENESAS || ARCH_SHMOBILE || COMPILE_TEST That's better indeed :-) A dependency on CONFIG_PM is still needed as ARCH_RENESAS doesn't depend on it. -- Regards, Laurent Pinchart
Re: [PATCH 01/39] dt-bindings: display: Add Renesas SH-Mobile LCDC bindings
On Fri, Jun 23, 2023 at 05:19:45PM +0200, Geert Uytterhoeven wrote: > On Fri, Jun 23, 2023 at 4:43 PM Laurent Pinchart wrote: > > On Thu, Jun 22, 2023 at 11:21:13AM +0200, Geert Uytterhoeven wrote: > > > Add device tree bindings for the LCD Controller (LCDC) found in Renesas > > > SuperH SH-Mobile and ARM SH/R-Mobile SOCs. > > > > > > Based on a plain text prototype by Laurent Pinchart. > > > > > > Signed-off-by: Geert Uytterhoeven > > > > --- /dev/null > > > +++ b/Documentation/devicetree/bindings/display/renesas,shmobile-lcdc.yaml > > > @@ -0,0 +1,108 @@ > > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > > > +%YAML 1.2 > > > +--- > > > +$id: http://devicetree.org/schemas/display/renesas,shmobile-lcdc.yaml# > > > +$schema: http://devicetree.org/meta-schemas/core.yaml# > > > + > > > +title: Renesas SH-Mobile LCD Controller (LCDC) > > > + > > > +maintainers: > > > + - Laurent Pinchart > > > > I'd be happy if you co-maintained this with me :-) Or even took > > ownership completely. > > OK. Thinking about it ;-) > > > > + > > > +properties: > > > + compatible: > > > +enum: > > > + - renesas,r8a7740-lcdc # R-Mobile A1 > > > + - renesas,sh73a0-lcdc # SH-Mobile AG5 > > > + > > > + reg: > > > +maxItems: 1 > > > + > > > + interrupts: > > > +maxItems: 1 > > > + > > > + clocks: > > > +minItems: 1 > > > +maxItems: 5 > > > +description: > > > + Only the functional clock is mandatory. > > > + Some of the optional clocks are model-dependent (e.g. "video" > > > (a.k.a. > > > + "vou" or "dv_clk") is available on R-Mobile A1 only). > > > + > > > + clock-names: > > > +minItems: 1 > > > +maxItems: 5 > > > +items: > > > + enum: [ fck, media, lclk, hdmi, video ] > > > > Switching to per-item descriptions would allow documenting which clock > > applies to which SoC. > > > > Are enum items unique by default ? > > Given how about all clocks but fck are optional, it's a bit hard > to handle this in a perfect way. > Note that "pattern: '^dclkin\.[0123]$'" in renesas,du.yaml has the same issue. > > > This would allow a combination of clocks that doesn't include the fck > > clock, that's not right. > > Right. But when fixing the first to "fck", you have to duplicate all others. > So it should become something like: > > - const: fck > - enum: [ media, lclk, hdmi, video ] > - enum: [ media, lclk, hdmi, video ] > - enum: [ media, lclk, hdmi, video ] > - enum: [ media, lclk, hdmi, video ] It's not great. Any input from the DT maintainers ? > > > + > > > + power-domains: > > > +maxItems: 1 > > > + > > > + ports: > > > +$ref: /schemas/graph.yaml#/properties/ports > > > +description: | > > > + The connections to the output video ports are modeled using the OF > > > graph > > > + bindings specified in Documentation/devicetree/bindings/graph.txt. > > > > it's available in YAML form now. I'd just drop the "specified in ...". > > OK. > > > > + The number of ports and their assignment are model-dependent. > > > + Each port shall have a single endpoint. > > > + > > > +properties: > > > + port@0: > > > +$ref: /schemas/graph.yaml#/properties/port > > > +description: LCD port (R-Mobile A1 and SH-Mobile AG5) > > > +unevaluatedProperties: false > > > + > > > + port@1: > > > +$ref: /schemas/graph.yaml#/properties/port > > > +description: HDMI port (R-Mobile A1 LCDC1 and SH-Mobile AG5) > > > +unevaluatedProperties: false > > > + > > > + port@2: > > > +$ref: /schemas/graph.yaml#/properties/port > > > +description: MIPI-DSI port (SH-Mobile AG5) > > > +unevaluatedProperties: false > > > > Let's condition the ports on the compatible value to enable automatic > > validation. > > > > > + > > > +required: > > > + - port@0 > > > > Based on the above, port@1 is required too as it's present on all > > supported SoCs. Let's condition this on the compatible value too. > > It does not depend solely on the SoC, but also on the LCDC instance. > port@1 is not available on R-Mobile A1 LCDC0, only on LCDC1. Ah, my bad. It can't be mandatory indeed. I'd still prefer conditioning ports to the compatible string for proper validation. -- Regards, Laurent Pinchart
Re: [PATCH 10/39] drm: renesas: shmobile: Improve shmob_drm_format_info table
Hi Geert, Thank you for the patch. On Thu, Jun 22, 2023 at 11:21:22AM +0200, Geert Uytterhoeven wrote: > Improve the table containing hardware information related to the > supported plane formats: > 1. Move (part of) the overlay format register settings from multiple > switch() statements spread across the code into the table, like is > already done for the primary plane register settings, > 2. Remove the .yuv field, as that information can easily be extracted > from the register settings using a new helper macro, > 3. Shrink and move the .bpp field to reduce table size. > > Signed-off-by: Geert Uytterhoeven > --- > .../gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 29 ++ > .../gpu/drm/renesas/shmobile/shmob_drm_kms.c | 42 ++ > .../gpu/drm/renesas/shmobile/shmob_drm_kms.h | 9 ++- > .../drm/renesas/shmobile/shmob_drm_plane.c| 56 ++- > 4 files changed, 47 insertions(+), 89 deletions(-) I like this :-) Reviewed-by: Laurent Pinchart > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > index cd492806105e5b5d..9bfdfa7c6e2b1001 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > @@ -221,31 +221,12 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc > *scrtc) > lcdc_write(sdev, LDDFR, format->lddfr | LDDFR_CF1); > lcdc_write(sdev, LDMLSR, scrtc->line_size); > lcdc_write(sdev, LDSA1R, scrtc->dma[0]); > - if (format->yuv) > + if (shmob_drm_format_is_yuv(format)) > lcdc_write(sdev, LDSA2R, scrtc->dma[1]); > lcdc_write(sdev, LDSM1R, 0); > > /* Word and long word swap. */ > - switch (format->fourcc) { > - case DRM_FORMAT_RGB565: > - case DRM_FORMAT_NV21: > - case DRM_FORMAT_NV61: > - case DRM_FORMAT_NV42: > - value = LDDDSR_LS | LDDDSR_WS; > - break; > - case DRM_FORMAT_RGB888: > - case DRM_FORMAT_NV12: > - case DRM_FORMAT_NV16: > - case DRM_FORMAT_NV24: > - value = LDDDSR_LS | LDDDSR_WS | LDDDSR_BS; > - break; > - case DRM_FORMAT_ARGB: > - case DRM_FORMAT_XRGB: > - default: > - value = LDDDSR_LS; > - break; > - } > - lcdc_write(sdev, LDDDSR, value); > + lcdc_write(sdev, LDDDSR, format->ldddsr); > > /* Setup planes. */ > drm_for_each_legacy_plane(plane, dev) { > @@ -304,12 +285,12 @@ static void shmob_drm_crtc_compute_base(struct > shmob_drm_crtc *scrtc, > struct drm_gem_dma_object *gem; > unsigned int bpp; > > - bpp = scrtc->format->yuv ? 8 : scrtc->format->bpp; > + bpp = shmob_drm_format_is_yuv(scrtc->format) ? 8 : scrtc->format->bpp; > gem = drm_fb_dma_get_gem_obj(fb, 0); > scrtc->dma[0] = gem->dma_addr + fb->offsets[0] > + y * fb->pitches[0] + x * bpp / 8; > > - if (scrtc->format->yuv) { > + if (shmob_drm_format_is_yuv(scrtc->format)) { > bpp = scrtc->format->bpp - 8; > gem = drm_fb_dma_get_gem_obj(fb, 1); > scrtc->dma[1] = gem->dma_addr + fb->offsets[1] > @@ -326,7 +307,7 @@ static void shmob_drm_crtc_update_base(struct > shmob_drm_crtc *scrtc) > shmob_drm_crtc_compute_base(scrtc, crtc->x, crtc->y); > > lcdc_write_mirror(sdev, LDSA1R, scrtc->dma[0]); > - if (scrtc->format->yuv) > + if (shmob_drm_format_is_yuv(scrtc->format)) > lcdc_write_mirror(sdev, LDSA2R, scrtc->dma[1]); > > lcdc_write(sdev, LDRCNTR, lcdc_read(sdev, LDRCNTR) ^ LDRCNTR_MRS); > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c > index 99381cc0abf3ae1f..8fd360149743f8e2 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_kms.c > @@ -27,53 +27,73 @@ static const struct shmob_drm_format_info > shmob_drm_format_infos[] = { > { > .fourcc = DRM_FORMAT_RGB565, > .bpp = 16, > - .yuv = false, > .lddfr = LDDFR_PKF_RGB16, > + .ldddsr = LDDDSR_LS | LDDDSR_WS, > + .ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_SWPW | > + LDBBSIFR_RY | LDBBSIFR_RPKF_RGB16, > }, { > .fourcc = DRM_FORMAT_RGB888, > .bpp = 24, > - .yuv = false, > .lddfr = LDDFR_PKF_RGB24, > + .ldddsr = LDDDSR_LS | LDDDSR_WS | LDDDSR_BS, > + .ldbbsifr = LDBBSIFR_AL_1 | LDBBSIFR_SWPL | LDBBSIFR_SWPW | > + LDBBSIFR_SWPB | LDBBSIFR_RY | LDBBSIFR_RPKF_RGB24, > }, { > .fourcc = DRM_FORMAT_ARGB, > .bpp = 32, > - .yuv = false, > .lddfr = LDDFR_PKF_ARGB32, > + .ldddsr = LDDDSR_LS, > + .ldbbsifr = LDBBSI
Re: [PATCH drm-next v5 03/14] drm: manager to keep track of GPUs VA mappings
On 6/23/23 09:16, Christian König wrote: Am 22.06.23 um 17:07 schrieb Danilo Krummrich: On 6/22/23 17:04, Danilo Krummrich wrote: On 6/22/23 16:42, Christian König wrote: Am 22.06.23 um 16:22 schrieb Danilo Krummrich: On 6/22/23 15:54, Christian König wrote: Am 20.06.23 um 14:23 schrieb Danilo Krummrich: Hi Christian, On 6/20/23 08:45, Christian König wrote: Hi Danilo, sorry for the delayed reply. I've trying to dig myself out of a hole at the moment. No worries, thank you for taking a look anyway! Am 20.06.23 um 02:42 schrieb Danilo Krummrich: [SNIP] diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h index bbc721870c13..5ec8148a30ee 100644 --- a/include/drm/drm_gem.h +++ b/include/drm/drm_gem.h @@ -36,6 +36,8 @@ #include #include +#include +#include #include @@ -379,6 +381,18 @@ struct drm_gem_object { */ struct dma_resv _resv; + /** + * @gpuva: + * + * Provides the list of GPU VAs attached to this GEM object. + * + * Drivers should lock list accesses with the GEMs &dma_resv lock + * (&drm_gem_object.resv). + */ + struct { + struct list_head list; + } gpuva; + /** * @funcs: * I'm pretty sure that it's not a good idea to attach this directly to the GEM object. Why do you think so? IMHO having a common way to connect mappings to their backing buffers is a good thing, since every driver needs this connection anyway. E.g. when a BO gets evicted, drivers can just iterate the list of mappings and, as the circumstances require, invalidate the corresponding mappings or to unmap all existing mappings of a given buffer. What would be the advantage to let every driver implement a driver specific way of keeping this connection? Flexibility. For example on amdgpu the mappings of a BO are groups by VM address spaces. E.g. the BO points to multiple bo_vm structures which in turn have lists of their mappings. Isn't this (almost) the same relationship I introduce with the GPUVA manager? If you would switch over to the GPUVA manager right now, it would be that every GEM has a list of it's mappings (the gpuva list). The mapping is represented by struct drm_gpuva (of course embedded in driver specific structure(s)) which has a pointer to the VM address space it is part of, namely the GPUVA manager instance. And the GPUVA manager keeps a maple tree of it's mappings as well. If you still would like to *directly* (indirectly you already have that relationship) keep a list of GPUVA managers (VM address spaces) per GEM, you could still do that in a driver specific way. Do I miss something? How do you efficiently find only the mappings of a BO in one VM? Actually, I think this case should even be more efficient than with a BO having a list of GPUVAs (or mappings): *than with a BO having a list of VMs: Having a list of GPUVAs per GEM, each GPUVA has a pointer to it's VM. Hence, you'd only need to iterate the list of mappings for a given BO and check the mappings VM pointer. Yeah, and that is extremely time consuming if you have tons of mappings in different VMs. Having a list of VMs per BO, you'd have to iterate the whole VM to find the mappings having a pointer to the given BO, right? No, you don't seem to understand what I'm suggesting. Currently you have a list of mappings attached to the BO, so when you need to make sure that a specific BO is up to date in a specific VM you either need to iterate over the VM or the BO. Neither of that is a good idea. What you need is a representation of the data used for each BO+VM combination. In other words another indirection which allows you to handle all the mappings of a BO inside a VM at once. Ok, after having a quick look at amdgpu, I can see what you mean. The missing piece for me was that the BO+VM abstraction itself keeps a list of mappings for this specific BO and VM. Just to make it obvious for other people following the discussion, let me quickly sketch up how this approach would look like for the GPUVA manager: 1. We would need a new structure to represent the BO+VM combination, something like: struct drm_gpuva_mgr_gem { struct drm_gpuva_manager *mgr; struct drm_gem_object *obj; struct list_head gpuva_list; }; with a less horrible name, hopefully. 2. Create an instance of struct drm_gpuva_mgr_gem once a GEM becomes associated with a GPUVA manager (VM) and attach it to the GEMs, as by now, "gpuva" list. In amdgpu, for example, this seems to be the case once a GEM object is opened, since there is one VM per file_priv. However, for other drivers this could be different, hence drivers would need to take care about this. 3. Attach GPUVAs to the new gpuva_list of the corresponding instance of struct drm_gpuva_mgr_gem. 4. Drivers would need to clean up the instance of struct drm_gpuva_mgr_gem, once the GEM is not ass
Re: [PATCH 06/39] drm: renesas: shmobile: Add support for Runtime PM
Hi Laurent, On Fri, Jun 23, 2023 at 5:11 PM Laurent Pinchart wrote: > On Fri, Jun 23, 2023 at 06:07:44PM +0300, Laurent Pinchart wrote: > > On Thu, Jun 22, 2023 at 11:21:18AM +0200, Geert Uytterhoeven wrote: > > > The SH-Mobile LCD Controller is part of a PM Domain on all relevant SoCs > > > (clock domain on all, power domain on some). Hence it may not be > > > sufficient to manage the LCDC module clock explicitly (e.g. if the > > > selected clock source differs from SHMOB_DRM_CLK_BUS). > > > > > > Fix this by using Runtime PM instead. > > > > > > Signed-off-by: Geert Uytterhoeven > > > --- > > > drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 11 ++- > > > drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 5 + > > > 2 files changed, 15 insertions(+), 1 deletion(-) > > > > > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > > > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > > > index fbfd906844da490c..84dbf35025d7be63 100644 > > > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > > > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > > > @@ -9,6 +9,7 @@ > > > > > > #include > > > #include > > > +#include > > > > > > #include > > > #include > > > @@ -170,10 +171,16 @@ static void shmob_drm_crtc_start(struct > > > shmob_drm_crtc *scrtc) > > > if (WARN_ON(format == NULL)) > > > return; > > > > > > + ret = pm_runtime_resume_and_get(sdev->dev); > > > + if (ret) > > > + return; > > > + > > > /* Enable clocks before accessing the hardware. */ > > > ret = shmob_drm_clk_on(sdev); > > > > This would be best located in the runtime PM resume handler. Same for > > disabling clocks in the runtime PM suspend handler. > > The driver should then depend on CONFIG_PM. There's no indirect > dependency through CONFIG_DRM as far as I can tell, but there's one > through ARCH_SHMOBILE. This then got me puzzled, as ARCH_SHMOBILE is > defined in arch/sh/Kconfig, and this driver depends on ARM. Am I missing > something ? Vommit 4bd65789ba847f39 ("drm: shmobile: Make DRM_SHMOBILE visible on Renesas SoC platforms") in drm-next: - depends on DRM && ARM - depends on ARCH_SHMOBILE || COMPILE_TEST + depends on DRM + depends on ARCH_RENESAS || ARCH_SHMOBILE || COMPILE_TEST Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Re: [PATCH 01/39] dt-bindings: display: Add Renesas SH-Mobile LCDC bindings
Hi Laurent, On Fri, Jun 23, 2023 at 4:43 PM Laurent Pinchart wrote: > On Thu, Jun 22, 2023 at 11:21:13AM +0200, Geert Uytterhoeven wrote: > > Add device tree bindings for the LCD Controller (LCDC) found in Renesas > > SuperH SH-Mobile and ARM SH/R-Mobile SOCs. > > > > Based on a plain text prototype by Laurent Pinchart. > > > > Signed-off-by: Geert Uytterhoeven > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/display/renesas,shmobile-lcdc.yaml > > @@ -0,0 +1,108 @@ > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > > +%YAML 1.2 > > +--- > > +$id: http://devicetree.org/schemas/display/renesas,shmobile-lcdc.yaml# > > +$schema: http://devicetree.org/meta-schemas/core.yaml# > > + > > +title: Renesas SH-Mobile LCD Controller (LCDC) > > + > > +maintainers: > > + - Laurent Pinchart > > I'd be happy if you co-maintained this with me :-) Or even took > ownership completely. OK. Thinking about it ;-) > > + > > +properties: > > + compatible: > > +enum: > > + - renesas,r8a7740-lcdc # R-Mobile A1 > > + - renesas,sh73a0-lcdc # SH-Mobile AG5 > > + > > + reg: > > +maxItems: 1 > > + > > + interrupts: > > +maxItems: 1 > > + > > + clocks: > > +minItems: 1 > > +maxItems: 5 > > +description: > > + Only the functional clock is mandatory. > > + Some of the optional clocks are model-dependent (e.g. "video" (a.k.a. > > + "vou" or "dv_clk") is available on R-Mobile A1 only). > > + > > + clock-names: > > +minItems: 1 > > +maxItems: 5 > > +items: > > + enum: [ fck, media, lclk, hdmi, video ] > > Switching to per-item descriptions would allow documenting which clock > applies to which SoC. > > Are enum items unique by default ? Given how about all clocks but fck are optional, it's a bit hard to handle this in a perfect way. Note that "pattern: '^dclkin\.[0123]$'" in renesas,du.yaml has the same issue. > This would allow a combination of clocks that doesn't include the fck > clock, that's not right. Right. But when fixing the first to "fck", you have to duplicate all others. So it should become something like: - const: fck - enum: [ media, lclk, hdmi, video ] - enum: [ media, lclk, hdmi, video ] - enum: [ media, lclk, hdmi, video ] - enum: [ media, lclk, hdmi, video ] > > > + > > + power-domains: > > +maxItems: 1 > > + > > + ports: > > +$ref: /schemas/graph.yaml#/properties/ports > > +description: | > > + The connections to the output video ports are modeled using the OF > > graph > > + bindings specified in Documentation/devicetree/bindings/graph.txt. > > it's available in YAML form now. I'd just drop the "specified in ...". OK. > > + The number of ports and their assignment are model-dependent. > > + Each port shall have a single endpoint. > > + > > +properties: > > + port@0: > > +$ref: /schemas/graph.yaml#/properties/port > > +description: LCD port (R-Mobile A1 and SH-Mobile AG5) > > +unevaluatedProperties: false > > + > > + port@1: > > +$ref: /schemas/graph.yaml#/properties/port > > +description: HDMI port (R-Mobile A1 LCDC1 and SH-Mobile AG5) > > +unevaluatedProperties: false > > + > > + port@2: > > +$ref: /schemas/graph.yaml#/properties/port > > +description: MIPI-DSI port (SH-Mobile AG5) > > +unevaluatedProperties: false > > Let's condition the ports on the compatible value to enable automatic > validation. > > > + > > +required: > > + - port@0 > > Based on the above, port@1 is required too as it's present on all > supported SoCs. Let's condition this on the compatible value too. It does not depend solely on the SoC, but also on the LCDC instance. port@1 is not available on R-Mobile A1 LCDC0, only on LCDC1. Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Re: [PATCH v2] drm/bridge: ps8640: Drop the ability of ps8640 to fetch the EDID
On Fri, 16 Jun 2023 16:55:17 -0700, Douglas Anderson wrote: > In order to read the EDID from an eDP panel, you not only need to > power on the bridge chip itself but also the panel. In the ps8640 > driver, this was made to work by having the bridge chip manually power > the panel on by calling pre_enable() on everything connectorward on > the bridge chain. This worked OK, but... > > ...when trying to do the same thing on ti-sn65dsi86, feedback was that > this wasn't a great idea. As a result, we designed the "DP AUX" > bus. With the design we ended up with the panel driver itself was in > charge of reading the EDID. The panel driver could power itself on and > the bridge chip was able to power itself on because it implemented the > DP AUX bus. > > [...] Applied, thanks! [1/1] drm/bridge: ps8640: Drop the ability of ps8640 to fetch the EDID https://cgit.freedesktop.org/drm/drm-misc/commit/?id=26195af57798 Rob
Re: [PATCH 09/39] drm: renesas: shmobile: Add missing YCbCr formats
On Thu, Jun 22, 2023 at 11:21:21AM +0200, Geert Uytterhoeven wrote: > The primary plane supports various YCbCr formats, and the CRTC code > already knows how to handle them. Enable support for the missing > formats by adding them to the table of supported modes. > > Signed-off-by: Geert Uytterhoeven Reviewed-by: Laurent Pinchart > --- > drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 6 ++ > 1 file changed, 6 insertions(+) > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > index 84dbf35025d7be63..cd492806105e5b5d 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > @@ -493,6 +493,12 @@ static const uint32_t modeset_formats[] = { > DRM_FORMAT_RGB888, > DRM_FORMAT_ARGB, > DRM_FORMAT_XRGB, > + DRM_FORMAT_NV12, > + DRM_FORMAT_NV21, > + DRM_FORMAT_NV16, > + DRM_FORMAT_NV61, > + DRM_FORMAT_NV24, > + DRM_FORMAT_NV42, > }; > > static const struct drm_plane_funcs primary_plane_funcs = { -- Regards, Laurent Pinchart
Re: [PATCH 06/39] drm: renesas: shmobile: Add support for Runtime PM
On Fri, Jun 23, 2023 at 06:07:44PM +0300, Laurent Pinchart wrote: > Hi Geert, > > Thank you for the patch. > > On Thu, Jun 22, 2023 at 11:21:18AM +0200, Geert Uytterhoeven wrote: > > The SH-Mobile LCD Controller is part of a PM Domain on all relevant SoCs > > (clock domain on all, power domain on some). Hence it may not be > > sufficient to manage the LCDC module clock explicitly (e.g. if the > > selected clock source differs from SHMOB_DRM_CLK_BUS). > > > > Fix this by using Runtime PM instead. > > > > Signed-off-by: Geert Uytterhoeven > > --- > > drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 11 ++- > > drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 5 + > > 2 files changed, 15 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > > index fbfd906844da490c..84dbf35025d7be63 100644 > > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > > @@ -9,6 +9,7 @@ > > > > #include > > #include > > +#include > > > > #include > > #include > > @@ -170,10 +171,16 @@ static void shmob_drm_crtc_start(struct > > shmob_drm_crtc *scrtc) > > if (WARN_ON(format == NULL)) > > return; > > > > + ret = pm_runtime_resume_and_get(sdev->dev); > > + if (ret) > > + return; > > + > > /* Enable clocks before accessing the hardware. */ > > ret = shmob_drm_clk_on(sdev); > > This would be best located in the runtime PM resume handler. Same for > disabling clocks in the runtime PM suspend handler. The driver should then depend on CONFIG_PM. There's no indirect dependency through CONFIG_DRM as far as I can tell, but there's one through ARCH_SHMOBILE. This then got me puzzled, as ARCH_SHMOBILE is defined in arch/sh/Kconfig, and this driver depends on ARM. Am I missing something ? > > - if (ret < 0) > > + if (ret < 0) { > > + pm_runtime_put(sdev->dev); > > return; > > + } > > > > /* Reset and enable the LCDC. */ > > lcdc_write(sdev, LDCNT2R, lcdc_read(sdev, LDCNT2R) | LDCNT2R_BR); > > @@ -271,6 +278,8 @@ static void shmob_drm_crtc_stop(struct shmob_drm_crtc > > *scrtc) > > /* Stop clocks. */ > > shmob_drm_clk_off(sdev); > > > > + pm_runtime_put(sdev->dev); > > + > > scrtc->started = false; > > } > > > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > > index 30493ce874192e3e..4f01caa119637032 100644 > > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > > @@ -13,6 +13,7 @@ > > #include > > #include > > #include > > +#include > > #include > > > > #include > > @@ -216,6 +217,10 @@ static int shmob_drm_probe(struct platform_device > > *pdev) > > if (IS_ERR(sdev->mmio)) > > return PTR_ERR(sdev->mmio); > > > > + ret = devm_pm_runtime_enable(&pdev->dev); > > + if (ret) > > + return ret; > > + > > I would move this after shmob_drm_setup_clocks(), to ensure that the > runtime PM suspend and resume handlers will have access to clocks. > > > ret = shmob_drm_setup_clocks(sdev, pdata->clk_source); > > if (ret < 0) > > return ret; -- Regards, Laurent Pinchart
Re: [PATCH 06/39] drm: renesas: shmobile: Add support for Runtime PM
Hi Geert, Thank you for the patch. On Thu, Jun 22, 2023 at 11:21:18AM +0200, Geert Uytterhoeven wrote: > The SH-Mobile LCD Controller is part of a PM Domain on all relevant SoCs > (clock domain on all, power domain on some). Hence it may not be > sufficient to manage the LCDC module clock explicitly (e.g. if the > selected clock source differs from SHMOB_DRM_CLK_BUS). > > Fix this by using Runtime PM instead. > > Signed-off-by: Geert Uytterhoeven > --- > drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 11 ++- > drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 5 + > 2 files changed, 15 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > index fbfd906844da490c..84dbf35025d7be63 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > @@ -9,6 +9,7 @@ > > #include > #include > +#include > > #include > #include > @@ -170,10 +171,16 @@ static void shmob_drm_crtc_start(struct shmob_drm_crtc > *scrtc) > if (WARN_ON(format == NULL)) > return; > > + ret = pm_runtime_resume_and_get(sdev->dev); > + if (ret) > + return; > + > /* Enable clocks before accessing the hardware. */ > ret = shmob_drm_clk_on(sdev); This would be best located in the runtime PM resume handler. Same for disabling clocks in the runtime PM suspend handler. > - if (ret < 0) > + if (ret < 0) { > + pm_runtime_put(sdev->dev); > return; > + } > > /* Reset and enable the LCDC. */ > lcdc_write(sdev, LDCNT2R, lcdc_read(sdev, LDCNT2R) | LDCNT2R_BR); > @@ -271,6 +278,8 @@ static void shmob_drm_crtc_stop(struct shmob_drm_crtc > *scrtc) > /* Stop clocks. */ > shmob_drm_clk_off(sdev); > > + pm_runtime_put(sdev->dev); > + > scrtc->started = false; > } > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > index 30493ce874192e3e..4f01caa119637032 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > @@ -13,6 +13,7 @@ > #include > #include > #include > +#include > #include > > #include > @@ -216,6 +217,10 @@ static int shmob_drm_probe(struct platform_device *pdev) > if (IS_ERR(sdev->mmio)) > return PTR_ERR(sdev->mmio); > > + ret = devm_pm_runtime_enable(&pdev->dev); > + if (ret) > + return ret; > + I would move this after shmob_drm_setup_clocks(), to ensure that the runtime PM suspend and resume handlers will have access to clocks. > ret = shmob_drm_setup_clocks(sdev, pdata->clk_source); > if (ret < 0) > return ret; -- Regards, Laurent Pinchart
Re: [PATCH 08/39] drm: renesas: shmobile: Use %p4cc to print fourcc code
Hi Geert, Thank you for the patch. On Thu, Jun 22, 2023 at 11:21:20AM +0200, Geert Uytterhoeven wrote: > Replace the last printing of an hexadecimal fourcc format code by a > pretty-printed format name, using the "%p4cc" format specifier. > > Signed-off-by: Geert Uytterhoeven Reviewed-by: Laurent Pinchart > --- > drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c > index 7e49e2873da1bb6f..36fedb2b74c8b7a2 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c > @@ -184,8 +184,8 @@ shmob_drm_plane_update(struct drm_plane *plane, struct > drm_crtc *crtc, > > format = shmob_drm_format_info(fb->format->format); > if (format == NULL) { > - dev_dbg(sdev->dev, "update_plane: unsupported format %08x\n", > - fb->format->format); > + dev_dbg(sdev->dev, "update_plane: unsupported format %p4cc\n", > + &fb->format->format); > return -EINVAL; > } > -- Regards, Laurent Pinchart
Re: [PATCH 07/39] drm: renesas: shmobile: Restore indentation of shmob_drm_setup_clocks()
Hi Geert, Thank you for the patch. On Thu, Jun 22, 2023 at 11:21:19AM +0200, Geert Uytterhoeven wrote: > Commit 56550d94cbaeaa19 ("Drivers: gpu: remove __dev* attributes.") > forgot to realign the continuation of the parameter section of > shmob_drm_setup_clocks(). > > Signed-off-by: Geert Uytterhoeven Reviewed-by: Laurent Pinchart > --- > drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > index 4f01caa119637032..d272e6273c782178 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c > @@ -67,7 +67,7 @@ static int shmob_drm_init_interface(struct shmob_drm_device > *sdev) > } > > static int shmob_drm_setup_clocks(struct shmob_drm_device *sdev, > - enum shmob_drm_clk_source clksrc) > + enum shmob_drm_clk_source clksrc) > { > struct clk *clk; > char *clkname; -- Regards, Laurent Pinchart
Re: [PATCH 05/39] drm: renesas: shmobile: Correct encoder/connector types
Hi Geert, Thank you for the patch. On Thu, Jun 22, 2023 at 11:21:17AM +0200, Geert Uytterhoeven wrote: > The first encoder output on the SH-Mobile LCD Controller is a DPI > parallel bus. However, at the time of introduction of the driver, no > encoder or connector types were defined yet for the DPI parallel bus, > hence the driver used the ones for LVDS instead. > > Adjust the types accordingly. > > Signed-off-by: Geert Uytterhoeven > --- > drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > index 11dd2bc803e7cb62..fbfd906844da490c 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c > @@ -598,7 +598,7 @@ int shmob_drm_encoder_create(struct shmob_drm_device > *sdev) > encoder->possible_crtcs = 1; > > ret = drm_simple_encoder_init(sdev->ddev, encoder, > - DRM_MODE_ENCODER_LVDS); > + DRM_MODE_ENCODER_DPI); You can use DRM_MODE_ENCODER_NONE, that will simplify the code when adding support for additional outputs. The encoder type was exposed to userspace by mistake, and AFAIU is unused by userspace, so it doesn't need to be specified. Reviewed-by: Laurent Pinchart > if (ret < 0) > return ret; > > @@ -684,7 +684,7 @@ int shmob_drm_connector_create(struct shmob_drm_device > *sdev, > connector->display_info.height_mm = sdev->pdata->panel.height_mm; > > ret = drm_connector_init(sdev->ddev, connector, &connector_funcs, > - DRM_MODE_CONNECTOR_LVDS); > + DRM_MODE_CONNECTOR_DPI); > if (ret < 0) > return ret; > -- Regards, Laurent Pinchart
Re: [PATCH 03/39] drm: renesas: shmobile: Fix overlay plane disable
Hi Geert, Thank you for the patch. On Thu, Jun 22, 2023 at 11:21:15AM +0200, Geert Uytterhoeven wrote: > Merely writing zero to the CHn Source Image Format Register is not > sufficient to disable a plane, as the programmed register value is not > propagated immediately to the current side. This can be seen when using > the -P option of modetest: the extra plane is displayed correctly, but > does not disappear after exit. > > Fix this by doing the full update dance using the Blend Control > Register, like is done when enabling the plane. > > Signed-off-by: Geert Uytterhoeven Reviewed-by: Laurent Pinchart > --- > drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c > index 850986cee848226a..0e34573c3cb3d032 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c > @@ -215,7 +215,10 @@ static int shmob_drm_plane_disable(struct drm_plane > *plane, > > splane->format = NULL; > > + lcdc_write(sdev, LDBCR, LDBCR_UPC(splane->index)); > lcdc_write(sdev, LDBnBSIFR(splane->index), 0); > + lcdc_write(sdev, LDBCR, > +LDBCR_UPF(splane->index) | LDBCR_UPD(splane->index)); > return 0; > } > -- Regards, Laurent Pinchart
Re: [PATCH 04/39] drm: renesas: shmobile: Fix ARGB32 overlay format typo
Hi Geert, Thank you for the patch. On Thu, Jun 22, 2023 at 11:21:16AM +0200, Geert Uytterhoeven wrote: > When configurating a CHn Source Image Format Register (LDBBSIFR), one > should use the corresponding LDBBSIFR_RPKF_* definition for overlay > planes, not the DDFR_PKF_* definition for the primary plane. > > Fortunately both definitions resolve to the same value, so this bug did > not cause any harm. > > Signed-off-by: Geert Uytterhoeven With the typo in the commit message fixed, Reviewed-by: Laurent Pinchart > --- > drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c > b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c > index 0e34573c3cb3d032..7e49e2873da1bb6f 100644 > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c > @@ -94,10 +94,10 @@ static void __shmob_drm_plane_setup(struct > shmob_drm_plane *splane, > format |= LDBBSIFR_AL_1 | LDBBSIFR_RY | LDBBSIFR_RPKF_RGB24; > break; > case DRM_FORMAT_ARGB: > - format |= LDBBSIFR_AL_PK | LDBBSIFR_RY | LDDFR_PKF_ARGB32; > + format |= LDBBSIFR_AL_PK | LDBBSIFR_RY | LDBBSIFR_RPKF_ARGB32; > break; > case DRM_FORMAT_XRGB: > - format |= LDBBSIFR_AL_1 | LDBBSIFR_RY | LDDFR_PKF_ARGB32; > + format |= LDBBSIFR_AL_1 | LDBBSIFR_RY | LDBBSIFR_RPKF_ARGB32; > break; > case DRM_FORMAT_NV12: > case DRM_FORMAT_NV21: -- Regards, Laurent Pinchart
Re: [PATCH 02/39] media: uapi: Add MEDIA_BUS_FMT_RGB666_2X9 variants
Hi Geert, Thank you for the patch. On Thu, Jun 22, 2023 at 11:21:14AM +0200, Geert Uytterhoeven wrote: > Add the RGB666 9:9 formats MEDIA_BUS_FMT_RGB666_2X9_BE and > MEDIA_BUS_FMT_RGB666_2X9_LE. The former is supported by the SH-Mobile > LCD Controller. If MEDIA_BUS_FMT_RGB666_2X9_LE isn't supported, I'd leave it out for now. It can be added later once a driver needs it. Reviewed-by: Laurent Pinchart > Signed-off-by: Geert Uytterhoeven > Cc: Mauro Carvalho Chehab > Cc: linux-me...@vger.kernel.org > --- > .../media/v4l/subdev-formats.rst | 144 ++ > include/uapi/linux/media-bus-format.h | 4 +- > 2 files changed, 147 insertions(+), 1 deletion(-) > > diff --git a/Documentation/userspace-api/media/v4l/subdev-formats.rst > b/Documentation/userspace-api/media/v4l/subdev-formats.rst > index a3a35eeed70846ba..4bbcdec101384cb1 100644 > --- a/Documentation/userspace-api/media/v4l/subdev-formats.rst > +++ b/Documentation/userspace-api/media/v4l/subdev-formats.rst > @@ -949,6 +949,150 @@ The following tables list existing packed RGB formats. >- b\ :sub:`2` >- b\ :sub:`1` >- b\ :sub:`0` > +* .. _MEDIA-BUS-FMT-RGB666-2X9-BE: > + > + - MEDIA_BUS_FMT_RGB666_2X9_BE > + - 0x1025 > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - r\ :sub:`5` > + - r\ :sub:`4` > + - r\ :sub:`3` > + - r\ :sub:`2` > + - r\ :sub:`1` > + - r\ :sub:`0` > + - g\ :sub:`5` > + - g\ :sub:`4` > + - g\ :sub:`3` > +* - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - g\ :sub:`2` > + - g\ :sub:`1` > + - g\ :sub:`0` > + - b\ :sub:`5` > + - b\ :sub:`4` > + - b\ :sub:`3` > + - b\ :sub:`2` > + - b\ :sub:`1` > + - b\ :sub:`0` > +* .. _MEDIA-BUS-FMT-RGB666-2X9-LE: > + > + - MEDIA_BUS_FMT_RGB666_2X9_LE > + - 0x1026 > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - g\ :sub:`2` > + - g\ :sub:`1` > + - g\ :sub:`0` > + - b\ :sub:`5` > + - b\ :sub:`4` > + - b\ :sub:`3` > + - b\ :sub:`2` > + - b\ :sub:`1` > + - b\ :sub:`0` > +* - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - > + - r\ :sub:`5` > + - r\ :sub:`4` > + - r\ :sub:`3` > + - r\ :sub:`2` > + - r\ :sub:`1` > + - r\ :sub:`0` > + - g\ :sub:`5` > + - g\ :sub:`4` > + - g\ :sub:`3` > * .. _MEDIA-BUS-FMT-BGR666-1X18: > >- MEDIA_BUS_FMT_BGR666_1X18 > diff --git a/include/uapi/linux/media-bus-format.h > b/include/uapi/linux/media-bus-format.h > index a03c543cb072de30..07105f530400511e 100644 > --- a/include/uapi/linux/media-bus-format.h > +++ b/include/uapi/linux/media-bus-format.h > @@ -34,7 +34,7 @@ > > #define MEDIA_BUS_FMT_FIXED 0x0001 > > -/* RGB - next is 0x1025 */ > +/* RGB - next is 0x1027 */ > #define MEDIA_BUS_FMT_RGB444_1X120x1016 > #define MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE0x1001 > #define MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE0x1002 > @@ -46,6 +46,8 @@ > #define MEDIA_BUS_FMT_RGB565_2X8_BE 0x1007 > #define MEDIA_BUS_FMT_RGB565_2X8_LE 0x1008 > #define MEDIA_BUS_FMT_RGB666_1X180x1009 > +#define MEDIA_BUS_FMT_RGB666_2X9_BE 0x1025 > +#define MEDIA_BUS_FMT_RGB666_2X9_LE 0x1026 > #define MEDIA_BUS_FMT_BGR666_1X180x1023 > #define MEDIA_BUS_FMT_RBG888_1X240x100e > #define MEDIA_BUS_FMT_RGB666_1X24_CPADHI 0x1015 -- Regards, Laurent Pinchart
Re: [PATCH V4 1/8] drivers/acpi: Add support for Wifi band RF mitigations
On Wed, Jun 21, 2023 at 7:47 AM Evan Quan wrote: > > From: Mario Limonciello > > Due to electrical and mechanical constraints in certain platform designs > there may be likely interference of relatively high-powered harmonics of > the (G-)DDR memory clocks with local radio module frequency bands used > by Wifi 6/6e/7. > > To mitigate this, AMD has introduced an ACPI based mechanism that > devices can use to notify active use of particular frequencies so > that devices can make relative internal adjustments as necessary > to avoid this resonance. > > In order for a device to support this, the expected flow for device > driver or subsystems: > > Drivers/subsystems contributing frequencies: > > 1) During probe, check `wbrf_supported_producer` to see if WBRF supported The prefix should be acpi_wbrf_ or acpi_amd_wbrf_ even, so it is clear that this uses ACPI and is AMD-specific. Whether or not there needs to be an intermediate library wrapped around this is a different matter.
Re: [PATCH 01/39] dt-bindings: display: Add Renesas SH-Mobile LCDC bindings
Hi Geert, Thank you for the patch. On Thu, Jun 22, 2023 at 11:21:13AM +0200, Geert Uytterhoeven wrote: > Add device tree bindings for the LCD Controller (LCDC) found in Renesas > SuperH SH-Mobile and ARM SH/R-Mobile SOCs. > > Based on a plain text prototype by Laurent Pinchart. > > Signed-off-by: Geert Uytterhoeven > Cc: Rob Herring > Cc: Krzysztof Kozlowski > Cc: Conor Dooley > Cc: devicet...@vger.kernel.org > --- > Changes compared to Laurent's original: > - Convert to json-schema, > - Rename compatible values from "renesas,lcdc-" to > "renesas,-lcdc", > - Add power-domains property, > - Add MIPI-DSI port on SH-Mobile AG5, > - Update example to reflect reality, > - Add to MAINTAINERS. > --- > .../display/renesas,shmobile-lcdc.yaml| 108 ++ > MAINTAINERS | 1 + > 2 files changed, 109 insertions(+) > create mode 100644 > Documentation/devicetree/bindings/display/renesas,shmobile-lcdc.yaml > > diff --git > a/Documentation/devicetree/bindings/display/renesas,shmobile-lcdc.yaml > b/Documentation/devicetree/bindings/display/renesas,shmobile-lcdc.yaml > new file mode 100644 > index ..72a39fce7294d56d > --- /dev/null > +++ b/Documentation/devicetree/bindings/display/renesas,shmobile-lcdc.yaml > @@ -0,0 +1,108 @@ > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/display/renesas,shmobile-lcdc.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: Renesas SH-Mobile LCD Controller (LCDC) > + > +maintainers: > + - Laurent Pinchart I'd be happy if you co-maintained this with me :-) Or even took ownership completely. > + > +properties: > + compatible: > +enum: > + - renesas,r8a7740-lcdc # R-Mobile A1 > + - renesas,sh73a0-lcdc # SH-Mobile AG5 > + > + reg: > +maxItems: 1 > + > + interrupts: > +maxItems: 1 > + > + clocks: > +minItems: 1 > +maxItems: 5 > +description: > + Only the functional clock is mandatory. > + Some of the optional clocks are model-dependent (e.g. "video" (a.k.a. > + "vou" or "dv_clk") is available on R-Mobile A1 only). > + > + clock-names: > +minItems: 1 > +maxItems: 5 > +items: > + enum: [ fck, media, lclk, hdmi, video ] Switching to per-item descriptions would allow documenting which clock applies to which SoC. Are enum items unique by default ? This would allow a combination of clocks that doesn't include the fck clock, that's not right. > + > + power-domains: > +maxItems: 1 > + > + ports: > +$ref: /schemas/graph.yaml#/properties/ports > +description: | > + The connections to the output video ports are modeled using the OF > graph > + bindings specified in Documentation/devicetree/bindings/graph.txt. it's available in YAML form now. I'd just drop the "specified in ...". > + The number of ports and their assignment are model-dependent. > + Each port shall have a single endpoint. > + > +properties: > + port@0: > +$ref: /schemas/graph.yaml#/properties/port > +description: LCD port (R-Mobile A1 and SH-Mobile AG5) > +unevaluatedProperties: false > + > + port@1: > +$ref: /schemas/graph.yaml#/properties/port > +description: HDMI port (R-Mobile A1 LCDC1 and SH-Mobile AG5) > +unevaluatedProperties: false > + > + port@2: > +$ref: /schemas/graph.yaml#/properties/port > +description: MIPI-DSI port (SH-Mobile AG5) > +unevaluatedProperties: false Let's condition the ports on the compatible value to enable automatic validation. > + > +required: > + - port@0 Based on the above, port@1 is required too as it's present on all supported SoCs. Let's condition this on the compatible value too. > + > +unevaluatedProperties: false > + > +required: > + - compatible > + - reg > + - interrupts > + - clocks > + - clock-names > + - power-domains > + - ports > + > +additionalProperties: false > + > +examples: > + - | > +#include > +#include > + > +lcdc0: lcd-controller@fe94 { > +compatible = "renesas,r8a7740-lcdc"; > +reg = <0xfe94 0x4000>; > +interrupts = ; > +clocks = <&mstp1_clks R8A7740_CLK_LCDC0>, > + <&cpg_clocks R8A7740_CLK_M3>, <&lcdlclk0_clk>, > + <&vou_clk>; > +clock-names = "fck", "media", "lclk", "video"; > +power-domains = <&pd_a4lc>; > +status = "disabled"; > + > +ports { > +#address-cells = <1>; > +#size-cells = <0>; > + > +port@0 { > +reg = <0>; > + > +lcdc0_rgb: endpoint { > +}; > +}; > +}; > +}; > diff --git a/MAINTAINERS b/MAINTAINERS > index 83e9f4ac6bedaa9f..dc1935c196cb0e0b 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -7023,6 +7023,7 @@ F: > Documen
[PATCH] drm/kms: log when querying an object not included in lease
User-space may query an existing object not included in a lease. Make it easier to debug such situations by logging a debug message. Signed-off-by: Simon Ser Reviewed-by: Daniel Vetter --- drivers/gpu/drm/drm_mode_object.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_mode_object.c b/drivers/gpu/drm/drm_mode_object.c index ba1608effc0f..ac0d2ce3f870 100644 --- a/drivers/gpu/drm/drm_mode_object.c +++ b/drivers/gpu/drm/drm_mode_object.c @@ -147,8 +147,10 @@ struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev, obj = NULL; if (obj && drm_mode_object_lease_required(obj->type) && - !_drm_lease_held(file_priv, obj->id)) + !_drm_lease_held(file_priv, obj->id)) { + drm_dbg_kms(dev, "[OBJECT:%d] not included in lease", id); obj = NULL; + } if (obj && obj->free_cb) { if (!kref_get_unless_zero(&obj->refcount)) -- 2.41.0
Re: [PATCH v5 1/2] drm/msm/dpu: retrieve DSI DSC struct through priv->dsi[0]
On 6/22/2023 11:36 AM, Dmitry Baryshkov wrote: On Thu, 22 Jun 2023 at 20:25, Kuogee Hsieh wrote: Currently struct drm_dsc_config for DSI is populated at display setup during system boot up. This mechanism works fine with embedded display but not for pluggable displays as the struct drm_dsc_config will become stale once external display is unplugged. Nit: "In preparation of adding support for DP DSC..." If you don't mind, I'll append this phrase while applying the patch. please, thank for your helps. Move storing of DSI DSC struct to atomic_enable() so that same mechanism will work for both embedded display and pluggable displays. Changes in v4: -- fix checkpatch.pl warning Changes in v5: -- delete dpu_encoder_get_dsc_config() from atomic_mode_set Reviewed-by: Dmitry Baryshkov Signed-off-by: Kuogee Hsieh --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 42 - 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 2e1873d..edc559d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -543,11 +543,24 @@ bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc) return (num_dsc > 0) && (num_dsc > intf_count); } +static struct drm_dsc_config *dpu_encoder_get_dsc_config(struct drm_encoder *drm_enc) +{ + struct msm_drm_private *priv = drm_enc->dev->dev_private; + struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc); + int index = dpu_enc->disp_info.h_tile_instance[0]; + + if (dpu_enc->disp_info.intf_type == INTF_DSI) + return msm_dsi_get_dsc_config(priv->dsi[index]); + + return NULL; +} + static struct msm_display_topology dpu_encoder_get_topology( struct dpu_encoder_virt *dpu_enc, struct dpu_kms *dpu_kms, struct drm_display_mode *mode, - struct drm_crtc_state *crtc_state) + struct drm_crtc_state *crtc_state, + struct drm_dsc_config *dsc) { struct msm_display_topology topology = {0}; int i, intf_count = 0; @@ -579,7 +592,7 @@ static struct msm_display_topology dpu_encoder_get_topology( topology.num_intf = intf_count; - if (dpu_enc->dsc) { + if (dsc) { /* * In case of Display Stream Compression (DSC), we would use * 2 DSC encoders, 2 layer mixers and 1 interface @@ -605,6 +618,7 @@ static int dpu_encoder_virt_atomic_check( struct drm_display_mode *adj_mode; struct msm_display_topology topology; struct dpu_global_state *global_state; + struct drm_dsc_config *dsc; int i = 0; int ret = 0; @@ -640,7 +654,9 @@ static int dpu_encoder_virt_atomic_check( } } - topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode, crtc_state); + dsc = dpu_encoder_get_dsc_config(drm_enc); + + topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode, crtc_state, dsc); /* * Release and Allocate resources on every modeset @@ -1072,14 +1088,12 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, dpu_enc->hw_pp[i] = i < num_pp ? to_dpu_hw_pingpong(hw_pp[i]) : NULL; - if (dpu_enc->dsc) { - num_dsc = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, - drm_enc->base.id, DPU_HW_BLK_DSC, - hw_dsc, ARRAY_SIZE(hw_dsc)); - for (i = 0; i < num_dsc; i++) { - dpu_enc->hw_dsc[i] = to_dpu_hw_dsc(hw_dsc[i]); - dsc_mask |= BIT(dpu_enc->hw_dsc[i]->idx - DSC_0); - } + num_dsc = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, + drm_enc->base.id, DPU_HW_BLK_DSC, + hw_dsc, ARRAY_SIZE(hw_dsc)); + for (i = 0; i < num_dsc; i++) { + dpu_enc->hw_dsc[i] = to_dpu_hw_dsc(hw_dsc[i]); + dsc_mask |= BIT(dpu_enc->hw_dsc[i]->idx - DSC_0); } dpu_enc->dsc_mask = dsc_mask; @@ -1187,6 +1201,8 @@ static void dpu_encoder_virt_atomic_enable(struct drm_encoder *drm_enc, dpu_enc = to_dpu_encoder_virt(drm_enc); + dpu_enc->dsc = dpu_encoder_get_dsc_config(drm_enc); + mutex_lock(&dpu_enc->enc_lock); cur_mode = &dpu_enc->base.crtc->state->adjusted_mode; @@ -2109,8 +2125,10 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc) phys_enc->hw_pp->merge_3d->idx); } - if (dpu_enc->d
Re: [PATCH v2 3/4] drm: Remove references to removed transitional helpers
Hi Geert, Thank you for the patch. On Fri, Jun 09, 2023 at 03:44:29PM +0200, Geert Uytterhoeven wrote: > The transitional helpers were removed a long time ago, but some > references stuck. Remove them. > > Fixes: 21ebe615c16994f3 ("drm: Remove transitional helpers") > Signed-off-by: Geert Uytterhoeven Reviewed-by: Laurent Pinchart > --- > v2: > - Drop "first part" in drivers/gpu/drm/drm_plane_helper.c. > --- > drivers/gpu/drm/drm_plane_helper.c | 12 +- > include/drm/drm_crtc.h | 5 --- > include/drm/drm_modeset_helper_vtables.h | 48 +++- > 3 files changed, 23 insertions(+), 42 deletions(-) > > diff --git a/drivers/gpu/drm/drm_plane_helper.c > b/drivers/gpu/drm/drm_plane_helper.c > index c91e454eba097942..5e95089676ff81ed 100644 > --- a/drivers/gpu/drm/drm_plane_helper.c > +++ b/drivers/gpu/drm/drm_plane_helper.c > @@ -40,8 +40,8 @@ > /** > * DOC: overview > * > - * This helper library has two parts. The first part has support to implement > - * primary plane support on top of the normal CRTC configuration interface. > + * This helper library contains helpers to implement primary plane support on > + * top of the normal CRTC configuration interface. > * Since the legacy &drm_mode_config_funcs.set_config interface ties the > primary > * plane together with the CRTC state this does not allow userspace to > disable > * the primary plane itself. The default primary plane only expose XRBG > and > @@ -51,14 +51,6 @@ > * planes, and newly merged drivers must not rely upon these transitional > * helpers. > * > - * The second part also implements transitional helpers which allow drivers > to > - * gradually switch to the atomic helper infrastructure for plane updates. > Once > - * that switch is complete drivers shouldn't use these any longer, instead > using > - * the proper legacy implementations for update and disable plane hooks > provided > - * by the atomic helpers. > - * > - * Again drivers are strongly urged to switch to the new interfaces. > - * > * The plane helpers share the function table structures with other helpers, > * specifically also the atomic helpers. See &struct drm_plane_helper_funcs > for > * the details. > diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h > index 8e1cbc75143ef216..8b48a1974da3143c 100644 > --- a/include/drm/drm_crtc.h > +++ b/include/drm/drm_crtc.h > @@ -77,11 +77,6 @@ struct drm_plane_helper_funcs; > * intended to indicate whether a full modeset is needed, rather than > strictly > * describing what has changed in a commit. See also: > * drm_atomic_crtc_needs_modeset() > - * > - * WARNING: Transitional helpers (like drm_helper_crtc_mode_set() or > - * drm_helper_crtc_mode_set_base()) do not maintain many of the derived > control > - * state like @plane_mask so drivers not converted over to atomic helpers > should > - * not rely on these being accurate! > */ > struct drm_crtc_state { > /** @crtc: backpointer to the CRTC */ > diff --git a/include/drm/drm_modeset_helper_vtables.h > b/include/drm/drm_modeset_helper_vtables.h > index 965faf082a6d1acb..e3c3ac615909474b 100644 > --- a/include/drm/drm_modeset_helper_vtables.h > +++ b/include/drm/drm_modeset_helper_vtables.h > @@ -59,8 +59,8 @@ enum mode_set_atomic { > /** > * struct drm_crtc_helper_funcs - helper operations for CRTCs > * > - * These hooks are used by the legacy CRTC helpers, the transitional plane > - * helpers and the new atomic modesetting helpers. > + * These hooks are used by the legacy CRTC helpers and the new atomic > + * modesetting helpers. > */ > struct drm_crtc_helper_funcs { > /** > @@ -216,9 +216,7 @@ struct drm_crtc_helper_funcs { >* >* This callback is used to update the display mode of a CRTC without >* changing anything of the primary plane configuration. This fits the > - * requirement of atomic and hence is used by the atomic helpers. It is > - * also used by the transitional plane helpers to implement a > - * @mode_set hook in drm_helper_crtc_mode_set(). > + * requirement of atomic and hence is used by the atomic helpers. >* >* Note that the display pipe is completely off when this function is >* called. Atomic drivers which need hardware to be running before they > @@ -333,8 +331,8 @@ struct drm_crtc_helper_funcs { >* all updated. Again the recommendation is to just call check helpers >* until a maximal configuration is reached. >* > - * This callback is used by the atomic modeset helpers and by the > - * transitional plane helpers, but it is optional. > + * This callback is used by the atomic modeset helpers, but it is > + * optional. >* >* NOTE: >* > @@ -373,8 +371,8 @@ struct drm_crtc_helper_funcs { >* has picked. See drm_atomic_helper_commit_planes() for a discussion of >* the tradeoffs and variants of
Re: [PATCH v2 2/4] drm/todo: Convert list of fbconv links to footnotes
Hi Geert, Thank you for the patch. On Fri, Jun 09, 2023 at 03:44:28PM +0200, Geert Uytterhoeven wrote: > Convert the references to fbconv links to footnotes, so they can be > navigated. > > Signed-off-by: Geert Uytterhoeven > --- > v2: > - New. > --- > Documentation/gpu/todo.rst | 10 +- > 1 file changed, 5 insertions(+), 5 deletions(-) > > diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst > index 6c328613c049fc1d..ce1d4e22c327063b 100644 > --- a/Documentation/gpu/todo.rst > +++ b/Documentation/gpu/todo.rst > @@ -753,16 +753,16 @@ existing hardware. The new driver's call-back functions > are filled from > existing fbdev code. > > More complex fbdev drivers can be refactored step-by-step into a DRM > -driver with the help of the DRM fbconv helpers. [1] These helpers provide > +driver with the help of the DRM fbconv helpers [4]_. These helpers provide > the transition layer between the DRM core infrastructure and the fbdev > driver interface. Create a new DRM driver on top of the fbconv helpers, > copy over the fbdev driver, and hook it up to the DRM code. Examples for > -several fbdev drivers are available at [1] and a tutorial of this process > -available at [2]. The result is a primitive DRM driver that can run X11 > +several fbdev drivers are available at [4]_ and a tutorial of this process > +available at [5]_. The result is a primitive DRM driver that can run X11 When using footnotes, the main text must read correctly if you ignore the notes. This isn't the case for the second and third footnotes here. Examples for several fbdev drivers are available in Thomas Zimmermann's fbconv tree [4]_, as well as a tutorial of this process [5]_. I'm not making a call on whether that's better or not that's better than the current situation. An alternative is to use plain links: Examples for several fbdev drivers are available in 'Thomas Zimmermann's fbconv tree`_, as well as a `tutorial of this process`_. .. _Thomas Zimmermann's fbconv tree: https://gitlab.freedesktop.org/tzimmermann/linux/tree/fbconv .. _tutorial of this process: https://gitlab.freedesktop.org/tzimmermann/linux/blob/fbconv/drivers/gpu/drm/drm_fbconv_helper.c > and Weston. > > - - [1] https://gitlab.freedesktop.org/tzimmermann/linux/tree/fbconv > - - [2] > https://gitlab.freedesktop.org/tzimmermann/linux/blob/fbconv/drivers/gpu/drm/drm_fbconv_helper.c > + .. [4] https://gitlab.freedesktop.org/tzimmermann/linux/tree/fbconv > + .. [5] > https://gitlab.freedesktop.org/tzimmermann/linux/blob/fbconv/drivers/gpu/drm/drm_fbconv_helper.c > > Contact: Thomas Zimmermann > -- Regards, Laurent Pinchart
Re: [PATCH] dma-buf: keep the signaling time of merged fences v2
On Fri, Jun 23, 2023 at 5:09 AM Christian König wrote: > > Some Android CTS is testing for that. > > v2: use the current time if the fence is still in the signaling path and > the timestamp not yet available. > > Signed-off-by: Christian König Acked-by: Alex Deucher > --- > drivers/dma-buf/dma-fence-unwrap.c | 20 +--- > drivers/dma-buf/dma-fence.c| 5 +++-- > drivers/gpu/drm/drm_syncobj.c | 2 +- > include/linux/dma-fence.h | 2 +- > 4 files changed, 22 insertions(+), 7 deletions(-) > > diff --git a/drivers/dma-buf/dma-fence-unwrap.c > b/drivers/dma-buf/dma-fence-unwrap.c > index 7002bca792ff..46c2d3a474cd 100644 > --- a/drivers/dma-buf/dma-fence-unwrap.c > +++ b/drivers/dma-buf/dma-fence-unwrap.c > @@ -66,18 +66,32 @@ struct dma_fence *__dma_fence_unwrap_merge(unsigned int > num_fences, > { > struct dma_fence_array *result; > struct dma_fence *tmp, **array; > + ktime_t timestamp; > unsigned int i; > size_t count; > > count = 0; > + timestamp = ns_to_ktime(0); > for (i = 0; i < num_fences; ++i) { > - dma_fence_unwrap_for_each(tmp, &iter[i], fences[i]) > - if (!dma_fence_is_signaled(tmp)) > + dma_fence_unwrap_for_each(tmp, &iter[i], fences[i]) { > + if (!dma_fence_is_signaled(tmp)) { > ++count; > + } else if (test_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT, > + &tmp->flags)) { > + if (ktime_after(tmp->timestamp, timestamp)) > + timestamp = tmp->timestamp; > + } else { > + /* > +* Use the current time if the fence is > +* currently signaling. > +*/ > + timestamp = ktime_get(); > + } > + } > } > > if (count == 0) > - return dma_fence_get_stub(); > + return dma_fence_allocate_private_stub(timestamp); > > array = kmalloc_array(count, sizeof(*array), GFP_KERNEL); > if (!array) > diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c > index f177c56269bb..ad076f208760 100644 > --- a/drivers/dma-buf/dma-fence.c > +++ b/drivers/dma-buf/dma-fence.c > @@ -150,10 +150,11 @@ EXPORT_SYMBOL(dma_fence_get_stub); > > /** > * dma_fence_allocate_private_stub - return a private, signaled fence > + * @timestamp: timestamp when the fence was signaled > * > * Return a newly allocated and signaled stub fence. > */ > -struct dma_fence *dma_fence_allocate_private_stub(void) > +struct dma_fence *dma_fence_allocate_private_stub(ktime_t timestamp) > { > struct dma_fence *fence; > > @@ -169,7 +170,7 @@ struct dma_fence *dma_fence_allocate_private_stub(void) > set_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, > &fence->flags); > > - dma_fence_signal(fence); > + dma_fence_signal_timestamp(fence, timestamp); > > return fence; > } > diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c > index 0c2be8360525..04589a35eb09 100644 > --- a/drivers/gpu/drm/drm_syncobj.c > +++ b/drivers/gpu/drm/drm_syncobj.c > @@ -353,7 +353,7 @@ EXPORT_SYMBOL(drm_syncobj_replace_fence); > */ > static int drm_syncobj_assign_null_handle(struct drm_syncobj *syncobj) > { > - struct dma_fence *fence = dma_fence_allocate_private_stub(); > + struct dma_fence *fence = > dma_fence_allocate_private_stub(ktime_get()); > > if (IS_ERR(fence)) > return PTR_ERR(fence); > diff --git a/include/linux/dma-fence.h b/include/linux/dma-fence.h > index d54b595a0fe0..0d678e9a7b24 100644 > --- a/include/linux/dma-fence.h > +++ b/include/linux/dma-fence.h > @@ -606,7 +606,7 @@ static inline signed long dma_fence_wait(struct dma_fence > *fence, bool intr) > void dma_fence_set_deadline(struct dma_fence *fence, ktime_t deadline); > > struct dma_fence *dma_fence_get_stub(void); > -struct dma_fence *dma_fence_allocate_private_stub(void); > +struct dma_fence *dma_fence_allocate_private_stub(ktime_t timestamp); > u64 dma_fence_context_alloc(unsigned num); > > extern const struct dma_fence_ops dma_fence_array_ops; > -- > 2.34.1 >
[PATCH 7/7] drm/msm/dpu: merge dpu_csc_blk and dpu_dsc_blk into dpu_simple_blk
Merge struct dpu_csc_blk and struct dpu_dsc_blk into new struct dpu_simple_blk, which contains just base and length. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 15 +-- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h index 7cb9ef940225..4b3fb104c412 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -283,11 +283,6 @@ struct dpu_scaler_blk { u32 version; }; -struct dpu_csc_blk { - u32 base; - u32 len; -}; - /** * struct dpu_pp_blk : Pixel processing sub-blk information * @base: offset of this sub-block relative to the block offset @@ -301,11 +296,11 @@ struct dpu_pp_blk { }; /** - * struct dpu_dsc_blk - DSC Encoder sub-blk information + * struct dpu_simple_blk - DSC Encoder sub-blk information * @base: offset of this sub-block relative to the block offset * @len: register block length of this sub-block */ -struct dpu_dsc_blk { +struct dpu_simple_blk { u32 base; u32 len; }; @@ -403,7 +398,7 @@ struct dpu_sspp_sub_blks { u32 max_per_pipe_bw; u32 qseed_ver; struct dpu_scaler_blk scaler_blk; - struct dpu_pp_blk csc_blk; + struct dpu_simple_blk csc_blk; const u32 *format_list; u32 num_formats; @@ -444,8 +439,8 @@ struct dpu_pingpong_sub_blks { * @ctl: DSC controller sub-block */ struct dpu_dsc_sub_blks { - struct dpu_dsc_blk enc; - struct dpu_dsc_blk ctl; + struct dpu_simple_blk enc; + struct dpu_simple_blk ctl; }; /** -- 2.39.2
[PATCH 3/7] drm/msm/dpu: Drop unused num argument from relevant macros
From: Ryan McCann Drop unused parameter "num" from all VIG and DMA sub-block macros. Update calls to relevant macros to reflect change. Signed-off-by: Ryan McCann [DB: also added VIG_SBLK and VIG_SBLK_ROT] Signed-off-by: Dmitry Baryshkov --- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 62 +-- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index d4a5b18d4dae..2c101d4d243c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -248,7 +248,7 @@ static const uint32_t wb2_formats[] = { */ /* SSPP common configuration */ -#define _VIG_SBLK(num, sdma_pri, qseed_ver) \ +#define _VIG_SBLK(sdma_pri, qseed_ver) \ { \ .maxdwnscale = MAX_DOWNSCALE_RATIO, \ .maxupscale = MAX_UPSCALE_RATIO, \ @@ -264,7 +264,7 @@ static const uint32_t wb2_formats[] = { .rotation_cfg = NULL, \ } -#define _VIG_SBLK_ROT(num, sdma_pri, qseed_ver, rot_cfg) \ +#define _VIG_SBLK_ROT(sdma_pri, qseed_ver, rot_cfg) \ { \ .maxdwnscale = MAX_DOWNSCALE_RATIO, \ .maxupscale = MAX_UPSCALE_RATIO, \ @@ -280,7 +280,7 @@ static const uint32_t wb2_formats[] = { .rotation_cfg = rot_cfg, \ } -#define _DMA_SBLK(num, sdma_pri) \ +#define _DMA_SBLK(sdma_pri) \ { \ .maxdwnscale = SSPP_UNITY_SCALE, \ .maxupscale = SSPP_UNITY_SCALE, \ @@ -292,13 +292,13 @@ static const uint32_t wb2_formats[] = { } static const struct dpu_sspp_sub_blks msm8998_vig_sblk_0 = - _VIG_SBLK("0", 0, DPU_SSPP_SCALER_QSEED3); + _VIG_SBLK(0, DPU_SSPP_SCALER_QSEED3); static const struct dpu_sspp_sub_blks msm8998_vig_sblk_1 = - _VIG_SBLK("1", 0, DPU_SSPP_SCALER_QSEED3); + _VIG_SBLK(0, DPU_SSPP_SCALER_QSEED3); static const struct dpu_sspp_sub_blks msm8998_vig_sblk_2 = - _VIG_SBLK("2", 0, DPU_SSPP_SCALER_QSEED3); + _VIG_SBLK(0, DPU_SSPP_SCALER_QSEED3); static const struct dpu_sspp_sub_blks msm8998_vig_sblk_3 = - _VIG_SBLK("3", 0, DPU_SSPP_SCALER_QSEED3); + _VIG_SBLK(0, DPU_SSPP_SCALER_QSEED3); static const struct dpu_rotation_cfg dpu_rot_sc7280_cfg_v2 = { .rot_maxheight = 1088, @@ -307,49 +307,49 @@ static const struct dpu_rotation_cfg dpu_rot_sc7280_cfg_v2 = { }; static const struct dpu_sspp_sub_blks sdm845_vig_sblk_0 = - _VIG_SBLK("0", 5, DPU_SSPP_SCALER_QSEED3); + _VIG_SBLK(5, DPU_SSPP_SCALER_QSEED3); static const struct dpu_sspp_sub_blks sdm845_vig_sblk_1 = - _VIG_SBLK("1", 6, DPU_SSPP_SCALER_QSEED3); + _VIG_SBLK(6, DPU_SSPP_SCALER_QSEED3); static const struct dpu_sspp_sub_blks sdm845_vig_sblk_2 = - _VIG_SBLK("2", 7, DPU_SSPP_SCALER_QSEED3); + _VIG_SBLK(7, DPU_SSPP_SCALER_QSEED3); static const struct dpu_sspp_sub_blks sdm845_vig_sblk_3 = - _VIG_SBLK("3", 8, DPU_SSPP_SCALER_QSEED3); + _VIG_SBLK(8, DPU_SSPP_SCALER_QSEED3); -static const struct dpu_sspp_sub_blks sdm845_dma_sblk_0 = _DMA_SBLK("8", 1); -static const struct dpu_sspp_sub_blks sdm845_dma_sblk_1 = _DMA_SBLK("9", 2); -static const struct dpu_sspp_sub_blks sdm845_dma_sblk_2 = _DMA_SBLK("10", 3); -static const struct dpu_sspp_sub_blks sdm845_dma_sblk_3 = _DMA_SBLK("11", 4); +static const struct dpu_sspp_sub_blks sdm845_dma_sblk_0 = _DMA_SBLK(1); +static const struct dpu_sspp_sub_blks sdm845_dma_sblk_1 = _DMA_SBLK(2); +static const struct dpu_sspp_sub_blks sdm845_dma_sblk_2 = _DMA_SBLK(3); +static const struct dpu_sspp_sub_blks sdm845_dma_sblk_3 = _DMA_SBLK(4); static const struct dpu_sspp_sub_blks sc7180_vig_sblk_0 = - _VIG_SBLK("0", 4, DPU_SSPP_SCALER_QSEED4); + _VIG_SBLK(4, DPU_SSPP_SCALER_QSEED4); static const struct dpu_sspp_sub_blks sc7280_vig_sblk_0 = - _VIG_SBLK_ROT("0", 4, DPU_SSPP_SCALER_QSEED4, &dpu_rot_sc7280_cfg_v2); + _VIG_SBLK_ROT(4, DPU_SSPP_SCALER_QSEED4, &dpu_rot_sc7280_cfg_v2); static const struct dpu_sspp_sub_blks sm6115_vig_sblk_0 = - _VIG_SBLK("0", 2, DPU_SSPP_SCALER_QSEED4); + _VIG_SBLK(2, DPU_SSPP_SCALER_QSEED4); static const struct dpu_sspp_sub_blks sm8250_vig_sblk_0 = - _VIG_SBLK("0", 5, DPU_SSPP_SCALER_QSEED4); + _VIG_SBLK(5, DPU_SSPP_SCALER_QSEED4); static const struct dpu_sspp_sub_blks sm8250_vig_sblk_1 =
[PATCH 2/7] drm/msm/dpu: drop the field `name' from DPU_HW_SUBBLK_INFO
There is little point in having a separate field with the name in the sub-block info. Ryan pointed out that some (most) of of sub-blocks do not even fill this field. The handling code also usually knows, which sub-block it is now looking at. Drop the unused field completely. Suggested-by: Ryan McCann Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 8 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 2 -- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 4a99144a5a85..d4a5b18d4dae 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -253,9 +253,9 @@ static const uint32_t wb2_formats[] = { .maxdwnscale = MAX_DOWNSCALE_RATIO, \ .maxupscale = MAX_UPSCALE_RATIO, \ .smart_dma_priority = sdma_pri, \ - .scaler_blk = {.name = STRCAT("sspp_scaler", num), \ + .scaler_blk = { \ .base = 0xa00, .len = 0xa0,}, \ - .csc_blk = {.name = STRCAT("sspp_csc", num), \ + .csc_blk = { \ .base = 0x1a00, .len = 0x100,}, \ .format_list = plane_formats_yuv, \ .num_formats = ARRAY_SIZE(plane_formats_yuv), \ @@ -269,9 +269,9 @@ static const uint32_t wb2_formats[] = { .maxdwnscale = MAX_DOWNSCALE_RATIO, \ .maxupscale = MAX_UPSCALE_RATIO, \ .smart_dma_priority = sdma_pri, \ - .scaler_blk = {.name = STRCAT("sspp_scaler", num), \ + .scaler_blk = { \ .base = 0xa00, .len = 0xa0,}, \ - .csc_blk = {.name = STRCAT("sspp_csc", num), \ + .csc_blk = { \ .base = 0x1a00, .len = 0x100,}, \ .format_list = plane_formats_yuv, \ .num_formats = ARRAY_SIZE(plane_formats_yuv), \ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h index bf7a525206ee..a102a8b0f8e1 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -273,13 +273,11 @@ enum { /** * MACRO DPU_HW_SUBBLK_INFO - information of HW sub-block inside DPU - * @name: string name for debug purposes * @base: offset of this sub-block relative to the block * offset * @lenregister block length of this sub-block */ #define DPU_HW_SUBBLK_INFO \ - char name[DPU_HW_BLK_NAME_LEN]; \ u32 base; \ u32 len -- 2.39.2
[PATCH 6/7] drm/msm/dpu: drop DPU_HW_SUBBLK_INFO macro
As the subblock info is now mostly gone, inline and drop the macro DPU_HW_SUBBLK_INFO. Signed-off-by: Dmitry Baryshkov --- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h| 31 +-- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h index 8dae416d2dc6..7cb9ef940225 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -271,46 +271,43 @@ enum { u32 len; \ unsigned long features -/** - * MACRO DPU_HW_SUBBLK_INFO - information of HW sub-block inside DPU - * @base: offset of this sub-block relative to the block - * offset - * @lenregister block length of this sub-block - */ -#define DPU_HW_SUBBLK_INFO \ - u32 base; \ - u32 len - /** * struct dpu_scaler_blk: Scaler information - * @info: HW register and features supported by this sub-blk + * @base: offset of this sub-block relative to the block offset + * @len: register block length of this sub-block * @version: qseed block revision */ struct dpu_scaler_blk { - DPU_HW_SUBBLK_INFO; + u32 base; + u32 len; u32 version; }; struct dpu_csc_blk { - DPU_HW_SUBBLK_INFO; + u32 base; + u32 len; }; /** * struct dpu_pp_blk : Pixel processing sub-blk information - * @info: HW register and features supported by this sub-blk + * @base: offset of this sub-block relative to the block offset + * @len: register block length of this sub-block * @version: HW Algorithm version */ struct dpu_pp_blk { - DPU_HW_SUBBLK_INFO; + u32 base; + u32 len; u32 version; }; /** * struct dpu_dsc_blk - DSC Encoder sub-blk information - * @info: HW register and features supported by this sub-blk + * @base: offset of this sub-block relative to the block offset + * @len: register block length of this sub-block */ struct dpu_dsc_blk { - DPU_HW_SUBBLK_INFO; + u32 base; + u32 len; }; /** -- 2.39.2
[PATCH 0/7] drm/msm/dpu: simplify DPU sub-blocks info
Ryan pointed out [1] that some (most) of of sub-blocks do not fill the field `name'. Further research showed that we can drop the fields `name' and `id' and further simplify the catalog. The handling code also usually knows, which sub-block it is now looking at. Drop unused field and arguments and merge some of sub-block declarations. I did not merge inter-generation VIG_SBLK definitions, this is pending another cleanup (which will also switch to using hardcoded scaler version). Dependencies: [2] [1] https://patchwork.freedesktop.org/patch/543903/?series=119773&rev=1 [2] https://patchwork.freedesktop.org/series/118839/ Dmitry Baryshkov (6): drm/msm/dpu: drop the `id' field from DPU_HW_SUBBLK_INFO drm/msm/dpu: drop the field `name' from DPU_HW_SUBBLK_INFO drm/msm/dpu: drop the `smart_dma_priority' field from struct dpu_sspp_sub_blks drm/msm/dpu: deduplicate some (most) of SSPP sub-blocks drm/msm/dpu: drop DPU_HW_SUBBLK_INFO macro drm/msm/dpu: merge dpu_csc_blk and dpu_dsc_blk into dpu_simple_blk Ryan McCann (1): drm/msm/dpu: Drop unused num argument from relevant macros .../msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 16 +-- .../msm/disp/dpu1/catalog/dpu_4_0_sdm845.h| 16 +-- .../msm/disp/dpu1/catalog/dpu_5_0_sm8150.h| 16 +-- .../msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 16 +-- .../msm/disp/dpu1/catalog/dpu_6_0_sm8250.h| 16 +-- .../msm/disp/dpu1/catalog/dpu_6_2_sc7180.h| 8 +- .../msm/disp/dpu1/catalog/dpu_6_3_sm6115.h| 4 +- .../msm/disp/dpu1/catalog/dpu_6_4_sm6350.h| 8 +- .../msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h | 4 +- .../msm/disp/dpu1/catalog/dpu_6_9_sm6375.h| 4 +- .../msm/disp/dpu1/catalog/dpu_7_0_sm8350.h| 16 +-- .../msm/disp/dpu1/catalog/dpu_7_2_sc7280.h| 8 +- .../msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 16 +-- .../msm/disp/dpu1/catalog/dpu_8_1_sm8450.h| 16 +-- .../msm/disp/dpu1/catalog/dpu_9_0_sm8550.h| 20 +-- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 122 +++--- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h| 48 +++ 17 files changed, 154 insertions(+), 200 deletions(-) -- 2.39.2
[PATCH 5/7] drm/msm/dpu: deduplicate some (most) of SSPP sub-blocks
As we have dropped the variadic parts of SSPP sub-blocks declarations, deduplicate them now, reducing memory cruft. Do not deduplicate the VIG sub-blocks for different platforms since this is pending another cleanup/rework (of scaler version). Signed-off-by: Dmitry Baryshkov --- .../msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 16 +++--- .../msm/disp/dpu1/catalog/dpu_4_0_sdm845.h| 16 +++--- .../msm/disp/dpu1/catalog/dpu_5_0_sm8150.h| 16 +++--- .../msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 16 +++--- .../msm/disp/dpu1/catalog/dpu_6_0_sm8250.h| 16 +++--- .../msm/disp/dpu1/catalog/dpu_6_2_sc7180.h| 8 +-- .../msm/disp/dpu1/catalog/dpu_6_3_sm6115.h| 4 +- .../msm/disp/dpu1/catalog/dpu_6_4_sm6350.h| 8 +-- .../msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h | 4 +- .../msm/disp/dpu1/catalog/dpu_6_9_sm6375.h| 4 +- .../msm/disp/dpu1/catalog/dpu_7_0_sm8350.h| 16 +++--- .../msm/disp/dpu1/catalog/dpu_7_2_sc7280.h| 8 +-- .../msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 16 +++--- .../msm/disp/dpu1/catalog/dpu_8_1_sm8450.h| 16 +++--- .../msm/disp/dpu1/catalog/dpu_9_0_sm8550.h| 20 +++ .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 52 --- 16 files changed, 103 insertions(+), 133 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h index 7d87dc2d7b1b..d49030449c85 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h @@ -75,7 +75,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { .name = "sspp_0", .id = SSPP_VIG0, .base = 0x4000, .len = 0x1ac, .features = VIG_MSM8998_MASK, - .sblk = &msm8998_vig_sblk_0, + .sblk = &msm8998_vig_sblk, .xin_id = 0, .type = SSPP_TYPE_VIG, .clk_ctrl = DPU_CLK_CTRL_VIG0, @@ -83,7 +83,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { .name = "sspp_1", .id = SSPP_VIG1, .base = 0x6000, .len = 0x1ac, .features = VIG_MSM8998_MASK, - .sblk = &msm8998_vig_sblk_1, + .sblk = &msm8998_vig_sblk, .xin_id = 4, .type = SSPP_TYPE_VIG, .clk_ctrl = DPU_CLK_CTRL_VIG1, @@ -91,7 +91,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { .name = "sspp_2", .id = SSPP_VIG2, .base = 0x8000, .len = 0x1ac, .features = VIG_MSM8998_MASK, - .sblk = &msm8998_vig_sblk_2, + .sblk = &msm8998_vig_sblk, .xin_id = 8, .type = SSPP_TYPE_VIG, .clk_ctrl = DPU_CLK_CTRL_VIG2, @@ -99,7 +99,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { .name = "sspp_3", .id = SSPP_VIG3, .base = 0xa000, .len = 0x1ac, .features = VIG_MSM8998_MASK, - .sblk = &msm8998_vig_sblk_3, + .sblk = &msm8998_vig_sblk, .xin_id = 12, .type = SSPP_TYPE_VIG, .clk_ctrl = DPU_CLK_CTRL_VIG3, @@ -107,7 +107,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { .name = "sspp_8", .id = SSPP_DMA0, .base = 0x24000, .len = 0x1ac, .features = DMA_MSM8998_MASK, - .sblk = &sdm845_dma_sblk_0, + .sblk = &dpu_dma_sblk, .xin_id = 1, .type = SSPP_TYPE_DMA, .clk_ctrl = DPU_CLK_CTRL_DMA0, @@ -115,7 +115,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { .name = "sspp_9", .id = SSPP_DMA1, .base = 0x26000, .len = 0x1ac, .features = DMA_MSM8998_MASK, - .sblk = &sdm845_dma_sblk_1, + .sblk = &dpu_dma_sblk, .xin_id = 5, .type = SSPP_TYPE_DMA, .clk_ctrl = DPU_CLK_CTRL_DMA1, @@ -123,7 +123,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { .name = "sspp_10", .id = SSPP_DMA2, .base = 0x28000, .len = 0x1ac, .features = DMA_CURSOR_MSM8998_MASK, - .sblk = &sdm845_dma_sblk_2, + .sblk = &dpu_dma_sblk, .xin_id = 9, .type = SSPP_TYPE_DMA, .clk_ctrl = DPU_CLK_CTRL_DMA2, @@ -131,7 +131,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { .name = "sspp_11", .id = SSPP_DMA3, .base = 0x2a000, .len = 0x1ac, .features = DMA_CURSOR_MSM8998_MASK, - .sblk = &sdm845_dma_sblk_3, + .sblk = &dpu_dma_sblk, .xin_id = 13, .type = SSPP_TYPE_DMA, .clk_ctrl = DPU_CLK_CTRL_DMA3, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h b/drivers/gpu/drm/msm/dis
[PATCH 4/7] drm/msm/dpu: drop the `smart_dma_priority' field from struct dpu_sspp_sub_blks
In preparation to deduplicating SSPP subblocks, drop the (unused) `smart_dma_priority' field from struct dpu_sspp_sub_blks. If it is needed later (e.g. for SmartDMA v1), it should be added to the SSPP declarations themselves. Signed-off-by: Dmitry Baryshkov --- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 66 +-- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h| 2 - 2 files changed, 31 insertions(+), 37 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 2c101d4d243c..33cc56d3bbfe 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -248,11 +248,10 @@ static const uint32_t wb2_formats[] = { */ /* SSPP common configuration */ -#define _VIG_SBLK(sdma_pri, qseed_ver) \ +#define _VIG_SBLK(qseed_ver) \ { \ .maxdwnscale = MAX_DOWNSCALE_RATIO, \ .maxupscale = MAX_UPSCALE_RATIO, \ - .smart_dma_priority = sdma_pri, \ .scaler_blk = { \ .base = 0xa00, .len = 0xa0,}, \ .csc_blk = { \ @@ -264,11 +263,10 @@ static const uint32_t wb2_formats[] = { .rotation_cfg = NULL, \ } -#define _VIG_SBLK_ROT(sdma_pri, qseed_ver, rot_cfg) \ +#define _VIG_SBLK_ROT(qseed_ver, rot_cfg) \ { \ .maxdwnscale = MAX_DOWNSCALE_RATIO, \ .maxupscale = MAX_UPSCALE_RATIO, \ - .smart_dma_priority = sdma_pri, \ .scaler_blk = { \ .base = 0xa00, .len = 0xa0,}, \ .csc_blk = { \ @@ -280,11 +278,10 @@ static const uint32_t wb2_formats[] = { .rotation_cfg = rot_cfg, \ } -#define _DMA_SBLK(sdma_pri) \ +#define _DMA_SBLK \ { \ .maxdwnscale = SSPP_UNITY_SCALE, \ .maxupscale = SSPP_UNITY_SCALE, \ - .smart_dma_priority = sdma_pri, \ .format_list = plane_formats, \ .num_formats = ARRAY_SIZE(plane_formats), \ .virt_format_list = plane_formats, \ @@ -292,13 +289,13 @@ static const uint32_t wb2_formats[] = { } static const struct dpu_sspp_sub_blks msm8998_vig_sblk_0 = - _VIG_SBLK(0, DPU_SSPP_SCALER_QSEED3); + _VIG_SBLK(DPU_SSPP_SCALER_QSEED3); static const struct dpu_sspp_sub_blks msm8998_vig_sblk_1 = - _VIG_SBLK(0, DPU_SSPP_SCALER_QSEED3); + _VIG_SBLK(DPU_SSPP_SCALER_QSEED3); static const struct dpu_sspp_sub_blks msm8998_vig_sblk_2 = - _VIG_SBLK(0, DPU_SSPP_SCALER_QSEED3); + _VIG_SBLK(DPU_SSPP_SCALER_QSEED3); static const struct dpu_sspp_sub_blks msm8998_vig_sblk_3 = - _VIG_SBLK(0, DPU_SSPP_SCALER_QSEED3); + _VIG_SBLK(DPU_SSPP_SCALER_QSEED3); static const struct dpu_rotation_cfg dpu_rot_sc7280_cfg_v2 = { .rot_maxheight = 1088, @@ -307,61 +304,60 @@ static const struct dpu_rotation_cfg dpu_rot_sc7280_cfg_v2 = { }; static const struct dpu_sspp_sub_blks sdm845_vig_sblk_0 = - _VIG_SBLK(5, DPU_SSPP_SCALER_QSEED3); + _VIG_SBLK(DPU_SSPP_SCALER_QSEED3); static const struct dpu_sspp_sub_blks sdm845_vig_sblk_1 = - _VIG_SBLK(6, DPU_SSPP_SCALER_QSEED3); + _VIG_SBLK(DPU_SSPP_SCALER_QSEED3); static const struct dpu_sspp_sub_blks sdm845_vig_sblk_2 = - _VIG_SBLK(7, DPU_SSPP_SCALER_QSEED3); + _VIG_SBLK(DPU_SSPP_SCALER_QSEED3); static const struct dpu_sspp_sub_blks sdm845_vig_sblk_3 = - _VIG_SBLK(8, DPU_SSPP_SCALER_QSEED3); + _VIG_SBLK(DPU_SSPP_SCALER_QSEED3); -static const struct dpu_sspp_sub_blks sdm845_dma_sblk_0 = _DMA_SBLK(1); -static const struct dpu_sspp_sub_blks sdm845_dma_sblk_1 = _DMA_SBLK(2); -static const struct dpu_sspp_sub_blks sdm845_dma_sblk_2 = _DMA_SBLK(3); -static const struct dpu_sspp_sub_blks sdm845_dma_sblk_3 = _DMA_SBLK(4); +static const struct dpu_sspp_sub_blks sdm845_dma_sblk_0 = _DMA_SBLK; +static const struct dpu_sspp_sub_blks sdm845_dma_sblk_1 = _DMA_SBLK; +static const struct dpu_sspp_sub_blks sdm845_dma_sblk_2 = _DMA_SBLK; +static const struct dpu_sspp_sub_blks sdm845_dma_sblk_3 = _DMA_SBLK; static const struct dpu_sspp_sub_blks sc7180_vig_sblk_0 = - _VIG_SBLK(4, DPU_SSPP_SCALER_QSEED4); + _VIG_SBLK(DPU_SSPP_SCALER_QSEED4); static const struct dpu_sspp_sub_blks sc7280_vig_sblk_0 = - _VIG_SBLK_ROT(4, DPU_SSPP_SCALER_QSEED4, &dpu_rot_sc7280_cfg_v2); + _VIG_SBLK_ROT(DPU_SSPP_SCALER_QSEED4, &dpu_rot_sc7280_cfg_v2); static const struct dpu_sspp_sub_blks sm6115_vig_sblk_0 = - _
[PATCH 1/7] drm/msm/dpu: drop the `id' field from DPU_HW_SUBBLK_INFO
The field `id' is not used for subblocks. The handling code usually knows, which sub-block it is now looking at. Drop the field completely. Signed-off-by: Dmitry Baryshkov --- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 24 ++- .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h| 2 -- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 3efa22429e5f..4a99144a5a85 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -254,10 +254,8 @@ static const uint32_t wb2_formats[] = { .maxupscale = MAX_UPSCALE_RATIO, \ .smart_dma_priority = sdma_pri, \ .scaler_blk = {.name = STRCAT("sspp_scaler", num), \ - .id = qseed_ver, \ .base = 0xa00, .len = 0xa0,}, \ .csc_blk = {.name = STRCAT("sspp_csc", num), \ - .id = DPU_SSPP_CSC_10BIT, \ .base = 0x1a00, .len = 0x100,}, \ .format_list = plane_formats_yuv, \ .num_formats = ARRAY_SIZE(plane_formats_yuv), \ @@ -272,10 +270,8 @@ static const uint32_t wb2_formats[] = { .maxupscale = MAX_UPSCALE_RATIO, \ .smart_dma_priority = sdma_pri, \ .scaler_blk = {.name = STRCAT("sspp_scaler", num), \ - .id = qseed_ver, \ .base = 0xa00, .len = 0xa0,}, \ .csc_blk = {.name = STRCAT("sspp_csc", num), \ - .id = DPU_SSPP_CSC_10BIT, \ .base = 0x1a00, .len = 0x100,}, \ .format_list = plane_formats_yuv, \ .num_formats = ARRAY_SIZE(plane_formats_yuv), \ @@ -417,12 +413,14 @@ static const struct dpu_lm_sub_blks qcm2290_lm_sblk = { * DSPP sub blocks config */ static const struct dpu_dspp_sub_blks msm8998_dspp_sblk = { - .pcc = {.id = DPU_DSPP_PCC, .base = 0x1700, + .pcc = { + .base = 0x1700, .len = 0x90, .version = 0x10007}, }; static const struct dpu_dspp_sub_blks sm8150_dspp_sblk = { - .pcc = {.id = DPU_DSPP_PCC, .base = 0x1700, + .pcc = { + .base = 0x1700, .len = 0x90, .version = 0x4}, }; @@ -430,20 +428,24 @@ static const struct dpu_dspp_sub_blks sm8150_dspp_sblk = { * PINGPONG sub blocks config */ static const struct dpu_pingpong_sub_blks sdm845_pp_sblk_te = { - .te2 = {.id = DPU_PINGPONG_TE2, .base = 0x2000, .len = 0x0, + .te2 = { + .base = 0x2000, .len = 0x0, .version = 0x1}, - .dither = {.id = DPU_PINGPONG_DITHER, .base = 0x30e0, + .dither = { + .base = 0x30e0, .len = 0x20, .version = 0x1}, }; static const struct dpu_pingpong_sub_blks sdm845_pp_sblk = { - .dither = {.id = DPU_PINGPONG_DITHER, .base = 0x30e0, + .dither = { + .base = 0x30e0, .len = 0x20, .version = 0x1}, }; static const struct dpu_pingpong_sub_blks sc7280_pp_sblk = { - .dither = {.id = DPU_PINGPONG_DITHER, .base = 0xe0, - .len = 0x20, .version = 0x2}, + .dither = { + .base = 0xe0, + .len = 0x20, .version = 0x2}, }; /* diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h index 3b816e36d12d..bf7a525206ee 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -274,14 +274,12 @@ enum { /** * MACRO DPU_HW_SUBBLK_INFO - information of HW sub-block inside DPU * @name: string name for debug purposes - * @id:enum identifying this sub-block * @base: offset of this sub-block relative to the block * offset * @lenregister block length of this sub-block */ #define DPU_HW_SUBBLK_INFO \ char name[DPU_HW_BLK_NAME_LEN]; \ - u32 id; \ u32 base; \ u32 len -- 2.39.2
Re: [PATCH] drm/ttm: fix warning that we shouldn't mix && and ||
On Fri, Jun 23, 2023 at 3:09 AM Christian König wrote: > > Trivial warning fix. > > Signed-off-by: Christian König > Fixes: 4481913607e5 ("drm/ttm: fix bulk_move corruption when adding a entry") Reviewed-by: Alex Deucher > --- > drivers/gpu/drm/ttm/ttm_resource.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/ttm/ttm_resource.c > b/drivers/gpu/drm/ttm/ttm_resource.c > index e51dbc7a2d53..46ff9c75bb12 100644 > --- a/drivers/gpu/drm/ttm/ttm_resource.c > +++ b/drivers/gpu/drm/ttm/ttm_resource.c > @@ -114,7 +114,7 @@ static void ttm_lru_bulk_move_del(struct > ttm_lru_bulk_move *bulk, > struct ttm_lru_bulk_move_pos *pos = ttm_lru_bulk_move_pos(bulk, res); > > if (unlikely(WARN_ON(!pos->first || !pos->last) || > -pos->first == res && pos->last == res)) { > +(pos->first == res && pos->last == res))) { > pos->first = NULL; > pos->last = NULL; > } else if (pos->first == res) { > -- > 2.34.1 >
Re: [PATCH v3 9/9] drm/mediatek: dp: Add support for embedded DisplayPort aux-bus
On Tue, Apr 04, 2023 at 12:48:00PM +0200, AngeloGioacchino Del Regno wrote: > For the eDP case we can support using aux-bus on MediaTek DP: this > gives us the possibility to declare our panel as generic "panel-edp" > which will automatically configure the timings and available modes > via the EDID that we read from it. > > To do this, move the panel parsing at the end of the probe function > so that the hardware is initialized beforehand and also initialize > the DPTX AUX block and power both on as, when we populate the > aux-bus, the panel driver will trigger an EDID read to perform > panel detection. > > Last but not least, since now the AUX transfers can happen in the > separated aux-bus, it was necessary to add an exclusion for the > cable_plugged_in check in `mtk_dp_aux_transfer()` and the easiest > way to do this is to simply ignore checking that when the bridge > type is eDP. > > Signed-off-by: AngeloGioacchino Del Regno > > --- > drivers/gpu/drm/mediatek/mtk_dp.c | 61 ++- > 1 file changed, 51 insertions(+), 10 deletions(-) > > diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c > b/drivers/gpu/drm/mediatek/mtk_dp.c > index a67143c22024..8109f5b4392b 100644 > --- a/drivers/gpu/drm/mediatek/mtk_dp.c > +++ b/drivers/gpu/drm/mediatek/mtk_dp.c [..] > @@ -2571,6 +2585,33 @@ static int mtk_dp_probe(struct platform_device *pdev) > mtk_dp->need_debounce = true; > timer_setup(&mtk_dp->debounce_timer, mtk_dp_debounce_timer, 0); > > + if (mtk_dp->bridge.type == DRM_MODE_CONNECTOR_eDP) { > + /* Initialize, reset and poweron the DPTX AUX block */ > + mtk_dp_initialize_aux_settings(mtk_dp); > + mtk_dp_power_enable(mtk_dp); > + > + /* Power on the panel to allow EDID read from aux-bus */ > + mtk_dp_aux_panel_poweron(mtk_dp, true); > + > + ret = devm_of_dp_aux_populate_bus(&mtk_dp->aux, NULL); This patch causes .../bin/aarch64-none-linux-gnu-ld: Unexpected GOT/PLT entries detected! .../bin/aarch64-none-linux-gnu-ld: Unexpected run-time procedure linkages detected! .../bin/aarch64-none-linux-gnu-ld: drivers/gpu/drm/mediatek/mtk_dp.o: in function `mtk_dp_probe': .../drivers/gpu/drm/mediatek/mtk_dp.c:2595: undefined reference to `devm_of_dp_aux_populate_bus' You need diff --git a/drivers/gpu/drm/mediatek/Kconfig b/drivers/gpu/drm/mediatek/Kconfig index b451dee64d34..76cab28e010c 100644 --- a/drivers/gpu/drm/mediatek/Kconfig +++ b/drivers/gpu/drm/mediatek/Kconfig @@ -26,6 +26,7 @@ config DRM_MEDIATEK_DP select PHY_MTK_DP select DRM_DISPLAY_HELPER select DRM_DISPLAY_DP_HELPER + select DRM_DP_AUX_BUS help DRM/KMS Display Port driver for MediaTek SoCs. Thanks, Nícolas
Re: [PATCH 0/3] MediaTek DRM: Clean up CMDQ support and ifdefs
On 23/06/2023 11:49, AngeloGioacchino Del Regno wrote: This series changes MediaTek CMDQ support to use the mtk-cmdq-helper functions, removing duplicated cmdq setup code in mtk-drm and also removing all instances of `#if IS_REACHABLE(CONFIG_MTK_CMDQ)` while keeping compatibility with both CONFIG_MTK_CMDQ=n and =m/=y. This applies on top of [1] and [2]. [1]:https://lore.kernel.org/lkml/20230524093412.92211-1-angelogioacchino.delre...@collabora.com [2]:https://lore.kernel.org/lkml/20230608084727.74403-1-angelogioacchino.delre...@collabora.com Hi Angelo, Can you provide a public branch to test it please ? I tried to apply the dependencies but still have an issue with the 3rd one: https://lore.kernel.org/lkml/20230523104234.7849-1-angelogioacchino.delre...@collabora.com OK https://lore.kernel.org/lkml/20230524093412.92211-1-angelogioacchino.delre...@collabora.com OK https://lore.kernel.org/lkml/20230608084727.74403-1-angelogioacchino.delre...@collabora.com KO Thanks -- Regards, Alexandre
Re: [PATCH v10 07/11] drm/etnaviv: Add support for the dma coherent device
Hi, On 2023/6/23 19:52, Robin Murphy wrote: On 2023-06-20 10:47, Sui Jingfeng wrote: From: Sui Jingfeng Loongson CPUs maintain cache coherency by hardware, which means that the data in the CPU cache is identical to the data in main system memory. As for the peripheral device, most of Loongson chips chose to define the peripherals as DMA coherent by default, device drivers do not need to maintain the coherency between a processor and an I/O device manually. There are exceptions, for LS2K1000 SoC, part of peripheral device can be configured as DMA non-coherent. But there is no released version of such firmware exist in the market. Peripherals of older LS2K1000 is also DMA non-coherent, but they are nearly outdated. So, those are trivial cases. Nevertheless, kernel space still need to do the probe work, because vivante GPU IP has been integrated into various platform. Hence, this patch add runtime detection code to probe if a specific GPU is DMA coherent, If the answer is yes, we are going to utilize such features. On Loongson platform, When a buffer is accessed by both the GPU and the CPU, the driver should prefer ETNA_BO_CACHED over ETNA_BO_WC. This patch also add a new parameter: etnaviv_param_gpu_coherent, which allow userspace to know if such a feature is available. Because write-combined BO is still preferred in some case, especially where don't need CPU read, for example, uploading compiled shader bin. Cc: Lucas Stach Cc: Christian Gmeiner Cc: Philipp Zabel Cc: Bjorn Helgaas Cc: Daniel Vetter Signed-off-by: Sui Jingfeng --- drivers/gpu/drm/etnaviv/etnaviv_drv.c | 35 + drivers/gpu/drm/etnaviv/etnaviv_drv.h | 6 drivers/gpu/drm/etnaviv/etnaviv_gem.c | 22 ++--- drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c | 7 - drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 4 +++ include/uapi/drm/etnaviv_drm.h | 1 + 6 files changed, 70 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index 0a365e96d371..d8e788aa16cb 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -5,7 +5,9 @@ #include #include +#include /* * This header is for implementations of dma_map_ops and related code. * It should not be included in drivers just using the DMA API. */ 1) The driver can not pass the compile, without include the linux/dma-map-ops.h You may be right, but Lucas suggest using dev_is_dma_coherent() function. because the dev_is_dma_coherent() function is defined in dma-map-ops.h. for our platform its: ``` static inline bool dev_is_dma_coherent(struct device *dev) { return true; } ``` 2. drm/exynos and drm/msm also include this handler ``` $ cd drivers/gpu/drm $ find . -name "*.c" -type f | xargs grep "dma-map-ops.h" ./exynos/exynos_drm_dma.c:#include ./msm/msm_gem.c:#include ``` #include +#include #include #include @@ -24,6 +26,34 @@ #include "etnaviv_pci_drv.h" #include "etnaviv_perfmon.h" +static struct device_node *etnaviv_of_first_available_node(void) +{ + struct device_node *core_node; + + for_each_compatible_node(core_node, NULL, "vivante,gc") { + if (of_device_is_available(core_node)) + return core_node; + } + + return NULL; +} + +static bool etnaviv_is_dma_coherent(struct device *dev) +{ + struct device_node *np; + bool coherent; + + np = etnaviv_of_first_available_node(); + if (np) { + coherent = of_dma_is_coherent(np); + of_node_put(np); + } else { + coherent = dev_is_dma_coherent(dev); + } Please use device_get_dma_attr() like other well-behaved drivers. OK, I agree with you. ``` priv->dma_coherent = device_get_dma_attr(&pdev->dev) == DEV_DMA_COHERENT; ``` Lucas, Is above code Snippet looks fine to you? + + return coherent; +} + /* * etnaviv private data construction and destructions: */ @@ -52,6 +82,11 @@ etnaviv_alloc_private(struct device *dev, struct drm_device *drm) return ERR_PTR(-ENOMEM); } + priv->dma_coherent = etnaviv_is_dma_coherent(dev); + + if (priv->dma_coherent) + drm_info(drm, "%s is dma coherent\n", dev_name(dev)); I'm pretty sure the end-user doesn't care. OK, i will delete it at the next version. + return priv; } diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.h b/drivers/gpu/drm/etnaviv/etnaviv_drv.h index 9cd72948cfad..644e5712c050 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.h @@ -46,6 +46,12 @@ struct etnaviv_drm_private { struct xarray active_contexts; u32 next_context_id; + /* + * If true, the GPU is capable of snooping cpu cache. Here, it + * also means that cache coherency is enforced by the hardware. + */ + bool dma_coherent; + /* list of GEM objects: */ struct mutex gem_lock;
[PATCH v2 3/3] dt-bindings: display: msm: sm8550-mdss: document displayport controller subnode
Document the optional displayport controller subnode of the SM8550 MDSS. Acked-by: Rob Herring Signed-off-by: Neil Armstrong --- .../devicetree/bindings/display/msm/qcom,sm8550-mdss.yaml | 8 1 file changed, 8 insertions(+) diff --git a/Documentation/devicetree/bindings/display/msm/qcom,sm8550-mdss.yaml b/Documentation/devicetree/bindings/display/msm/qcom,sm8550-mdss.yaml index 887be33ba108..70ce7cb7a80d 100644 --- a/Documentation/devicetree/bindings/display/msm/qcom,sm8550-mdss.yaml +++ b/Documentation/devicetree/bindings/display/msm/qcom,sm8550-mdss.yaml @@ -42,6 +42,14 @@ patternProperties: compatible: const: qcom,sm8550-dpu + "^displayport-controller@[0-9a-f]+$": +type: object +properties: + compatible: +items: + - const: qcom,sm8550-dp + - const: qcom,sm8350-dp + "^dsi@[0-9a-f]+$": type: object properties: -- 2.34.1
[PATCH v2 1/3] dt-bindings: display: msm: sm8350-mdss: document displayport controller subnode
Document the optional displayport controller subnode of the SM8350 MDSS. Acked-by: Rob Herring Signed-off-by: Neil Armstrong --- Documentation/devicetree/bindings/display/msm/qcom,sm8350-mdss.yaml | 6 ++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/display/msm/qcom,sm8350-mdss.yaml b/Documentation/devicetree/bindings/display/msm/qcom,sm8350-mdss.yaml index 79a226e4cc6a..f2cbeb435f1b 100644 --- a/Documentation/devicetree/bindings/display/msm/qcom,sm8350-mdss.yaml +++ b/Documentation/devicetree/bindings/display/msm/qcom,sm8350-mdss.yaml @@ -52,6 +52,12 @@ patternProperties: compatible: const: qcom,sm8350-dpu + "^displayport-controller@[0-9a-f]+$": +type: object +properties: + compatible: +const: qcom,sm8350-dp + "^dsi@[0-9a-f]+$": type: object properties: -- 2.34.1
[PATCH v2 0/3] dt-bindings: display: msm: document the SM8[345]50 displayport MDSS subnode
Document the displayport subnode to fix the bindings check error: arch/arm64/boot/dts/qcom/sm8550-mtp.dtb: display-subsystem@ae0: Unevaluated properties are not allowed ('displayport-controller@ae9' was unexpected) From schema: Documentation/devicetree/bindings/display/msm/qcom,sm8550-mdss.yaml And same for SM8350 and SM8450. Signed-off-by: Neil Armstrong --- Changes in v2: - Removed duplicate "document" in commit messages - Added review trailers - Link to v1: https://lore.kernel.org/r/20230621-topic-sm8x50-upstream-mdss-bindings-dp-subnode-v1-0-8bf386b37...@linaro.org --- Neil Armstrong (3): dt-bindings: display: msm: sm8350-mdss: document displayport controller subnode dt-bindings: display: msm: sm8450-mdss: document displayport controller subnode dt-bindings: display: msm: sm8550-mdss: document displayport controller subnode .../devicetree/bindings/display/msm/qcom,sm8350-mdss.yaml | 6 ++ .../devicetree/bindings/display/msm/qcom,sm8450-mdss.yaml | 8 .../devicetree/bindings/display/msm/qcom,sm8550-mdss.yaml | 8 3 files changed, 22 insertions(+) --- base-commit: 15e71592dbae49a674429c618a10401d7f992ac3 change-id: 20230621-topic-sm8x50-upstream-mdss-bindings-dp-subnode-4fe367bf5cbe Best regards, -- Neil Armstrong
[PATCH v2 2/3] dt-bindings: display: msm: sm8450-mdss: document displayport controller subnode
Document the optional displayport controller subnode of the SM8450 MDSS. Acked-by: Rob Herring Signed-off-by: Neil Armstrong --- .../devicetree/bindings/display/msm/qcom,sm8450-mdss.yaml | 8 1 file changed, 8 insertions(+) diff --git a/Documentation/devicetree/bindings/display/msm/qcom,sm8450-mdss.yaml b/Documentation/devicetree/bindings/display/msm/qcom,sm8450-mdss.yaml index f26eb5643aed..494e2a080e99 100644 --- a/Documentation/devicetree/bindings/display/msm/qcom,sm8450-mdss.yaml +++ b/Documentation/devicetree/bindings/display/msm/qcom,sm8450-mdss.yaml @@ -42,6 +42,14 @@ patternProperties: compatible: const: qcom,sm8450-dpu + "^displayport-controller@[0-9a-f]+$": +type: object +properties: + compatible: +items: + - const: qcom,sm8450-dp + - const: qcom,sm8350-dp + "^dsi@[0-9a-f]+$": type: object properties: -- 2.34.1
Re: [PATCH] drm/amd/amdgpu: Properly tune the size of struct
Hi Su, kernel test robot noticed the following build warnings: [auto build test WARNING on drm-misc/drm-misc-next] [also build test WARNING on linus/master v6.4-rc7 next-20230623] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Su-Hui/drm-amd-amdgpu-Properly-tune-the-size-of-struct/20230620-130013 base: git://anongit.freedesktop.org/drm/drm-misc drm-misc-next patch link: https://lore.kernel.org/r/20230620045919.492128-1-suhui%40nfschina.com patch subject: [PATCH] drm/amd/amdgpu: Properly tune the size of struct config: riscv-randconfig-s032-20230622 (https://download.01.org/0day-ci/archive/20230623/202306232056.uocmpruz-...@intel.com/config) compiler: riscv64-linux-gcc (GCC) 12.3.0 reproduce: (https://download.01.org/0day-ci/archive/20230623/202306232056.uocmpruz-...@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot | Closes: https://lore.kernel.org/oe-kbuild-all/202306232056.uocmpruz-...@intel.com/ sparse warnings: (new ones prefixed by >>) drivers/gpu/drm/amd/amdgpu/../display/dc/bios/command_table.c:914:43: sparse: expected unsigned int [addressable] [assigned] [usertype] ulSymClock drivers/gpu/drm/amd/amdgpu/../display/dc/bios/command_table.c:914:43: sparse: got restricted __le16 [usertype] drivers/gpu/drm/amd/amdgpu/../display/dc/bios/command_table.c:991:40: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned short [addressable] [assigned] [usertype] usRefDiv @@ got restricted __le16 [usertype] @@ drivers/gpu/drm/amd/amdgpu/../display/dc/bios/command_table.c:991:40: sparse: expected unsigned short [addressable] [assigned] [usertype] usRefDiv drivers/gpu/drm/amd/amdgpu/../display/dc/bios/command_table.c:991:40: sparse: got restricted __le16 [usertype] drivers/gpu/drm/amd/amdgpu/../display/dc/bios/command_table.c:993:39: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned short [addressable] [assigned] [usertype] usFbDiv @@ got restricted __le16 [usertype] @@ drivers/gpu/drm/amd/amdgpu/../display/dc/bios/command_table.c:993:39: sparse: expected unsigned short [addressable] [assigned] [usertype] usFbDiv drivers/gpu/drm/amd/amdgpu/../display/dc/bios/command_table.c:993:39: sparse: got restricted __le16 [usertype] drivers/gpu/drm/amd/amdgpu/../display/dc/bios/command_table.c:1001:44: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned short [addressable] [assigned] [usertype] usPixelClock @@ got restricted __le16 [usertype] @@ drivers/gpu/drm/amd/amdgpu/../display/dc/bios/command_table.c:1001:44: sparse: expected unsigned short [addressable] [assigned] [usertype] usPixelClock drivers/gpu/drm/amd/amdgpu/../display/dc/bios/command_table.c:1001:44: sparse: got restricted __le16 [usertype] drivers/gpu/drm/amd/amdgpu/../display/dc/bios/command_table.c:1064:40: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned short [addressable] [assigned] [usertype] usFbDiv @@ got restricted __le16 [usertype] @@ drivers/gpu/drm/amd/amdgpu/../display/dc/bios/command_table.c:1064:40: sparse: expected unsigned short [addressable] [assigned] [usertype] usFbDiv drivers/gpu/drm/amd/amdgpu/../display/dc/bios/command_table.c:1064:40: sparse: got restricted __le16 [usertype] drivers/gpu/drm/amd/amdgpu/../display/dc/bios/command_table.c:1066:47: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned int [addressable] [assigned] [usertype] ulFbDivDecFrac @@ got restricted __le32 [usertype] @@ drivers/gpu/drm/amd/amdgpu/../display/dc/bios/command_table.c:1066:47: sparse: expected unsigned int [addressable] [assigned] [usertype] ulFbDivDecFrac drivers/gpu/drm/amd/amdgpu/../display/dc/bios/command_table.c:1066:47: sparse: got restricted __le32 [usertype] drivers/gpu/drm/amd/amdgpu/../display/dc/bios/command_table.c:1079:45: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned short [addressable] [assigned] [usertype] usPixelClock @@ got restricted __le16 [usertype] @@ drivers/gpu/drm/amd/amdgpu/../display/dc/bios/command_table.c:1079:45: sparse: expected unsigned short [addressable] [assigned] [usertype] usPixelClock drivers/gpu/drm/amd/amdgpu/../display/dc/bios/command_table.c:1079:45: sparse: got restricted __le16 [usertype] drivers/gpu/drm/amd/amdgpu/../display/dc/bios/command_table.c:1153:40: sparse: sparse: incorrect type in assignment (diff
Re: [PATCH v10 07/11] drm/etnaviv: Add support for the dma coherent device
On 2023-06-20 10:47, Sui Jingfeng wrote: From: Sui Jingfeng Loongson CPUs maintain cache coherency by hardware, which means that the data in the CPU cache is identical to the data in main system memory. As for the peripheral device, most of Loongson chips chose to define the peripherals as DMA coherent by default, device drivers do not need to maintain the coherency between a processor and an I/O device manually. There are exceptions, for LS2K1000 SoC, part of peripheral device can be configured as DMA non-coherent. But there is no released version of such firmware exist in the market. Peripherals of older LS2K1000 is also DMA non-coherent, but they are nearly outdated. So, those are trivial cases. Nevertheless, kernel space still need to do the probe work, because vivante GPU IP has been integrated into various platform. Hence, this patch add runtime detection code to probe if a specific GPU is DMA coherent, If the answer is yes, we are going to utilize such features. On Loongson platform, When a buffer is accessed by both the GPU and the CPU, the driver should prefer ETNA_BO_CACHED over ETNA_BO_WC. This patch also add a new parameter: etnaviv_param_gpu_coherent, which allow userspace to know if such a feature is available. Because write-combined BO is still preferred in some case, especially where don't need CPU read, for example, uploading compiled shader bin. Cc: Lucas Stach Cc: Christian Gmeiner Cc: Philipp Zabel Cc: Bjorn Helgaas Cc: Daniel Vetter Signed-off-by: Sui Jingfeng --- drivers/gpu/drm/etnaviv/etnaviv_drv.c | 35 + drivers/gpu/drm/etnaviv/etnaviv_drv.h | 6 drivers/gpu/drm/etnaviv/etnaviv_gem.c | 22 ++--- drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c | 7 - drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 4 +++ include/uapi/drm/etnaviv_drm.h | 1 + 6 files changed, 70 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index 0a365e96d371..d8e788aa16cb 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -5,7 +5,9 @@ #include #include +#include /* * This header is for implementations of dma_map_ops and related code. * It should not be included in drivers just using the DMA API. */ #include +#include #include #include @@ -24,6 +26,34 @@ #include "etnaviv_pci_drv.h" #include "etnaviv_perfmon.h" +static struct device_node *etnaviv_of_first_available_node(void) +{ + struct device_node *core_node; + + for_each_compatible_node(core_node, NULL, "vivante,gc") { + if (of_device_is_available(core_node)) + return core_node; + } + + return NULL; +} + +static bool etnaviv_is_dma_coherent(struct device *dev) +{ + struct device_node *np; + bool coherent; + + np = etnaviv_of_first_available_node(); + if (np) { + coherent = of_dma_is_coherent(np); + of_node_put(np); + } else { + coherent = dev_is_dma_coherent(dev); + } Please use device_get_dma_attr() like other well-behaved drivers. + + return coherent; +} + /* * etnaviv private data construction and destructions: */ @@ -52,6 +82,11 @@ etnaviv_alloc_private(struct device *dev, struct drm_device *drm) return ERR_PTR(-ENOMEM); } + priv->dma_coherent = etnaviv_is_dma_coherent(dev); + + if (priv->dma_coherent) + drm_info(drm, "%s is dma coherent\n", dev_name(dev)); I'm pretty sure the end-user doesn't care. + return priv; } diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.h b/drivers/gpu/drm/etnaviv/etnaviv_drv.h index 9cd72948cfad..644e5712c050 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.h @@ -46,6 +46,12 @@ struct etnaviv_drm_private { struct xarray active_contexts; u32 next_context_id; + /* +* If true, the GPU is capable of snooping cpu cache. Here, it +* also means that cache coherency is enforced by the hardware. +*/ + bool dma_coherent; + /* list of GEM objects: */ struct mutex gem_lock; struct list_head gem_list; diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c index b5f73502e3dd..39bdc3774f2d 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c @@ -343,6 +343,7 @@ void *etnaviv_gem_vmap(struct drm_gem_object *obj) static void *etnaviv_gem_vmap_impl(struct etnaviv_gem_object *obj) { struct page **pages; + pgprot_t prot; lockdep_assert_held(&obj->lock); @@ -350,8 +351,19 @@ static void *etnaviv_gem_vmap_impl(struct etnaviv_gem_object *obj) if (IS_ERR(pages)) return NULL; - return vmap(pages, obj->base.size >> PAGE_SHIFT, -
Re: [PATCH 1/2] drm/msm/dpu: fix DSC 1.2 block lengths
On 23/06/2023 09:54, Marijn Suijten wrote: On 2023-06-22 22:47:04, Abhinav Kumar wrote: On 6/22/2023 6:37 PM, Dmitry Baryshkov wrote: All DSC_BLK_1_2 declarations incorrectly pass 0x29c as the block length. This includes the common block itself, enc subblocks and some empty space around. Change that to pass 0x4 instead, the length of common register block itself. Fixes: 0d1b10c63346 ("drm/msm/dpu: add DSC 1.2 hw blocks for relevant chipsets") Signed-off-by: Dmitry Baryshkov There is no need of a fixes tag for this. This is not a bug but was intentional. Till we added sub-block parsing support we had to dump the whole block. And hence I would suggest this change should be merged after the sub-block parsing change otherwise we wont have full register dumps for DSC. This was indeed intentional, we discussed it in [1]. In fact I asked to make it 0xf00 + 0x10 or 0xf80 + 0x10 to also cover the CTL registers, but that change didn't make it through. 0x29c is an arbitrary number that I have no clue what it was based on. This should have been NAKed. or at least TODOed. [1]: https://lore.kernel.org/linux-arm-msm/y2whfntyo2rbrg3taazjdw5sijle6k6swzl4uutcxm6tmuayh4@uxdur74uasua/ - Marijn -- With best wishes Dmitry
Re: [PATCH v2 1/2] dt-bindings: backlight: document new property default-brightness-level
On Fri, Jun 23, 2023 at 10:19:57AM +0300, Alexandru Ardelean wrote: > On Thu, Jun 22, 2023 at 5:13 AM Rob Herring wrote: > > > +++ b/Documentation/devicetree/bindings/leds/backlight/gpio-backlight.yaml > > >default-on: > > > -description: enable the backlight at boot. > > > +description: > > > + The default power state of the backlight at boot. > > > type: boolean > > > > > > + default-brightness-level: > > > +description: > > > + The default brightness level on device init. The value can be 0 or > > > 1. > > > + If omitted, the value is 1. In the context of the "gpio-backlight" > > > driver > > > + the effect of this setting will be that the backlight is on/off. > > > + The difference between this setting and "default-on" is that this > > > handles > > > + brightness, while "default-on" handles the power setting of the > > > device. > > > > What power setting? You only have 1 GPIO to control here which is 2 > > states. There are at least three states: On/Off/HiZ . Currently the DT description isn't acually rich enough to allow drivers to safely use the HiZ state so that is not why this change is potentially useful today (but does illustrate why it is not "wrong" to put it on the h/ware description). > > I fail to see why you need 6 possible states with all the > > combinations of 2 properties. > > So, the "default-on" bool gets converted to backlight power settings, > which eventually gets converted back to GPIO values (at some point). > Which sounds quirky (when saying/writing it). Modern DT practice is to for the display to link to backlight. This gives display control over power state (so backlight automatically follows the display power state). On such systems the backlight will be turned "on" when the display hardware comes up (regardless of whether or not default-on is set). Thus this control covers the case where we have a display that is readable when the GPIO is off (e.g. transflexive LCD or epaper). A display that is readable with the GPIO off means the default brightness brightness at boot can meaningfully be zero. In this case the backlight is nominally on but the GPIO is off. In short, this becomes part of the hardware description, rather than merely being a driver feature, due to the effect of linking display to backlight in the DT. Note also that most backlights do expose on/off via DT for the same reasons (when the off and zero states both result in the backlight output pin doing physically the same thing). > But, yeah. > That's one thing that also made me a bit undecided to send this. > On the one hand I like the uniformity it brings. > On the other hand, because there is the legacy behavior (the > "default-on" property, and the fact that we can use the GPIO DT > settings to control this) just explodes complexity/quirks. > > We can probably just drop this. > I'll also admit that my doc-writing skills aren't too great. It may be potentially useful for people building kit with sunlight readable displays and trivial backlights as a backup in the dark. Of course if the pin the backlight is connected to is PWM capable then the PWM backlight is probably a better bet ;-) . Daniel.
Re: [PATCH] drm: mediatek: mtk_dsi: Fix NO_EOT_PACKET settings/handling
On 23/06/2023 11:47, AngeloGioacchino Del Regno wrote: Il 23/05/23 12:42, AngeloGioacchino Del Regno ha scritto: Due to the initial confusion about MIPI_DSI_MODE_EOT_PACKET, properly renamed to MIPI_DSI_MODE_NO_EOT_PACKET, reflecting its actual meaning, both the DSI_TXRX_CON register setting for bit (HSTX_)DIS_EOT and the later calculation for horizontal sync-active (HSA), back (HBP) and front (HFP) porches got incorrect due to the logic being inverted. This means that a number of settings were wrong because: - DSI_TXRX_CON register setting: bit (HSTX_)DIS_EOT should be set in order to disable the End of Transmission packet; - Horizontal Sync and Back/Front porches: The delta used to calculate all of HSA, HBP and HFP should account for the additional EOT packet. Before this change... - Bit (HSTX_)DIS_EOT was being set when EOT packet was enabled; - For HSA/HBP/HFP delta... all three were wrong, as words were added when EOT disabled, instead of when EOT packet enabled! Invert the logic around flag MIPI_DSI_MODE_NO_EOT_PACKET in the MediaTek DSI driver to fix the aforementioned issues. Fixes: 8b2b99fd7931 ("drm/mediatek: dsi: Fine tune the line time caused by EOTp") Fixes: 2d52bfba09d1 ("drm/mediatek: add non-continuous clock mode and EOT packet control") Signed-off-by: AngeloGioacchino Del Regno Gentle ping for an important fix. Regards, Angelo --- drivers/gpu/drm/mediatek/mtk_dsi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c index 7d5250351193..b0ab38e59db9 100644 --- a/drivers/gpu/drm/mediatek/mtk_dsi.c +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c @@ -407,7 +407,7 @@ static void mtk_dsi_rxtx_control(struct mtk_dsi *dsi) if (dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) tmp_reg |= HSTX_CKLP_EN; - if (!(dsi->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET)) + if (dsi->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET) tmp_reg |= DIS_EOT; writel(tmp_reg, dsi->regs + DSI_TXRX_CTRL); @@ -484,7 +484,7 @@ static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi) timing->da_hs_zero + timing->da_hs_exit + 3; delta = dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST ? 18 : 12; - delta += dsi->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET ? 2 : 0; + delta += dsi->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET ? 0 : 2; horizontal_frontporch_byte = vm->hfront_porch * dsi_tmp_buf_bpp; horizontal_front_back_byte = horizontal_frontporch_byte + horizontal_backporch_byte; Sounds logic Reviewed-by: Alexandre Mergnat -- Regards, Alexandre
Re: [PATCH 1/2] drm/msm/dpu: fix DSC 1.2 block lengths
On 23/06/2023 08:47, Abhinav Kumar wrote: On 6/22/2023 6:37 PM, Dmitry Baryshkov wrote: All DSC_BLK_1_2 declarations incorrectly pass 0x29c as the block length. This includes the common block itself, enc subblocks and some empty space around. Change that to pass 0x4 instead, the length of common register block itself. Fixes: 0d1b10c63346 ("drm/msm/dpu: add DSC 1.2 hw blocks for relevant chipsets") Signed-off-by: Dmitry Baryshkov There is no need of a fixes tag for this. This is not a bug but was intentional. We have other subblocks which are not dumped withoyt Ryan's patchset. So this declaration should be corrected. Till we added sub-block parsing support we had to dump the whole block. And hence I would suggest this change should be merged after the sub-block parsing change otherwise we wont have full register dumps for DSC. No, the order should be opposite: this is merged first, then subblocks dumping can use block->len in all the cases. Also, please add : Suggested-by: Ryan McCann More likely: Reported-by: Ryan McCann --- .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h | 8 .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 2 +- .../gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 12 ++-- .../gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 8 .../gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 8 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h index 8da424eaee6a..6edf323f381f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h @@ -159,10 +159,10 @@ static const struct dpu_merge_3d_cfg sm8350_merge_3d[] = { * its own different sub block address. */ static const struct dpu_dsc_cfg sm8350_dsc[] = { - DSC_BLK_1_2("dce_0_0", DSC_0, 0x8, 0x29c, 0, dsc_sblk_0), - DSC_BLK_1_2("dce_0_1", DSC_1, 0x8, 0x29c, 0, dsc_sblk_1), - DSC_BLK_1_2("dce_1_0", DSC_2, 0x81000, 0x29c, BIT(DPU_DSC_NATIVE_42x_EN), dsc_sblk_0), - DSC_BLK_1_2("dce_1_1", DSC_3, 0x81000, 0x29c, BIT(DPU_DSC_NATIVE_42x_EN), dsc_sblk_1), + DSC_BLK_1_2("dce_0_0", DSC_0, 0x8, 0x4, 0, dsc_sblk_0), + DSC_BLK_1_2("dce_0_1", DSC_1, 0x8, 0x4, 0, dsc_sblk_1), + DSC_BLK_1_2("dce_1_0", DSC_2, 0x81000, 0x4, BIT(DPU_DSC_NATIVE_42x_EN), dsc_sblk_0), + DSC_BLK_1_2("dce_1_1", DSC_3, 0x81000, 0x4, BIT(DPU_DSC_NATIVE_42x_EN), dsc_sblk_1), }; static const struct dpu_intf_cfg sm8350_intf[] = { diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h index 900fee410e11..5354003aa8be 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h @@ -104,7 +104,7 @@ static const struct dpu_pingpong_cfg sc7280_pp[] = { /* NOTE: sc7280 only has one DSC hard slice encoder */ static const struct dpu_dsc_cfg sc7280_dsc[] = { - DSC_BLK_1_2("dce_0_0", DSC_0, 0x8, 0x29c, BIT(DPU_DSC_NATIVE_42x_EN), dsc_sblk_0), + DSC_BLK_1_2("dce_0_0", DSC_0, 0x8, 0x4, BIT(DPU_DSC_NATIVE_42x_EN), dsc_sblk_0), }; static const struct dpu_wb_cfg sc7280_wb[] = { diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h index f6ce6b090f71..1d374abec1fd 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h @@ -148,12 +148,12 @@ static const struct dpu_merge_3d_cfg sc8280xp_merge_3d[] = { * its own different sub block address. */ static const struct dpu_dsc_cfg sc8280xp_dsc[] = { - DSC_BLK_1_2("dce_0_0", DSC_0, 0x8, 0x29c, 0, dsc_sblk_0), - DSC_BLK_1_2("dce_0_1", DSC_1, 0x8, 0x29c, 0, dsc_sblk_1), - DSC_BLK_1_2("dce_1_0", DSC_2, 0x81000, 0x29c, BIT(DPU_DSC_NATIVE_42x_EN), dsc_sblk_0), - DSC_BLK_1_2("dce_1_1", DSC_3, 0x81000, 0x29c, BIT(DPU_DSC_NATIVE_42x_EN), dsc_sblk_1), - DSC_BLK_1_2("dce_2_0", DSC_4, 0x82000, 0x29c, 0, dsc_sblk_0), - DSC_BLK_1_2("dce_2_1", DSC_5, 0x82000, 0x29c, 0, dsc_sblk_1), + DSC_BLK_1_2("dce_0_0", DSC_0, 0x8, 0x4, 0, dsc_sblk_0), + DSC_BLK_1_2("dce_0_1", DSC_1, 0x8, 0x4, 0, dsc_sblk_1), + DSC_BLK_1_2("dce_1_0", DSC_2, 0x81000, 0x4, BIT(DPU_DSC_NATIVE_42x_EN), dsc_sblk_0), + DSC_BLK_1_2("dce_1_1", DSC_3, 0x81000, 0x4, BIT(DPU_DSC_NATIVE_42x_EN), dsc_sblk_1), + DSC_BLK_1_2("dce_2_0", DSC_4, 0x82000, 0x4, 0, dsc_sblk_0), + DSC_BLK_1_2("dce_2_1", DSC_5, 0x82000, 0x4, 0, dsc_sblk_1), }; /* TODO: INTF 3, 8 and 7 are used for MST, marked as INTF_NONE for now */ diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h index 8d13c369213c..79447d8cab05 100644 --- a/drivers/gpu/
Re: [PATCH 05/29] drm/panfrost: dynamically allocate the drm-panfrost shrinker
On 22/06/2023 09:39, Qi Zheng wrote: > From: Qi Zheng > > In preparation for implementing lockless slab shrink, > we need to dynamically allocate the drm-panfrost shrinker, > so that it can be freed asynchronously using kfree_rcu(). > Then it doesn't need to wait for RCU read-side critical > section when releasing the struct panfrost_device. > > Signed-off-by: Qi Zheng > --- > drivers/gpu/drm/panfrost/panfrost_device.h| 2 +- > .../gpu/drm/panfrost/panfrost_gem_shrinker.c | 24 ++- > 2 files changed, 14 insertions(+), 12 deletions(-) > > diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h > b/drivers/gpu/drm/panfrost/panfrost_device.h > index b0126b9fbadc..e667e5689353 100644 > --- a/drivers/gpu/drm/panfrost/panfrost_device.h > +++ b/drivers/gpu/drm/panfrost/panfrost_device.h > @@ -118,7 +118,7 @@ struct panfrost_device { > > struct mutex shrinker_lock; > struct list_head shrinker_list; > - struct shrinker shrinker; > + struct shrinker *shrinker; > > struct panfrost_devfreq pfdevfreq; > }; > diff --git a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c > b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c > index bf0170782f25..2a5513eb9e1f 100644 > --- a/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c > +++ b/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c > @@ -18,8 +18,7 @@ > static unsigned long > panfrost_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control > *sc) > { > - struct panfrost_device *pfdev = > - container_of(shrinker, struct panfrost_device, shrinker); > + struct panfrost_device *pfdev = shrinker->private_data; > struct drm_gem_shmem_object *shmem; > unsigned long count = 0; > > @@ -65,8 +64,7 @@ static bool panfrost_gem_purge(struct drm_gem_object *obj) > static unsigned long > panfrost_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control > *sc) > { > - struct panfrost_device *pfdev = > - container_of(shrinker, struct panfrost_device, shrinker); > + struct panfrost_device *pfdev = shrinker->private_data; > struct drm_gem_shmem_object *shmem, *tmp; > unsigned long freed = 0; > > @@ -100,10 +98,15 @@ panfrost_gem_shrinker_scan(struct shrinker *shrinker, > struct shrink_control *sc) > void panfrost_gem_shrinker_init(struct drm_device *dev) > { > struct panfrost_device *pfdev = dev->dev_private; > - pfdev->shrinker.count_objects = panfrost_gem_shrinker_count; > - pfdev->shrinker.scan_objects = panfrost_gem_shrinker_scan; > - pfdev->shrinker.seeks = DEFAULT_SEEKS; > - WARN_ON(register_shrinker(&pfdev->shrinker, "drm-panfrost")); > + > + pfdev->shrinker = shrinker_alloc_and_init(panfrost_gem_shrinker_count, > + panfrost_gem_shrinker_scan, 0, > + DEFAULT_SEEKS, 0, pfdev); > + if (pfdev->shrinker && > + register_shrinker(pfdev->shrinker, "drm-panfrost")) { > + shrinker_free(pfdev->shrinker); > + WARN_ON(1); > + } So we didn't have good error handling here before, but this is significantly worse. Previously if register_shrinker() failed then the driver could safely continue without a shrinker - it would waste memory but still function. However we now have two failure conditions: * shrinker_alloc_init() returns NULL. No warning and NULL deferences will happen later. * register_shrinker() fails, shrinker_free() will free pdev->shrinker we get a warning, but followed by a use-after-free later. I think we need to modify panfrost_gem_shrinker_init() to be able to return an error, so a change something like the below (untested) before your change. Steve 8<--- diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c index bbada731bbbd..f705bbdea360 100644 --- a/drivers/gpu/drm/panfrost/panfrost_drv.c +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c @@ -598,10 +598,14 @@ static int panfrost_probe(struct platform_device *pdev) if (err < 0) goto err_out1; - panfrost_gem_shrinker_init(ddev); + err = panfrost_gem_shrinker_init(ddev); + if (err) + goto err_out2; return 0; +err_out2: + drm_dev_unregister(ddev); err_out1: pm_runtime_disable(pfdev->dev); panfrost_device_fini(pfdev); diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.h b/drivers/gpu/drm/panfrost/panfrost_gem.h index ad2877eeeccd..863d2ec8d4f0 100644 --- a/drivers/gpu/drm/panfrost/panfrost_gem.h +++ b/drivers/gpu/drm/panfrost/panfrost_gem.h @@ -81,7 +81,7 @@ panfrost_gem_mapping_get(struct panfrost_gem_object *bo, void panfrost_gem_mapping_put(struct panfrost_gem_mapping *mapping); void panfrost_gem_teardown_mappings_locked(struct panfrost_gem_object *bo); -void panfrost_gem_shrinker_init(struct drm_device *dev); +int panfrost_gem_shrinker_init(struct drm_device *dev); void panfr
[PATCH 3/3] drm/mediatek: Move CMDQ setup to mtk_drm_cmdq_init() function
In order to enhance human readability, separating the optional CMDQ mailbox initialization from the rest of the CRTC creation machinery, move it to a new mtk_drm_cmdq_init() function. Signed-off-by: AngeloGioacchino Del Regno --- drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 83 ++--- 1 file changed, 48 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c index 88c63330a421..bff65c8c6a0e 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c @@ -826,6 +826,48 @@ struct device *mtk_drm_crtc_dma_dev_get(struct drm_crtc *crtc) return mtk_crtc->dma_dev; } +static int mtk_drm_cmdq_init(struct device *dev, struct mtk_drm_private *priv, +struct mtk_drm_crtc *mtk_crtc) +{ + int ret; + + mtk_crtc->cmdq_client = cmdq_mbox_create(mtk_crtc->mmsys_dev, priv->mbox_index); + if (IS_ERR(mtk_crtc->cmdq_client)) { + ret = PTR_ERR(mtk_crtc->cmdq_client); + dev_dbg(dev, "Failed to create CMDQ client: %d\n", ret); + goto error; + } + + /* Setup the CMDQ handler callback */ + mtk_crtc->cmdq_client->priv = mtk_crtc; + mtk_crtc->cmdq_client->client.rx_callback = ddp_cmdq_cb; + + ret = of_property_read_u32_index(priv->mutex_node, "mediatek,gce-events", +priv->mbox_index, &mtk_crtc->cmdq_event); + if (ret) { + dev_dbg(dev, "Failed to get mediatek,gce-events: %d\n", ret); + goto free_mbox; + } + + mtk_crtc->cmdq_handle = cmdq_pkt_create(mtk_crtc->cmdq_client, PAGE_SIZE); + if (IS_ERR(mtk_crtc->cmdq_handle)) { + ret = PTR_ERR(mtk_crtc->cmdq_handle); + dev_err(dev, "Failed to create cmdq packet: %d\n", ret); + goto free_mbox; + } + + /* for sending blocking cmd in crtc disable */ + init_waitqueue_head(&mtk_crtc->cb_blocking_queue); + + return 0; + +free_mbox: + cmdq_mbox_destroy(mtk_crtc->cmdq_client); +error: + mtk_crtc->cmdq_client = NULL; + return ret; +} + int mtk_drm_crtc_create(struct drm_device *drm_dev, const unsigned int *path, unsigned int path_len, int priv_data_index) @@ -942,42 +984,13 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev, drm_crtc_enable_color_mgmt(&mtk_crtc->base, 0, has_ctm, gamma_lut_size); mutex_init(&mtk_crtc->hw_lock); - i = priv->mbox_index++; - - mtk_crtc->cmdq_client = cmdq_mbox_create(mtk_crtc->mmsys_dev, i); - if (IS_ERR(mtk_crtc->cmdq_client)) { - ret = PTR_ERR(mtk_crtc->cmdq_client); - dev_dbg(dev, "Failed to create CMDQ client: %d\n", ret); - mtk_crtc->cmdq_client = NULL; - return 0; - } - - /* Setup the CMDQ handler callback */ - mtk_crtc->cmdq_client->priv = mtk_crtc; - mtk_crtc->cmdq_client->client.rx_callback = ddp_cmdq_cb; + ret = mtk_drm_cmdq_init(dev, priv, mtk_crtc); + if (ret) + dev_info(dev, "No CMDQ support for CRTC%d: using CPU writes\n", +drm_crtc_index(&mtk_crtc->base)); - if (mtk_crtc->cmdq_client) { - ret = of_property_read_u32_index(priv->mutex_node, -"mediatek,gce-events", -i, -&mtk_crtc->cmdq_event); - if (ret) { - dev_dbg(dev, "mtk_crtc %d failed to get mediatek,gce-events property\n", - drm_crtc_index(&mtk_crtc->base)); - cmdq_mbox_destroy(mtk_crtc->cmdq_client); - mtk_crtc->cmdq_client = NULL; - } else { - mtk_crtc->cmdq_handle = cmdq_pkt_create(mtk_crtc->cmdq_client, PAGE_SIZE); - if (ret) { - dev_dbg(dev, "mtk_crtc %d failed to create cmdq packet\n", - drm_crtc_index(&mtk_crtc->base)); - cmdq_mbox_destroy(mtk_crtc->cmdq_client); - mtk_crtc->cmdq_client = NULL; - } - } + /* Unconditionally increment mbox_index */ + priv->mbox_index++; - /* for sending blocking cmd in crtc disable */ - init_waitqueue_head(&mtk_crtc->cb_blocking_queue); - } return 0; } -- 2.40.1
[PATCH 2/3] drm/mediatek: Remove all preprocessor ifs for CONFIG_MTK_CMDQ
Since this driver was migrated to use the MediaTek CMDQ helpers, it's not anymore necessary to exclude CMDQ related code with preprocessor if branches, as CMDQ is optional and the helpers are providing the necessary inline functions to manage the case in which CONFIG_MTK_CMDQ is not set. Clean up all instances of `#if IS_REACHABLE(CONFIG_MTK_CMDQ)` from all drivers in drm/mediatek. Signed-off-by: AngeloGioacchino Del Regno --- drivers/gpu/drm/mediatek/mtk_disp_aal.c | 2 -- drivers/gpu/drm/mediatek/mtk_disp_ccorr.c | 2 -- drivers/gpu/drm/mediatek/mtk_disp_color.c | 2 -- drivers/gpu/drm/mediatek/mtk_disp_gamma.c | 2 -- drivers/gpu/drm/mediatek/mtk_disp_merge.c | 2 -- drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 2 -- drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 2 -- drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 22 +++-- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 12 --- drivers/gpu/drm/mediatek/mtk_ethdr.c| 6 ++ drivers/gpu/drm/mediatek/mtk_mdp_rdma.c | 3 +-- 11 files changed, 6 insertions(+), 51 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_aal.c b/drivers/gpu/drm/mediatek/mtk_disp_aal.c index 17a4d4a3b040..3faed081ea10 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_aal.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_aal.c @@ -119,11 +119,9 @@ static int mtk_disp_aal_probe(struct platform_device *pdev) if (IS_ERR(priv->regs)) return dev_err_probe(dev, PTR_ERR(priv->regs), "failed to ioremap aal\n"); -#if IS_REACHABLE(CONFIG_MTK_CMDQ) ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0); if (ret) dev_dbg(dev, "get mediatek,gce-client-reg fail!\n"); -#endif priv->data = of_device_get_match_data(dev); platform_set_drvdata(pdev, priv); diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c b/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c index 3f4bf7319f17..5a901ded8086 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c @@ -174,11 +174,9 @@ static int mtk_disp_ccorr_probe(struct platform_device *pdev) if (IS_ERR(priv->regs)) return dev_err_probe(dev, PTR_ERR(priv->regs), "failed to ioremap ccorr\n"); -#if IS_REACHABLE(CONFIG_MTK_CMDQ) ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0); if (ret) dev_dbg(dev, "get mediatek,gce-client-reg fail!\n"); -#endif priv->data = of_device_get_match_data(dev); platform_set_drvdata(pdev, priv); diff --git a/drivers/gpu/drm/mediatek/mtk_disp_color.c b/drivers/gpu/drm/mediatek/mtk_disp_color.c index b188d3393f99..af866039bc38 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_color.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_color.c @@ -112,11 +112,9 @@ static int mtk_disp_color_probe(struct platform_device *pdev) if (IS_ERR(priv->regs)) return dev_err_probe(dev, PTR_ERR(priv->regs), "failed to ioremap color\n"); -#if IS_REACHABLE(CONFIG_MTK_CMDQ) ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0); if (ret) dev_dbg(dev, "get mediatek,gce-client-reg fail!\n"); -#endif priv->data = of_device_get_match_data(dev); platform_set_drvdata(pdev, priv); diff --git a/drivers/gpu/drm/mediatek/mtk_disp_gamma.c b/drivers/gpu/drm/mediatek/mtk_disp_gamma.c index 1bf709bac0cf..64ba5c5b631f 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_gamma.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_gamma.c @@ -278,11 +278,9 @@ static int mtk_disp_gamma_probe(struct platform_device *pdev) if (IS_ERR(priv->regs)) return dev_err_probe(dev, PTR_ERR(priv->regs), "failed to ioremap gamma\n"); -#if IS_REACHABLE(CONFIG_MTK_CMDQ) ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0); if (ret) dev_dbg(dev, "get mediatek,gce-client-reg fail!\n"); -#endif priv->data = of_device_get_match_data(dev); platform_set_drvdata(pdev, priv); diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c b/drivers/gpu/drm/mediatek/mtk_disp_merge.c index 60e0b4e70978..69b6f7229339 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_merge.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c @@ -269,11 +269,9 @@ static int mtk_disp_merge_probe(struct platform_device *pdev) return PTR_ERR(priv->reset_ctl); } -#if IS_REACHABLE(CONFIG_MTK_CMDQ) ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0); if (ret) dev_dbg(dev, "get mediatek,gce-client-reg fail!\n"); -#endif priv->fifo_en = of_property_read_bool(dev->of_node, "mediatek,merge-fifo-en"); diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 4c00e42ef0a8..854c7545d67d 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -531,11 +531
[PATCH 1/3] drm/mediatek: Dynamically allocate CMDQ and use helper functions
Instead of stack allocating the cmdq_client and cmdq_handle structures switch them to pointers, allowing us to migrate this driver to use the common functions provided by mtk-cmdq-helper. In order to do this, it was also necessary to add a `priv` pointer to struct cmdq_client, as that's used to pass (in this case) a mtk_crtc handle to the ddp_cmdq_cb() mailbox RX callback function. Signed-off-by: AngeloGioacchino Del Regno --- drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 107 +++- include/linux/soc/mediatek/mtk-cmdq.h | 1 + 2 files changed, 32 insertions(+), 76 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c index 0df62b076f49..b63289ab6787 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c @@ -50,8 +50,8 @@ struct mtk_drm_crtc { boolpending_async_planes; #if IS_REACHABLE(CONFIG_MTK_CMDQ) - struct cmdq_client cmdq_client; - struct cmdq_pkt cmdq_handle; + struct cmdq_client *cmdq_client; + struct cmdq_pkt *cmdq_handle; u32 cmdq_event; u32 cmdq_vblank_cnt; wait_queue_head_t cb_blocking_queue; @@ -108,47 +108,6 @@ static void mtk_drm_finish_page_flip(struct mtk_drm_crtc *mtk_crtc) } } -#if IS_REACHABLE(CONFIG_MTK_CMDQ) -static int mtk_drm_cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt *pkt, - size_t size) -{ - struct device *dev; - dma_addr_t dma_addr; - - pkt->va_base = kzalloc(size, GFP_KERNEL); - if (!pkt->va_base) { - kfree(pkt); - return -ENOMEM; - } - pkt->buf_size = size; - pkt->cl = (void *)client; - - dev = client->chan->mbox->dev; - dma_addr = dma_map_single(dev, pkt->va_base, pkt->buf_size, - DMA_TO_DEVICE); - if (dma_mapping_error(dev, dma_addr)) { - dev_err(dev, "dma map failed, size=%u\n", (u32)(u64)size); - kfree(pkt->va_base); - kfree(pkt); - return -ENOMEM; - } - - pkt->pa_base = dma_addr; - - return 0; -} - -static void mtk_drm_cmdq_pkt_destroy(struct cmdq_pkt *pkt) -{ - struct cmdq_client *client = (struct cmdq_client *)pkt->cl; - - dma_unmap_single(client->chan->mbox->dev, pkt->pa_base, pkt->buf_size, -DMA_TO_DEVICE); - kfree(pkt->va_base); - kfree(pkt); -} -#endif - static void mtk_drm_crtc_destroy(struct drm_crtc *crtc) { struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc); @@ -156,12 +115,9 @@ static void mtk_drm_crtc_destroy(struct drm_crtc *crtc) mtk_mutex_put(mtk_crtc->mutex); #if IS_REACHABLE(CONFIG_MTK_CMDQ) - mtk_drm_cmdq_pkt_destroy(&mtk_crtc->cmdq_handle); - - if (mtk_crtc->cmdq_client.chan) { - mbox_free_channel(mtk_crtc->cmdq_client.chan); - mtk_crtc->cmdq_client.chan = NULL; - } + cmdq_pkt_destroy(mtk_crtc->cmdq_handle); + cmdq_mbox_destroy(mtk_crtc->cmdq_client); + mtk_crtc->cmdq_client = NULL; #endif for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) { @@ -288,7 +244,7 @@ static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg) { struct cmdq_cb_data *data = mssg; struct cmdq_client *cmdq_cl = container_of(cl, struct cmdq_client, client); - struct mtk_drm_crtc *mtk_crtc = container_of(cmdq_cl, struct mtk_drm_crtc, cmdq_client); + struct mtk_drm_crtc *mtk_crtc = (struct mtk_drm_crtc *)cmdq_cl->priv; struct mtk_crtc_state *state; unsigned int i; @@ -546,7 +502,7 @@ static void mtk_drm_crtc_update_config(struct mtk_drm_crtc *mtk_crtc, bool needs_vblank) { #if IS_REACHABLE(CONFIG_MTK_CMDQ) - struct cmdq_pkt *cmdq_handle = &mtk_crtc->cmdq_handle; + struct cmdq_pkt *cmdq_handle = mtk_crtc->cmdq_handle; #endif struct drm_crtc *crtc = &mtk_crtc->base; struct mtk_drm_private *priv = crtc->dev->dev_private; @@ -584,14 +540,14 @@ static void mtk_drm_crtc_update_config(struct mtk_drm_crtc *mtk_crtc, mtk_mutex_release(mtk_crtc->mutex); } #if IS_REACHABLE(CONFIG_MTK_CMDQ) - if (mtk_crtc->cmdq_client.chan) { - mbox_flush(mtk_crtc->cmdq_client.chan, 2000); + if (mtk_crtc->cmdq_client) { + mbox_flush(mtk_crtc->cmdq_client->chan, 2000); cmdq_handle->cmd_buf_size = 0; cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event); cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event, false); mtk_crtc_ddp_config(crtc, cmdq_handle); cmdq_pkt_finalize(cmdq_handle); - dma_sync_single_for_device(mtk_crtc->cm
[PATCH 0/3] MediaTek DRM: Clean up CMDQ support and ifdefs
This series changes MediaTek CMDQ support to use the mtk-cmdq-helper functions, removing duplicated cmdq setup code in mtk-drm and also removing all instances of `#if IS_REACHABLE(CONFIG_MTK_CMDQ)` while keeping compatibility with both CONFIG_MTK_CMDQ=n and =m/=y. This applies on top of [1] and [2]. [1]: https://lore.kernel.org/lkml/20230524093412.92211-1-angelogioacchino.delre...@collabora.com [2]: https://lore.kernel.org/lkml/20230608084727.74403-1-angelogioacchino.delre...@collabora.com AngeloGioacchino Del Regno (3): drm/mediatek: Dynamically allocate CMDQ and use helper functions drm/mediatek: Remove all preprocessor ifs for CONFIG_MTK_CMDQ drm/mediatek: Move CMDQ setup to mtk_drm_cmdq_init() function drivers/gpu/drm/mediatek/mtk_disp_aal.c | 2 - drivers/gpu/drm/mediatek/mtk_disp_ccorr.c | 2 - drivers/gpu/drm/mediatek/mtk_disp_color.c | 2 - drivers/gpu/drm/mediatek/mtk_disp_gamma.c | 2 - drivers/gpu/drm/mediatek/mtk_disp_merge.c | 2 - drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 2 - drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 2 - drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 178 +++- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 12 -- drivers/gpu/drm/mediatek/mtk_ethdr.c| 6 +- drivers/gpu/drm/mediatek/mtk_mdp_rdma.c | 3 +- include/linux/soc/mediatek/mtk-cmdq.h | 1 + 12 files changed, 69 insertions(+), 145 deletions(-) -- 2.40.1
Re: [PATCH] drm: mediatek: mtk_dsi: Fix NO_EOT_PACKET settings/handling
Il 23/05/23 12:42, AngeloGioacchino Del Regno ha scritto: Due to the initial confusion about MIPI_DSI_MODE_EOT_PACKET, properly renamed to MIPI_DSI_MODE_NO_EOT_PACKET, reflecting its actual meaning, both the DSI_TXRX_CON register setting for bit (HSTX_)DIS_EOT and the later calculation for horizontal sync-active (HSA), back (HBP) and front (HFP) porches got incorrect due to the logic being inverted. This means that a number of settings were wrong because: - DSI_TXRX_CON register setting: bit (HSTX_)DIS_EOT should be set in order to disable the End of Transmission packet; - Horizontal Sync and Back/Front porches: The delta used to calculate all of HSA, HBP and HFP should account for the additional EOT packet. Before this change... - Bit (HSTX_)DIS_EOT was being set when EOT packet was enabled; - For HSA/HBP/HFP delta... all three were wrong, as words were added when EOT disabled, instead of when EOT packet enabled! Invert the logic around flag MIPI_DSI_MODE_NO_EOT_PACKET in the MediaTek DSI driver to fix the aforementioned issues. Fixes: 8b2b99fd7931 ("drm/mediatek: dsi: Fine tune the line time caused by EOTp") Fixes: 2d52bfba09d1 ("drm/mediatek: add non-continuous clock mode and EOT packet control") Signed-off-by: AngeloGioacchino Del Regno Gentle ping for an important fix. Regards, Angelo --- drivers/gpu/drm/mediatek/mtk_dsi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c index 7d5250351193..b0ab38e59db9 100644 --- a/drivers/gpu/drm/mediatek/mtk_dsi.c +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c @@ -407,7 +407,7 @@ static void mtk_dsi_rxtx_control(struct mtk_dsi *dsi) if (dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) tmp_reg |= HSTX_CKLP_EN; - if (!(dsi->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET)) + if (dsi->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET) tmp_reg |= DIS_EOT; writel(tmp_reg, dsi->regs + DSI_TXRX_CTRL); @@ -484,7 +484,7 @@ static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi) timing->da_hs_zero + timing->da_hs_exit + 3; delta = dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST ? 18 : 12; - delta += dsi->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET ? 2 : 0; + delta += dsi->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET ? 0 : 2; horizontal_frontporch_byte = vm->hfront_porch * dsi_tmp_buf_bpp; horizontal_front_back_byte = horizontal_frontporch_byte + horizontal_backporch_byte;
[PATCH] drm/ast: Fix default resolution when no monitor is connected on DP
Since commit fae7d186403e ("drm/probe-helper: Default to 640x480 if no EDID on DP") The default resolution is now 640x480 when no monitor is connected. But Aspeed graphics is mostly used in servers, where no monitor is attached. This also affects the "remote" resolution to 640x480, which is inconvenient, and breaks the anaconda installer. So when no EDID is present, set 1024x768 as preferred resolution. Fixes: fae7d186403e ("drm/probe-helper: Default to 640x480 if no EDID on DP") Signed-off-by: Jocelyn Falempe --- drivers/gpu/drm/ast/ast_mode.c | 26 -- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 36374828f6c8..8f7b7cc021c7 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -1589,9 +1589,31 @@ static const struct drm_connector_helper_funcs ast_dp501_connector_helper_funcs .get_modes = ast_dp501_connector_helper_get_modes, }; +static int ast_dp_probe_single_connector_modes(struct drm_connector *connector, + uint32_t maxX, uint32_t maxY) +{ + int ret; + struct drm_display_mode *mode; + + ret = drm_helper_probe_single_connector_modes(connector, maxX, maxY); + /* +* When no monitor are detected, DP now default to 640x480 +* As aspeed is mostly used in remote server, and DP monitors are +* rarely attached, it's better to default to 1024x768 +*/ + if (!connector->edid_blob_ptr) { + list_for_each_entry(mode, &connector->modes, head) { + if (mode->hdisplay == 1024 && mode->vdisplay == 768) + mode->type |= DRM_MODE_TYPE_PREFERRED; + drm_mode_sort(&connector->modes); + } + } + return ret; +} + static const struct drm_connector_funcs ast_dp501_connector_funcs = { .reset = drm_atomic_helper_connector_reset, - .fill_modes = drm_helper_probe_single_connector_modes, + .fill_modes = ast_dp_probe_single_connector_modes, .destroy = drm_connector_cleanup, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, @@ -1678,7 +1700,7 @@ static const struct drm_connector_helper_funcs ast_astdp_connector_helper_funcs static const struct drm_connector_funcs ast_astdp_connector_funcs = { .reset = drm_atomic_helper_connector_reset, - .fill_modes = drm_helper_probe_single_connector_modes, + .fill_modes = ast_dp_probe_single_connector_modes, .destroy = drm_connector_cleanup, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, base-commit: 0adec22702d497385dbdc52abb165f379a00efba -- 2.40.1
Re: [PATCH v2 06/14] drm/ast: Set PCI config before accessing I/O registers
Hi, On 2023/6/23 17:02, Thomas Zimmermann wrote: Hi Am 22.06.23 um 17:42 schrieb Sui Jingfeng: [...] + ret = ast_init_pci_config(pdev); + if (ret) + return ERR_PTR(ret); + Is the calling to ast_init_pci_config() absolute necessary ? I'm asking this question because I think this function is needed to be run only when the chip need POST. On normal case, when you call pcim_enable_device() function, the pci_enable_device() function will do such thing for you. You're right. We could probably remove this code from the driver. I don't want to do this in a patchset that is about refactoring. Maybe in a later patch. OK, this sound fine then. ``` int pci_enable_device(struct pci_dev *dev) { return pci_enable_device_flags(dev, IORESOURCE_MEM | IORESOURCE_IO); } ``` if (!ast_is_vga_enabled(dev)) { drm_info(dev, "VGA not enabled on entry, requesting chip POST\n"); need_post = true; diff --git a/drivers/gpu/drm/ast/ast_post.c b/drivers/gpu/drm/ast/ast_post.c index aa3f2cb00f82c..2da5bdb4bac45 100644 --- a/drivers/gpu/drm/ast/ast_post.c +++ b/drivers/gpu/drm/ast/ast_post.c @@ -361,12 +361,6 @@ static void ast_init_dram_reg(struct drm_device *dev) void ast_post_gpu(struct drm_device *dev) { struct ast_device *ast = to_ast_device(dev); - struct pci_dev *pdev = to_pci_dev(dev->dev); - u32 reg; - - pci_read_config_dword(pdev, 0x04, ®); - reg |= 0x3; - pci_write_config_dword(pdev, 0x04, reg); You have changed the semantics after this patch is applied . Yes, it still works. But would you like to explain something about this? I'm looking at the function, but I don't see the change in semantics. I only moved the PCI calls and added error detection. What do you mean? Sorry, I'm using the wrong word. :-) I means that this function is only needed to be call in ast_post_gpu() function. In fact, on my platform the ast_post_gpu() don't get called even. I suspect ast_post_gpu() will get called only when the firmware does not initial the card. OK, You can take another look at this function in the future. I'm also feel OK about this series. Best regards Thomas We want to learn more knowledge from your patch. ast_enable_vga(dev); ast_open_key(ast); -- Jingfeng
[PATCH] dma-buf: keep the signaling time of merged fences v2
Some Android CTS is testing for that. v2: use the current time if the fence is still in the signaling path and the timestamp not yet available. Signed-off-by: Christian König --- drivers/dma-buf/dma-fence-unwrap.c | 20 +--- drivers/dma-buf/dma-fence.c| 5 +++-- drivers/gpu/drm/drm_syncobj.c | 2 +- include/linux/dma-fence.h | 2 +- 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/drivers/dma-buf/dma-fence-unwrap.c b/drivers/dma-buf/dma-fence-unwrap.c index 7002bca792ff..46c2d3a474cd 100644 --- a/drivers/dma-buf/dma-fence-unwrap.c +++ b/drivers/dma-buf/dma-fence-unwrap.c @@ -66,18 +66,32 @@ struct dma_fence *__dma_fence_unwrap_merge(unsigned int num_fences, { struct dma_fence_array *result; struct dma_fence *tmp, **array; + ktime_t timestamp; unsigned int i; size_t count; count = 0; + timestamp = ns_to_ktime(0); for (i = 0; i < num_fences; ++i) { - dma_fence_unwrap_for_each(tmp, &iter[i], fences[i]) - if (!dma_fence_is_signaled(tmp)) + dma_fence_unwrap_for_each(tmp, &iter[i], fences[i]) { + if (!dma_fence_is_signaled(tmp)) { ++count; + } else if (test_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT, + &tmp->flags)) { + if (ktime_after(tmp->timestamp, timestamp)) + timestamp = tmp->timestamp; + } else { + /* +* Use the current time if the fence is +* currently signaling. +*/ + timestamp = ktime_get(); + } + } } if (count == 0) - return dma_fence_get_stub(); + return dma_fence_allocate_private_stub(timestamp); array = kmalloc_array(count, sizeof(*array), GFP_KERNEL); if (!array) diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c index f177c56269bb..ad076f208760 100644 --- a/drivers/dma-buf/dma-fence.c +++ b/drivers/dma-buf/dma-fence.c @@ -150,10 +150,11 @@ EXPORT_SYMBOL(dma_fence_get_stub); /** * dma_fence_allocate_private_stub - return a private, signaled fence + * @timestamp: timestamp when the fence was signaled * * Return a newly allocated and signaled stub fence. */ -struct dma_fence *dma_fence_allocate_private_stub(void) +struct dma_fence *dma_fence_allocate_private_stub(ktime_t timestamp) { struct dma_fence *fence; @@ -169,7 +170,7 @@ struct dma_fence *dma_fence_allocate_private_stub(void) set_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &fence->flags); - dma_fence_signal(fence); + dma_fence_signal_timestamp(fence, timestamp); return fence; } diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 0c2be8360525..04589a35eb09 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -353,7 +353,7 @@ EXPORT_SYMBOL(drm_syncobj_replace_fence); */ static int drm_syncobj_assign_null_handle(struct drm_syncobj *syncobj) { - struct dma_fence *fence = dma_fence_allocate_private_stub(); + struct dma_fence *fence = dma_fence_allocate_private_stub(ktime_get()); if (IS_ERR(fence)) return PTR_ERR(fence); diff --git a/include/linux/dma-fence.h b/include/linux/dma-fence.h index d54b595a0fe0..0d678e9a7b24 100644 --- a/include/linux/dma-fence.h +++ b/include/linux/dma-fence.h @@ -606,7 +606,7 @@ static inline signed long dma_fence_wait(struct dma_fence *fence, bool intr) void dma_fence_set_deadline(struct dma_fence *fence, ktime_t deadline); struct dma_fence *dma_fence_get_stub(void); -struct dma_fence *dma_fence_allocate_private_stub(void); +struct dma_fence *dma_fence_allocate_private_stub(ktime_t timestamp); u64 dma_fence_context_alloc(unsigned num); extern const struct dma_fence_ops dma_fence_array_ops; -- 2.34.1
Re: [PATCH v2 00/10] drm/panel and i2c-hid: Allow panels and touchscreens to power sequence together
On Tue, Jun 13, 2023 at 08:56:39AM -0700, Doug Anderson wrote: > Hi, > > On Tue, Jun 13, 2023 at 5:06 AM Maxime Ripard wrote: > > > > > > What I'm trying to say is: could we just make it work by passing a bunch > > > > of platform_data, 2-3 callbacks and a device registration from the panel > > > > driver directly? > > > > > > I think I'm still confused about what you're proposing. Sorry! :( Let > > > me try rephrasing why I'm confused and perhaps we can get on the same > > > page. :-) > > > > > > First, I guess I'm confused about how you have one of these devices > > > "register" the other device. > > > > > > I can understand how one device might "register" its sub-devices in > > > the MFD case. To make it concrete, we can look at a PMIC like > > > max77686.c. The parent MFD device gets probed and then it's in charge > > > of creating all of its sub-devices. These sub-devices are intimately > > > tied to one another. They have shared data structures and can > > > coordinate power sequencing and whatnot. All good. > > > > We don't necessarily need to use MFD, but yeah, we could just register a > > device for the i2c-hid driver to probe from (using > > i2c_new_client_device?) > > I think this can work for devices where the panel and touchscreen are > truly integrated where the panel driver knows enough about the related > touchscreen to fully describe and instantiate it. It doesn't work > quite as well for cases where the power and reset lines are shared > just because of what a given board designer did. To handle that, each > panel driver would need to get enough DT properties added to it so > that it could fully describe any arbitrary touchscreen, right? > > Let's think about the generic panel-edp driver. This driver runs the > panel on many sc7180-trogdor laptops, including coachz, lazor, and > pompom. All three of those boards have a shared power rail for the > touchscreen and panel. If you look at "sc7180-trogdor-coachz.dtsi", > you can see the touchscreen currently looks like this: > > ap_ts: touchscreen@5d { > compatible = "goodix,gt7375p"; > reg = <0x5d>; > pinctrl-names = "default"; > pinctrl-0 = <&ts_int_l>, <&ts_reset_l>; > > interrupt-parent = <&tlmm>; > interrupts = <9 IRQ_TYPE_LEVEL_LOW>; > > reset-gpios = <&tlmm 8 GPIO_ACTIVE_LOW>; > > vdd-supply = <&pp3300_ts>; > }; > > In "sc7180-trogdor-lazor.dtsi" we have: > > ap_ts: touchscreen@10 { > compatible = "hid-over-i2c"; > reg = <0x10>; > pinctrl-names = "default"; > pinctrl-0 = <&ts_int_l>, <&ts_reset_l>; > > interrupt-parent = <&tlmm>; > interrupts = <9 IRQ_TYPE_LEVEL_LOW>; > > post-power-on-delay-ms = <20>; > hid-descr-addr = <0x0001>; > > vdd-supply = <&pp3300_ts>; > }; > > In both cases "pp3300_ts" is simply another name for "pp3300_dx_edp" > > So I think to do what you propose, we need to add this information to > the panel-edp DT node so that it could dynamically construct the i2c > device for the touchscreen: > > a) Which touchscreen is actually connected (generic hid-over-i2c, > goodix, ...). I guess this would be a "compatible" string? > > b) Which i2c bus that device is hooked up to. > > c) Which i2c address that device is hooked up to. > > d) What the touchscreen interrupt GPIO is. > > e) Possibly what the "hid-descr-addr" for the touchscreen is. > > f) Any extra timing information needed to be passed to the touchscreen > driver, like "post-power-on-delay-ms" > > The "pinctrl" stuff would be easy to subsume into the panel's DT node, > at least. ...and, in this case, we could skip the "vdd-supply" since > the panel and eDP are sharing power rails (which is what got us into > this situation). ...but, the above is still a lot. At this point, it > would make sense to have a sub-node under the panel to describe it, > which we could do but it starts to feel weird. We'd essentially be > describing an i2c device but not under the i2c controller it belongs > to. > > I guess I'd also say that the above design also need additional code > if/when someone had a touchscreen that used a different communication > method, like SPI. > > So I guess the tl;dr of all the above is that I think it could all work if: > > 1. We described the touchscreen in a sub-node of the panel. > > 2. We added a property to the panel saying what the true parent of the > touchscreen was (an I2C controller, a SPI controller, ...) and what > type of controller it was ("SPI" vs "I2C"). > > 3. We added some generic helpers that panels could call that would > understand how to instantiate the touchscreen under the appropriate > controller. > > 4. From there, we added a new private / generic API between panels and > touchscreens letting them know that the panel was turning on/off. > > That seems much more complex to me, though. It also seems like an > awkward way to describe it in DT. Yeah, I guess you're right. I wish we had something simpler, but I can't think of any better way. S
Re: [PATCH] drm/mgag200: set variable mgag200_modeset storage-class-specifier to static
On 23/06/2023 10:28, Thomas Zimmermann wrote: Am 17.05.23 um 15:41 schrieb Tom Rix: smatch reports drivers/gpu/drm/mgag200/mgag200_drv.c:23:5: warning: symbol 'mgag200_modeset' was not declared. Should it be static? This variable is only used in its defining file, so it should be static Signed-off-by: Tom Rix Reviewed-by: Thomas Zimmermann --- drivers/gpu/drm/mgag200/mgag200_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c index 976f0ab2006b..abddf37f0ea1 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.c +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c @@ -20,7 +20,7 @@ #include "mgag200_drv.h" -int mgag200_modeset = -1; +static int mgag200_modeset = -1; MODULE_PARM_DESC(modeset, "Disable/Enable modesetting"); module_param_named(modeset, mgag200_modeset, int, 0400); applied to drm-misc-next Thanks for your contribution. -- Jocelyn
Re: [PATCH v2 06/14] drm/ast: Set PCI config before accessing I/O registers
Hi Am 22.06.23 um 17:42 schrieb Sui Jingfeng: [...] + ret = ast_init_pci_config(pdev); + if (ret) + return ERR_PTR(ret); + Is the calling to ast_init_pci_config() absolute necessary ? I'm asking this question because I think this function is needed to be run only when the chip need POST. On normal case, when you call pcim_enable_device() function, the pci_enable_device() function will do such thing for you. You're right. We could probably remove this code from the driver. I don't want to do this in a patchset that is about refactoring. Maybe in a later patch. ``` int pci_enable_device(struct pci_dev *dev) { return pci_enable_device_flags(dev, IORESOURCE_MEM | IORESOURCE_IO); } ``` if (!ast_is_vga_enabled(dev)) { drm_info(dev, "VGA not enabled on entry, requesting chip POST\n"); need_post = true; diff --git a/drivers/gpu/drm/ast/ast_post.c b/drivers/gpu/drm/ast/ast_post.c index aa3f2cb00f82c..2da5bdb4bac45 100644 --- a/drivers/gpu/drm/ast/ast_post.c +++ b/drivers/gpu/drm/ast/ast_post.c @@ -361,12 +361,6 @@ static void ast_init_dram_reg(struct drm_device *dev) void ast_post_gpu(struct drm_device *dev) { struct ast_device *ast = to_ast_device(dev); - struct pci_dev *pdev = to_pci_dev(dev->dev); - u32 reg; - - pci_read_config_dword(pdev, 0x04, ®); - reg |= 0x3; - pci_write_config_dword(pdev, 0x04, reg); You have changed the semantics after this patch is applied . Yes, it still works. But would you like to explain something about this? I'm looking at the function, but I don't see the change in semantics. I only moved the PCI calls and added error detection. What do you mean? Best regards Thomas We want to learn more knowledge from your patch. ast_enable_vga(dev); ast_open_key(ast); -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg) OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH] drm/mgag200: set variable mgag200_modeset storage-class-specifier to static
Am 17.05.23 um 15:41 schrieb Tom Rix: smatch reports drivers/gpu/drm/mgag200/mgag200_drv.c:23:5: warning: symbol 'mgag200_modeset' was not declared. Should it be static? This variable is only used in its defining file, so it should be static Signed-off-by: Tom Rix Reviewed-by: Thomas Zimmermann --- drivers/gpu/drm/mgag200/mgag200_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c index 976f0ab2006b..abddf37f0ea1 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.c +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c @@ -20,7 +20,7 @@ #include "mgag200_drv.h" -int mgag200_modeset = -1; +static int mgag200_modeset = -1; MODULE_PARM_DESC(modeset, "Disable/Enable modesetting"); module_param_named(modeset, mgag200_modeset, int, 0400); -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg) OpenPGP_signature Description: OpenPGP digital signature
Re: [PATCH v3] drm/sched: Call drm_sched_fence_set_parent() from drm_sched_fence_scheduled()
On Fri, 23 Jun 2023 09:52:04 +0200 Boris Brezillon wrote: > Drivers that can delegate waits to the firmware/GPU pass the scheduled > fence to drm_sched_job_add_dependency(), and issue wait commands to > the firmware/GPU at job submission time. For this to be possible, they > need all their 'native' dependencies to have a valid parent since this > is where the actual HW fence information are encoded. > > In drm_sched_main(), we currently call drm_sched_fence_set_parent() > after drm_sched_fence_scheduled(), leaving a short period of time > during which the job depending on this fence can be submitted. > > Since setting parent and signaling the fence are two things that are > kinda related (you can't have a parent if the job hasn't been scheduled), > it probably makes sense to pass the parent fence to > drm_sched_fence_scheduled() and let it call drm_sched_fence_set_parent() > before it signals the scheduled fence. > > Here is a detailed description of the race we are fixing here: > > Thread A Thread B > > - calls drm_sched_fence_scheduled() > - signals s_fence->scheduled which > wakes up thread B > > - entity dep signaled, checking > the next dep > - no more deps waiting > - entity is picked for job > submission by drm_gpu_scheduler > - run_job() is called > - run_job() tries to > collect native fence info from > s_fence->parent, but it's > NULL => > BOOM, we can't do our native > wait > > - calls drm_sched_fence_set_parent() > > v2: > * Fix commit message > > v3: > * Add a detailed description of the race to the commit message > * Add Luben's R-b > FYI, I didn't put a Fixes tag because the various moves/modifications that happened on this file will make it hard to backport anyway, and no one complained about it so far. But if we want to have one, it would probably be: Fixes: 754ce0fa55c4 ("drm/amd: add parent for sched fence") > Signed-off-by: Boris Brezillon > Cc: Frank Binns > Cc: Sarah Walker > Cc: Donald Robson > Cc: Luben Tuikov > Cc: David Airlie > Cc: Daniel Vetter > Cc: Sumit Semwal > Cc: "Christian König" > Reviewed-by: Luben Tuikov > --- > drivers/gpu/drm/scheduler/sched_fence.c | 40 +++-- > drivers/gpu/drm/scheduler/sched_main.c | 3 +- > include/drm/gpu_scheduler.h | 5 ++-- > 3 files changed, 28 insertions(+), 20 deletions(-) > > diff --git a/drivers/gpu/drm/scheduler/sched_fence.c > b/drivers/gpu/drm/scheduler/sched_fence.c > index fe9c6468e440..b6e70ddb4ee5 100644 > --- a/drivers/gpu/drm/scheduler/sched_fence.c > +++ b/drivers/gpu/drm/scheduler/sched_fence.c > @@ -48,8 +48,32 @@ static void __exit drm_sched_fence_slab_fini(void) > kmem_cache_destroy(sched_fence_slab); > } > > -void drm_sched_fence_scheduled(struct drm_sched_fence *fence) > +static void drm_sched_fence_set_parent(struct drm_sched_fence *s_fence, > +struct dma_fence *fence) > { > + /* > + * smp_store_release() to ensure another thread racing us > + * in drm_sched_fence_set_deadline_finished() sees the > + * fence's parent set before test_bit() > + */ > + smp_store_release(&s_fence->parent, dma_fence_get(fence)); > + if (test_bit(DRM_SCHED_FENCE_FLAG_HAS_DEADLINE_BIT, > + &s_fence->finished.flags)) > + dma_fence_set_deadline(fence, s_fence->deadline); > +} > + > +void drm_sched_fence_scheduled(struct drm_sched_fence *fence, > +struct dma_fence *parent) > +{ > + /* Set the parent before signaling the scheduled fence, such that, > + * any waiter expecting the parent to be filled after the job has > + * been scheduled (which is the case for drivers delegating waits > + * to some firmware) doesn't have to busy wait for parent to show > + * up. > + */ > + if (!IS_ERR_OR_NULL(parent)) > + drm_sched_fence_set_parent(fence, parent); > + > dma_fence_signal(&fence->scheduled); > } > > @@ -179,20 +203,6 @@ struct drm_sched_fence *to_drm_sched_fence(struct > dma_fence *f) > } > EXPORT_SYMBOL(to_drm_sched_fence); > > -void drm_sched_fence_set_parent(struct drm_sched_fence *s_fence, > - struct dma_fence *fence) > -{ > - /* > - * smp_store_release() to ensure another thread racing us > - * in drm_sched_fence_set_deadline_finished() sees the > - * fence's parent set before test_bit() > - */ > - smp_store_release(&s_fence->parent, dma_fence_get(
[PATCH v3] drm/sched: Call drm_sched_fence_set_parent() from drm_sched_fence_scheduled()
Drivers that can delegate waits to the firmware/GPU pass the scheduled fence to drm_sched_job_add_dependency(), and issue wait commands to the firmware/GPU at job submission time. For this to be possible, they need all their 'native' dependencies to have a valid parent since this is where the actual HW fence information are encoded. In drm_sched_main(), we currently call drm_sched_fence_set_parent() after drm_sched_fence_scheduled(), leaving a short period of time during which the job depending on this fence can be submitted. Since setting parent and signaling the fence are two things that are kinda related (you can't have a parent if the job hasn't been scheduled), it probably makes sense to pass the parent fence to drm_sched_fence_scheduled() and let it call drm_sched_fence_set_parent() before it signals the scheduled fence. Here is a detailed description of the race we are fixing here: Thread AThread B - calls drm_sched_fence_scheduled() - signals s_fence->scheduled which wakes up thread B - entity dep signaled, checking the next dep - no more deps waiting - entity is picked for job submission by drm_gpu_scheduler - run_job() is called - run_job() tries to collect native fence info from s_fence->parent, but it's NULL => BOOM, we can't do our native wait - calls drm_sched_fence_set_parent() v2: * Fix commit message v3: * Add a detailed description of the race to the commit message * Add Luben's R-b Signed-off-by: Boris Brezillon Cc: Frank Binns Cc: Sarah Walker Cc: Donald Robson Cc: Luben Tuikov Cc: David Airlie Cc: Daniel Vetter Cc: Sumit Semwal Cc: "Christian König" Reviewed-by: Luben Tuikov --- drivers/gpu/drm/scheduler/sched_fence.c | 40 +++-- drivers/gpu/drm/scheduler/sched_main.c | 3 +- include/drm/gpu_scheduler.h | 5 ++-- 3 files changed, 28 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/scheduler/sched_fence.c b/drivers/gpu/drm/scheduler/sched_fence.c index fe9c6468e440..b6e70ddb4ee5 100644 --- a/drivers/gpu/drm/scheduler/sched_fence.c +++ b/drivers/gpu/drm/scheduler/sched_fence.c @@ -48,8 +48,32 @@ static void __exit drm_sched_fence_slab_fini(void) kmem_cache_destroy(sched_fence_slab); } -void drm_sched_fence_scheduled(struct drm_sched_fence *fence) +static void drm_sched_fence_set_parent(struct drm_sched_fence *s_fence, + struct dma_fence *fence) { + /* +* smp_store_release() to ensure another thread racing us +* in drm_sched_fence_set_deadline_finished() sees the +* fence's parent set before test_bit() +*/ + smp_store_release(&s_fence->parent, dma_fence_get(fence)); + if (test_bit(DRM_SCHED_FENCE_FLAG_HAS_DEADLINE_BIT, +&s_fence->finished.flags)) + dma_fence_set_deadline(fence, s_fence->deadline); +} + +void drm_sched_fence_scheduled(struct drm_sched_fence *fence, + struct dma_fence *parent) +{ + /* Set the parent before signaling the scheduled fence, such that, +* any waiter expecting the parent to be filled after the job has +* been scheduled (which is the case for drivers delegating waits +* to some firmware) doesn't have to busy wait for parent to show +* up. +*/ + if (!IS_ERR_OR_NULL(parent)) + drm_sched_fence_set_parent(fence, parent); + dma_fence_signal(&fence->scheduled); } @@ -179,20 +203,6 @@ struct drm_sched_fence *to_drm_sched_fence(struct dma_fence *f) } EXPORT_SYMBOL(to_drm_sched_fence); -void drm_sched_fence_set_parent(struct drm_sched_fence *s_fence, - struct dma_fence *fence) -{ - /* -* smp_store_release() to ensure another thread racing us -* in drm_sched_fence_set_deadline_finished() sees the -* fence's parent set before test_bit() -*/ - smp_store_release(&s_fence->parent, dma_fence_get(fence)); - if (test_bit(DRM_SCHED_FENCE_FLAG_HAS_DEADLINE_BIT, -&s_fence->finished.flags)) - dma_fence_set_deadline(fence, s_fence->deadline); -} - struct drm_sched_fence *drm_sched_fence_alloc(struct drm_sched_entity *entity, void *owner) { diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c index aea5a90ff98b..eff0a7f42f69 100644 --- a/drivers/gpu/drm/scheduler
Re: [Intel-gfx] [PATCH 3/4] drm/ttm: Don't leak a resource on eviction error
Hi Christian and Thomas, > > > > > diff --git a/drivers/gpu/drm/ttm/ttm_bo.c > > > > > b/drivers/gpu/drm/ttm/ttm_bo.c > > > > > index 615d30c4262d..89530f2a027f 100644 > > > > > --- a/drivers/gpu/drm/ttm/ttm_bo.c > > > > > +++ b/drivers/gpu/drm/ttm/ttm_bo.c > > > > > @@ -462,14 +462,14 @@ static int ttm_bo_evict(struct > > > > > ttm_buffer_object *bo, > > > > > ret = ttm_bo_handle_move_mem(bo, evict_mem, true, ctx, &hop); > > > > > if (ret == -EMULTIHOP) { > > > > > ret = ttm_bo_bounce_temp_buffer(bo, &evict_mem, ctx, &hop); > > > > > - if (ret) { > > > > > - if (ret != -ERESTARTSYS && ret != -EINTR) > > > > > - pr_err("Buffer eviction failed\n"); > > > > > - ttm_resource_free(bo, &evict_mem); > > > > > - goto out; > > > > > - } > > > > > - /* try and move to final place now. */ > > > > > - goto bounce; > > > > > + if (!ret) > > > > > + /* try and move to final place now. */ > > > > > + goto bounce; > > > > As we are at this, can't we replace this with a while()? Goto's > > > > used instead of a while loop are a fist in the eye... > > > > > > I'm completely OK with that. this patch already did away with one of > > > them. Let's hear Christian's opinion first, though. > > > > I'm not a fan of that goto either, but could we somehow avoid the > > while(1) ? E.g. something like do { } while (!ret) after handling the > > multihop? > > I think the construct that makes it most obvious what's happening, although > it needs two tests for -EMULTIHOP is something like > > do { > > if (ret != -EMULTIHOP) > break; > > } while (ret ==-EMULTIHOP); even better :) Thank you! Andi
Re: [PATCH 1/3] dt-bindings: display: msm: sm8350-mdss: document displayport controller subnode
On 23/06/2023 09:27, Marijn Suijten wrote: On 2023-06-21 11:26:25, Neil Armstrong wrote: Document the optional document displayport controller subnode document the optional *document*? Same in the other patches IIRC. oops, will re-spin with this fixed thanks! - Marijn of the SM8350 MDSS. Signed-off-by: Neil Armstrong --- Documentation/devicetree/bindings/display/msm/qcom,sm8350-mdss.yaml | 6 ++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/display/msm/qcom,sm8350-mdss.yaml b/Documentation/devicetree/bindings/display/msm/qcom,sm8350-mdss.yaml index 79a226e4cc6a..f2cbeb435f1b 100644 --- a/Documentation/devicetree/bindings/display/msm/qcom,sm8350-mdss.yaml +++ b/Documentation/devicetree/bindings/display/msm/qcom,sm8350-mdss.yaml @@ -52,6 +52,12 @@ patternProperties: compatible: const: qcom,sm8350-dpu + "^displayport-controller@[0-9a-f]+$": +type: object +properties: + compatible: +const: qcom,sm8350-dp + "^dsi@[0-9a-f]+$": type: object properties: -- 2.34.1
[PATCH 14/29] jbd2, ext4: dynamically allocate the jbd2-journal shrinker
From: Qi Zheng In preparation for implementing lockless slab shrink, we need to dynamically allocate the jbd2-journal shrinker, so that it can be freed asynchronously using kfree_rcu(). Then it doesn't need to wait for RCU read-side critical section when releasing the struct journal_s. Signed-off-by: Qi Zheng --- fs/jbd2/journal.c| 32 +++- include/linux/jbd2.h | 2 +- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index eee3c0ae349a..92a2f4360b5f 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -1301,7 +1301,7 @@ static int jbd2_min_tag_size(void) static unsigned long jbd2_journal_shrink_scan(struct shrinker *shrink, struct shrink_control *sc) { - journal_t *journal = container_of(shrink, journal_t, j_shrinker); + journal_t *journal = shrink->private_data; unsigned long nr_to_scan = sc->nr_to_scan; unsigned long nr_shrunk; unsigned long count; @@ -1327,7 +1327,7 @@ static unsigned long jbd2_journal_shrink_scan(struct shrinker *shrink, static unsigned long jbd2_journal_shrink_count(struct shrinker *shrink, struct shrink_control *sc) { - journal_t *journal = container_of(shrink, journal_t, j_shrinker); + journal_t *journal = shrink->private_data; unsigned long count; count = percpu_counter_read_positive(&journal->j_checkpoint_jh_count); @@ -1415,21 +1415,27 @@ static journal_t *journal_init_common(struct block_device *bdev, journal->j_superblock = (journal_superblock_t *)bh->b_data; journal->j_shrink_transaction = NULL; - journal->j_shrinker.scan_objects = jbd2_journal_shrink_scan; - journal->j_shrinker.count_objects = jbd2_journal_shrink_count; - journal->j_shrinker.seeks = DEFAULT_SEEKS; - journal->j_shrinker.batch = journal->j_max_transaction_buffers; if (percpu_counter_init(&journal->j_checkpoint_jh_count, 0, GFP_KERNEL)) goto err_cleanup; - if (register_shrinker(&journal->j_shrinker, "jbd2-journal:(%u:%u)", - MAJOR(bdev->bd_dev), MINOR(bdev->bd_dev))) { - percpu_counter_destroy(&journal->j_checkpoint_jh_count); - goto err_cleanup; - } + journal->j_shrinker = shrinker_alloc_and_init(jbd2_journal_shrink_count, + jbd2_journal_shrink_scan, + journal->j_max_transaction_buffers, + DEFAULT_SEEKS, 0, journal); + if (!journal->j_shrinker) + goto err_shrinker; + + if (register_shrinker(journal->j_shrinker, "jbd2-journal:(%u:%u)", + MAJOR(bdev->bd_dev), MINOR(bdev->bd_dev))) + goto err_register; + return journal; +err_register: + shrinker_free(journal->j_shrinker); +err_shrinker: + percpu_counter_destroy(&journal->j_checkpoint_jh_count); err_cleanup: brelse(journal->j_sb_buffer); kfree(journal->j_wbuf); @@ -2190,9 +2196,9 @@ int jbd2_journal_destroy(journal_t *journal) brelse(journal->j_sb_buffer); } - if (journal->j_shrinker.flags & SHRINKER_REGISTERED) { + if (journal->j_shrinker->flags & SHRINKER_REGISTERED) { percpu_counter_destroy(&journal->j_checkpoint_jh_count); - unregister_shrinker(&journal->j_shrinker); + unregister_and_free_shrinker(journal->j_shrinker); } if (journal->j_proc_entry) jbd2_stats_proc_exit(journal); diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index 44c298aa58d4..beb4c4586320 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h @@ -891,7 +891,7 @@ struct journal_s * Journal head shrinker, reclaim buffer's journal head which * has been written back. */ - struct shrinker j_shrinker; + struct shrinker *j_shrinker; /** * @j_checkpoint_jh_count: -- 2.30.2
[PATCH 10/29] vmw_balloon: dynamically allocate the vmw-balloon shrinker
In preparation for implementing lockless slab shrink, we need to dynamically allocate the vmw-balloon shrinker, so that it can be freed asynchronously using kfree_rcu(). Then it doesn't need to wait for RCU read-side critical section when releasing the struct vmballoon. Signed-off-by: Qi Zheng --- drivers/misc/vmw_balloon.c | 16 ++-- 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/misc/vmw_balloon.c b/drivers/misc/vmw_balloon.c index 9ce9b9e0e9b6..2f86f666b476 100644 --- a/drivers/misc/vmw_balloon.c +++ b/drivers/misc/vmw_balloon.c @@ -380,7 +380,7 @@ struct vmballoon { /** * @shrinker: shrinker interface that is used to avoid over-inflation. */ - struct shrinker shrinker; + struct shrinker *shrinker; /** * @shrinker_registered: whether the shrinker was registered. @@ -1569,7 +1569,7 @@ static unsigned long vmballoon_shrinker_count(struct shrinker *shrinker, static void vmballoon_unregister_shrinker(struct vmballoon *b) { if (b->shrinker_registered) - unregister_shrinker(&b->shrinker); + unregister_and_free_shrinker(b->shrinker); b->shrinker_registered = false; } @@ -1581,14 +1581,18 @@ static int vmballoon_register_shrinker(struct vmballoon *b) if (!vmwballoon_shrinker_enable) return 0; - b->shrinker.scan_objects = vmballoon_shrinker_scan; - b->shrinker.count_objects = vmballoon_shrinker_count; - b->shrinker.seeks = DEFAULT_SEEKS; + b->shrinker = shrinker_alloc_and_init(vmballoon_shrinker_count, + vmballoon_shrinker_scan, + 0, DEFAULT_SEEKS, 0, b); + if (!b->shrinker) + return -ENOMEM; - r = register_shrinker(&b->shrinker, "vmw-balloon"); + r = register_shrinker(b->shrinker, "vmw-balloon"); if (r == 0) b->shrinker_registered = true; + else + shrinker_free(b->shrinker); return r; } -- 2.30.2
Re: [PATCH 24/29] mm: vmscan: make global slab shrink lockless
> 2023年6月23日 上午12:42,Qi Zheng 写道: > > > > On 2023/6/22 23:12, Vlastimil Babka wrote: >> On 6/22/23 10:53, Qi Zheng wrote: >>> The shrinker_rwsem is a global read-write lock in >>> shrinkers subsystem, which protects most operations >>> such as slab shrink, registration and unregistration >>> of shrinkers, etc. This can easily cause problems in >>> the following cases. >>> >>> 1) When the memory pressure is high and there are many >>>filesystems mounted or unmounted at the same time, >>>slab shrink will be affected (down_read_trylock() >>>failed). >>> >>>Such as the real workload mentioned by Kirill Tkhai: >>> >>>``` >>>One of the real workloads from my experience is start >>>of an overcommitted node containing many starting >>>containers after node crash (or many resuming containers >>>after reboot for kernel update). In these cases memory >>>pressure is huge, and the node goes round in long reclaim. >>>``` >>> >>> 2) If a shrinker is blocked (such as the case mentioned >>>in [1]) and a writer comes in (such as mount a fs), >>>then this writer will be blocked and cause all >>>subsequent shrinker-related operations to be blocked. >>> >>> Even if there is no competitor when shrinking slab, there >>> may still be a problem. If we have a long shrinker list >>> and we do not reclaim enough memory with each shrinker, >>> then the down_read_trylock() may be called with high >>> frequency. Because of the poor multicore scalability of >>> atomic operations, this can lead to a significant drop >>> in IPC (instructions per cycle). >>> >>> We used to implement the lockless slab shrink with >>> SRCU [1], but then kernel test robot reported -88.8% >>> regression in stress-ng.ramfs.ops_per_sec test case [2], >>> so we reverted it [3]. >>> >>> This commit uses the refcount+RCU method [4] proposed by >>> by Dave Chinner to re-implement the lockless global slab >>> shrink. The memcg slab shrink is handled in the subsequent >>> patch. >>> >>> Currently, the shrinker instances can be divided into >>> the following three types: >>> >>> a) global shrinker instance statically defined in the kernel, >>> such as workingset_shadow_shrinker. >>> >>> b) global shrinker instance statically defined in the kernel >>> modules, such as mmu_shrinker in x86. >>> >>> c) shrinker instance embedded in other structures. >>> >>> For case a, the memory of shrinker instance is never freed. >>> For case b, the memory of shrinker instance will be freed >>> after the module is unloaded. But we will call synchronize_rcu() >>> in free_module() to wait for RCU read-side critical section to >>> exit. For case c, the memory of shrinker instance will be >>> dynamically freed by calling kfree_rcu(). So we can use >>> rcu_read_{lock,unlock}() to ensure that the shrinker instance >>> is valid. >>> >>> The shrinker::refcount mechanism ensures that the shrinker >>> instance will not be run again after unregistration. So the >>> structure that records the pointer of shrinker instance can be >>> safely freed without waiting for the RCU read-side critical >>> section. >>> >>> In this way, while we implement the lockless slab shrink, we >>> don't need to be blocked in unregister_shrinker() to wait >>> RCU read-side critical section. >>> >>> The following are the test results: >>> >>> stress-ng --timeout 60 --times --verify --metrics-brief --ramfs 9 & >>> >>> 1) Before applying this patchset: >>> >>> setting to a 60 second run per stressor >>> dispatching hogs: 9 ramfs >>> stressor bogo ops real time usr time sys time bogo ops/s >>> bogo ops/s >>>(secs)(secs)(secs) (real time) >>> (usr+sys time) >>> ramfs880623 60.02 7.71226.93 14671.45 >>> 3753.09 >>> ramfs: >>> 1 System Management Interrupt >>> for a 60.03s run time: >>> 5762.40s available CPU time >>>7.71s user time ( 0.13%) >>> 226.93s system time ( 3.94%) >>> 234.64s total time ( 4.07%) >>> load average: 8.54 3.06 2.11 >>> passed: 9: ramfs (9) >>> failed: 0 >>> skipped: 0 >>> successful run completed in 60.03s (1 min, 0.03 secs) >>> >>> 2) After applying this patchset: >>> >>> setting to a 60 second run per stressor >>> dispatching hogs: 9 ramfs >>> stressor bogo ops real time usr time sys time bogo ops/s >>> bogo ops/s >>>(secs)(secs)(secs) (real time) >>> (usr+sys time) >>> ramfs847562 60.02 7.44230.22 14120.66 >>> 3566.23 >>> ramfs: >>> 4 System Management Interrupts >>> for a 60.12s run time: >>> 5771.95s available CPU time >>>7.44s user time ( 0.13%) >>> 230.22s system time ( 3.99%) >>> 237.66s total time ( 4.12%) >>> load average: 8.18 2.43 0.84 >>> passed: 9: ramfs (9) >>> failed: 0 >>> skipped: 0 >>> successful run completed in 60.12s (1 min, 0.12
[PATCH 20/29] zsmalloc: dynamically allocate the mm-zspool shrinker
In preparation for implementing lockless slab shrink, we need to dynamically allocate the mm-zspool shrinker, so that it can be freed asynchronously using kfree_rcu(). Then it doesn't need to wait for RCU read-side critical section when releasing the struct zs_pool. Signed-off-by: Qi Zheng --- mm/zsmalloc.c | 28 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c index 3f057970504e..c03b34ae637e 100644 --- a/mm/zsmalloc.c +++ b/mm/zsmalloc.c @@ -229,7 +229,7 @@ struct zs_pool { struct zs_pool_stats stats; /* Compact classes */ - struct shrinker shrinker; + struct shrinker *shrinker; #ifdef CONFIG_ZSMALLOC_STAT struct dentry *stat_dentry; @@ -2107,8 +2107,7 @@ static unsigned long zs_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc) { unsigned long pages_freed; - struct zs_pool *pool = container_of(shrinker, struct zs_pool, - shrinker); + struct zs_pool *pool = shrinker->private_data; /* * Compact classes and calculate compaction delta. @@ -2126,8 +2125,7 @@ static unsigned long zs_shrinker_count(struct shrinker *shrinker, int i; struct size_class *class; unsigned long pages_to_free = 0; - struct zs_pool *pool = container_of(shrinker, struct zs_pool, - shrinker); + struct zs_pool *pool = shrinker->private_data; for (i = ZS_SIZE_CLASSES - 1; i >= 0; i--) { class = pool->size_class[i]; @@ -2142,18 +2140,24 @@ static unsigned long zs_shrinker_count(struct shrinker *shrinker, static void zs_unregister_shrinker(struct zs_pool *pool) { - unregister_shrinker(&pool->shrinker); + unregister_and_free_shrinker(pool->shrinker); } static int zs_register_shrinker(struct zs_pool *pool) { - pool->shrinker.scan_objects = zs_shrinker_scan; - pool->shrinker.count_objects = zs_shrinker_count; - pool->shrinker.batch = 0; - pool->shrinker.seeks = DEFAULT_SEEKS; + int ret; + + pool->shrinker = shrinker_alloc_and_init(zs_shrinker_count, +zs_shrinker_scan, 0, +DEFAULT_SEEKS, 0, pool); + if (!pool->shrinker) + return -ENOMEM; - return register_shrinker(&pool->shrinker, "mm-zspool:%s", -pool->name); + ret = register_shrinker(pool->shrinker, "mm-zspool:%s", pool->name); + if (ret) + shrinker_free(pool->shrinker); + + return ret; } static int calculate_zspage_chain_size(int class_size) -- 2.30.2
[PATCH 06/29] dm: dynamically allocate the dm-bufio shrinker
In preparation for implementing lockless slab shrink, we need to dynamically allocate the dm-bufio shrinker, so that it can be freed asynchronously using kfree_rcu(). Then it doesn't need to wait for RCU read-side critical section when releasing the struct dm_bufio_client. Signed-off-by: Qi Zheng --- drivers/md/dm-bufio.c | 23 +-- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c index eea977662e81..9472470d456d 100644 --- a/drivers/md/dm-bufio.c +++ b/drivers/md/dm-bufio.c @@ -963,7 +963,7 @@ struct dm_bufio_client { sector_t start; - struct shrinker shrinker; + struct shrinker *shrinker; struct work_struct shrink_work; atomic_long_t need_shrink; @@ -2385,7 +2385,7 @@ static unsigned long dm_bufio_shrink_scan(struct shrinker *shrink, struct shrink { struct dm_bufio_client *c; - c = container_of(shrink, struct dm_bufio_client, shrinker); + c = shrink->private_data; atomic_long_add(sc->nr_to_scan, &c->need_shrink); queue_work(dm_bufio_wq, &c->shrink_work); @@ -2394,7 +2394,7 @@ static unsigned long dm_bufio_shrink_scan(struct shrinker *shrink, struct shrink static unsigned long dm_bufio_shrink_count(struct shrinker *shrink, struct shrink_control *sc) { - struct dm_bufio_client *c = container_of(shrink, struct dm_bufio_client, shrinker); + struct dm_bufio_client *c = shrink->private_data; unsigned long count = cache_total(&c->cache); unsigned long retain_target = get_retain_buffers(c); unsigned long queued_for_cleanup = atomic_long_read(&c->need_shrink); @@ -2507,14 +2507,15 @@ struct dm_bufio_client *dm_bufio_client_create(struct block_device *bdev, unsign INIT_WORK(&c->shrink_work, shrink_work); atomic_long_set(&c->need_shrink, 0); - c->shrinker.count_objects = dm_bufio_shrink_count; - c->shrinker.scan_objects = dm_bufio_shrink_scan; - c->shrinker.seeks = 1; - c->shrinker.batch = 0; - r = register_shrinker(&c->shrinker, "dm-bufio:(%u:%u)", + c->shrinker = shrinker_alloc_and_init(dm_bufio_shrink_count, + dm_bufio_shrink_scan, 0, 1, 0, c); + if (!c->shrinker) + goto bad; + + r = register_shrinker(c->shrinker, "dm-bufio:(%u:%u)", MAJOR(bdev->bd_dev), MINOR(bdev->bd_dev)); if (r) - goto bad; + goto bad_shrinker; mutex_lock(&dm_bufio_clients_lock); dm_bufio_client_count++; @@ -2524,6 +2525,8 @@ struct dm_bufio_client *dm_bufio_client_create(struct block_device *bdev, unsign return c; +bad_shrinker: + shrinker_free(c->shrinker); bad: while (!list_empty(&c->reserved_buffers)) { struct dm_buffer *b = list_to_buffer(c->reserved_buffers.next); @@ -2554,7 +2557,7 @@ void dm_bufio_client_destroy(struct dm_bufio_client *c) drop_buffers(c); - unregister_shrinker(&c->shrinker); + unregister_and_free_shrinker(c->shrinker); flush_work(&c->shrink_work); mutex_lock(&dm_bufio_clients_lock); -- 2.30.2
[PATCH 14/29] jbd2, ext4: dynamically allocate the jbd2-journal shrinker
In preparation for implementing lockless slab shrink, we need to dynamically allocate the jbd2-journal shrinker, so that it can be freed asynchronously using kfree_rcu(). Then it doesn't need to wait for RCU read-side critical section when releasing the struct journal_s. Signed-off-by: Qi Zheng --- fs/jbd2/journal.c| 32 +++- include/linux/jbd2.h | 2 +- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index eee3c0ae349a..92a2f4360b5f 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -1301,7 +1301,7 @@ static int jbd2_min_tag_size(void) static unsigned long jbd2_journal_shrink_scan(struct shrinker *shrink, struct shrink_control *sc) { - journal_t *journal = container_of(shrink, journal_t, j_shrinker); + journal_t *journal = shrink->private_data; unsigned long nr_to_scan = sc->nr_to_scan; unsigned long nr_shrunk; unsigned long count; @@ -1327,7 +1327,7 @@ static unsigned long jbd2_journal_shrink_scan(struct shrinker *shrink, static unsigned long jbd2_journal_shrink_count(struct shrinker *shrink, struct shrink_control *sc) { - journal_t *journal = container_of(shrink, journal_t, j_shrinker); + journal_t *journal = shrink->private_data; unsigned long count; count = percpu_counter_read_positive(&journal->j_checkpoint_jh_count); @@ -1415,21 +1415,27 @@ static journal_t *journal_init_common(struct block_device *bdev, journal->j_superblock = (journal_superblock_t *)bh->b_data; journal->j_shrink_transaction = NULL; - journal->j_shrinker.scan_objects = jbd2_journal_shrink_scan; - journal->j_shrinker.count_objects = jbd2_journal_shrink_count; - journal->j_shrinker.seeks = DEFAULT_SEEKS; - journal->j_shrinker.batch = journal->j_max_transaction_buffers; if (percpu_counter_init(&journal->j_checkpoint_jh_count, 0, GFP_KERNEL)) goto err_cleanup; - if (register_shrinker(&journal->j_shrinker, "jbd2-journal:(%u:%u)", - MAJOR(bdev->bd_dev), MINOR(bdev->bd_dev))) { - percpu_counter_destroy(&journal->j_checkpoint_jh_count); - goto err_cleanup; - } + journal->j_shrinker = shrinker_alloc_and_init(jbd2_journal_shrink_count, + jbd2_journal_shrink_scan, + journal->j_max_transaction_buffers, + DEFAULT_SEEKS, 0, journal); + if (!journal->j_shrinker) + goto err_shrinker; + + if (register_shrinker(journal->j_shrinker, "jbd2-journal:(%u:%u)", + MAJOR(bdev->bd_dev), MINOR(bdev->bd_dev))) + goto err_register; + return journal; +err_register: + shrinker_free(journal->j_shrinker); +err_shrinker: + percpu_counter_destroy(&journal->j_checkpoint_jh_count); err_cleanup: brelse(journal->j_sb_buffer); kfree(journal->j_wbuf); @@ -2190,9 +2196,9 @@ int jbd2_journal_destroy(journal_t *journal) brelse(journal->j_sb_buffer); } - if (journal->j_shrinker.flags & SHRINKER_REGISTERED) { + if (journal->j_shrinker->flags & SHRINKER_REGISTERED) { percpu_counter_destroy(&journal->j_checkpoint_jh_count); - unregister_shrinker(&journal->j_shrinker); + unregister_and_free_shrinker(journal->j_shrinker); } if (journal->j_proc_entry) jbd2_stats_proc_exit(journal); diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index 44c298aa58d4..beb4c4586320 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h @@ -891,7 +891,7 @@ struct journal_s * Journal head shrinker, reclaim buffer's journal head which * has been written back. */ - struct shrinker j_shrinker; + struct shrinker *j_shrinker; /** * @j_checkpoint_jh_count: -- 2.30.2