Re: [PATCH RFC v4 6/7] drm/msm/dpu: Allow NULL FBs in atomic commit

2023-06-30 Thread Pekka Paalanen
On Fri, 30 Jun 2023 03:52:37 +0300
Dmitry Baryshkov  wrote:

> On 30/06/2023 03:25, Jessica Zhang wrote:
> > Since solid fill planes allow for a NULL framebuffer in a valid commit,
> > add NULL framebuffer checks to atomic commit calls within DPU.
> > 
> > Signed-off-by: Jessica Zhang 
> > ---
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  |  9 ++-
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 45 
> > +++
> >   2 files changed, 36 insertions(+), 18 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
> > b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > index 1edf2b6b0a26..d1b37d2cc202 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > @@ -451,6 +451,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc 
> > *crtc,
> > struct drm_plane_state *state;
> > struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state);
> > struct dpu_plane_state *pstate = NULL;
> > +   const struct msm_format *fmt;
> > struct dpu_format *format;
> > struct dpu_hw_ctl *ctl = mixer->lm_ctl;
> >   
> > @@ -470,7 +471,13 @@ static void _dpu_crtc_blend_setup_mixer(struct 
> > drm_crtc *crtc,
> > pstate = to_dpu_plane_state(state);
> > fb = state->fb;
> >   
> > -   format = to_dpu_format(msm_framebuffer_format(pstate->base.fb));
> > +   if (state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb)
> > +   fmt = msm_framebuffer_format(pstate->base.fb);
> > +   else
> > +   fmt = dpu_get_msm_format(&_dpu_crtc_get_kms(crtc)->base,
> > +   DRM_FORMAT_RGBA, 0);  
> 
> The DRM_FORMAT_RGBA should be defined somewhere in patch 1 as format 
> for the solid_fill, then that define can be used in this patch.

Isn't this just a driver-specific decision to convert a RGB323232
solid_fill to be presented as a RGBA?

Though, below there is ABGR used for something... inconsistent?


Thanks,
pq

> 
> > +
> > +   format = to_dpu_format(fmt);
> >   
> > if (pstate->stage == DPU_STAGE_BASE && format->alpha_enable)
> > bg_alpha_enable = true;
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
> > b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > index 5f0984ce62b1..4476722f03bb 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > @@ -837,8 +837,10 @@ static int dpu_plane_atomic_check(struct drm_plane 
> > *plane,
> >   
> > pipe_cfg->dst_rect = new_plane_state->dst;
> >   
> > -   fb_rect.x2 = new_plane_state->fb->width;
> > -   fb_rect.y2 = new_plane_state->fb->height;
> > +   if (new_plane_state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && 
> > new_plane_state->fb) {
> > +   fb_rect.x2 = new_plane_state->fb->width;
> > +   fb_rect.y2 = new_plane_state->fb->height;
> > +   }
> >   
> > /* Ensure fb size is supported */
> > if (drm_rect_width(&fb_rect) > MAX_IMG_WIDTH ||
> > @@ -848,10 +850,13 @@ static int dpu_plane_atomic_check(struct drm_plane 
> > *plane,
> > return -E2BIG;
> > }
> >   
> > -   fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
> > -
> > max_linewidth = pdpu->catalog->caps->max_linewidth;
> >   
> > +   if (drm_plane_solid_fill_enabled(new_plane_state))
> > +   fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR);
> > +   else
> > +   fmt = 
> > to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
> > +
> > if (drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) {
> > /*
> >  * In parallel multirect case only the half of the usual width
> > @@ -1082,21 +1087,32 @@ static void dpu_plane_sspp_atomic_update(struct 
> > drm_plane *plane)
> > struct drm_crtc *crtc = state->crtc;
> > struct drm_framebuffer *fb = state->fb;
> > bool is_rt_pipe;
> > -   const struct dpu_format *fmt =
> > -   to_dpu_format(msm_framebuffer_format(fb));
> > +   const struct dpu_format *fmt;
> > struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
> > struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
> > struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
> > struct msm_gem_address_space *aspace = kms->base.aspace;
> > struct dpu_hw_fmt_layout layout;
> > bool layout_valid = false;
> > -   int ret;
> >   
> > -   ret = dpu_format_populate_layout(aspace, fb, &layout);
> > -   if (ret)
> > -   DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
> > -   else
> > -   layout_valid = true;
> > +   if (state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb) {
> > +   int ret;
> > +
> > +   fmt = to_dpu_format(msm_framebuffer_format(fb));
> > +
> > +   ret = dpu_format_populate_layout(aspace, fb, &layout);
> > +   if (ret)
> > +   DPU_ERROR_PLANE(pdpu, "fai

Re: [PATCH RFC v4 7/7] drm/msm/dpu: Use DRM solid_fill property

2023-06-30 Thread Pekka Paalanen
On Thu, 29 Jun 2023 17:25:06 -0700
Jessica Zhang  wrote:

> Drop DPU_PLANE_COLOR_FILL_FLAG and check the DRM solid_fill property to
> determine if the plane is solid fill. In addition drop the DPU plane
> color_fill field as we can now use drm_plane_state.solid_fill instead,
> and pass in drm_plane_state.alpha to _dpu_plane_color_fill_pipe() to
> allow userspace to configure the alpha value for the solid fill color.
> 
> Signed-off-by: Jessica Zhang 
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 21 +++--
>  1 file changed, 15 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index 4476722f03bb..11d4fb771a1f 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -42,7 +42,6 @@
>  #define SHARP_SMOOTH_THR_DEFAULT 8
>  #define SHARP_NOISE_THR_DEFAULT  2
>  
> -#define DPU_PLANE_COLOR_FILL_FLAGBIT(31)
>  #define DPU_ZPOS_MAX 255
>  
>  /*
> @@ -82,7 +81,6 @@ struct dpu_plane {
>  
>   enum dpu_sspp pipe;
>  
> - uint32_t color_fill;
>   bool is_error;
>   bool is_rt_pipe;
>   const struct dpu_mdss_cfg *catalog;
> @@ -606,6 +604,17 @@ static void _dpu_plane_color_fill_pipe(struct 
> dpu_plane_state *pstate,
>   _dpu_plane_setup_scaler(pipe, fmt, true, &pipe_cfg, pstate->rotation);
>  }
>  
> +static uint32_t _dpu_plane_get_fill_color(struct drm_solid_fill solid_fill)
> +{
> + uint32_t ret = 0;
> +
> + ret |= ((uint8_t) solid_fill.b) << 16;
> + ret |= ((uint8_t) solid_fill.g) << 8;
> + ret |= ((uint8_t) solid_fill.r);

solid_fill.r, g and b are uint32_t, yes?

What's the value encoding in the UAPI? That doc was missing.

I wouldn't expect the UAPI to use 32-bit variables if it was
essentially 8-bit, so this conversion looks wrong.

Nominal color value 1.0 in u8 is 0xff. The same in u32 is probably
0x? So a simple cast to u8 won't work. You'd want to take the
upper 8 bits instead.


Thanks,
pq

> +
> + return ret;
> +}
> +
>  /**
>   * _dpu_plane_color_fill - enables color fill on plane
>   * @pdpu:   Pointer to DPU plane object
> @@ -977,9 +986,9 @@ void dpu_plane_flush(struct drm_plane *plane)
>   if (pdpu->is_error)
>   /* force white frame with 100% alpha pipe output on error */
>   _dpu_plane_color_fill(pdpu, 0xFF, 0xFF);
> - else if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG)
> - /* force 100% alpha */
> - _dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF);
> + else if (drm_plane_solid_fill_enabled(plane->state))
> + _dpu_plane_color_fill(pdpu, 
> _dpu_plane_get_fill_color(plane->state->solid_fill),
> + plane->state->alpha);
>   else {
>   dpu_plane_flush_csc(pdpu, &pstate->pipe);
>   dpu_plane_flush_csc(pdpu, &pstate->r_pipe);
> @@ -1024,7 +1033,7 @@ static void dpu_plane_sspp_update_pipe(struct drm_plane 
> *plane,
>   }
>  
>   /* override for color fill */
> - if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG) {
> + if (drm_plane_solid_fill_enabled(plane->state)) {
>   _dpu_plane_set_qos_ctrl(plane, pipe, false);
>  
>   /* skip remaining processing on color fill */
> 



pgpMQc1w_Z33P.pgp
Description: OpenPGP digital signature


Re: [PATCH RFC v4 1/7] drm: Introduce solid fill DRM plane property

2023-06-30 Thread Pekka Paalanen
On Thu, 29 Jun 2023 17:25:00 -0700
Jessica Zhang  wrote:

> Document and add support for solid_fill property to drm_plane. In
> addition, add support for setting and getting the values for solid_fill.
> 
> To enable solid fill planes, userspace must assign a property blob to
> the "solid_fill" plane property containing the following information:
> 
> struct drm_solid_fill_info {
>   u8 version;
>   u32 r, g, b;
> };
> 
> Signed-off-by: Jessica Zhang 

Hi Jessica,

I've left some general UAPI related comments here.

> ---
>  drivers/gpu/drm/drm_atomic_state_helper.c |  9 +
>  drivers/gpu/drm/drm_atomic_uapi.c | 55 
> +++
>  drivers/gpu/drm/drm_blend.c   | 33 +++
>  include/drm/drm_blend.h   |  1 +
>  include/drm/drm_plane.h   | 43 
>  5 files changed, 141 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c 
> b/drivers/gpu/drm/drm_atomic_state_helper.c
> index 784e63d70a42..fe14be2bd2b2 100644
> --- a/drivers/gpu/drm/drm_atomic_state_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_state_helper.c
> @@ -253,6 +253,11 @@ void __drm_atomic_helper_plane_state_reset(struct 
> drm_plane_state *plane_state,
>   plane_state->alpha = DRM_BLEND_ALPHA_OPAQUE;
>   plane_state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
>  
> + if (plane_state->solid_fill_blob) {
> + drm_property_blob_put(plane_state->solid_fill_blob);
> + plane_state->solid_fill_blob = NULL;
> + }
> +
>   if (plane->color_encoding_property) {
>   if (!drm_object_property_get_default_value(&plane->base,
>  
> plane->color_encoding_property,
> @@ -335,6 +340,9 @@ void __drm_atomic_helper_plane_duplicate_state(struct 
> drm_plane *plane,
>   if (state->fb)
>   drm_framebuffer_get(state->fb);
>  
> + if (state->solid_fill_blob)
> + drm_property_blob_get(state->solid_fill_blob);
> +
>   state->fence = NULL;
>   state->commit = NULL;
>   state->fb_damage_clips = NULL;
> @@ -384,6 +392,7 @@ void __drm_atomic_helper_plane_destroy_state(struct 
> drm_plane_state *state)
>   drm_crtc_commit_put(state->commit);
>  
>   drm_property_blob_put(state->fb_damage_clips);
> + drm_property_blob_put(state->solid_fill_blob);
>  }
>  EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state);
>  
> diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
> b/drivers/gpu/drm/drm_atomic_uapi.c
> index d867e7f9f2cd..a28b4ee79444 100644
> --- a/drivers/gpu/drm/drm_atomic_uapi.c
> +++ b/drivers/gpu/drm/drm_atomic_uapi.c
> @@ -316,6 +316,51 @@ drm_atomic_set_crtc_for_connector(struct 
> drm_connector_state *conn_state,
>  }
>  EXPORT_SYMBOL(drm_atomic_set_crtc_for_connector);
>  
> +static int drm_atomic_set_solid_fill_prop(struct drm_plane_state *state,
> + struct drm_property_blob *blob)
> +{
> + int ret = 0;
> + int blob_version;
> +
> + if (blob == state->solid_fill_blob)
> + return 0;
> +
> + drm_property_blob_put(state->solid_fill_blob);
> + state->solid_fill_blob = NULL;

Is it ok to destroy old state before it is guaranteed that the new
state is accepted?

> +
> + memset(&state->solid_fill, 0, sizeof(state->solid_fill));
> +
> + if (blob) {
> + struct drm_solid_fill_info *user_info = (struct 
> drm_solid_fill_info *)blob->data;
> +
> + if (blob->length != sizeof(struct drm_solid_fill_info)) {
> + drm_dbg_atomic(state->plane->dev,
> +"[PLANE:%d:%s] bad solid fill blob 
> length: %zu\n",
> +state->plane->base.id, 
> state->plane->name,
> +blob->length);
> + return -EINVAL;
> + }
> +
> + blob_version = user_info->version;
> +
> + /* Add more versions if necessary */
> + if (blob_version == 1) {
> + state->solid_fill.r = user_info->r;
> + state->solid_fill.g = user_info->g;
> + state->solid_fill.b = user_info->b;
> + } else {
> + drm_dbg_atomic(state->plane->dev,
> +"[PLANE:%d:%s] failed to set solid fill 
> (ret=%d)\n",
> +state->plane->base.id, 
> state->plane->name,
> +ret);
> + return -EINVAL;

Btw. how does the atomic check machinery work here?

I expect that a TEST_ONLY atomic commit will do all the above checks
and return failure if anything is not right. Right?

> + }
> + state->solid_fill_blob = drm_property_blob_get(blob);
> + }
> +
> + return ret;
> +}
> +
>  static void set_out_fence_for_crtc(struct drm_atomic_state *state,
>  

Re: [PATCH RFC v4 2/7] drm: Introduce pixel_source DRM plane property

2023-06-30 Thread Pekka Paalanen
On Fri, 30 Jun 2023 03:42:28 +0300
Dmitry Baryshkov  wrote:

> On 30/06/2023 03:25, Jessica Zhang wrote:
> > Add support for pixel_source property to drm_plane and related
> > documentation.
> > 
> > This enum property will allow user to specify a pixel source for the
> > plane. Possible pixel sources will be defined in the
> > drm_plane_pixel_source enum.
> > 
> > The current possible pixel sources are DRM_PLANE_PIXEL_SOURCE_FB and
> > DRM_PLANE_PIXEL_SOURCE_COLOR. The default value is *_SOURCE_FB.  
> 
> I think, this should come before the solid fill property addition. First 
> you tell that there is a possibility to define other pixel sources, then 
> additional sources are defined.

Hi,

that would be logical indeed.

> > 
> > Signed-off-by: Jessica Zhang 
> > ---
> >   drivers/gpu/drm/drm_atomic_state_helper.c |  1 +
> >   drivers/gpu/drm/drm_atomic_uapi.c |  4 ++
> >   drivers/gpu/drm/drm_blend.c   | 81 
> > +++
> >   include/drm/drm_blend.h   |  2 +
> >   include/drm/drm_plane.h   | 21 
> >   5 files changed, 109 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c 
> > b/drivers/gpu/drm/drm_atomic_state_helper.c
> > index fe14be2bd2b2..86fb876efbe6 100644
> > --- a/drivers/gpu/drm/drm_atomic_state_helper.c
> > +++ b/drivers/gpu/drm/drm_atomic_state_helper.c
> > @@ -252,6 +252,7 @@ void __drm_atomic_helper_plane_state_reset(struct 
> > drm_plane_state *plane_state,
> >   
> > plane_state->alpha = DRM_BLEND_ALPHA_OPAQUE;
> > plane_state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
> > +   plane_state->pixel_source = DRM_PLANE_PIXEL_SOURCE_FB;
> >   
> > if (plane_state->solid_fill_blob) {
> > drm_property_blob_put(plane_state->solid_fill_blob);
> > diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
> > b/drivers/gpu/drm/drm_atomic_uapi.c
> > index a28b4ee79444..6e59c21af66b 100644
> > --- a/drivers/gpu/drm/drm_atomic_uapi.c
> > +++ b/drivers/gpu/drm/drm_atomic_uapi.c
> > @@ -596,6 +596,8 @@ static int drm_atomic_plane_set_property(struct 
> > drm_plane *plane,
> > drm_property_blob_put(solid_fill);
> >   
> > return ret;
> > +   } else if (property == plane->pixel_source_property) {
> > +   state->pixel_source = val;
> > } else if (property == plane->alpha_property) {
> > state->alpha = val;
> > } else if (property == plane->blend_mode_property) {  
> 
> I think, it was pointed out in the discussion that drm_mode_setplane() 
> (a pre-atomic IOCTL to turn the plane on and off) should also reset 
> pixel_source to FB.
> 
> > @@ -671,6 +673,8 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
> > } else if (property == plane->solid_fill_property) {
> > *val = state->solid_fill_blob ?
> > state->solid_fill_blob->base.id : 0;
> > +   } else if (property == plane->pixel_source_property) {
> > +   *val = state->pixel_source;
> > } else if (property == plane->alpha_property) {
> > *val = state->alpha;
> > } else if (property == plane->blend_mode_property) {
> > diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
> > index 38c3c5d6453a..8c100a957ee2 100644
> > --- a/drivers/gpu/drm/drm_blend.c
> > +++ b/drivers/gpu/drm/drm_blend.c
> > @@ -189,6 +189,18 @@
> >*solid_fill is set up with 
> > drm_plane_create_solid_fill_property(). It
> >*contains pixel data that drivers can use to fill a plane.
> >*
> > + * pixel_source:
> > + * pixel_source is set up with drm_plane_create_pixel_source_property().
> > + * It is used to toggle the source of pixel data for the plane.

Other sources than the selected one are ignored?

> > + *
> > + * Possible values:

Wouldn't hurt to explicitly mention here that this is an enum.

> > + *
> > + * "FB":
> > + * Framebuffer source
> > + *
> > + * "COLOR":
> > + * solid_fill source

I think these two should be more explicit. Framebuffer source is the
usual source from the property "FB_ID". Solid fill source comes from
the property "solid_fill".

Why "COLOR" and not, say, "SOLID_FILL"?

> > + *
> >* Note that all the property extensions described here apply either to 
> > the
> >* plane or the CRTC (e.g. for the background color, which currently is 
> > not
> >* exposed and assumed to be black).
> > @@ -648,3 +660,72 @@ int drm_plane_create_solid_fill_property(struct 
> > drm_plane *plane)
> > return 0;
> >   }
> >   EXPORT_SYMBOL(drm_plane_create_solid_fill_property);
> > +
> > +/**
> > + * drm_plane_create_pixel_source_property - create a new pixel source 
> > property
> > + * @plane: drm plane
> > + * @supported_sources: bitmask of supported pixel_sources for the driver 
> > (NOT
> > + * including DRM_PLANE_PIXEL_SOURCE_FB, as it will be 
> > supported
> > + * by default).  
> 
> I'd say this is too strong. I'd 

Re: [PATCH RFC v4 1/7] drm: Introduce solid fill DRM plane property

2023-06-30 Thread Dmitry Baryshkov

On 30/06/2023 03:25, Jessica Zhang wrote:

Document and add support for solid_fill property to drm_plane. In
addition, add support for setting and getting the values for solid_fill.

To enable solid fill planes, userspace must assign a property blob to
the "solid_fill" plane property containing the following information:

struct drm_solid_fill_info {
u8 version;
u32 r, g, b;
};

Signed-off-by: Jessica Zhang 
---
  drivers/gpu/drm/drm_atomic_state_helper.c |  9 +
  drivers/gpu/drm/drm_atomic_uapi.c | 55 +++
  drivers/gpu/drm/drm_blend.c   | 33 +++
  include/drm/drm_blend.h   |  1 +
  include/drm/drm_plane.h   | 43 
  5 files changed, 141 insertions(+)


Also, I think the point which we missed up to now. Could you please add 
both new properties to dri/N/state debugfs?


--
With best wishes
Dmitry



Re: [PATCH RFC v4 2/7] drm: Introduce pixel_source DRM plane property

2023-06-30 Thread Sebastian Wick
On Fri, Jun 30, 2023 at 2:26 AM Jessica Zhang  wrote:
>
> Add support for pixel_source property to drm_plane and related
> documentation.
>
> This enum property will allow user to specify a pixel source for the
> plane. Possible pixel sources will be defined in the
> drm_plane_pixel_source enum.
>
> The current possible pixel sources are DRM_PLANE_PIXEL_SOURCE_FB and
> DRM_PLANE_PIXEL_SOURCE_COLOR. The default value is *_SOURCE_FB.
>
> Signed-off-by: Jessica Zhang 
> ---
>  drivers/gpu/drm/drm_atomic_state_helper.c |  1 +
>  drivers/gpu/drm/drm_atomic_uapi.c |  4 ++
>  drivers/gpu/drm/drm_blend.c   | 81 
> +++
>  include/drm/drm_blend.h   |  2 +
>  include/drm/drm_plane.h   | 21 
>  5 files changed, 109 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c 
> b/drivers/gpu/drm/drm_atomic_state_helper.c
> index fe14be2bd2b2..86fb876efbe6 100644
> --- a/drivers/gpu/drm/drm_atomic_state_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_state_helper.c
> @@ -252,6 +252,7 @@ void __drm_atomic_helper_plane_state_reset(struct 
> drm_plane_state *plane_state,
>
> plane_state->alpha = DRM_BLEND_ALPHA_OPAQUE;
> plane_state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
> +   plane_state->pixel_source = DRM_PLANE_PIXEL_SOURCE_FB;
>
> if (plane_state->solid_fill_blob) {
> drm_property_blob_put(plane_state->solid_fill_blob);
> diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
> b/drivers/gpu/drm/drm_atomic_uapi.c
> index a28b4ee79444..6e59c21af66b 100644
> --- a/drivers/gpu/drm/drm_atomic_uapi.c
> +++ b/drivers/gpu/drm/drm_atomic_uapi.c
> @@ -596,6 +596,8 @@ static int drm_atomic_plane_set_property(struct drm_plane 
> *plane,
> drm_property_blob_put(solid_fill);
>
> return ret;
> +   } else if (property == plane->pixel_source_property) {
> +   state->pixel_source = val;
> } else if (property == plane->alpha_property) {
> state->alpha = val;
> } else if (property == plane->blend_mode_property) {
> @@ -671,6 +673,8 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
> } else if (property == plane->solid_fill_property) {
> *val = state->solid_fill_blob ?
> state->solid_fill_blob->base.id : 0;
> +   } else if (property == plane->pixel_source_property) {
> +   *val = state->pixel_source;
> } else if (property == plane->alpha_property) {
> *val = state->alpha;
> } else if (property == plane->blend_mode_property) {
> diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
> index 38c3c5d6453a..8c100a957ee2 100644
> --- a/drivers/gpu/drm/drm_blend.c
> +++ b/drivers/gpu/drm/drm_blend.c
> @@ -189,6 +189,18 @@
>   * solid_fill is set up with drm_plane_create_solid_fill_property(). It
>   * contains pixel data that drivers can use to fill a plane.
>   *
> + * pixel_source:
> + * pixel_source is set up with drm_plane_create_pixel_source_property().
> + * It is used to toggle the source of pixel data for the plane.
> + *
> + * Possible values:
> + *
> + * "FB":
> + * Framebuffer source
> + *
> + * "COLOR":
> + * solid_fill source
> + *
>   * Note that all the property extensions described here apply either to the
>   * plane or the CRTC (e.g. for the background color, which currently is not
>   * exposed and assumed to be black).
> @@ -648,3 +660,72 @@ int drm_plane_create_solid_fill_property(struct 
> drm_plane *plane)
> return 0;
>  }
>  EXPORT_SYMBOL(drm_plane_create_solid_fill_property);
> +
> +/**
> + * drm_plane_create_pixel_source_property - create a new pixel source 
> property
> + * @plane: drm plane
> + * @supported_sources: bitmask of supported pixel_sources for the driver (NOT
> + * including DRM_PLANE_PIXEL_SOURCE_FB, as it will be 
> supported
> + * by default).
> + *
> + * This creates a new property describing the current source of pixel data 
> for the
> + * plane.
> + *
> + * The property is exposed to userspace as an enumeration property called
> + * "pixel_source" and has the following enumeration values:
> + *
> + * "FB":
> + * Framebuffer pixel source
> + *
> + * "COLOR":
> + * Solid fill color pixel source

Can we add a "NONE" value?

I know it has been discussed earlier if we *need*  this and I don't
think we do. I just think it would be better API design to disable
planes this way than having to know that a framebuffer pixel source
with a NULL framebuffer disables the plane. Obviously also keep the
old behavior for backwards compatibility.

> + *
> + * Returns:
> + * Zero on success, negative errno on failure.
> + */
> +int drm_plane_create_pixel_source_property(struct drm_plane *plane,
> +  unsigned int supported_sources)
> +{
> + 

Re: [PATCH RFC v4 1/7] drm: Introduce solid fill DRM plane property

2023-06-30 Thread Jessica Zhang




On 6/30/2023 3:33 AM, Dmitry Baryshkov wrote:

On 30/06/2023 03:25, Jessica Zhang wrote:

Document and add support for solid_fill property to drm_plane. In
addition, add support for setting and getting the values for solid_fill.

To enable solid fill planes, userspace must assign a property blob to
the "solid_fill" plane property containing the following information:

struct drm_solid_fill_info {
u8 version;
u32 r, g, b;
};

Signed-off-by: Jessica Zhang 
---
  drivers/gpu/drm/drm_atomic_state_helper.c |  9 +
  drivers/gpu/drm/drm_atomic_uapi.c | 55 
+++

  drivers/gpu/drm/drm_blend.c   | 33 +++
  include/drm/drm_blend.h   |  1 +
  include/drm/drm_plane.h   | 43 
  5 files changed, 141 insertions(+)


Also, I think the point which we missed up to now. Could you please add 
both new properties to dri/N/state debugfs?


Hi Dmitry,

Good catch -- acked.

Thanks,

Jessica Zhang



--
With best wishes
Dmitry



Re: [PATCH RFC v4 3/7] drm/atomic: Move framebuffer checks to helper

2023-06-30 Thread Jessica Zhang




On 6/29/2023 5:43 PM, Dmitry Baryshkov wrote:

On 30/06/2023 03:25, Jessica Zhang wrote:

Currently framebuffer checks happen directly in
drm_atomic_plane_check(). Move these checks into their own helper
method.

Signed-off-by: Jessica Zhang 
---
  drivers/gpu/drm/drm_atomic.c | 130 
---

  1 file changed, 74 insertions(+), 56 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index b4c6ffc438da..404b984d2d9f 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -580,6 +580,76 @@ plane_switching_crtc(const struct drm_plane_state 
*old_plane_state,

  return true;
  }
+static int drm_atomic_check_fb(const struct drm_plane_state *state)
+{
+    struct drm_plane *plane = state->plane;
+    const struct drm_framebuffer *fb = state->fb;
+    struct drm_mode_rect *clips;
+
+    uint32_t num_clips;
+    unsigned int fb_width, fb_height;
+    int ret;
+
+    /* Check whether this plane supports the fb pixel format. */
+    ret = drm_plane_check_pixel_format(plane, fb->format->format,
+   fb->modifier);
+
+    if (ret) {
+    drm_dbg_atomic(plane->dev,
+   "[PLANE:%d:%s] invalid pixel format %p4cc, 
modifier 0x%llx\n",

+   plane->base.id, plane->name,
+   &fb->format->format, fb->modifier);
+    return ret;
+    }
+
+    fb_width = fb->width << 16;
+    fb_height = fb->height << 16;
+
+    /* Make sure source coordinates are inside the fb. */
+    if (state->src_w > fb_width ||
+    state->src_x > fb_width - state->src_w ||
+    state->src_h > fb_height ||
+    state->src_y > fb_height - state->src_h) {
+    drm_dbg_atomic(plane->dev,
+   "[PLANE:%d:%s] invalid source coordinates "
+   "%u.%06ux%u.%06u+%u.%06u+%u.%06u (fb %ux%u)\n",
+   plane->base.id, plane->name,
+   state->src_w >> 16,
+   ((state->src_w & 0x) * 15625) >> 10,
+   state->src_h >> 16,
+   ((state->src_h & 0x) * 15625) >> 10,
+   state->src_x >> 16,
+   ((state->src_x & 0x) * 15625) >> 10,
+   state->src_y >> 16,
+   ((state->src_y & 0x) * 15625) >> 10,
+   fb->width, fb->height);
+    return -ENOSPC;
+    }
+
+    clips = __drm_plane_get_damage_clips(state);
+    num_clips = drm_plane_get_damage_clips_count(state);
+
+    /* Make sure damage clips are valid and inside the fb. */
+    while (num_clips > 0) {
+    if (clips->x1 >= clips->x2 ||
+    clips->y1 >= clips->y2 ||
+    clips->x1 < 0 ||
+    clips->y1 < 0 ||
+    clips->x2 > fb_width ||
+    clips->y2 > fb_height) {
+    drm_dbg_atomic(plane->dev,
+   "[PLANE:%d:%s] invalid damage clip %d %d %d 
%d\n",

+   plane->base.id, plane->name, clips->x1,
+   clips->y1, clips->x2, clips->y2);
+    return -EINVAL;
+    }
+    clips++;
+    num_clips--;
+    }
+
+    return 0;
+}
+
  /**
   * drm_atomic_plane_check - check plane state
   * @old_plane_state: old plane state to check
@@ -596,9 +666,6 @@ static int drm_atomic_plane_check(const struct 
drm_plane_state *old_plane_state,

  struct drm_plane *plane = new_plane_state->plane;
  struct drm_crtc *crtc = new_plane_state->crtc;
  const struct drm_framebuffer *fb = new_plane_state->fb;
-    unsigned int fb_width, fb_height;
-    struct drm_mode_rect *clips;
-    uint32_t num_clips;
  int ret;
  /* either *both* CRTC and FB must be set, or neither */
@@ -625,17 +692,6 @@ static int drm_atomic_plane_check(const struct 
drm_plane_state *old_plane_state,

  return -EINVAL;
  }
-    /* Check whether this plane supports the fb pixel format. */
-    ret = drm_plane_check_pixel_format(plane, fb->format->format,
-   fb->modifier);
-    if (ret) {
-    drm_dbg_atomic(plane->dev,
-   "[PLANE:%d:%s] invalid pixel format %p4cc, 
modifier 0x%llx\n",

-   plane->base.id, plane->name,
-   &fb->format->format, fb->modifier);
-    return ret;
-    }
-
  /* Give drivers some help against integer overflows */
  if (new_plane_state->crtc_w > INT_MAX ||
  new_plane_state->crtc_x > INT_MAX - (int32_t) 
new_plane_state->crtc_w ||
@@ -649,49 +705,11 @@ static int drm_atomic_plane_check(const struct 
drm_plane_state *old_plane_state,

  return -ERANGE;
  }
-    fb_width = fb->width << 16;
-    fb_height = fb->height << 16;
-    /* Make sure source coordinates are inside the fb. */
-    if (new_plane_state->src_w > fb_width ||
-    new_plane_state->src_x > fb_width - new_plane_state->src_w ||
-    new_plane_state->src_h > fb_height ||
-    new_plane_state->src_y > fb_height - new_plane_state->

Re: [PATCH RFC v4 2/7] drm: Introduce pixel_source DRM plane property

2023-06-30 Thread Jessica Zhang




On 6/30/2023 7:43 AM, Sebastian Wick wrote:

On Fri, Jun 30, 2023 at 2:26 AM Jessica Zhang  wrote:


Add support for pixel_source property to drm_plane and related
documentation.

This enum property will allow user to specify a pixel source for the
plane. Possible pixel sources will be defined in the
drm_plane_pixel_source enum.

The current possible pixel sources are DRM_PLANE_PIXEL_SOURCE_FB and
DRM_PLANE_PIXEL_SOURCE_COLOR. The default value is *_SOURCE_FB.

Signed-off-by: Jessica Zhang 
---
  drivers/gpu/drm/drm_atomic_state_helper.c |  1 +
  drivers/gpu/drm/drm_atomic_uapi.c |  4 ++
  drivers/gpu/drm/drm_blend.c   | 81 +++
  include/drm/drm_blend.h   |  2 +
  include/drm/drm_plane.h   | 21 
  5 files changed, 109 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c 
b/drivers/gpu/drm/drm_atomic_state_helper.c
index fe14be2bd2b2..86fb876efbe6 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -252,6 +252,7 @@ void __drm_atomic_helper_plane_state_reset(struct 
drm_plane_state *plane_state,

 plane_state->alpha = DRM_BLEND_ALPHA_OPAQUE;
 plane_state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
+   plane_state->pixel_source = DRM_PLANE_PIXEL_SOURCE_FB;

 if (plane_state->solid_fill_blob) {
 drm_property_blob_put(plane_state->solid_fill_blob);
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
b/drivers/gpu/drm/drm_atomic_uapi.c
index a28b4ee79444..6e59c21af66b 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -596,6 +596,8 @@ static int drm_atomic_plane_set_property(struct drm_plane 
*plane,
 drm_property_blob_put(solid_fill);

 return ret;
+   } else if (property == plane->pixel_source_property) {
+   state->pixel_source = val;
 } else if (property == plane->alpha_property) {
 state->alpha = val;
 } else if (property == plane->blend_mode_property) {
@@ -671,6 +673,8 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
 } else if (property == plane->solid_fill_property) {
 *val = state->solid_fill_blob ?
 state->solid_fill_blob->base.id : 0;
+   } else if (property == plane->pixel_source_property) {
+   *val = state->pixel_source;
 } else if (property == plane->alpha_property) {
 *val = state->alpha;
 } else if (property == plane->blend_mode_property) {
diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
index 38c3c5d6453a..8c100a957ee2 100644
--- a/drivers/gpu/drm/drm_blend.c
+++ b/drivers/gpu/drm/drm_blend.c
@@ -189,6 +189,18 @@
   * solid_fill is set up with drm_plane_create_solid_fill_property(). It
   * contains pixel data that drivers can use to fill a plane.
   *
+ * pixel_source:
+ * pixel_source is set up with drm_plane_create_pixel_source_property().
+ * It is used to toggle the source of pixel data for the plane.
+ *
+ * Possible values:
+ *
+ * "FB":
+ * Framebuffer source
+ *
+ * "COLOR":
+ * solid_fill source
+ *
   * Note that all the property extensions described here apply either to the
   * plane or the CRTC (e.g. for the background color, which currently is not
   * exposed and assumed to be black).
@@ -648,3 +660,72 @@ int drm_plane_create_solid_fill_property(struct drm_plane 
*plane)
 return 0;
  }
  EXPORT_SYMBOL(drm_plane_create_solid_fill_property);
+
+/**
+ * drm_plane_create_pixel_source_property - create a new pixel source property
+ * @plane: drm plane
+ * @supported_sources: bitmask of supported pixel_sources for the driver (NOT
+ * including DRM_PLANE_PIXEL_SOURCE_FB, as it will be 
supported
+ * by default).
+ *
+ * This creates a new property describing the current source of pixel data for 
the
+ * plane.
+ *
+ * The property is exposed to userspace as an enumeration property called
+ * "pixel_source" and has the following enumeration values:
+ *
+ * "FB":
+ * Framebuffer pixel source
+ *
+ * "COLOR":
+ * Solid fill color pixel source


Can we add a "NONE" value?

I know it has been discussed earlier if we *need*  this and I don't
think we do. I just think it would be better API design to disable
planes this way than having to know that a framebuffer pixel source
with a NULL framebuffer disables the plane. Obviously also keep the
old behavior for backwards compatibility.


Hi Sebastian,

Sounds good.

So if pixel_source == NONE disables the planes, would that mean cases 
where pixel_source == COLOR && solid_fill_blob == NULL, the atomic 
commit should throw an error?


Thanks,

Jessica Zhang




+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int drm_plane_create_pixel_source_property(struct drm_plane *plane,

Re: [PATCH RFC v4 4/7] drm/atomic: Loosen FB atomic checks

2023-06-30 Thread Jessica Zhang




On 6/29/2023 5:48 PM, Dmitry Baryshkov wrote:

On 30/06/2023 03:25, Jessica Zhang wrote:

Loosen the requirements for atomic and legacy commit so that, in cases
where solid fill planes is enabled but no FB is set, the commit can
still go through.

This includes adding framebuffer NULL checks in other areas to account
for FB being NULL when solid fill is enabled.

Signed-off-by: Jessica Zhang 
---
  drivers/gpu/drm/drm_atomic.c    | 14 +++---
  drivers/gpu/drm/drm_atomic_helper.c | 34 
--

  drivers/gpu/drm/drm_plane.c |  8 
  include/drm/drm_atomic_helper.h |  4 ++--
  include/drm/drm_plane.h | 28 
  5 files changed, 61 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 404b984d2d9f..ec9681c25366 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -668,14 +668,14 @@ static int drm_atomic_plane_check(const struct 
drm_plane_state *old_plane_state,

  const struct drm_framebuffer *fb = new_plane_state->fb;
  int ret;
-    /* either *both* CRTC and FB must be set, or neither */
-    if (crtc && !fb) {
-    drm_dbg_atomic(plane->dev, "[PLANE:%d:%s] CRTC set but no FB\n",
+    /* either *both* CRTC and pixel source must be set, or neither */
+    if (crtc && !drm_plane_has_visible_data(new_plane_state)) {
+    drm_dbg_atomic(plane->dev, "[PLANE:%d:%s] CRTC set but no 
visible data\n",

 plane->base.id, plane->name);
  return -EINVAL;
-    } else if (fb && !crtc) {
-    drm_dbg_atomic(plane->dev, "[PLANE:%d:%s] FB set but no CRTC\n",
-   plane->base.id, plane->name);
+    } else if (drm_plane_has_visible_data(new_plane_state) && !crtc) {
+    drm_dbg_atomic(plane->dev, "[PLANE:%d:%s] Source %d has 
visible data but no CRTC\n",
+   plane->base.id, plane->name, 
new_plane_state->pixel_source);

  return -EINVAL;
  }
@@ -706,7 +706,7 @@ static int drm_atomic_plane_check(const struct 
drm_plane_state *old_plane_state,

  }
-    if (fb) {
+    if (new_plane_state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && 
fb) {

  ret = drm_atomic_check_fb(new_plane_state);
  if (ret)
  return ret;
diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c

index 41b8066f61ff..d05ec9ef2b3e 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -864,7 +864,7 @@ int drm_atomic_helper_check_plane_state(struct 
drm_plane_state *plane_state,

  *src = drm_plane_state_src(plane_state);
  *dst = drm_plane_state_dest(plane_state);
-    if (!fb) {
+    if (!drm_plane_has_visible_data(plane_state)) {
  plane_state->visible = false;
  return 0;
  }
@@ -881,25 +881,31 @@ int drm_atomic_helper_check_plane_state(struct 
drm_plane_state *plane_state,

  return -EINVAL;
  }
-    drm_rect_rotate(src, fb->width << 16, fb->height << 16, rotation);
+    if (plane_state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb) {
+    drm_rect_rotate(src, fb->width << 16, fb->height << 16, 
rotation);

-    /* Check scaling */
-    hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
-    vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
-    if (hscale < 0 || vscale < 0) {
-    drm_dbg_kms(plane_state->plane->dev,
-    "Invalid scaling of plane\n");
-    drm_rect_debug_print("src: ", &plane_state->src, true);
-    drm_rect_debug_print("dst: ", &plane_state->dst, false);
-    return -ERANGE;
+    /* Check scaling */
+    hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
+    vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
+
+    if (hscale < 0 || vscale < 0) {
+    drm_dbg_kms(plane_state->plane->dev,
+    "Invalid scaling of plane\n");
+    drm_rect_debug_print("src: ", &plane_state->src, true);
+    drm_rect_debug_print("dst: ", &plane_state->dst, false);
+    return -ERANGE;
+    }
  }
  if (crtc_state->enable)
  drm_mode_get_hv_timing(&crtc_state->mode, &clip.x2, &clip.y2);
-    plane_state->visible = drm_rect_clip_scaled(src, dst, &clip);
-
-    drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, 
rotation);

+    if (plane_state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb) {
+    plane_state->visible = drm_rect_clip_scaled(src, dst, &clip);
+    drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, 
rotation);

+    } else if (drm_plane_solid_fill_enabled(plane_state)) {
+    plane_state->visible = true;
+    }
  if (!plane_state->visible)
  /*
diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
index 24e7998d1731..5f19a27ba182 100644
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ 

Re: [PATCH RFC v4 5/7] drm/msm/dpu: Add solid fill and pixel source properties

2023-06-30 Thread Jessica Zhang




On 6/29/2023 5:49 PM, Dmitry Baryshkov wrote:

On 30/06/2023 03:25, Jessica Zhang wrote:

Add solid_fill and pixel_source properties to DPU plane

Signed-off-by: Jessica Zhang 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 2 ++
  1 file changed, 2 insertions(+)


This should be the last commit.


Hi Dmitry,

Acked, will move this to the end.

Thanks,

Jessica Zhang


Otherwise:

Reviewed-by: Dmitry Baryshkov 



diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c

index c2aaaded07ed..5f0984ce62b1 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1429,6 +1429,8 @@ struct drm_plane *dpu_plane_init(struct 
drm_device *dev,

  DPU_ERROR("failed to install zpos property, rc = %d\n", ret);
  drm_plane_create_alpha_property(plane);
+    drm_plane_create_solid_fill_property(plane);
+    drm_plane_create_pixel_source_property(plane, 
BIT(DRM_PLANE_PIXEL_SOURCE_COLOR));

  drm_plane_create_blend_mode_property(plane,
  BIT(DRM_MODE_BLEND_PIXEL_NONE) |
  BIT(DRM_MODE_BLEND_PREMULTI) |



--
With best wishes
Dmitry



Re: [PATCH RFC v4 6/7] drm/msm/dpu: Allow NULL FBs in atomic commit

2023-06-30 Thread Jessica Zhang




On 6/30/2023 1:21 AM, Pekka Paalanen wrote:

On Fri, 30 Jun 2023 03:52:37 +0300
Dmitry Baryshkov  wrote:


On 30/06/2023 03:25, Jessica Zhang wrote:

Since solid fill planes allow for a NULL framebuffer in a valid commit,
add NULL framebuffer checks to atomic commit calls within DPU.

Signed-off-by: Jessica Zhang 
---
   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  |  9 ++-
   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 45 
+++
   2 files changed, 36 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 1edf2b6b0a26..d1b37d2cc202 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -451,6 +451,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc 
*crtc,
struct drm_plane_state *state;
struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state);
struct dpu_plane_state *pstate = NULL;
+   const struct msm_format *fmt;
struct dpu_format *format;
struct dpu_hw_ctl *ctl = mixer->lm_ctl;
   
@@ -470,7 +471,13 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,

pstate = to_dpu_plane_state(state);
fb = state->fb;
   
-		format = to_dpu_format(msm_framebuffer_format(pstate->base.fb));

+   if (state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb)
+   fmt = msm_framebuffer_format(pstate->base.fb);
+   else
+   fmt = dpu_get_msm_format(&_dpu_crtc_get_kms(crtc)->base,
+   DRM_FORMAT_RGBA, 0);


The DRM_FORMAT_RGBA should be defined somewhere in patch 1 as format
for the solid_fill, then that define can be used in this patch.


Isn't this just a driver-specific decision to convert a RGB323232
solid_fill to be presented as a RGBA?


Hi Dmitry and Pekka,

Yes, the ABGR format is specific to msm/dpu. In earlier revisions of 
the series, we had come to an agreement that the solid fill property 
should take RGB323232 to match the similar Wayland single pixel buffer 
protocol [1].


[1] 
https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/104




Though, below there is ABGR used for something... inconsistent?


Typo on my part. The format should be consistently ABGR.

Thanks,

Jessica Zhang




Thanks,
pq




+
+   format = to_dpu_format(fmt);
   
   		if (pstate->stage == DPU_STAGE_BASE && format->alpha_enable)

bg_alpha_enable = true;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 5f0984ce62b1..4476722f03bb 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -837,8 +837,10 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
   
   	pipe_cfg->dst_rect = new_plane_state->dst;
   
-	fb_rect.x2 = new_plane_state->fb->width;

-   fb_rect.y2 = new_plane_state->fb->height;
+   if (new_plane_state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && 
new_plane_state->fb) {
+   fb_rect.x2 = new_plane_state->fb->width;
+   fb_rect.y2 = new_plane_state->fb->height;
+   }
   
   	/* Ensure fb size is supported */

if (drm_rect_width(&fb_rect) > MAX_IMG_WIDTH ||
@@ -848,10 +850,13 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
return -E2BIG;
}
   
-	fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));

-
max_linewidth = pdpu->catalog->caps->max_linewidth;
   
+	if (drm_plane_solid_fill_enabled(new_plane_state))

+   fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR);
+   else
+   fmt = 
to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
+
if (drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) {
/*
 * In parallel multirect case only the half of the usual width
@@ -1082,21 +1087,32 @@ static void dpu_plane_sspp_atomic_update(struct 
drm_plane *plane)
struct drm_crtc *crtc = state->crtc;
struct drm_framebuffer *fb = state->fb;
bool is_rt_pipe;
-   const struct dpu_format *fmt =
-   to_dpu_format(msm_framebuffer_format(fb));
+   const struct dpu_format *fmt;
struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
struct msm_gem_address_space *aspace = kms->base.aspace;
struct dpu_hw_fmt_layout layout;
bool layout_valid = false;
-   int ret;
   
-	ret = dpu_format_populate_layout(aspace, fb, &layout);

-   if (ret)
-   DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
-   else
-   layout_valid = true;
+   if (state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB

Re: [PATCH RFC v4 7/7] drm/msm/dpu: Use DRM solid_fill property

2023-06-30 Thread Jessica Zhang




On 6/29/2023 5:59 PM, Dmitry Baryshkov wrote:

On 30/06/2023 03:25, Jessica Zhang wrote:

Drop DPU_PLANE_COLOR_FILL_FLAG and check the DRM solid_fill property to
determine if the plane is solid fill. In addition drop the DPU plane
color_fill field as we can now use drm_plane_state.solid_fill instead,
and pass in drm_plane_state.alpha to _dpu_plane_color_fill_pipe() to
allow userspace to configure the alpha value for the solid fill color.

Signed-off-by: Jessica Zhang 


Reviewed-by: Dmitry Baryshkov 

Minor suggestion below.


---
  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 21 +++--
  1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c

index 4476722f03bb..11d4fb771a1f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -42,7 +42,6 @@
  #define SHARP_SMOOTH_THR_DEFAULT    8
  #define SHARP_NOISE_THR_DEFAULT    2
-#define DPU_PLANE_COLOR_FILL_FLAG    BIT(31)
  #define DPU_ZPOS_MAX 255
  /*
@@ -82,7 +81,6 @@ struct dpu_plane {
  enum dpu_sspp pipe;
-    uint32_t color_fill;
  bool is_error;
  bool is_rt_pipe;
  const struct dpu_mdss_cfg *catalog;
@@ -606,6 +604,17 @@ static void _dpu_plane_color_fill_pipe(struct 
dpu_plane_state *pstate,
  _dpu_plane_setup_scaler(pipe, fmt, true, &pipe_cfg, 
pstate->rotation);

  }
+static uint32_t _dpu_plane_get_fill_color(struct drm_solid_fill 
solid_fill)


Please consider accepting drm_plane_state instead and handling alpha 
here. Then _dpu_color_fill can accept rgba colour instead of separate 
RGB and alpha values.


Hi Dmitry,

Do you mean adding a patch to refactor _dpu_plane_color_fill() to accept 
an RGBA color?


Since, currently, the `color` parameter gets truncated to a BGR888 value 
and OR'd with the `alpha` parameter [1].


Thanks,

Jessica Zhang

[1] 
https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c#L682





+{
+    uint32_t ret = 0;
+
+    ret |= ((uint8_t) solid_fill.b) << 16;
+    ret |= ((uint8_t) solid_fill.g) << 8;
+    ret |= ((uint8_t) solid_fill.r);
+
+    return ret;
+}
+
  /**
   * _dpu_plane_color_fill - enables color fill on plane
   * @pdpu:   Pointer to DPU plane object
@@ -977,9 +986,9 @@ void dpu_plane_flush(struct drm_plane *plane)
  if (pdpu->is_error)
  /* force white frame with 100% alpha pipe output on error */
  _dpu_plane_color_fill(pdpu, 0xFF, 0xFF);
-    else if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG)
-    /* force 100% alpha */
-    _dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF);
+    else if (drm_plane_solid_fill_enabled(plane->state))
+    _dpu_plane_color_fill(pdpu, 
_dpu_plane_get_fill_color(plane->state->solid_fill),

+    plane->state->alpha);
  else {
  dpu_plane_flush_csc(pdpu, &pstate->pipe);
  dpu_plane_flush_csc(pdpu, &pstate->r_pipe);
@@ -1024,7 +1033,7 @@ static void dpu_plane_sspp_update_pipe(struct 
drm_plane *plane,

  }
  /* override for color fill */
-    if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG) {
+    if (drm_plane_solid_fill_enabled(plane->state)) {
  _dpu_plane_set_qos_ctrl(plane, pipe, false);
  /* skip remaining processing on color fill */



--
With best wishes
Dmitry



[PATCH v4 0/6] drm: Add support for atomic async page-flip

2023-06-30 Thread André Almeida
Hi,

This work from me and Simon adds support for DRM_MODE_PAGE_FLIP_ASYNC through
the atomic API. This feature is already available via the legacy API. The use
case is to be able to present a new frame immediately (or as soon as
possible), even if after missing a vblank. This might result in tearing, but
it's useful when a high framerate is desired, such as for gaming.

Differently from earlier versions, this one refuses to flip if any prop changes
for async flips. The idea is that the fast path of immediate page flips doesn't
play well with modeset changes, so only the fb_id can be changed. The exception
is for mode_id changes, that might be referring to an identical mode (which
would skip a modeset). This is done to make the async API more similar to the
normal API.

Thanks,
André

Changes from v3:
 - Add new patch to reject prop changes
 - Add a documentation clarifying the KMS atomic state set

v3: 
https://lore.kernel.org/dri-devel/20220929184307.258331-1-cont...@emersion.fr/

- User-space patch: https://github.com/Plagman/gamescope/pull/595
- IGT tests: 
https://gitlab.freedesktop.org/andrealmeid/igt-gpu-tools/-/tree/atomic_async_page_flip

André Almeida (2):
  drm: Refuse to async flip with atomic prop changes
  drm/doc: Define KMS atomic state set

Simon Ser (4):
  drm: allow DRM_MODE_PAGE_FLIP_ASYNC for atomic commits
  drm: introduce DRM_CAP_ATOMIC_ASYNC_PAGE_FLIP
  drm: introduce drm_mode_config.atomic_async_page_flip_not_supported
  amd/display: indicate support for atomic async page-flips on DC

 Documentation/gpu/drm-uapi.rst   | 19 +
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c |  1 +
 drivers/gpu/drm/drm_atomic_helper.c  |  5 ++
 drivers/gpu/drm/drm_atomic_uapi.c| 80 ++--
 drivers/gpu/drm/drm_crtc_internal.h  |  2 +-
 drivers/gpu/drm/drm_ioctl.c  |  5 ++
 drivers/gpu/drm/drm_mode_object.c|  2 +-
 drivers/gpu/drm/i915/display/intel_display.c |  1 +
 drivers/gpu/drm/nouveau/nouveau_display.c|  1 +
 include/drm/drm_mode_config.h| 11 +++
 include/uapi/drm/drm.h   | 10 ++-
 include/uapi/drm/drm_mode.h  |  9 +++
 12 files changed, 137 insertions(+), 9 deletions(-)

-- 
2.41.0



[PATCH v4 1/6] drm: allow DRM_MODE_PAGE_FLIP_ASYNC for atomic commits

2023-06-30 Thread André Almeida
From: Simon Ser 

If the driver supports it, allow user-space to supply the
DRM_MODE_PAGE_FLIP_ASYNC flag to request an async page-flip.
Set drm_crtc_state.async_flip accordingly.

Document that drivers will reject atomic commits if an async
flip isn't possible. This allows user-space to fall back to
something else. For instance, Xorg falls back to a blit.
Another option is to wait as close to the next vblank as
possible before performing the page-flip to reduce latency.

Signed-off-by: Simon Ser 
Reviewed-by: Alex Deucher 
Co-developed-by: André Almeida 
Signed-off-by: André Almeida 
---
v4: no changes
---
 drivers/gpu/drm/drm_atomic_uapi.c | 28 +---
 include/uapi/drm/drm_mode.h   |  9 +
 2 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
b/drivers/gpu/drm/drm_atomic_uapi.c
index d867e7f9f2cd..dfd4cf7169df 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -1286,6 +1286,18 @@ static void complete_signaling(struct drm_device *dev,
kfree(fence_state);
 }
 
+static void
+set_async_flip(struct drm_atomic_state *state)
+{
+   struct drm_crtc *crtc;
+   struct drm_crtc_state *crtc_state;
+   int i;
+
+   for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
+   crtc_state->async_flip = true;
+   }
+}
+
 int drm_mode_atomic_ioctl(struct drm_device *dev,
  void *data, struct drm_file *file_priv)
 {
@@ -1326,9 +1338,16 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
}
 
if (arg->flags & DRM_MODE_PAGE_FLIP_ASYNC) {
-   drm_dbg_atomic(dev,
-  "commit failed: invalid flag 
DRM_MODE_PAGE_FLIP_ASYNC\n");
-   return -EINVAL;
+   if (!dev->mode_config.async_page_flip) {
+   drm_dbg_atomic(dev,
+  "commit failed: DRM_MODE_PAGE_FLIP_ASYNC 
not supported\n");
+   return -EINVAL;
+   }
+   if (dev->mode_config.atomic_async_page_flip_not_supported) {
+   drm_dbg_atomic(dev,
+  "commit failed: DRM_MODE_PAGE_FLIP_ASYNC 
not supported with atomic\n");
+   return -EINVAL;
+   }
}
 
/* can't test and expect an event at the same time. */
@@ -1426,6 +1445,9 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
if (ret)
goto out;
 
+   if (arg->flags & DRM_MODE_PAGE_FLIP_ASYNC)
+   set_async_flip(state);
+
if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) {
ret = drm_atomic_check_only(state);
} else if (arg->flags & DRM_MODE_ATOMIC_NONBLOCK) {
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 46becedf5b2f..56342ba2c11a 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -949,6 +949,15 @@ struct hdr_output_metadata {
  * Request that the page-flip is performed as soon as possible, ie. with no
  * delay due to waiting for vblank. This may cause tearing to be visible on
  * the screen.
+ *
+ * When used with atomic uAPI, the driver will return an error if the hardware
+ * doesn't support performing an asynchronous page-flip for this update.
+ * User-space should handle this, e.g. by falling back to a regular page-flip.
+ *
+ * Note, some hardware might need to perform one last synchronous page-flip
+ * before being able to switch to asynchronous page-flips. As an exception,
+ * the driver will return success even though that first page-flip is not
+ * asynchronous.
  */
 #define DRM_MODE_PAGE_FLIP_ASYNC 0x02
 #define DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE 0x4
-- 
2.41.0



[PATCH v4 2/6] drm: introduce DRM_CAP_ATOMIC_ASYNC_PAGE_FLIP

2023-06-30 Thread André Almeida
From: Simon Ser 

This new kernel capability indicates whether async page-flips are
supported via the atomic uAPI. DRM clients can use it to check
for support before feeding DRM_MODE_PAGE_FLIP_ASYNC to the kernel.

Make it clear that DRM_CAP_ASYNC_PAGE_FLIP is for legacy uAPI only.

Signed-off-by: Simon Ser 
Reviewed-by: André Almeida 
Reviewed-by: Alex Deucher 
Signed-off-by: André Almeida 
---
v4: no changes
---
 drivers/gpu/drm/drm_ioctl.c |  5 +
 include/uapi/drm/drm.h  | 10 +-
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 7c9d66ee917d..8f756b99260d 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -302,6 +302,11 @@ static int drm_getcap(struct drm_device *dev, void *data, 
struct drm_file *file_
case DRM_CAP_CRTC_IN_VBLANK_EVENT:
req->value = 1;
break;
+   case DRM_CAP_ATOMIC_ASYNC_PAGE_FLIP:
+   req->value = drm_core_check_feature(dev, DRIVER_ATOMIC) &&
+dev->mode_config.async_page_flip &&
+
!dev->mode_config.atomic_async_page_flip_not_supported;
+   break;
default:
return -EINVAL;
}
diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
index a87ca2d4..54c558f81f3c 100644
--- a/include/uapi/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -706,7 +706,8 @@ struct drm_gem_open {
 /**
  * DRM_CAP_ASYNC_PAGE_FLIP
  *
- * If set to 1, the driver supports &DRM_MODE_PAGE_FLIP_ASYNC.
+ * If set to 1, the driver supports &DRM_MODE_PAGE_FLIP_ASYNC for legacy
+ * page-flips.
  */
 #define DRM_CAP_ASYNC_PAGE_FLIP0x7
 /**
@@ -767,6 +768,13 @@ struct drm_gem_open {
  * Documentation/gpu/drm-mm.rst, section "DRM Sync Objects".
  */
 #define DRM_CAP_SYNCOBJ_TIMELINE   0x14
+/**
+ * DRM_CAP_ATOMIC_ASYNC_PAGE_FLIP
+ *
+ * If set to 1, the driver supports &DRM_MODE_PAGE_FLIP_ASYNC for atomic
+ * commits.
+ */
+#define DRM_CAP_ATOMIC_ASYNC_PAGE_FLIP 0x15
 
 /* DRM_IOCTL_GET_CAP ioctl argument type */
 struct drm_get_cap {
-- 
2.41.0



[PATCH v4 3/6] drm: introduce drm_mode_config.atomic_async_page_flip_not_supported

2023-06-30 Thread André Almeida
From: Simon Ser 

This new field indicates whether the driver has the necessary logic
to support async page-flips via the atomic uAPI. This is leveraged by
the next commit to allow user-space to use this functionality.

All atomic drivers setting drm_mode_config.async_page_flip are updated
to also set drm_mode_config.atomic_async_page_flip_not_supported. We
will gradually check and update these drivers to properly handle
drm_crtc_state.async_flip in their atomic logic.

The goal of this negative flag is the same as
fb_modifiers_not_supported: we want to eventually get rid of all
drivers missing atomic support for async flips. New drivers should not
set this flag, instead they should support atomic async flips (if
they support async flips at all). IOW, we don't want more drivers
with async flip support for legacy but not atomic.

Signed-off-by: Simon Ser 
Reviewed-by: André Almeida 
Reviewed-by: Alex Deucher 
Signed-off-by: André Almeida 
---
v4: no changes
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  1 +
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c  |  1 +
 drivers/gpu/drm/i915/display/intel_display.c  |  1 +
 drivers/gpu/drm/nouveau/nouveau_display.c |  1 +
 include/drm/drm_mode_config.h | 11 +++
 5 files changed, 15 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 7acd73e5004f..258461826140 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3970,6 +3970,7 @@ static int amdgpu_dm_mode_config_init(struct 
amdgpu_device *adev)
adev_to_drm(adev)->mode_config.prefer_shadow = 1;
/* indicates support for immediate flip */
adev_to_drm(adev)->mode_config.async_page_flip = true;
+   adev_to_drm(adev)->mode_config.atomic_async_page_flip_not_supported = 
true;
 
state = kzalloc(sizeof(*state), GFP_KERNEL);
if (!state)
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c 
b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
index 29603561d501..8afb22b1e730 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
@@ -639,6 +639,7 @@ static int atmel_hlcdc_dc_modeset_init(struct drm_device 
*dev)
dev->mode_config.max_height = dc->desc->max_height;
dev->mode_config.funcs = &mode_config_funcs;
dev->mode_config.async_page_flip = true;
+   dev->mode_config.atomic_async_page_flip_not_supported = true;
 
return 0;
 }
diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index 0aae9a1eb3d5..a5c503ca9168 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -8318,6 +8318,7 @@ static void intel_mode_config_init(struct 
drm_i915_private *i915)
mode_config->helper_private = &intel_mode_config_funcs;
 
mode_config->async_page_flip = HAS_ASYNC_FLIPS(i915);
+   mode_config->atomic_async_page_flip_not_supported = true;
 
/*
 * Maximum framebuffer dimensions, chosen to match
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c 
b/drivers/gpu/drm/nouveau/nouveau_display.c
index ec3487fc..f497dcd9e22f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -709,6 +709,7 @@ nouveau_display_create(struct drm_device *dev)
dev->mode_config.async_page_flip = false;
else
dev->mode_config.async_page_flip = true;
+   dev->mode_config.atomic_async_page_flip_not_supported = true;
 
drm_kms_helper_poll_init(dev);
drm_kms_helper_poll_disable(dev);
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 973119a9176b..47b005671e6a 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -918,6 +918,17 @@ struct drm_mode_config {
 */
bool async_page_flip;
 
+   /**
+* @atomic_async_page_flip_not_supported:
+*
+* If true, the driver does not support async page-flips with the
+* atomic uAPI. This is only used by old drivers which haven't yet
+* accomodated for &drm_crtc_state.async_flip in their atomic logic,
+* even if they have &drm_mode_config.async_page_flip set to true.
+* New drivers shall not set this flag.
+*/
+   bool atomic_async_page_flip_not_supported;
+
/**
 * @fb_modifiers_not_supported:
 *
-- 
2.41.0



[PATCH v4 4/6] amd/display: indicate support for atomic async page-flips on DC

2023-06-30 Thread André Almeida
From: Simon Ser 

amdgpu_dm_commit_planes() already sets the flip_immediate flag for
async page-flips. This flag is used to set the UNP_FLIP_CONTROL
register. Thus, no additional change is required to handle async
page-flips with the atomic uAPI.

Signed-off-by: Simon Ser 
Reviewed-by: André Almeida 
Reviewed-by: Alex Deucher 
Signed-off-by: André Almeida 
---
v4: no changes
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 258461826140..7acd73e5004f 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3970,7 +3970,6 @@ static int amdgpu_dm_mode_config_init(struct 
amdgpu_device *adev)
adev_to_drm(adev)->mode_config.prefer_shadow = 1;
/* indicates support for immediate flip */
adev_to_drm(adev)->mode_config.async_page_flip = true;
-   adev_to_drm(adev)->mode_config.atomic_async_page_flip_not_supported = 
true;
 
state = kzalloc(sizeof(*state), GFP_KERNEL);
if (!state)
-- 
2.41.0



[PATCH v4 5/6] drm: Refuse to async flip with atomic prop changes

2023-06-30 Thread André Almeida
Given that prop changes may lead to modesetting, which would defeat the
fast path of the async flip, refuse any atomic prop change for async
flips in atomic API. The only exceptions are the framebuffer ID to flip
to and the mode ID, that could be referring to an identical mode.

Signed-off-by: André Almeida 
---
v4: new patch
---
 drivers/gpu/drm/drm_atomic_helper.c |  5 +++
 drivers/gpu/drm/drm_atomic_uapi.c   | 52 +++--
 drivers/gpu/drm/drm_crtc_internal.h |  2 +-
 drivers/gpu/drm/drm_mode_object.c   |  2 +-
 4 files changed, 56 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index 2c2c9caf0be5..1e2973f0e1f6 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -629,6 +629,11 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
WARN_ON(!drm_modeset_is_locked(&crtc->mutex));
 
if (!drm_mode_equal(&old_crtc_state->mode, 
&new_crtc_state->mode)) {
+   if (new_crtc_state->async_flip) {
+   drm_dbg_atomic(dev, "[CRTC:%d:%s] no mode 
changes allowed during async flip\n",
+  crtc->base.id, crtc->name);
+   return -EINVAL;
+   }
drm_dbg_atomic(dev, "[CRTC:%d:%s] mode changed\n",
   crtc->base.id, crtc->name);
new_crtc_state->mode_changed = true;
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
b/drivers/gpu/drm/drm_atomic_uapi.c
index dfd4cf7169df..536c21f53b5f 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -972,13 +972,28 @@ int drm_atomic_connector_commit_dpms(struct 
drm_atomic_state *state,
return ret;
 }
 
+static int drm_atomic_check_prop_changes(int ret, uint64_t old_val, uint64_t 
prop_value,
+struct drm_property *prop)
+{
+   if (ret != 0 || old_val != prop_value) {
+   drm_dbg_atomic(prop->dev,
+  "[PROP:%d:%s] No prop can be changed during 
async flip\n",
+  prop->base.id, prop->name);
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
 int drm_atomic_set_property(struct drm_atomic_state *state,
struct drm_file *file_priv,
struct drm_mode_object *obj,
struct drm_property *prop,
-   uint64_t prop_value)
+   uint64_t prop_value,
+   bool async_flip)
 {
struct drm_mode_object *ref;
+   uint64_t old_val;
int ret;
 
if (!drm_property_change_valid_get(prop, prop_value, &ref))
@@ -995,6 +1010,13 @@ int drm_atomic_set_property(struct drm_atomic_state 
*state,
break;
}
 
+   if (async_flip) {
+   ret = drm_atomic_connector_get_property(connector, 
connector_state,
+   prop, &old_val);
+   ret = drm_atomic_check_prop_changes(ret, old_val, 
prop_value, prop);
+   break;
+   }
+
ret = drm_atomic_connector_set_property(connector,
connector_state, file_priv,
prop, prop_value);
@@ -1003,6 +1025,7 @@ int drm_atomic_set_property(struct drm_atomic_state 
*state,
case DRM_MODE_OBJECT_CRTC: {
struct drm_crtc *crtc = obj_to_crtc(obj);
struct drm_crtc_state *crtc_state;
+   struct drm_mode_config *config = &crtc->dev->mode_config;
 
crtc_state = drm_atomic_get_crtc_state(state, crtc);
if (IS_ERR(crtc_state)) {
@@ -1010,6 +1033,18 @@ int drm_atomic_set_property(struct drm_atomic_state 
*state,
break;
}
 
+   /*
+* We allow mode_id changes here for async flips, because we
+* check later on drm_atomic_helper_check_modeset() callers if
+* there are modeset changes or they are equal
+*/
+   if (async_flip && prop != config->prop_mode_id) {
+   ret = drm_atomic_crtc_get_property(crtc, crtc_state,
+  prop, &old_val);
+   ret = drm_atomic_check_prop_changes(ret, old_val, 
prop_value, prop);
+   break;
+   }
+
ret = drm_atomic_crtc_set_property(crtc,
crtc_state, prop, prop_value);
break;
@@ -1017,6 +1052,7 @@ int drm_atomic_set_property(struct drm_atomic_state 
*state,
case DRM_MODE_OBJECT_PLANE: {
struct drm

[PATCH v4 6/6] drm/doc: Define KMS atomic state set

2023-06-30 Thread André Almeida
Specify how the atomic state is maintained between userspace and
kernel, plus the special case for async flips.

Signed-off-by: André Almeida 
---
v4: new patch
---
 Documentation/gpu/drm-uapi.rst | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/Documentation/gpu/drm-uapi.rst b/Documentation/gpu/drm-uapi.rst
index 65fb3036a580..5464376051cc 100644
--- a/Documentation/gpu/drm-uapi.rst
+++ b/Documentation/gpu/drm-uapi.rst
@@ -486,3 +486,22 @@ and the CRTC index is its position in this array.
 
 .. kernel-doc:: include/uapi/drm/drm_mode.h
:internal:
+
+KMS atomic state
+
+
+If a userspace using the DRM atomic API would like to change the modeset, it
+needs to do in an atomic way, changing all desired properties in a single
+commit. Following commits may contain the same properties again, as if they 
were
+new. The kernel can then judge if those properties requires modesetting and 
real
+changes, or it's just the same state as before. In summary, userspace commits 
do
+not need to set the minimal state as possible and can commit redundant
+information, and the kernel will ignore it.
+
+An observation must be made for atomic operations with 
DRM_MODE_PAGE_FLIP_ASYNC.
+In such scenarios properties values can be sent, but the if they change
+something, the kernel will reject the flip. This is done because property
+changes can lead to modesetting, that would defeat the goal of flipping as fast
+as possible. The only exceptions are the framebuffer ID to be flipped to and
+mode IDs changes, which could be referring to an identical mode, thus not
+requiring modeset.
-- 
2.41.0