From: james qian wang (Arm Technology China) Date: Fri, 17 May 2019 10:05:06 +0000 (+0100) Subject: drm/komeda: Add komeda_fb_check_src_coords X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=df860f98bcd52c5425b40eb53e6a46ddbb6f1adc;p=openwrt%2Fstaging%2Fblogic.git drm/komeda: Add komeda_fb_check_src_coords 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) Signed-off-by: Liviu Dudau --- diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c index f0593726d127..50858401da05 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c @@ -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) { diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.h b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.h index f4046e2e6f74..c61ca98a3a63 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.h +++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.h @@ -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, diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c index 042d4d749d18..d9f4e883bf43 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c @@ -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);