diff options
author | Terence Hampson <thampson@codeaurora.org> | 2015-09-01 15:50:52 -0400 |
---|---|---|
committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 20:45:33 -0700 |
commit | 778f349a00061ace41f5ebd10d700335b0cf532a (patch) | |
tree | aa8cd8c4a048731ac77b1a1477a4ebb67164a9d6 /drivers/video | |
parent | d9f95bd8d910d2d889b2eb57e3bb2e51d20d43d1 (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.c | 9 | ||||
-rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp.h | 3 | ||||
-rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_ctl.c | 19 | ||||
-rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_formats.h | 52 | ||||
-rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_util.c | 25 | ||||
-rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_wfd.c | 23 |
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; |