On Tue, Dec 04, 2018 at 05:49:12PM +0000, Liviu Dudau wrote:
> On Mon, Dec 03, 2018 at 11:32:01AM +0000, Ayan Halder wrote:
> > The constraints are as follows (for Mali-DP 500, 550, 650) :-
> > 
> > 1. AFBC is not supported for the formats defined in 
> > malidp_hw_format_is_linear_only()
> > 
> > 2. Some of the formats are supported only with AFBC modifiers. Thus we have
> > introduced a new function 'malidp_hw_format_is_afbc_only()' which verifies 
> > the same.
> > 
> > 3. AFBC_FORMAT_MOD_YTR needs to be provided for any RGB format.
> > 
> > 4. Formats <= 16bpp cannot support AFBC_FORMAT_MOD_SPLIT.
> > 
> > 5. CBR should not be set for non-subsampled formats.
> > 
> > 6. SMART layer does not support framebuffer with AFBC modifiers.
> > Return -EINVAL for such a scenario.
> > 
> > 7. AFBC_FORMAT_MOD_YTR is not supported for any YUV formats.
> > 
> > 8. Formats which are subsampled cannot support AFBC_FORMAT_MOD_SPLIT. 
> > However in
> > DP550, YUV_420_10BIT is supported with AFBC_FORMAT_MOD_SPLIT. This feature 
> > has
> > been identified with MALIDP_DEVICE_AFBC_YUV_420_10_SUPPORT_SPLIT.
> > 
> > 9. In DP550 and DP650, for YUYV, the hardware supports different format-ids 
> > to
> > be used with and without AFBC modifier. We have used the feature
> > 'MALIDP_DEVICE_AFBC_YUYV_USE_422_P2' to identify this characteristic.
> > 
> > Signed-off-by: Ayan Kumar halder <ayan.hal...@arm.com>
> > ---
> >  drivers/gpu/drm/arm/malidp_drv.c    |  23 +------
> >  drivers/gpu/drm/arm/malidp_drv.h    |   6 ++
> >  drivers/gpu/drm/arm/malidp_hw.c     |  71 +++++++++++++++++++--
> >  drivers/gpu/drm/arm/malidp_hw.h     |   5 +-
> >  drivers/gpu/drm/arm/malidp_mw.c     |   2 +-
> >  drivers/gpu/drm/arm/malidp_planes.c | 124 
> > +++++++++++++++++++++++++++++++++++-
> >  6 files changed, 199 insertions(+), 32 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/arm/malidp_drv.c 
> > b/drivers/gpu/drm/arm/malidp_drv.c
> > index b8db92f..2f0b553 100644
> > --- a/drivers/gpu/drm/arm/malidp_drv.c
> > +++ b/drivers/gpu/drm/arm/malidp_drv.c
> > @@ -264,29 +264,8 @@ static bool
> >  malidp_verify_afbc_framebuffer_caps(struct drm_device *dev,
> >                                 const struct drm_mode_fb_cmd2 *mode_cmd)
> >  {
> > -   const struct drm_format_info *info;
> > -
> > -   if ((mode_cmd->modifier[0] >> 56) != DRM_FORMAT_MOD_VENDOR_ARM) {
> > -           DRM_DEBUG_KMS("Unknown modifier (not Arm)\n");
> > +   if (malidp_format_mod_supported(dev, mode_cmd->pixel_format, 
> > mode_cmd->modifier[0]) == false)
> >             return false;
> > -   }
> > -
> > -   if (mode_cmd->modifier[0] &
> > -       ~DRM_FORMAT_MOD_ARM_AFBC(AFBC_MOD_VALID_BITS)) {
> > -           DRM_DEBUG_KMS("Unsupported modifiers\n");
> > -           return false;
> > -   }
> > -
> > -   info = drm_get_format_info(dev, mode_cmd);
> > -   if (!info) {
> > -           DRM_DEBUG_KMS("Unable to get the format information\n");
> > -           return false;
> > -   }
> > -
> > -   if (info->num_planes != 1) {
> > -           DRM_DEBUG_KMS("AFBC buffers expect one plane\n");
> > -           return false;
> > -   }
> >  
> >     if (mode_cmd->offsets[0] != 0) {
> >             DRM_DEBUG_KMS("AFBC buffers' plane offset should be 0\n");
> > diff --git a/drivers/gpu/drm/arm/malidp_drv.h 
> > b/drivers/gpu/drm/arm/malidp_drv.h
> > index b76c86f..019a682 100644
> > --- a/drivers/gpu/drm/arm/malidp_drv.h
> > +++ b/drivers/gpu/drm/arm/malidp_drv.h
> > @@ -90,6 +90,12 @@ struct malidp_crtc_state {
> >  int malidp_de_planes_init(struct drm_device *drm);
> >  int malidp_crtc_init(struct drm_device *drm);
> >  
> > +bool malidp_hw_format_is_linear_only(u32 format);
> > +bool malidp_hw_format_is_afbc_only(u32 format);
> > +
> > +bool malidp_format_mod_supported(struct drm_device *drm,
> > +                            u32 format, u64 modifier);
> > +
> >  #ifdef CONFIG_DEBUG_FS
> >  void malidp_error(struct malidp_drm *malidp,
> >               struct malidp_error_stats *error_stats, u32 status,
> > diff --git a/drivers/gpu/drm/arm/malidp_hw.c 
> > b/drivers/gpu/drm/arm/malidp_hw.c
> > index 25ac5890..4a774be 100644
> > --- a/drivers/gpu/drm/arm/malidp_hw.c
> > +++ b/drivers/gpu/drm/arm/malidp_hw.c
> > @@ -60,6 +60,8 @@ static const struct malidp_format_id 
> > malidp500_de_formats[] = {
> >  #define MALIDP_ID(__group, __format) \
> >     ((((__group) & 0x7) << 3) | ((__format) & 0x7))
> >  
> > +#define AFBC_YUV_422_FORMAT_ID     MALIDP_ID(5, 1)
> > +
> >  #define MALIDP_COMMON_FORMATS \
> >     /*    fourcc,   layers supporting the format,      internal id   */ \
> >     { DRM_FORMAT_ARGB2101010, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2 | 
> > SE_MEMWRITE, MALIDP_ID(0, 0) }, \
> > @@ -887,7 +889,10 @@ const struct malidp_hw 
> > malidp_device[MALIDP_MAX_DEVICES] = {
> >                     .se_base = MALIDP550_SE_BASE,
> >                     .dc_base = MALIDP550_DC_BASE,
> >                     .out_depth_base = MALIDP550_DE_OUTPUT_DEPTH,
> > -                   .features = MALIDP_REGMAP_HAS_CLEARIRQ | 
> > MALIDP_DEVICE_AFBC_SUPPORT_SPLIT | AFBC_SUPPORT_SPLIT_WITH_YUV_420_10,
> > +                   .features = MALIDP_REGMAP_HAS_CLEARIRQ |
> > +                               MALIDP_DEVICE_AFBC_SUPPORT_SPLIT |
> > +                               MALIDP_DEVICE_AFBC_YUV_420_10_SUPPORT_SPLIT 
> > |
> 
> Please roll some of these changes into patch 5/12.
> 
> > +                               MALIDP_DEVICE_AFBC_YUYV_USE_422_P2,
> >                     .n_layers = ARRAY_SIZE(malidp550_layers),
> >                     .layers = malidp550_layers,
> >                     .de_irq_map = {
> > @@ -933,7 +938,9 @@ const struct malidp_hw 
> > malidp_device[MALIDP_MAX_DEVICES] = {
> >                     .se_base = MALIDP550_SE_BASE,
> >                     .dc_base = MALIDP550_DC_BASE,
> >                     .out_depth_base = MALIDP550_DE_OUTPUT_DEPTH,
> > -                   .features = MALIDP_REGMAP_HAS_CLEARIRQ | 
> > MALIDP_DEVICE_AFBC_SUPPORT_SPLIT,
> > +                   .features = MALIDP_REGMAP_HAS_CLEARIRQ |
> > +                               MALIDP_DEVICE_AFBC_SUPPORT_SPLIT |
> > +                               MALIDP_DEVICE_AFBC_YUYV_USE_422_P2,
> >                     .n_layers = ARRAY_SIZE(malidp650_layers),
> >                     .layers = malidp650_layers,
> >                     .de_irq_map = {
> > @@ -982,19 +989,73 @@ const struct malidp_hw 
> > malidp_device[MALIDP_MAX_DEVICES] = {
> >  };
> >  
> >  u8 malidp_hw_get_format_id(const struct malidp_hw_regmap *map,
> > -                      u8 layer_id, u32 format)
> > +                      u8 layer_id, u32 format, bool has_modifier)
> >  {
> >     unsigned int i;
> >  
> >     for (i = 0; i < map->n_pixel_formats; i++) {
> >             if (((map->pixel_formats[i].layer & layer_id) == layer_id) &&
> > -               (map->pixel_formats[i].format == format))
> > -                   return map->pixel_formats[i].id;
> > +               (map->pixel_formats[i].format == format)) {
> > +
> > +                   /*
> > +                    * In some DP550 and DP650, DRM_FORMAT_YUYV + AFBC 
> > modifier
> > +                    * is supported by a different h/w format id than
> > +                    * DRM_FORMAT_YUYV (only).
> > +                    */
> > +                   if (format == DRM_FORMAT_YUYV &&
> > +                       (has_modifier) &&
> > +                       (map->features & 
> > MALIDP_DEVICE_AFBC_YUYV_USE_422_P2))
> > +                           return AFBC_YUV_422_FORMAT_ID;
> > +                   else
> > +                           return map->pixel_formats[i].id;
> > +           }
> >     }
> >  
> >     return MALIDP_INVALID_FORMAT_ID;
> >  }
> >  
> > +bool malidp_hw_format_is_linear_only(u32 format)
> > +{
> > +   switch (format) {
> > +   case DRM_FORMAT_ARGB2101010:
> > +   case DRM_FORMAT_RGBA1010102:
> > +   case DRM_FORMAT_BGRA1010102:
> > +   case DRM_FORMAT_ARGB8888:
> > +   case DRM_FORMAT_RGBA8888:
> > +   case DRM_FORMAT_BGRA8888:
> > +   case DRM_FORMAT_XBGR8888:
> > +   case DRM_FORMAT_XRGB8888:
> > +   case DRM_FORMAT_RGBX8888:
> > +   case DRM_FORMAT_BGRX8888:
> > +   case DRM_FORMAT_RGB888:
> > +   case DRM_FORMAT_RGB565:
> > +   case DRM_FORMAT_ARGB1555:
> > +   case DRM_FORMAT_RGBA5551:
> > +   case DRM_FORMAT_BGRA5551:
> > +   case DRM_FORMAT_UYVY:
> > +   case DRM_FORMAT_XYUV8888:
> > +   case DRM_FORMAT_XVYU2101010:
> > +   case DRM_FORMAT_X0L2:
> > +   case DRM_FORMAT_X0L0:
> > +           return true;
> > +   default:
> > +           return false;
> > +   }
> > +}
> > +
> > +bool malidp_hw_format_is_afbc_only(u32 format)
> > +{
> > +   switch (format) {
> > +   case DRM_FORMAT_VUY888:
> > +   case DRM_FORMAT_VUY101010:
> > +   case DRM_FORMAT_YUV420_8BIT:
> > +   case DRM_FORMAT_YUV420_10BIT:
> > +           return true;
> > +   default:
> > +           return false;
> > +   }
> > +}
> > +
> >  static void malidp_hw_clear_irq(struct malidp_hw_device *hwdev, u8 block, 
> > u32 irq)
> >  {
> >     u32 base = malidp_get_block_base(hwdev, block);
> > diff --git a/drivers/gpu/drm/arm/malidp_hw.h 
> > b/drivers/gpu/drm/arm/malidp_hw.h
> > index 27b907f..52188f0 100644
> > --- a/drivers/gpu/drm/arm/malidp_hw.h
> > +++ b/drivers/gpu/drm/arm/malidp_hw.h
> > @@ -97,7 +97,8 @@ struct malidp_se_config {
> >  /* regmap features */
> >  #define MALIDP_REGMAP_HAS_CLEARIRQ                         BIT(0)
> >  #define MALIDP_DEVICE_AFBC_SUPPORT_SPLIT                   BIT(1)
> > -#define AFBC_SUPPORT_SPLIT_WITH_YUV_420_10                 BIT(2)
> > +#define MALIDP_DEVICE_AFBC_YUV_420_10_SUPPORT_SPLIT                BIT(2)
> > +#define MALIDP_DEVICE_AFBC_YUYV_USE_422_P2                 BIT(3)
> >  
> >  struct malidp_hw_regmap {
> >     /* address offset of the DE register bank */
> > @@ -323,7 +324,7 @@ int malidp_se_irq_init(struct drm_device *drm, int irq);
> >  void malidp_se_irq_fini(struct malidp_hw_device *hwdev);
> >  
> >  u8 malidp_hw_get_format_id(const struct malidp_hw_regmap *map,
> > -                      u8 layer_id, u32 format);
> > +                      u8 layer_id, u32 format, bool has_modifier);
> >  
> >  static inline u8 malidp_hw_get_pitch_align(struct malidp_hw_device *hwdev, 
> > bool rotated)
> >  {
> > diff --git a/drivers/gpu/drm/arm/malidp_mw.c 
> > b/drivers/gpu/drm/arm/malidp_mw.c
> > index 91472e5..0484744 100644
> > --- a/drivers/gpu/drm/arm/malidp_mw.c
> > +++ b/drivers/gpu/drm/arm/malidp_mw.c
> > @@ -143,7 +143,7 @@ malidp_mw_encoder_atomic_check(struct drm_encoder 
> > *encoder,
> >  
> >     mw_state->format =
> >             malidp_hw_get_format_id(&malidp->dev->hw->map, SE_MEMWRITE,
> > -                                   fb->format->format);
> > +                                   fb->format->format, !!fb->modifier);
> >     if (mw_state->format == MALIDP_INVALID_FORMAT_ID) {
> >             struct drm_format_name_buf format_name;
> >  
> > diff --git a/drivers/gpu/drm/arm/malidp_planes.c 
> > b/drivers/gpu/drm/arm/malidp_planes.c
> > index cd60f73..0765cee 100644
> > --- a/drivers/gpu/drm/arm/malidp_planes.c
> > +++ b/drivers/gpu/drm/arm/malidp_planes.c
> > @@ -52,6 +52,8 @@
> >  #define MALIDP550_LS_ENABLE                0x01c
> >  #define MALIDP550_LS_R1_IN_SIZE            0x020
> >  
> > +#define MODIFIERS_COUNT_MAX                15
> > +
> >  /*
> >   * This 4-entry look-up-table is used to determine the full 8-bit alpha 
> > value
> >   * for formats with 1- or 2-bit alpha channels.
> > @@ -145,6 +147,117 @@ static void malidp_plane_atomic_print_state(struct 
> > drm_printer *p,
> >     drm_printf(p, "\tmmu_prefetch_pgsize=%d\n", ms->mmu_prefetch_pgsize);
> >  }
> >  
> > +bool malidp_format_mod_supported(struct drm_device *drm,
> > +                            u32 format, u64 modifier)
> > +{
> > +   const struct drm_format_info *info;
> > +   const u64 *modifiers;
> > +   struct malidp_drm *malidp = drm->dev_private;
> > +   const struct malidp_hw_regmap *map = &malidp->dev->hw->map;
> > +
> > +   if (WARN_ON(modifier == DRM_FORMAT_MOD_INVALID))
> > +           return false;
> > +
> > +   /* Some pixel formats are supported without any modifier */
> > +   if (modifier == DRM_FORMAT_MOD_LINEAR) {
> > +           /* However these pixel formats need to be supported with
> 
> Nitpick: multi-line comment style is to start with a line that contains
> only the marker for the start of the comment.
Agreed
> 
> > +            * modifiers only
> > +            */
> > +           return !malidp_hw_format_is_afbc_only(format);
> > +   }
> > +
> > +   if ((modifier >> 56) != DRM_FORMAT_MOD_VENDOR_ARM) {
> > +           DRM_ERROR("Unknown modifier (not Arm)\n");
> > +           return false;
> > +   }
> > +
> > +   if (modifier &
> > +       ~DRM_FORMAT_MOD_ARM_AFBC(AFBC_MOD_VALID_BITS)) {
> > +           DRM_DEBUG_KMS("Unsupported modifiers\n");
> > +           return false;
> > +   }
> > +
> > +   modifiers = malidp_format_modifiers;
> 
> Actually, looking again at patch 5/12 it looks to me like you could roll
> it into this patch completely.
>
Agreed, I will merge patch 5/12 "Defining a common list of AFBC
modifiers" with the current patch ("adding constraints for each format
and modifier").

> > +   while (*modifiers != DRM_FORMAT_MOD_INVALID) {
> > +           if (*modifiers == modifier) {
> > +                   /* SPLIT buffers must use SPARSE layout */
> > +                   if (WARN_ON_ONCE((modifier & AFBC_SPLIT) && !(modifier 
> > & AFBC_SPARSE)))
> > +                           return false;
> > +
> > +                   /* CBR only applies to YUV formats, where YTR should be 
> > always 0 */
> > +                   if (WARN_ON_ONCE((modifier & AFBC_CBR) && (modifier & 
> > AFBC_YTR)))
> > +                           return false;
> 
> You can take these checks outside the while() loop as they test if the
> modifier passed as a parameter is valid, which you should check before
> running through the array. If you do that, then the loop through the
> malidp_format_modifiers is a simple "if found, break out of loop" and
> then the next check will return false if you iterated over the entire
> list.
> 
Agreed
> > +
> > +                   break;
> > +           }
> > +
> > +           modifiers++;
> > +   }
> > +
> > +   /* return false, if the modifier was not found */
> > +   if (*modifiers == DRM_FORMAT_MOD_INVALID) {
> > +           DRM_DEBUG_KMS("Unsupported modifier\n");
> > +           return false;
> > +   }
> > +
> > +   info = drm_format_info(format);
> > +
> > +   if (info->num_planes != 1) {
> > +           DRM_DEBUG_KMS("AFBC buffers expect one plane\n");
> > +           return false;
> > +   }
> > +
> > +   if (malidp_hw_format_is_linear_only(format) == true) {
> > +           DRM_DEBUG_KMS("Given format (0x%x) is supported is linear mode 
> > only\n", format);
> > +           return false;
> > +   }
> > +
> > +   /*
> > +    * RGB formats need to provide YTR modifier and YUV formats should not
> > +    * provide YTR modifier.
> > +    */
> > +   if (!(info->is_yuv) != !!(modifier & AFBC_FORMAT_MOD_YTR)) {
> > +           DRM_DEBUG_KMS("AFBC_FORMAT_MOD_YTR is %s for %s formats\n",
> > +                         info->is_yuv ? "disallowed" : "mandatory",
> > +                         info->is_yuv ? "YUV" : "RGB");
> > +           return false;
> > +   }
> > +
> > +   if (modifier & AFBC_SPLIT) {
> > +           if (!info->is_yuv) {
> > +                   if (drm_format_plane_cpp(format, 0) <= 2) {
> > +                           DRM_DEBUG_KMS("RGB formats <= 16bpp are not 
> > supported with SPLIT\n");
> > +                           return false;
> > +                   }
> > +           }
> > +
> > +           if ((drm_format_horz_chroma_subsampling(format) != 1) ||
> > +               (drm_format_vert_chroma_subsampling(format) != 1)) {
> > +                   if (!(format == DRM_FORMAT_YUV420_10BIT &&
> > +                        (map->features & 
> > MALIDP_DEVICE_AFBC_YUV_420_10_SUPPORT_SPLIT))) {
> > +                           DRM_DEBUG_KMS("Formats which are sub-sampled 
> > should never be split\n");
> > +                           return false;
> > +                   }
> > +           }
> > +   }
> > +
> > +   if (modifier & AFBC_CBR) {
> > +           if ((drm_format_horz_chroma_subsampling(format) == 1) ||
> > +               (drm_format_vert_chroma_subsampling(format) == 1)) {
> > +                   DRM_DEBUG_KMS("Formats which are not sub-sampled should 
> > not have CBR set\n");
> > +                   return false;
> > +           }
> > +   }
> > +
> > +   return true;
> > +}
> > +
> > +static bool malidp_format_mod_supported_per_plane(struct drm_plane *plane,
> > +                                             u32 format, u64 modifier)
> > +{
> > +   return malidp_format_mod_supported(plane->dev, format, modifier);
> > +}
> > +
> >  static const struct drm_plane_funcs malidp_de_plane_funcs = {
> >     .update_plane = drm_atomic_helper_update_plane,
> >     .disable_plane = drm_atomic_helper_disable_plane,
> > @@ -153,6 +266,7 @@ static const struct drm_plane_funcs 
> > malidp_de_plane_funcs = {
> >     .atomic_duplicate_state = malidp_duplicate_plane_state,
> >     .atomic_destroy_state = malidp_destroy_plane_state,
> >     .atomic_print_state = malidp_plane_atomic_print_state,
> > +   .format_mod_supported = malidp_format_mod_supported_per_plane,
> >  };
> >  
> >  static int malidp_se_check_scaling(struct malidp_plane *mp,
> > @@ -406,8 +520,8 @@ static int malidp_de_plane_check(struct drm_plane 
> > *plane,
> >     fb = state->fb;
> >  
> >     ms->format = malidp_hw_get_format_id(&mp->hwdev->hw->map,
> > -                                        mp->layer->id,
> > -                                        fb->format->format);
> > +                                        mp->layer->id, fb->format->format,
> > +                                        !!fb->modifier);
> >     if (ms->format == MALIDP_INVALID_FORMAT_ID)
> >             return -EINVAL;
> >  
> > @@ -469,6 +583,12 @@ static int malidp_de_plane_check(struct drm_plane 
> > *plane,
> >                     return -EINVAL;
> >     }
> >  
> > +   /* SMART layer does not support AFBC */
> > +   if (mp->layer->id == DE_SMART && fb->modifier) {
> > +           DRM_ERROR("AFBC framebuffer not supported in SMART layer");
> > +           return -EINVAL;
> > +   }
> > +
> >     ms->rotmem_size = 0;
> >     if (state->rotation & MALIDP_ROTATED_MASK) {
> >             int val;
> > -- 
> > 2.7.4
> > 
> 
> Best regards,
> Liviu
> 
> 
> -- 
> ====================
> | I would like to |
> | fix the world,  |
> | but they're not |
> | giving me the   |
>  \ source code!  /
>   ---------------
>     ??\_(???)_/??
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to