diff options
| author | Adrian Salido-Moreno <adrianm@codeaurora.org> | 2012-12-20 13:01:39 -0800 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 20:15:01 -0700 |
| commit | cd32538dbc13c261ae8f313cd64e98063c80b3fb (patch) | |
| tree | 532f9b2a7ea9fade861d8ecd856b5c852270f57e | |
| parent | a6dc8943f3461e3066b2f61ded490cf6db5e90cc (diff) | |
msm: mdss: enable secure wfd support
Provide APIs to enable secure content display through wifi display.
Implement workaround to allocate a secure source pipe so that MDP is
allowed to write back to secure buffer.
Change-Id: I1c329fec726bec1ae721bc5f2ec39d3b21259e8d
Signed-off-by: Adrian Salido-Moreno <adrianm@codeaurora.org>
Signed-off-by: Deva Ramasubramanian <dramasub@codeaurora.org>
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_ctl.c | 6 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_hwio.h | 1 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_pipe.c | 28 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_wb.c | 107 |
4 files changed, 137 insertions, 5 deletions
diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c index 4d6298db9f0b..6a41fd45a1bd 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c +++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c @@ -883,7 +883,7 @@ static int mdss_mdp_mixer_setup(struct mdss_mdp_ctl *ctl, struct mdss_mdp_pipe *pipe; u32 off, blend_op, blend_stage; u32 mixercfg = 0, blend_color_out = 0, bgalpha = 0; - int stage; + int stage, secure = 0; if (!mixer) return -ENODEV; @@ -897,6 +897,7 @@ static int mdss_mdp_mixer_setup(struct mdss_mdp_ctl *ctl, mixercfg = 1 << (3 * pipe->num); if (pipe->src_fmt->alpha_enable) bgalpha = 1; + secure = pipe->flags & MDP_SECURE_OVERLAY_SESSION; } for (stage = MDSS_MDP_STAGE_0; stage < MDSS_MDP_MAX_STAGE; stage++) { @@ -914,7 +915,8 @@ static int mdss_mdp_mixer_setup(struct mdss_mdp_ctl *ctl, if (pipe->is_fg) { bgalpha = 0; - mixercfg = MDSS_MDP_LM_BORDER_COLOR; + if (!secure) + mixercfg = MDSS_MDP_LM_BORDER_COLOR; blend_op = (MDSS_MDP_BLEND_FG_ALPHA_FG_CONST | MDSS_MDP_BLEND_BG_ALPHA_BG_CONST); diff --git a/drivers/video/fbdev/msm/mdss_mdp_hwio.h b/drivers/video/fbdev/msm/mdss_mdp_hwio.h index 1c5c4b85629a..d4ffaffdf153 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_hwio.h +++ b/drivers/video/fbdev/msm/mdss_mdp_hwio.h @@ -221,6 +221,7 @@ enum mdss_mdp_sspp_chroma_samp_type { #define MDSS_MDP_SCALE_FILTER_CA 0x3 #define MDSS_MDP_SCALEY_EN BIT(1) #define MDSS_MDP_SCALEX_EN BIT(0) +#define MDSS_MDP_FMT_SOLID_FILL 0x4037FF #define MDSS_MDP_NUM_REG_MIXERS 3 #define MDSS_MDP_NUM_WB_MIXERS 2 diff --git a/drivers/video/fbdev/msm/mdss_mdp_pipe.c b/drivers/video/fbdev/msm/mdss_mdp_pipe.c index 0a525615300c..f84fd82af780 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_pipe.c +++ b/drivers/video/fbdev/msm/mdss_mdp_pipe.c @@ -709,6 +709,28 @@ static int mdss_mdp_src_addr_setup(struct mdss_mdp_pipe *pipe, return 0; } +static int mdss_mdp_pipe_solidfill_setup(struct mdss_mdp_pipe *pipe) +{ + int ret; + u32 secure, format; + + pr_debug("solid fill setup on pnum=%d\n", pipe->num); + + ret = mdss_mdp_image_setup(pipe); + if (ret) { + pr_err("image setup error for pnum=%d\n", pipe->num); + return ret; + } + + format = MDSS_MDP_FMT_SOLID_FILL; + secure = (pipe->flags & MDP_SECURE_OVERLAY_SESSION ? 0xF : 0x0); + + mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_SRC_FORMAT, format); + mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_SRC_ADDR_SW_STATUS, secure); + + return 0; +} + int mdss_mdp_pipe_queue_data(struct mdss_mdp_pipe *pipe, struct mdss_mdp_data *src_data) { @@ -731,6 +753,11 @@ int mdss_mdp_pipe_queue_data(struct mdss_mdp_pipe *pipe, mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false); params_changed = pipe->params_changed; + if (src_data == NULL) { + mdss_mdp_pipe_solidfill_setup(pipe); + goto update_nobuf; + } + if (params_changed) { pipe->params_changed = 0; @@ -768,6 +795,7 @@ int mdss_mdp_pipe_queue_data(struct mdss_mdp_pipe *pipe, goto done; } +update_nobuf: mdss_mdp_mixer_pipe_update(pipe, params_changed); pipe->play_cnt++; diff --git a/drivers/video/fbdev/msm/mdss_mdp_wb.c b/drivers/video/fbdev/msm/mdss_mdp_wb.c index 23efcb8c36fd..1d55fa9bf46e 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_wb.c +++ b/drivers/video/fbdev/msm/mdss_mdp_wb.c @@ -26,7 +26,6 @@ #include "mdss_mdp.h" #include "mdss_fb.h" -#define DEBUG_WRITEBACK enum mdss_mdp_wb_state { WB_OPEN, @@ -43,6 +42,8 @@ struct mdss_mdp_wb { struct list_head register_queue; wait_queue_head_t wait_q; u32 state; + int is_secure; + struct mdss_mdp_pipe *secure_pipe; }; enum mdss_mdp_wb_node_state { @@ -121,6 +122,72 @@ struct mdss_mdp_data *mdss_mdp_wb_debug_buffer(struct msm_fb_data_type *mfd) } #endif +int mdss_mdp_wb_set_secure(struct msm_fb_data_type *mfd, int enable) +{ + struct mdss_mdp_wb *wb; + struct mdss_mdp_pipe *pipe; + struct mdss_mdp_mixer *mixer; + + pr_debug("setting secure=%d\n", enable); + + wb = mfd->wb; + if (wb == NULL) { + pr_err("Invalid writeback session\n"); + return -ENODEV; + } + + wb->is_secure = enable; + pipe = wb->secure_pipe; + + if (!enable) { + if (pipe) { + /* unset pipe */ + mdss_mdp_mixer_pipe_unstage(pipe); + mdss_mdp_pipe_destroy(pipe); + wb->secure_pipe = NULL; + } + return 0; + } + + mixer = mdss_mdp_mixer_get(mfd->ctl, MDSS_MDP_MIXER_MUX_DEFAULT); + if (!mixer) { + pr_err("Unable to find mixer for wb\n"); + return -ENOENT; + } + + if (!pipe) { + pipe = mdss_mdp_pipe_alloc(mixer, MDSS_MDP_PIPE_TYPE_RGB); + if (!pipe) + pipe = mdss_mdp_pipe_alloc(mixer, + MDSS_MDP_PIPE_TYPE_VIG); + if (!pipe) { + pr_err("Unable to get pipe to set secure session\n"); + return -ENOMEM; + } + + pipe->src_fmt = mdss_mdp_get_format_params(MDP_RGBA_8888); + + pipe->mfd = mfd; + pipe->mixer_stage = MDSS_MDP_STAGE_BASE; + wb->secure_pipe = pipe; + } + + pipe->img_height = mixer->height; + pipe->img_width = mixer->width; + pipe->src.x = 0; + pipe->src.y = 0; + pipe->src.w = pipe->img_width; + pipe->src.h = pipe->img_height; + pipe->dst = pipe->src; + + pipe->flags = (enable ? MDP_SECURE_OVERLAY_SESSION : 0); + pipe->params_changed++; + + pr_debug("setting secure pipe=%d flags=%x\n", pipe->num, pipe->flags); + + return mdss_mdp_pipe_queue_data(pipe, NULL); +} + static int mdss_mdp_wb_init(struct msm_fb_data_type *mfd) { struct mdss_mdp_wb *wb; @@ -173,6 +240,10 @@ static int mdss_mdp_wb_terminate(struct msm_fb_data_type *mfd) kfree(node); } } + + wb->is_secure = false; + if (wb->secure_pipe) + mdss_mdp_pipe_destroy(wb->secure_pipe); mutex_unlock(&wb->lock); mfd->wb = NULL; @@ -257,6 +328,8 @@ static struct mdss_mdp_wb_data *get_local_node(struct mdss_mdp_wb *wb, buf = &node->buf_data.p[0]; buf->addr = (u32) (data->iova + data->offset); buf->len = UINT_MAX; /* trusted source */ + if (wb->is_secure) + buf->flags |= MDP_SECURE_OVERLAY_SESSION; ret = mdss_mdp_wb_register_node(wb, node); if (IS_ERR_VALUE(ret)) { pr_err("error registering wb node\n"); @@ -284,6 +357,8 @@ static struct mdss_mdp_wb_data *get_user_node(struct msm_fb_data_type *mfd, node->buf_data.num_planes = 1; buf = &node->buf_data.p[0]; + if (wb->is_secure) + buf->flags |= MDP_SECURE_OVERLAY_SESSION; ret = mdss_mdp_get_img(data, buf); if (IS_ERR_VALUE(ret)) { pr_err("error getting buffer info\n"); @@ -419,6 +494,9 @@ int mdss_mdp_wb_kickoff(struct mdss_mdp_ctl *ctl) wb = ctl->mfd->wb; if (wb) { mutex_lock(&wb->lock); + /* in case of reinit of control path need to reset secure */ + if (ctl->play_cnt == 0) + mdss_mdp_wb_set_secure(ctl->mfd, wb->is_secure); if (!list_empty(&wb->free_queue) && wb->state != WB_STOPING && wb->state != WB_STOP) { node = list_first_entry(&wb->free_queue, @@ -568,8 +646,31 @@ int msm_fb_writeback_terminate(struct fb_info *info) } EXPORT_SYMBOL(msm_fb_writeback_terminate); -int msm_fb_get_iommu_domain(void) +int msm_fb_get_iommu_domain(struct fb_info *info, int domain) { - return mdss_get_iommu_domain(MDSS_IOMMU_DOMAIN_UNSECURE); + int mdss_domain; + switch (domain) { + case MDP_IOMMU_DOMAIN_CP: + mdss_domain = MDSS_IOMMU_DOMAIN_SECURE; + break; + case MDP_IOMMU_DOMAIN_NS: + mdss_domain = MDSS_IOMMU_DOMAIN_UNSECURE; + break; + default: + pr_err("Invalid mdp iommu domain (%d)\n", domain); + return -EINVAL; + } + return mdss_get_iommu_domain(mdss_domain); } EXPORT_SYMBOL(msm_fb_get_iommu_domain); + +int msm_fb_writeback_set_secure(struct fb_info *info, int enable) +{ + struct msm_fb_data_type *mfd = (struct msm_fb_data_type *) info->par; + + if (!mfd) + return -ENODEV; + + return mdss_mdp_wb_set_secure(mfd, enable); +} +EXPORT_SYMBOL(msm_fb_writeback_set_secure); |
