summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2017-03-15 10:25:35 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2017-03-15 10:25:35 -0700
commit358a638e6968712c452888bf9ee4c1e385ee65c7 (patch)
tree2fb9cad4bcafa9c63b3e310d853870ce486c8a34
parent921b4d5582741edacd73296db059347cd0b6b1cd (diff)
parent1ddddebe7cab5a592cce0ba4a3d648073b64709b (diff)
Merge "msm: mdss: Fix source split validation"
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_layer.c126
1 files changed, 82 insertions, 44 deletions
diff --git a/drivers/video/fbdev/msm/mdss_mdp_layer.c b/drivers/video/fbdev/msm/mdss_mdp_layer.c
index f78600072ed0..fce667a2126d 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_layer.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_layer.c
@@ -2264,6 +2264,78 @@ static int __validate_multirect(struct msm_fb_data_type *mfd,
return 0;
}
+static int __check_source_split(struct mdp_input_layer *layer_list,
+ struct mdss_mdp_pipe **pipe_list, u32 index,
+ u32 left_lm_w, struct mdss_mdp_pipe **left_blend_pipe)
+{
+ int i = index - 1;
+ struct mdp_input_layer *curr, *prev;
+ struct mdp_rect *left, *right;
+ bool match = false;
+ struct mdss_mdp_pipe *left_pipe = NULL;
+
+ /*
+ * check if current layer is at same z_order as any of the
+ * previous layers, and fail if any or both are async layers,
+ * as async layers should have unique z_order.
+ *
+ * If it has same z_order and qualifies as a right blend,
+ * pass a pointer to the pipe representing previous overlay or
+ * in other terms left blend layer.
+ *
+ * Following logic of selecting left_blend has an inherent
+ * assumption that layer list is sorted on dst_x within a
+ * same z_order. Otherwise it will fail based on z_order checks.
+ */
+ curr = &layer_list[index];
+
+ while (i >= 0) {
+ if (layer_list[i].z_order == curr->z_order) {
+ pr_debug("z=%d found match @ %d of %d\n",
+ curr->z_order, i, index);
+ match = true;
+ break;
+ }
+ i--;
+ }
+
+ if (match) {
+ left_pipe = pipe_list[i];
+ prev = &layer_list[i];
+ left = &prev->dst_rect;
+ right = &curr->dst_rect;
+
+ if ((curr->flags & MDP_LAYER_ASYNC)
+ || (prev->flags & MDP_LAYER_ASYNC)) {
+ curr->error_code = -EINVAL;
+ pr_err("async curr should have unique z_order\n");
+ return curr->error_code;
+ }
+
+ /*
+ * check if curr is right blend by checking it's
+ * directly to the right.
+ */
+ if (((left->x + left->w) == right->x) &&
+ (left->y == right->y) && (left->h == right->h)) {
+ *left_blend_pipe = left_pipe;
+ MDSS_XLOG(curr->z_order, i, index);
+ }
+
+ /*
+ * if the curr is right at the left lm boundary and
+ * src split is not required then right blend is not
+ * required as it will lie only on the left mixer
+ */
+ if (!__layer_needs_src_split(prev) &&
+ ((left->x + left->w) == left_lm_w))
+ *left_blend_pipe = NULL;
+ }
+
+ return 0;
+}
+
+
/*
* __validate_layers() - validate input layers
* @mfd: Framebuffer data structure for display
@@ -2294,13 +2366,14 @@ static int __validate_layers(struct msm_fb_data_type *mfd,
struct mdss_data_type *mdata = mfd_to_mdata(mfd);
struct mdss_mdp_mixer *mixer = NULL;
- struct mdp_input_layer *layer, *prev_layer, *layer_list;
+ struct mdp_input_layer *layer, *layer_list;
struct mdss_mdp_validate_info_t *validate_info_list = NULL;
bool is_single_layer = false, force_validate;
enum layer_pipe_q pipe_q_type;
enum layer_zorder_used zorder_used[MDSS_MDP_MAX_STAGE] = {0};
enum mdss_mdp_pipe_rect rect_num;
struct mdp_destination_scaler_data *ds_data;
+ struct mdss_mdp_pipe *pipe_list[MAX_LAYER_COUNT] = {0};
ret = mutex_lock_interruptible(&mdp5_data->ov_lock);
if (ret)
@@ -2372,49 +2445,10 @@ static int __validate_layers(struct msm_fb_data_type *mfd,
dst_x = layer->dst_rect.x;
left_blend_pipe = NULL;
- prev_layer = (i > 0) ? &layer_list[i - 1] : NULL;
- /*
- * check if current layer is at same z_order as
- * previous one, and fail if any or both are async layers,
- * as async layers should have unique z_order.
- *
- * If it has same z_order and qualifies as a right blend,
- * pass a pointer to the pipe representing previous overlay or
- * in other terms left blend layer.
- *
- * Following logic of selecting left_blend has an inherent
- * assumption that layer list is sorted on dst_x within a
- * same z_order. Otherwise it will fail based on z_order checks.
- */
- if (prev_layer && (prev_layer->z_order == layer->z_order)) {
- struct mdp_rect *left = &prev_layer->dst_rect;
- struct mdp_rect *right = &layer->dst_rect;
-
- if ((layer->flags & MDP_LAYER_ASYNC)
- || (prev_layer->flags & MDP_LAYER_ASYNC)) {
- ret = -EINVAL;
- layer->error_code = ret;
- pr_err("async layer should have unique z_order\n");
- goto validate_exit;
- }
-
- /*
- * check if layer is right blend by checking it's
- * directly to the right.
- */
- if (((left->x + left->w) == right->x) &&
- (left->y == right->y) && (left->h == right->h))
- left_blend_pipe = pipe;
-
- /*
- * if the layer is right at the left lm boundary and
- * src split is not required then right blend is not
- * required as it will lie only on the left mixer
- */
- if (!__layer_needs_src_split(prev_layer) &&
- ((left->x + left->w) == left_lm_w))
- left_blend_pipe = NULL;
- }
+ if ((i > 0) &&
+ __check_source_split(layer_list, pipe_list, i, left_lm_w,
+ &left_blend_pipe))
+ goto validate_exit;
if (!is_split_lm(mfd) || __layer_needs_src_split(layer))
z = LAYER_ZORDER_BOTH;
@@ -2459,6 +2493,8 @@ static int __validate_layers(struct msm_fb_data_type *mfd,
else
left_plist[left_cnt++] = pipe;
+ pipe_list[i] = pipe;
+
if (layer->flags & MDP_LAYER_PP) {
memcpy(&pipe->pp_cfg, layer->pp_info,
sizeof(struct mdp_overlay_pp_params));
@@ -2551,6 +2587,8 @@ static int __validate_layers(struct msm_fb_data_type *mfd,
else
left_plist[left_cnt++] = pipe;
+ pipe_list[i] = pipe;
+
pr_debug("id:0x%x flags:0x%x dst_x:%d\n",
layer->pipe_ndx, layer->flags, layer->dst_rect.x);
layer->z_order -= MDSS_MDP_STAGE_0;