On Tue, Sep 01, 2020 at 11:30:47PM +0300, Roman Stratiienko wrote:
> Fixes: e1ef9006663b ("drm/sun4i: Wire in DE2 YUV support")
> Signed-off-by: Roman Stratiienko <r.stratiie...@gmail.com>
> 
> ---
> CC: meg...@megous.com
> CC: jernej.skra...@gmail.com
> CC: linux-su...@googlegroups.com
> CC: dri-devel@lists.freedesktop.org
> CC: linux-arm-ker...@lists.infradead.org
> CC: linux-ker...@vger.kernel.org
> 
> Hi, this patch fixes wrong colors during video playback for me.
> Implemented ugly for now, please review/suggest how to improve.

Why do you think the issue is at DRM level? Have you tried displaying a known
color image via a vi layer, and was it wrong?

I used DRM with YUV data in the past, and didn't notice any weird colors,
so I'm a bit skeptical.

regards,
        o.

> ---
>  drivers/gpu/drm/sun4i/sun8i_mixer.c    |  8 +++++++-
>  drivers/gpu/drm/sun4i/sun8i_mixer.h    |  2 +-
>  drivers/gpu/drm/sun4i/sun8i_ui_layer.c |  2 +-
>  drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 28 +++++++++++++++++++-------
>  4 files changed, 30 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c 
> b/drivers/gpu/drm/sun4i/sun8i_mixer.c
> index dce40c430100..bbbeef44899a 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c
> +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c
> @@ -31,6 +31,7 @@
>  struct de2_fmt_info {
>       u32     drm_fmt;
>       u32     de2_fmt;
> +     bool    swap_uv;
>  };
>  
>  static bool hw_preconfigured;
> @@ -219,14 +220,17 @@ static const struct de2_fmt_info de2_formats[] = {
>       {
>               .drm_fmt = DRM_FORMAT_YVU422,
>               .de2_fmt = SUN8I_MIXER_FBFMT_YUV422,
> +             .swap_uv = true,
>       },
>       {
>               .drm_fmt = DRM_FORMAT_YVU420,
>               .de2_fmt = SUN8I_MIXER_FBFMT_YUV420,
> +             .swap_uv = true,
>       },
>       {
>               .drm_fmt = DRM_FORMAT_YVU411,
>               .de2_fmt = SUN8I_MIXER_FBFMT_YUV411,
> +             .swap_uv = true,
>       },
>       {
>               .drm_fmt = DRM_FORMAT_P010,
> @@ -238,13 +242,15 @@ static const struct de2_fmt_info de2_formats[] = {
>       },
>  };
>  
> -int sun8i_mixer_drm_format_to_hw(u32 format, u32 *hw_format)
> +int sun8i_mixer_drm_format_to_hw(u32 format, u32 *hw_format, bool *swap_uv)
>  {
>       unsigned int i;
>  
>       for (i = 0; i < ARRAY_SIZE(de2_formats); ++i)
>               if (de2_formats[i].drm_fmt == format) {
>                       *hw_format = de2_formats[i].de2_fmt;
> +                     if (swap_uv)
> +                             *swap_uv = de2_formats[i].swap_uv;
>                       return 0;
>               }
>  
> diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h 
> b/drivers/gpu/drm/sun4i/sun8i_mixer.h
> index 79a74bca1ea3..6358ffd251f9 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_mixer.h
> +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h
> @@ -207,5 +207,5 @@ sun8i_channel_base(struct sun8i_mixer *mixer, int channel)
>               return DE2_CH_BASE + channel * DE2_CH_SIZE;
>  }
>  
> -int sun8i_mixer_drm_format_to_hw(u32 format, u32 *hw_format);
> +int sun8i_mixer_drm_format_to_hw(u32 format, u32 *hw_format, bool *swap_uv);
>  #endif /* _SUN8I_MIXER_H_ */
> diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c 
> b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
> index a7f21f08ec89..57bbd9f1071c 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
> +++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
> @@ -215,7 +215,7 @@ static int sun8i_ui_layer_update_formats(struct 
> sun8i_mixer *mixer, int channel,
>       ch_base = sun8i_channel_base(mixer, channel);
>  
>       fmt = state->fb->format;
> -     ret = sun8i_mixer_drm_format_to_hw(fmt->format, &hw_fmt);
> +     ret = sun8i_mixer_drm_format_to_hw(fmt->format, &hw_fmt, NULL);
>       if (ret || fmt->is_yuv) {
>               DRM_DEBUG_DRIVER("Invalid format\n");
>               return -EINVAL;
> diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c 
> b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
> index 3553e38ec642..4da51155c4d5 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
> +++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
> @@ -313,7 +313,7 @@ static int sun8i_vi_layer_update_formats(struct 
> sun8i_mixer *mixer, int channel,
>       ch_base = sun8i_channel_base(mixer, channel);
>  
>       fmt = state->fb->format;
> -     ret = sun8i_mixer_drm_format_to_hw(fmt->format, &hw_fmt);
> +     ret = sun8i_mixer_drm_format_to_hw(fmt->format, &hw_fmt, NULL);
>       if (ret) {
>               DRM_DEBUG_DRIVER("Invalid format\n");
>               return ret;
> @@ -368,8 +368,17 @@ static int sun8i_vi_layer_update_buffer(struct 
> sun8i_mixer *mixer, int channel,
>       struct drm_gem_cma_object *gem;
>       u32 dx, dy, src_x, src_y;
>       dma_addr_t paddr;
> +     bool swap_uv;
>       u32 ch_base;
> -     int i;
> +     u32 hw_fmt;
> +     int ret;
> +     int i, j;
> +
> +     ret = sun8i_mixer_drm_format_to_hw(plane->state->fb->format->format, 
> &hw_fmt, &swap_uv);
> +     if (ret) {
> +             DRM_DEBUG_DRIVER("Invalid format\n");
> +             return ret;
> +     }
>  
>       ch_base = sun8i_channel_base(mixer, channel);
>  
> @@ -377,7 +386,12 @@ static int sun8i_vi_layer_update_buffer(struct 
> sun8i_mixer *mixer, int channel,
>       src_x = (state->src.x1 >> 16) & ~(format->hsub - 1);
>       src_y = (state->src.y1 >> 16) & ~(format->vsub - 1);
>  
> -     for (i = 0; i < format->num_planes; i++) {
> +     for (j = 0; j < format->num_planes; j++) {
> +             i = j;
> +             if (swap_uv && i > 0 && format->num_planes == 3) {
> +                     i = j == 1 ? 2 : 1;
> +             }
> +
>               /* Get the physical address of the buffer in memory */
>               gem = drm_fb_cma_get_gem_obj(fb, i);
>  
> @@ -400,18 +414,18 @@ static int sun8i_vi_layer_update_buffer(struct 
> sun8i_mixer *mixer, int channel,
>  
>               /* Set the line width */
>               DRM_DEBUG_DRIVER("Layer %d. line width: %d bytes\n",
> -                              i + 1, fb->pitches[i]);
> +                              j + 1, fb->pitches[i]);
>               regmap_write(mixer->engine.regs,
>                            SUN8I_MIXER_CHAN_VI_LAYER_PITCH(ch_base,
> -                                                          overlay, i),
> +                                                          overlay, j),
>                            fb->pitches[i]);
>  
>               DRM_DEBUG_DRIVER("Setting %d. buffer address to %pad\n",
> -                              i + 1, &paddr);
> +                              j + 1, &paddr);
>  
>               regmap_write(mixer->engine.regs,
>                            SUN8I_MIXER_CHAN_VI_LAYER_TOP_LADDR(ch_base,
> -                                                              overlay, i),
> +                                                              overlay, j),
>                            lower_32_bits(paddr));
>       }
>  
> -- 
> 2.25.1
> 
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to