[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 4/9] drm/mcde: replace struct drm_simple_display_pipe with regular atomic helpers



On Wed Jul 8, 2026 at 9:02 PM CST, Thomas Zimmermann wrote:
> Hi
>
> Am 04.07.26 um 20:31 schrieb Ze Huang:
>> Convert MCDE to explicit plane, CRTC and encoder objects.
>>
>> Keep FIFO, event and framebuffer update sequencing intact, and install
>> GEM framebuffer prepare callback explicitly.
>>
>> Signed-off-by: Ze Huang <ze.huang@xxxxxxxxxxxxxxxx>
>> ---
>>   drivers/gpu/drm/mcde/mcde_display.c | 162 
>> +++++++++++++++++++++++++++---------
>>   drivers/gpu/drm/mcde/mcde_drm.h     |   6 +-
>>   drivers/gpu/drm/mcde/mcde_drv.c     |   3 +-
>>   3 files changed, 129 insertions(+), 42 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/mcde/mcde_display.c 
>> b/drivers/gpu/drm/mcde/mcde_display.c
>> index 257a6e84dd58..4d86fa5030eb 100644
>> --- a/drivers/gpu/drm/mcde/mcde_display.c
>> +++ b/drivers/gpu/drm/mcde/mcde_display.c
>> @@ -10,6 +10,7 @@
>>   #include <linux/regulator/consumer.h>
>>   #include <linux/media-bus-format.h>
>>   
>> +#include <drm/drm_atomic_helper.h>
>>   #include <drm/drm_device.h>
>>   #include <drm/drm_fb_dma_helper.h>
>>   #include <drm/drm_fourcc.h>
>> @@ -18,7 +19,6 @@
>>   #include <drm/drm_gem_dma_helper.h>
>>   #include <drm/drm_mipi_dsi.h>
>>   #include <drm/drm_print.h>
>> -#include <drm/drm_simple_kms_helper.h>
>>   #include <drm/drm_bridge.h>
>>   #include <drm/drm_vblank.h>
>>   #include <video/mipi_display.h>
>> @@ -132,7 +132,7 @@ void mcde_display_irq(struct mcde *mcde)
>>      writel(mispp, mcde->regs + MCDE_RISPP);
>>   
>>      if (vblank)
>> -            drm_crtc_handle_vblank(&mcde->pipe.crtc);
>> +            drm_crtc_handle_vblank(&mcde->crtc);
>>   
>>      if (misovl)
>>              dev_info(mcde->dev, "some stray overlay IRQ %08x\n", misovl);
>> @@ -157,13 +157,35 @@ void mcde_display_disable_irqs(struct mcde *mcde)
>>      writel(0xFFFFFFFF, mcde->regs + MCDE_RISCHNL);
>>   }
>>   
>> -static int mcde_display_check(struct drm_simple_display_pipe *pipe,
>> -                          struct drm_plane_state *pstate,
>> -                          struct drm_crtc_state *cstate)
>> +static int mcde_plane_helper_atomic_check(struct drm_plane *plane,
>> +                                      struct drm_atomic_commit *state)
>>   {
>> -    const struct drm_display_mode *mode = &cstate->mode;
>> -    struct drm_framebuffer *old_fb = pipe->plane.state->fb;
>> +    struct drm_plane_state *pstate = drm_atomic_get_new_plane_state(state, 
>> plane);
>> +    struct drm_crtc *crtc = pstate->crtc;
>> +    struct drm_crtc_state *cstate;
>> +    const struct drm_display_mode *mode;
>> +    struct drm_framebuffer *old_fb = plane->state->fb;
>>      struct drm_framebuffer *fb = pstate->fb;
>> +    int ret;
>> +
>> +    if (!crtc)
>> +            return 0;
>
> Your planes' atomic_check functions should always run 
> drm_atomic_helper_check_plane_state() first. Otherwise, the plane state 
> will be incorrect.
>
> If there is no crtc, simply pass NULL for the CRTC state.  I'd advise to 
> duplicate the pattern at [1] from lines 487 to 498.  After 
> _check_plane_state() ran, the atomic_check can do additional tests.
>
> If not looked over all the other patches for this problem, but this 
> comment would apply to all of them.
>
> [1] 
> https://elixir.bootlin.com/linux/v7.1.2/source/drivers/gpu/drm/mgag200/mgag200_mode.c#L487

Will follow, thanks

>
>> +
>> +    cstate = drm_atomic_get_new_crtc_state(state, crtc);
>> +    if (!cstate)
>> +            return 0;
>> +
>> +    ret = drm_atomic_helper_check_plane_state(pstate, cstate,
>> +                                              DRM_PLANE_NO_SCALING,
>> +                                              DRM_PLANE_NO_SCALING,
>> +                                              false, false);
>> +    if (ret)
>> +            return ret;
>> +
>> +    if (!pstate->visible)
>> +            return 0;
>> +
>> +    mode = &cstate->mode;
>>   
>>      if (fb) {
>>              u32 offset = drm_fb_dma_get_gem_addr(fb, pstate, 0);
>> @@ -1149,16 +1171,14 @@ static void mcde_setup_dsi(struct mcde *mcde, const 
>> struct drm_display_mode *mod
>>      *dsi_formatter_frame = formatter_frame;
>>   }
>>   
>> -static void mcde_display_enable(struct drm_simple_display_pipe *pipe,
>> -                            struct drm_crtc_state *cstate,
>> -                            struct drm_plane_state *plane_state)
>> +static void mcde_crtc_helper_atomic_enable(struct drm_crtc *crtc,
>> +                                       struct drm_atomic_commit *state)
>>   {
>> -    struct drm_crtc *crtc = &pipe->crtc;
>> -    struct drm_plane *plane = &pipe->plane;
>>      struct drm_device *drm = crtc->dev;
>>      struct mcde *mcde = to_mcde(drm);
>> +    struct drm_crtc_state *cstate = crtc->state;
>>      const struct drm_display_mode *mode = &cstate->mode;
>> -    struct drm_framebuffer *fb = plane->state->fb;
>> +    struct drm_framebuffer *fb = mcde->plane.state->fb;
>>      u32 format = fb->format->format;
>>      int dsi_pkt_size;
>>      int fifo_wtrmrk;
>> @@ -1298,9 +1318,9 @@ static void mcde_display_enable(struct 
>> drm_simple_display_pipe *pipe,
>>      dev_info(drm->dev, "MCDE display is enabled\n");
>>   }
>>   
>> -static void mcde_display_disable(struct drm_simple_display_pipe *pipe)
>> +static void mcde_crtc_helper_atomic_disable(struct drm_crtc *crtc,
>> +                                        struct drm_atomic_commit *state)
>>   {
>> -    struct drm_crtc *crtc = &pipe->crtc;
>>      struct drm_device *drm = crtc->dev;
>>      struct mcde *mcde = to_mcde(drm);
>>      struct drm_pending_vblank_event *event;
>> @@ -1381,17 +1401,23 @@ static void mcde_set_extsrc(struct mcde *mcde, u32 
>> buffer_address)
>>      writel(buffer_address + mcde->stride, mcde->regs + MCDE_EXTSRCXA1);
>>   }
>>   
>> -static void mcde_display_update(struct drm_simple_display_pipe *pipe,
>> -                            struct drm_plane_state *old_pstate)
>> +static void mcde_plane_helper_atomic_update(struct drm_plane *plane,
>> +                                        struct drm_atomic_commit *state)
>>   {
>> -    struct drm_crtc *crtc = &pipe->crtc;
>> -    struct drm_device *drm = crtc->dev;
>> -    struct mcde *mcde = to_mcde(drm);
>> -    struct drm_pending_vblank_event *event = crtc->state->event;
>> -    struct drm_plane *plane = &pipe->plane;
>> +    struct drm_crtc *crtc = plane->state->crtc;
>> +    struct drm_device *drm;
>> +    struct mcde *mcde;
>> +    struct drm_pending_vblank_event *event;
>>      struct drm_plane_state *pstate = plane->state;
>>      struct drm_framebuffer *fb = pstate->fb;
>>   
>> +    if (!crtc)
>> +            return;
>
> The helper first does vblank handling and then handles visibility by 
> testing "if (fb)". No need for this test.

Will drop it

>
>> +
>> +    drm = crtc->dev;
>> +    mcde = to_mcde(drm);
>> +    event = crtc->state->event;
>> +
>
> And this needs to handle !crtc without returning.
>
>>      /*
>>       * Handle any pending event first, we need to arm the vblank
>
> And the next block handled vblanks, which is not the right place. That's 
> a preexisting issue.  Vblank handling is better done in the crtc's 
> atomic_flush.

I'll move vblank handling logic to new atomic_flush function

>
> Best regards
> Thomas
>
>>       * interrupt before sending any update to the display so we don't
>> @@ -1443,9 +1469,8 @@ static void mcde_display_update(struct 
>> drm_simple_display_pipe *pipe,
>>      }
>>   }

Thanks,
Ze



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.