summaryrefslogtreecommitdiff
path: root/drivers/video
diff options
context:
space:
mode:
authorTerence Hampson <thampson@codeaurora.org>2015-09-01 15:50:52 -0400
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 20:45:33 -0700
commit778f349a00061ace41f5ebd10d700335b0cf532a (patch)
treeaa8cd8c4a048731ac77b1a1477a4ebb67164a9d6 /drivers/video
parentd9f95bd8d910d2d889b2eb57e3bb2e51d20d43d1 (diff)
msm: mdss: validate wfd dst formats
Validate wfd destination formats that make use of mdp writeback interface. Change-Id: I52b6faee259c4fcde733a96b7cc0b834eebe5ed9 Signed-off-by: Terence Hampson <thampson@codeaurora.org>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp.c9
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp.h3
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_ctl.c19
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_formats.h52
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_util.c25
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_wfd.c23
6 files changed, 110 insertions, 21 deletions
diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c
index 9d29efeb0348..d54b35ba7dc4 100644
--- a/drivers/video/fbdev/msm/mdss_mdp.c
+++ b/drivers/video/fbdev/msm/mdss_mdp.c
@@ -134,6 +134,12 @@ static struct msm_bus_scale_pdata mdp_reg_bus_scale_table = {
.active_only = true,
};
+u32 invalid_mdp107_wb_output_fmts[] = {
+ MDP_XRGB_8888,
+ MDP_RGBX_8888,
+ MDP_BGRX_8888,
+};
+
static void mdss_mdp_footswitch_ctrl(struct mdss_data_type *mdata, int on);
static int mdss_mdp_parse_dt(struct platform_device *pdev);
static int mdss_mdp_parse_dt_pipe(struct platform_device *pdev);
@@ -1183,6 +1189,9 @@ static void mdss_mdp_hw_rev_caps_init(struct mdss_data_type *mdata)
case MDSS_MDP_HW_REV_107:
mdss_set_quirk(mdata, MDSS_QUIRK_ROTCDP);
case MDSS_MDP_HW_REV_107_1:
+ mdss_mdp_format_flag_removal(invalid_mdp107_wb_output_fmts,
+ ARRAY_SIZE(invalid_mdp107_wb_output_fmts),
+ VALID_MDP_WB_INTF_FORMAT);
case MDSS_MDP_HW_REV_107_2:
mdata->max_target_zorder = 7; /* excluding base layer */
mdata->max_cursor_size = 128;
diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h
index 40fa1febda36..b576551fda37 100644
--- a/drivers/video/fbdev/msm/mdss_mdp.h
+++ b/drivers/video/fbdev/msm/mdss_mdp.h
@@ -48,6 +48,7 @@
#define OVERLAY_MAX 10
#define VALID_ROT_WB_FORMAT BIT(0)
+#define VALID_MDP_WB_INTF_FORMAT BIT(1)
#define C3_ALPHA 3 /* alpha */
#define C2_R_Cr 2 /* R/Cr */
@@ -1211,6 +1212,7 @@ int mdss_mdp_get_rau_strides(u32 w, u32 h, struct mdss_mdp_format_params *fmt,
struct mdss_mdp_plane_sizes *ps);
void mdss_mdp_data_calc_offset(struct mdss_mdp_data *data, u16 x, u16 y,
struct mdss_mdp_plane_sizes *ps, struct mdss_mdp_format_params *fmt);
+void mdss_mdp_format_flag_removal(u32 *table, u32 num, u32 remove_bits);
struct mdss_mdp_format_params *mdss_mdp_get_format_params(u32 format);
int mdss_mdp_validate_offset_for_ubwc_format(
struct mdss_mdp_format_params *fmt, u16 x, u16 y);
@@ -1284,6 +1286,7 @@ struct mdss_mdp_mixer *mdss_mdp_mixer_alloc(
struct mdss_mdp_ctl *ctl, u32 type, int mux, int rotator);
int mdss_mdp_mixer_free(struct mdss_mdp_mixer *mixer);
+bool mdss_mdp_is_wb_mdp_intf(u32 num, u32 reg_index);
struct mdss_mdp_writeback *mdss_mdp_wb_assign(u32 id, u32 reg_index);
struct mdss_mdp_writeback *mdss_mdp_wb_alloc(u32 caps, u32 reg_index);
void mdss_mdp_wb_free(struct mdss_mdp_writeback *wb);
diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c
index 7f9e147b13d1..fc5e3fe732d8 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c
@@ -4826,6 +4826,25 @@ struct mdss_mdp_writeback *mdss_mdp_wb_alloc(u32 caps, u32 reg_index)
return wb;
}
+bool mdss_mdp_is_wb_mdp_intf(u32 num, u32 reg_index)
+{
+ struct mdss_data_type *mdata = mdss_mdp_get_mdata();
+ struct mdss_mdp_writeback *wb = NULL;
+ bool wb_virtual_on;
+
+ wb_virtual_on = (mdata->nctl == mdata->nwb_offsets);
+
+ if (num >= mdata->nwb || (wb_virtual_on && reg_index >=
+ mdata->nwb_offsets))
+ return false;
+
+ wb = mdata->wb + num;
+ if (!wb)
+ return false;
+
+ return (wb->caps & MDSS_MDP_WB_INTF) ? true : false;
+}
+
struct mdss_mdp_writeback *mdss_mdp_wb_assign(u32 num, u32 reg_index)
{
struct mdss_data_type *mdata = mdss_mdp_get_mdata();
diff --git a/drivers/video/fbdev/msm/mdss_mdp_formats.h b/drivers/video/fbdev/msm/mdss_mdp_formats.h
index a88ecfa3a888..c3c114c4dc2d 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_formats.h
+++ b/drivers/video/fbdev/msm/mdss_mdp_formats.h
@@ -217,31 +217,34 @@ static struct mdss_mdp_format_params_ubwc mdss_mdp_format_ubwc_map[] = {
};
static struct mdss_mdp_format_params mdss_mdp_format_map[] = {
- FMT_RGB_565(MDP_RGB_565, MDSS_MDP_FETCH_LINEAR, VALID_ROT_WB_FORMAT,
- C1_B_Cb, C0_G_Y, C2_R_Cr),
- FMT_RGB_565(MDP_BGR_565, MDSS_MDP_FETCH_LINEAR, VALID_ROT_WB_FORMAT,
- C2_R_Cr, C0_G_Y, C1_B_Cb),
+ FMT_RGB_565(MDP_RGB_565, MDSS_MDP_FETCH_LINEAR, VALID_ROT_WB_FORMAT |
+ VALID_MDP_WB_INTF_FORMAT, C1_B_Cb, C0_G_Y, C2_R_Cr),
+ FMT_RGB_565(MDP_BGR_565, MDSS_MDP_FETCH_LINEAR, VALID_ROT_WB_FORMAT |
+ VALID_MDP_WB_INTF_FORMAT, C2_R_Cr, C0_G_Y, C1_B_Cb),
FMT_RGB_565(MDP_RGB_565_TILE, MDSS_MDP_FETCH_TILE, VALID_ROT_WB_FORMAT,
C1_B_Cb, C0_G_Y, C2_R_Cr),
FMT_RGB_565(MDP_BGR_565_TILE, MDSS_MDP_FETCH_TILE, VALID_ROT_WB_FORMAT,
C2_R_Cr, C0_G_Y, C1_B_Cb),
- FMT_RGB_888(MDP_RGB_888, MDSS_MDP_FETCH_LINEAR, VALID_ROT_WB_FORMAT,
- C2_R_Cr, C0_G_Y, C1_B_Cb),
- FMT_RGB_888(MDP_BGR_888, MDSS_MDP_FETCH_LINEAR, VALID_ROT_WB_FORMAT,
- C1_B_Cb, C0_G_Y, C2_R_Cr),
+ FMT_RGB_888(MDP_RGB_888, MDSS_MDP_FETCH_LINEAR, VALID_ROT_WB_FORMAT |
+ VALID_MDP_WB_INTF_FORMAT, C2_R_Cr, C0_G_Y, C1_B_Cb),
+ FMT_RGB_888(MDP_BGR_888, MDSS_MDP_FETCH_LINEAR, VALID_ROT_WB_FORMAT |
+ VALID_MDP_WB_INTF_FORMAT, C1_B_Cb, C0_G_Y, C2_R_Cr),
- FMT_RGB_8888(MDP_XRGB_8888, MDSS_MDP_FETCH_LINEAR, VALID_ROT_WB_FORMAT,
- 0, C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb),
+ FMT_RGB_8888(MDP_XRGB_8888, MDSS_MDP_FETCH_LINEAR, VALID_ROT_WB_FORMAT |
+ VALID_MDP_WB_INTF_FORMAT, 0, C3_ALPHA, C2_R_Cr, C0_G_Y,
+ C1_B_Cb),
FMT_RGB_8888(MDP_ARGB_8888, MDSS_MDP_FETCH_LINEAR, VALID_ROT_WB_FORMAT,
1, C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb),
FMT_RGB_8888(MDP_RGBA_8888, MDSS_MDP_FETCH_LINEAR, VALID_ROT_WB_FORMAT,
1, C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA),
- FMT_RGB_8888(MDP_RGBX_8888, MDSS_MDP_FETCH_LINEAR, VALID_ROT_WB_FORMAT,
- 0, C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA),
+ FMT_RGB_8888(MDP_RGBX_8888, MDSS_MDP_FETCH_LINEAR, VALID_ROT_WB_FORMAT |
+ VALID_MDP_WB_INTF_FORMAT, 0, C2_R_Cr, C0_G_Y, C1_B_Cb,
+ C3_ALPHA),
FMT_RGB_8888(MDP_BGRA_8888, MDSS_MDP_FETCH_LINEAR, VALID_ROT_WB_FORMAT,
1, C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA),
- FMT_RGB_8888(MDP_BGRX_8888, MDSS_MDP_FETCH_LINEAR, VALID_ROT_WB_FORMAT,
- 0, C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA),
+ FMT_RGB_8888(MDP_BGRX_8888, MDSS_MDP_FETCH_LINEAR, VALID_ROT_WB_FORMAT |
+ VALID_MDP_WB_INTF_FORMAT, 0, C1_B_Cb, C0_G_Y, C2_R_Cr,
+ C3_ALPHA),
FMT_RGB_8888(MDP_RGBA_8888_TILE, MDSS_MDP_FETCH_TILE,
VALID_ROT_WB_FORMAT, 1, C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA),
FMT_RGB_8888(MDP_ARGB_8888_TILE, MDSS_MDP_FETCH_TILE,
@@ -272,20 +275,27 @@ static struct mdss_mdp_format_params mdss_mdp_format_map[] = {
FMT_YUV_PSEUDO(MDP_Y_CBCR_H1V2, MDSS_MDP_FETCH_LINEAR,
MDSS_MDP_CHROMA_H1V2, VALID_ROT_WB_FORMAT, C1_B_Cb, C2_R_Cr),
FMT_YUV_PSEUDO(MDP_Y_CRCB_H2V2, MDSS_MDP_FETCH_LINEAR,
- MDSS_MDP_CHROMA_420, VALID_ROT_WB_FORMAT, C2_R_Cr, C1_B_Cb),
+ MDSS_MDP_CHROMA_420, VALID_ROT_WB_FORMAT |
+ VALID_MDP_WB_INTF_FORMAT, C2_R_Cr, C1_B_Cb),
FMT_YUV_PSEUDO(MDP_Y_CBCR_H2V2, MDSS_MDP_FETCH_LINEAR,
- MDSS_MDP_CHROMA_420, VALID_ROT_WB_FORMAT, C1_B_Cb, C2_R_Cr),
+ MDSS_MDP_CHROMA_420, VALID_ROT_WB_FORMAT |
+ VALID_MDP_WB_INTF_FORMAT, C1_B_Cb, C2_R_Cr),
FMT_YUV_PSEUDO(MDP_Y_CBCR_H2V2_VENUS, MDSS_MDP_FETCH_LINEAR,
- MDSS_MDP_CHROMA_420, VALID_ROT_WB_FORMAT, C1_B_Cb, C2_R_Cr),
+ MDSS_MDP_CHROMA_420, VALID_ROT_WB_FORMAT |
+ VALID_MDP_WB_INTF_FORMAT, C1_B_Cb, C2_R_Cr),
FMT_YUV_PSEUDO(MDP_Y_CRCB_H2V2_VENUS, MDSS_MDP_FETCH_LINEAR,
- MDSS_MDP_CHROMA_420, VALID_ROT_WB_FORMAT, C2_R_Cr, C1_B_Cb),
+ MDSS_MDP_CHROMA_420, VALID_ROT_WB_FORMAT |
+ VALID_MDP_WB_INTF_FORMAT, C2_R_Cr, C1_B_Cb),
FMT_YUV_PLANR(MDP_Y_CB_CR_H2V2, MDSS_MDP_FETCH_LINEAR,
- MDSS_MDP_CHROMA_420, VALID_ROT_WB_FORMAT, C2_R_Cr, C1_B_Cb),
+ MDSS_MDP_CHROMA_420, VALID_ROT_WB_FORMAT |
+ VALID_MDP_WB_INTF_FORMAT, C2_R_Cr, C1_B_Cb),
FMT_YUV_PLANR(MDP_Y_CR_CB_H2V2, MDSS_MDP_FETCH_LINEAR,
- MDSS_MDP_CHROMA_420, VALID_ROT_WB_FORMAT, C1_B_Cb, C2_R_Cr),
+ MDSS_MDP_CHROMA_420, VALID_ROT_WB_FORMAT |
+ VALID_MDP_WB_INTF_FORMAT, C1_B_Cb, C2_R_Cr),
FMT_YUV_PLANR(MDP_Y_CR_CB_GH2V2, MDSS_MDP_FETCH_LINEAR,
- MDSS_MDP_CHROMA_420, VALID_ROT_WB_FORMAT, C1_B_Cb, C2_R_Cr),
+ MDSS_MDP_CHROMA_420, VALID_ROT_WB_FORMAT |
+ VALID_MDP_WB_INTF_FORMAT, C1_B_Cb, C2_R_Cr),
{
FMT_YUV_COMMON(MDP_YCBCR_H1V1),
diff --git a/drivers/video/fbdev/msm/mdss_mdp_util.c b/drivers/video/fbdev/msm/mdss_mdp_util.c
index 668f19169c02..ec1d1402fe7a 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_util.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_util.c
@@ -236,6 +236,31 @@ hist_isr_done:
return IRQ_HANDLED;
}
+void mdss_mdp_format_flag_removal(u32 *table, u32 num, u32 remove_bits)
+{
+ struct mdss_mdp_format_params *fmt = NULL;
+ int i, j;
+
+ if (table == NULL) {
+ pr_err("Null table provided\n");
+ return;
+ }
+
+ for (i = 0; i < num; i++) {
+ if (table[i] > MDP_IMGTYPE_LIMIT) {
+ pr_err("Invalid format:%d, idx:%d\n", table[i], i);
+ continue;
+ }
+ for (j = 0; j < ARRAY_SIZE(mdss_mdp_format_map); j++) {
+ fmt = &mdss_mdp_format_map[i];
+ if (table[i] == fmt->format) {
+ fmt->flag &= ~remove_bits;
+ break;
+ }
+ }
+ }
+}
+
struct mdss_mdp_format_params *mdss_mdp_get_format_params(u32 format)
{
struct mdss_mdp_format_params *fmt = NULL;
diff --git a/drivers/video/fbdev/msm/mdss_mdp_wfd.c b/drivers/video/fbdev/msm/mdss_mdp_wfd.c
index 8798aece3805..aefec0f2f47c 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_wfd.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_wfd.c
@@ -291,11 +291,34 @@ void mdss_mdp_wfd_remove_data(struct mdss_mdp_wfd *wfd,
kfree(wfd_data);
}
+static int mdss_mdp_wfd_validate_out_configuration(struct mdss_mdp_wfd *wfd,
+ struct mdp_output_layer *layer)
+{
+ struct mdss_mdp_format_params *fmt = NULL;
+ struct mdss_mdp_ctl *ctl = wfd->ctl;
+ u32 wb_idx = layer->writeback_ndx;
+
+ if (mdss_mdp_is_wb_mdp_intf(wb_idx, ctl->num)) {
+ fmt = mdss_mdp_get_format_params(layer->buffer.format);
+ if (!(fmt->flag & VALID_MDP_WB_INTF_FORMAT)) {
+ pr_err("wb=%d does not support dst fmt:%d\n", wb_idx,
+ layer->buffer.format);
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
+
int mdss_mdp_wfd_validate(struct mdss_mdp_wfd *wfd,
struct mdp_output_layer *layer)
{
u32 wb_idx = layer->writeback_ndx;
+ if (mdss_mdp_wfd_validate_out_configuration(wfd, layer)) {
+ pr_err("failed to validate output config\n");
+ return -EINVAL;
+ }
+
if (wb_idx > wfd->ctl->mdata->nwb)
return -EINVAL;