drm/komeda: Add komeda_fb_check_src_coords
authorjames qian wang (Arm Technology China) <james.qian.wang@arm.com>
Fri, 17 May 2019 10:05:06 +0000 (11:05 +0100)
committerLiviu Dudau <Liviu.Dudau@arm.com>
Wed, 19 Jun 2019 10:42:17 +0000 (11:42 +0100)
Add komeda_fb_check_src_coords and check if the layer configured src
rect can meet the requirement of fb and fb format.

Signed-off-by: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com>
Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.h
drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c

index f0593726d127f707f72725aa8922c4c55f011e68..50858401da05ba9b5fe7ba3777f497ee5c9ad0e5 100644 (file)
@@ -214,6 +214,27 @@ err_cleanup:
        return ERR_PTR(ret);
 }
 
+int komeda_fb_check_src_coords(const struct komeda_fb *kfb,
+                              u32 src_x, u32 src_y, u32 src_w, u32 src_h)
+{
+       const struct drm_framebuffer *fb = &kfb->base;
+       const struct drm_format_info *info = fb->format;
+
+       if ((src_x + src_w > fb->width) || (src_y + src_h > fb->height)) {
+               DRM_DEBUG_ATOMIC("Invalid source coordinate.\n");
+               return -EINVAL;
+       }
+
+       if ((src_x % info->hsub) || (src_w % info->hsub) ||
+           (src_y % info->vsub) || (src_h % info->vsub)) {
+               DRM_DEBUG_ATOMIC("Wrong subsampling dimension x:%d, y:%d, w:%d, h:%d for format: %x.\n",
+                                src_x, src_y, src_w, src_h, info->format);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 dma_addr_t
 komeda_fb_get_pixel_addr(struct komeda_fb *kfb, int x, int y, int plane)
 {
index f4046e2e6f7420030c889bfb82227b6130f4f012..c61ca98a3a6370d8c4591b98c9774ff756f7f0a3 100644 (file)
@@ -38,6 +38,8 @@ struct komeda_fb {
 struct drm_framebuffer *
 komeda_fb_create(struct drm_device *dev, struct drm_file *file,
                const struct drm_mode_fb_cmd2 *mode_cmd);
+int komeda_fb_check_src_coords(const struct komeda_fb *kfb,
+                              u32 src_x, u32 src_y, u32 src_w, u32 src_h);
 dma_addr_t
 komeda_fb_get_pixel_addr(struct komeda_fb *kfb, int x, int y, int plane);
 bool komeda_fb_is_layer_supported(struct komeda_fb *kfb, u32 layer_type,
index 042d4d749d18ee319bbeb24e04103b56d5f972cd..d9f4e883bf43c79ec283464d419be87680fa5a53 100644 (file)
@@ -271,21 +271,33 @@ komeda_component_get_avail_scaler(struct komeda_component *c,
 
 static int
 komeda_layer_check_cfg(struct komeda_layer *layer,
-                      struct komeda_plane_state *kplane_st,
+                      struct komeda_fb *kfb,
                       struct komeda_data_flow_cfg *dflow)
 {
-       struct komeda_fb *kfb = to_kfb(kplane_st->base.fb);
+       u32 hsize_in, vsize_in;
 
        if (!komeda_fb_is_layer_supported(kfb, layer->layer_type, dflow->rot))
                return -EINVAL;
 
-       if (!in_range(&layer->hsize_in, dflow->in_w)) {
-               DRM_DEBUG_ATOMIC("src_w: %d is out of range.\n", dflow->in_w);
+       if (komeda_fb_check_src_coords(kfb, dflow->in_x, dflow->in_y,
+                                      dflow->in_w, dflow->in_h))
+               return -EINVAL;
+
+       if (layer->base.id == KOMEDA_COMPONENT_WB_LAYER) {
+               hsize_in = dflow->out_w;
+               vsize_in = dflow->out_h;
+       } else {
+               hsize_in = dflow->in_w;
+               vsize_in = dflow->in_h;
+       }
+
+       if (!in_range(&layer->hsize_in, hsize_in)) {
+               DRM_DEBUG_ATOMIC("invalidate src_w %d.\n", hsize_in);
                return -EINVAL;
        }
 
-       if (!in_range(&layer->vsize_in, dflow->in_h)) {
-               DRM_DEBUG_ATOMIC("src_h: %d is out of range.\n", dflow->in_h);
+       if (!in_range(&layer->vsize_in, vsize_in)) {
+               DRM_DEBUG_ATOMIC("invalidate src_h %d.\n", vsize_in);
                return -EINVAL;
        }
 
@@ -304,7 +316,7 @@ komeda_layer_validate(struct komeda_layer *layer,
        struct komeda_layer_state *st;
        int i, err;
 
-       err = komeda_layer_check_cfg(layer, kplane_st, dflow);
+       err = komeda_layer_check_cfg(layer, kfb, dflow);
        if (err)
                return err;
 
@@ -362,11 +374,11 @@ komeda_wb_layer_validate(struct komeda_layer *wb_layer,
        struct komeda_fb *kfb = to_kfb(conn_st->writeback_job->fb);
        struct komeda_component_state *c_st;
        struct komeda_layer_state *st;
-       int i;
+       int i, err;
 
-       if (!komeda_fb_is_layer_supported(kfb, wb_layer->layer_type,
-                                         dflow->rot))
-               return -EINVAL;
+       err = komeda_layer_check_cfg(wb_layer, kfb, dflow);
+       if (err)
+               return err;
 
        c_st = komeda_component_get_state_and_set_user(&wb_layer->base,
                        conn_st->state, conn_st->connector, conn_st->crtc);