Merge "msm: mdss: Enable secure display and camera feature for msmcobalt"
This commit is contained in:
commit
82933a003b
10 changed files with 352 additions and 95 deletions
|
@ -178,6 +178,7 @@ enum mdss_hw_capabilities {
|
||||||
MDSS_CAPS_CWB_SUPPORTED,
|
MDSS_CAPS_CWB_SUPPORTED,
|
||||||
MDSS_CAPS_MDP_VOTE_CLK_NOT_SUPPORTED,
|
MDSS_CAPS_MDP_VOTE_CLK_NOT_SUPPORTED,
|
||||||
MDSS_CAPS_AVR_SUPPORTED,
|
MDSS_CAPS_AVR_SUPPORTED,
|
||||||
|
MDSS_CAPS_SEC_DETACH_SMMU,
|
||||||
MDSS_CAPS_MAX,
|
MDSS_CAPS_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -221,6 +222,7 @@ struct mdss_smmu_client {
|
||||||
bool domain_attached;
|
bool domain_attached;
|
||||||
bool handoff_pending;
|
bool handoff_pending;
|
||||||
void __iomem *mmu_base;
|
void __iomem *mmu_base;
|
||||||
|
int domain;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mdss_mdp_qseed3_lut_tbl {
|
struct mdss_mdp_qseed3_lut_tbl {
|
||||||
|
@ -327,6 +329,7 @@ struct mdss_data_type {
|
||||||
u32 wfd_mode;
|
u32 wfd_mode;
|
||||||
u32 has_no_lut_read;
|
u32 has_no_lut_read;
|
||||||
atomic_t sd_client_count;
|
atomic_t sd_client_count;
|
||||||
|
atomic_t sc_client_count;
|
||||||
u8 has_wb_ad;
|
u8 has_wb_ad;
|
||||||
u8 has_non_scalar_rgb;
|
u8 has_non_scalar_rgb;
|
||||||
bool has_src_split;
|
bool has_src_split;
|
||||||
|
@ -519,6 +522,8 @@ struct mdss_data_type {
|
||||||
u32 max_dest_scaler_input_width;
|
u32 max_dest_scaler_input_width;
|
||||||
u32 max_dest_scaler_output_width;
|
u32 max_dest_scaler_output_width;
|
||||||
struct mdss_mdp_destination_scaler *ds;
|
struct mdss_mdp_destination_scaler *ds;
|
||||||
|
u32 sec_disp_en;
|
||||||
|
u32 sec_cam_en;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct mdss_data_type *mdss_res;
|
extern struct mdss_data_type *mdss_res;
|
||||||
|
@ -579,6 +584,14 @@ static inline int mdss_get_sd_client_cnt(void)
|
||||||
return atomic_read(&mdss_res->sd_client_count);
|
return atomic_read(&mdss_res->sd_client_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int mdss_get_sc_client_cnt(void)
|
||||||
|
{
|
||||||
|
if (!mdss_res)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return atomic_read(&mdss_res->sc_client_count);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void mdss_set_quirk(struct mdss_data_type *mdata,
|
static inline void mdss_set_quirk(struct mdss_data_type *mdata,
|
||||||
enum mdss_hw_quirk bit)
|
enum mdss_hw_quirk bit)
|
||||||
{
|
{
|
||||||
|
|
|
@ -47,6 +47,8 @@
|
||||||
#include <linux/msm-bus-board.h>
|
#include <linux/msm-bus-board.h>
|
||||||
#include <soc/qcom/scm.h>
|
#include <soc/qcom/scm.h>
|
||||||
#include <soc/qcom/rpm-smd.h>
|
#include <soc/qcom/rpm-smd.h>
|
||||||
|
#include "soc/qcom/secure_buffer.h"
|
||||||
|
#include <asm/cacheflush.h>
|
||||||
|
|
||||||
#include "mdss.h"
|
#include "mdss.h"
|
||||||
#include "mdss_fb.h"
|
#include "mdss_fb.h"
|
||||||
|
@ -64,6 +66,8 @@
|
||||||
#define RES_1080p (1088*1920)
|
#define RES_1080p (1088*1920)
|
||||||
#define RES_UHD (3840*2160)
|
#define RES_UHD (3840*2160)
|
||||||
|
|
||||||
|
#define MDP_DEVICE_ID 0x1A
|
||||||
|
|
||||||
struct mdss_data_type *mdss_res;
|
struct mdss_data_type *mdss_res;
|
||||||
static u32 mem_protect_sd_ctrl_id;
|
static u32 mem_protect_sd_ctrl_id;
|
||||||
|
|
||||||
|
@ -87,6 +91,7 @@ struct msm_mdp_interface mdp5 = {
|
||||||
|
|
||||||
#define MEM_PROTECT_SD_CTRL 0xF
|
#define MEM_PROTECT_SD_CTRL 0xF
|
||||||
#define MEM_PROTECT_SD_CTRL_FLAT 0x14
|
#define MEM_PROTECT_SD_CTRL_FLAT 0x14
|
||||||
|
#define MEM_PROTECT_SD_CTRL_SWITCH 0x18
|
||||||
|
|
||||||
static DEFINE_SPINLOCK(mdp_lock);
|
static DEFINE_SPINLOCK(mdp_lock);
|
||||||
static DEFINE_SPINLOCK(mdss_mdp_intr_lock);
|
static DEFINE_SPINLOCK(mdss_mdp_intr_lock);
|
||||||
|
@ -1329,7 +1334,9 @@ int mdss_iommu_ctrl(int enable)
|
||||||
if (mdata->iommu_ref_cnt == 0) {
|
if (mdata->iommu_ref_cnt == 0) {
|
||||||
rc = mdss_smmu_detach(mdata);
|
rc = mdss_smmu_detach(mdata);
|
||||||
if (mdss_has_quirk(mdata,
|
if (mdss_has_quirk(mdata,
|
||||||
MDSS_QUIRK_MIN_BUS_VOTE))
|
MDSS_QUIRK_MIN_BUS_VOTE) &&
|
||||||
|
(!mdata->sec_disp_en ||
|
||||||
|
!mdata->sec_cam_en))
|
||||||
mdss_bus_scale_set_quota(MDSS_HW_RT,
|
mdss_bus_scale_set_quota(MDSS_HW_RT,
|
||||||
0, 0);
|
0, 0);
|
||||||
}
|
}
|
||||||
|
@ -1985,6 +1992,7 @@ static void mdss_mdp_hw_rev_caps_init(struct mdss_data_type *mdata)
|
||||||
mdata->pixel_ram_size = 50 * 1024;
|
mdata->pixel_ram_size = 50 * 1024;
|
||||||
mdata->rects_per_sspp[MDSS_MDP_PIPE_TYPE_DMA] = 2;
|
mdata->rects_per_sspp[MDSS_MDP_PIPE_TYPE_DMA] = 2;
|
||||||
|
|
||||||
|
mem_protect_sd_ctrl_id = MEM_PROTECT_SD_CTRL_SWITCH;
|
||||||
set_bit(MDSS_QOS_PER_PIPE_IB, mdata->mdss_qos_map);
|
set_bit(MDSS_QOS_PER_PIPE_IB, mdata->mdss_qos_map);
|
||||||
set_bit(MDSS_QOS_REMAPPER, mdata->mdss_qos_map);
|
set_bit(MDSS_QOS_REMAPPER, mdata->mdss_qos_map);
|
||||||
set_bit(MDSS_QOS_TS_PREFILL, mdata->mdss_qos_map);
|
set_bit(MDSS_QOS_TS_PREFILL, mdata->mdss_qos_map);
|
||||||
|
@ -2015,6 +2023,7 @@ static void mdss_mdp_hw_rev_caps_init(struct mdss_data_type *mdata)
|
||||||
mdata->has_wb_ubwc = true;
|
mdata->has_wb_ubwc = true;
|
||||||
set_bit(MDSS_CAPS_10_BIT_SUPPORTED, mdata->mdss_caps_map);
|
set_bit(MDSS_CAPS_10_BIT_SUPPORTED, mdata->mdss_caps_map);
|
||||||
set_bit(MDSS_CAPS_AVR_SUPPORTED, mdata->mdss_caps_map);
|
set_bit(MDSS_CAPS_AVR_SUPPORTED, mdata->mdss_caps_map);
|
||||||
|
set_bit(MDSS_CAPS_SEC_DETACH_SMMU, mdata->mdss_caps_map);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
mdata->max_target_zorder = 4; /* excluding base layer */
|
mdata->max_target_zorder = 4; /* excluding base layer */
|
||||||
|
@ -4939,29 +4948,115 @@ static void mdss_mdp_footswitch_ctrl(struct mdss_data_type *mdata, int on)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int mdss_mdp_secure_display_ctrl(unsigned int enable)
|
int mdss_mdp_secure_session_ctrl(unsigned int enable, u64 flags)
|
||||||
{
|
{
|
||||||
|
struct mdss_data_type *mdata = mdss_mdp_get_mdata();
|
||||||
struct sd_ctrl_req {
|
struct sd_ctrl_req {
|
||||||
unsigned int enable;
|
unsigned int enable;
|
||||||
} __attribute__ ((__packed__)) request;
|
} __attribute__ ((__packed__)) request;
|
||||||
unsigned int resp = -1;
|
unsigned int resp = -1;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
uint32_t sid_info;
|
||||||
struct scm_desc desc;
|
struct scm_desc desc;
|
||||||
|
|
||||||
desc.args[0] = request.enable = enable;
|
if (test_bit(MDSS_CAPS_SEC_DETACH_SMMU, mdata->mdss_caps_map)) {
|
||||||
desc.arginfo = SCM_ARGS(1);
|
/*
|
||||||
|
* Prepare syscall to hypervisor to switch the secure_vmid
|
||||||
|
* between secure and non-secure contexts
|
||||||
|
*/
|
||||||
|
/* MDP secure SID */
|
||||||
|
sid_info = 0x1;
|
||||||
|
desc.arginfo = SCM_ARGS(4, SCM_VAL, SCM_RW, SCM_VAL, SCM_VAL);
|
||||||
|
desc.args[0] = MDP_DEVICE_ID;
|
||||||
|
desc.args[1] = SCM_BUFFER_PHYS(&sid_info);
|
||||||
|
desc.args[2] = sizeof(uint32_t);
|
||||||
|
|
||||||
if (!is_scm_armv8()) {
|
|
||||||
ret = scm_call(SCM_SVC_MP, MEM_PROTECT_SD_CTRL,
|
pr_debug("Enable/Disable: %d, Flags %llx\n", enable, flags);
|
||||||
&request, sizeof(request), &resp, sizeof(resp));
|
if (enable) {
|
||||||
} else {
|
if (flags & MDP_SECURE_DISPLAY_OVERLAY_SESSION) {
|
||||||
ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP,
|
desc.args[3] = VMID_CP_SEC_DISPLAY;
|
||||||
|
mdata->sec_disp_en = 1;
|
||||||
|
} else if (flags & MDP_SECURE_CAMERA_OVERLAY_SESSION) {
|
||||||
|
desc.args[3] = VMID_CP_CAMERA_PREVIEW;
|
||||||
|
mdata->sec_cam_en = 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* detach smmu contexts */
|
||||||
|
ret = mdss_smmu_detach(mdata);
|
||||||
|
if (ret) {
|
||||||
|
pr_err("Error while detaching smmu contexts ret = %d\n",
|
||||||
|
ret);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* let the driver think smmu is still attached */
|
||||||
|
mdata->iommu_attached = true;
|
||||||
|
|
||||||
|
dmac_flush_range(&sid_info, &sid_info + 1);
|
||||||
|
ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP,
|
||||||
mem_protect_sd_ctrl_id), &desc);
|
mem_protect_sd_ctrl_id), &desc);
|
||||||
resp = desc.ret[0];
|
if (ret) {
|
||||||
}
|
pr_err("Error scm_call MEM_PROTECT_SD_CTRL(%u) ret=%dm resp=%x\n",
|
||||||
|
enable, ret, resp);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
resp = desc.ret[0];
|
||||||
|
|
||||||
pr_debug("scm_call MEM_PROTECT_SD_CTRL(%u): ret=%d, resp=%x",
|
pr_debug("scm_call MEM_PROTECT_SD_CTRL(%u): ret=%d, resp=%x\n",
|
||||||
|
enable, ret, resp);
|
||||||
|
} else {
|
||||||
|
desc.args[3] = VMID_CP_PIXEL;
|
||||||
|
if (flags & MDP_SECURE_DISPLAY_OVERLAY_SESSION)
|
||||||
|
mdata->sec_disp_en = 0;
|
||||||
|
else if (flags & MDP_SECURE_CAMERA_OVERLAY_SESSION)
|
||||||
|
mdata->sec_cam_en = 0;
|
||||||
|
|
||||||
|
dmac_flush_range(&sid_info, &sid_info + 1);
|
||||||
|
ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP,
|
||||||
|
mem_protect_sd_ctrl_id), &desc);
|
||||||
|
if (ret)
|
||||||
|
MDSS_XLOG_TOUT_HANDLER("mdp", "dsi0_ctrl",
|
||||||
|
"dsi0_phy", "dsi1_ctrl",
|
||||||
|
"dsi1_phy", "vbif", "vbif_nrt",
|
||||||
|
"dbg_bus", "vbif_dbg_bus",
|
||||||
|
"panic");
|
||||||
|
resp = desc.ret[0];
|
||||||
|
|
||||||
|
pr_debug("scm_call MEM_PROTECT_SD_CTRL(%u): ret=%d, resp=%x\n",
|
||||||
|
enable, ret, resp);
|
||||||
|
|
||||||
|
/* re-attach smmu contexts */
|
||||||
|
mdata->iommu_attached = false;
|
||||||
|
ret = mdss_smmu_attach(mdata);
|
||||||
|
if (ret) {
|
||||||
|
pr_err("Error while attaching smmu contexts ret = %d\n",
|
||||||
|
ret);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MDSS_XLOG(enable);
|
||||||
|
} else {
|
||||||
|
desc.args[0] = request.enable = enable;
|
||||||
|
desc.arginfo = SCM_ARGS(1);
|
||||||
|
|
||||||
|
if (!is_scm_armv8()) {
|
||||||
|
ret = scm_call(SCM_SVC_MP, MEM_PROTECT_SD_CTRL,
|
||||||
|
&request,
|
||||||
|
sizeof(request),
|
||||||
|
&resp,
|
||||||
|
sizeof(resp));
|
||||||
|
} else {
|
||||||
|
ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP,
|
||||||
|
mem_protect_sd_ctrl_id), &desc);
|
||||||
|
resp = desc.ret[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
pr_debug("scm_call MEM_PROTECT_SD_CTRL(%u): ret=%d, resp=%x\n",
|
||||||
enable, ret, resp);
|
enable, ret, resp);
|
||||||
|
}
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
|
|
@ -92,6 +92,8 @@
|
||||||
*/
|
*/
|
||||||
#define ENABLE_PIXEL_EXT_ONLY 0x80000000
|
#define ENABLE_PIXEL_EXT_ONLY 0x80000000
|
||||||
|
|
||||||
|
/* Pipe flag to indicate this pipe contains secure camera buffer */
|
||||||
|
#define MDP_SECURE_CAMERA_OVERLAY_SESSION 0x100000000
|
||||||
/**
|
/**
|
||||||
* Destination Scaler control flags setting
|
* Destination Scaler control flags setting
|
||||||
*
|
*
|
||||||
|
@ -629,7 +631,7 @@ struct mdss_mdp_img_data {
|
||||||
dma_addr_t addr;
|
dma_addr_t addr;
|
||||||
unsigned long len;
|
unsigned long len;
|
||||||
u32 offset;
|
u32 offset;
|
||||||
u32 flags;
|
u64 flags;
|
||||||
u32 dir;
|
u32 dir;
|
||||||
u32 domain;
|
u32 domain;
|
||||||
bool mapped;
|
bool mapped;
|
||||||
|
@ -813,7 +815,7 @@ struct mdss_mdp_pipe {
|
||||||
struct file *file;
|
struct file *file;
|
||||||
bool is_handed_off;
|
bool is_handed_off;
|
||||||
|
|
||||||
u32 flags;
|
u64 flags;
|
||||||
u32 bwc_mode;
|
u32 bwc_mode;
|
||||||
|
|
||||||
/* valid only when pipe's output is crossing both layer mixers */
|
/* valid only when pipe's output is crossing both layer mixers */
|
||||||
|
@ -921,6 +923,7 @@ struct mdss_overlay_private {
|
||||||
u32 splash_mem_addr;
|
u32 splash_mem_addr;
|
||||||
u32 splash_mem_size;
|
u32 splash_mem_size;
|
||||||
u32 sd_enabled;
|
u32 sd_enabled;
|
||||||
|
u32 sc_enabled;
|
||||||
|
|
||||||
struct sw_sync_timeline *vsync_timeline;
|
struct sw_sync_timeline *vsync_timeline;
|
||||||
struct mdss_mdp_vsync_handler vsync_retire_handler;
|
struct mdss_mdp_vsync_handler vsync_retire_handler;
|
||||||
|
@ -1294,6 +1297,15 @@ static inline void mdss_update_sd_client(struct mdss_data_type *mdata,
|
||||||
atomic_add_unless(&mdss_res->sd_client_count, -1, 0);
|
atomic_add_unless(&mdss_res->sd_client_count, -1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void mdss_update_sc_client(struct mdss_data_type *mdata,
|
||||||
|
bool status)
|
||||||
|
{
|
||||||
|
if (status)
|
||||||
|
atomic_inc(&mdata->sc_client_count);
|
||||||
|
else
|
||||||
|
atomic_add_unless(&mdss_res->sc_client_count, -1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
static inline int mdss_mdp_get_wb_ctl_support(struct mdss_data_type *mdata,
|
static inline int mdss_mdp_get_wb_ctl_support(struct mdss_data_type *mdata,
|
||||||
bool rotator_session)
|
bool rotator_session)
|
||||||
{
|
{
|
||||||
|
@ -1511,6 +1523,7 @@ static inline bool mdss_mdp_is_map_needed(struct mdss_data_type *mdata,
|
||||||
struct mdss_mdp_img_data *data)
|
struct mdss_mdp_img_data *data)
|
||||||
{
|
{
|
||||||
u32 is_secure_ui = data->flags & MDP_SECURE_DISPLAY_OVERLAY_SESSION;
|
u32 is_secure_ui = data->flags & MDP_SECURE_DISPLAY_OVERLAY_SESSION;
|
||||||
|
u64 is_secure_camera = data->flags & MDP_SECURE_CAMERA_OVERLAY_SESSION;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For ULT Targets we need SMMU Map, to issue map call for secure Display.
|
* For ULT Targets we need SMMU Map, to issue map call for secure Display.
|
||||||
|
@ -1518,6 +1531,10 @@ static inline bool mdss_mdp_is_map_needed(struct mdss_data_type *mdata,
|
||||||
if (is_secure_ui && !mdss_has_quirk(mdata, MDSS_QUIRK_NEED_SECURE_MAP))
|
if (is_secure_ui && !mdss_has_quirk(mdata, MDSS_QUIRK_NEED_SECURE_MAP))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (is_secure_camera && test_bit(MDSS_CAPS_SEC_DETACH_SMMU,
|
||||||
|
mdata->mdss_caps_map))
|
||||||
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1574,7 +1591,7 @@ unsigned long mdss_mdp_get_clk_rate(u32 clk_idx, bool locked);
|
||||||
int mdss_mdp_vsync_clk_enable(int enable, bool locked);
|
int mdss_mdp_vsync_clk_enable(int enable, bool locked);
|
||||||
void mdss_mdp_clk_ctrl(int enable);
|
void mdss_mdp_clk_ctrl(int enable);
|
||||||
struct mdss_data_type *mdss_mdp_get_mdata(void);
|
struct mdss_data_type *mdss_mdp_get_mdata(void);
|
||||||
int mdss_mdp_secure_display_ctrl(unsigned int enable);
|
int mdss_mdp_secure_session_ctrl(unsigned int enable, u64 flags);
|
||||||
|
|
||||||
int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd);
|
int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd);
|
||||||
int mdss_mdp_dfps_update_params(struct msm_fb_data_type *mfd,
|
int mdss_mdp_dfps_update_params(struct msm_fb_data_type *mfd,
|
||||||
|
@ -1608,7 +1625,7 @@ int mdss_mdp_overlay_start(struct msm_fb_data_type *mfd);
|
||||||
void mdss_mdp_overlay_set_chroma_sample(
|
void mdss_mdp_overlay_set_chroma_sample(
|
||||||
struct mdss_mdp_pipe *pipe);
|
struct mdss_mdp_pipe *pipe);
|
||||||
int mdp_pipe_tune_perf(struct mdss_mdp_pipe *pipe,
|
int mdp_pipe_tune_perf(struct mdss_mdp_pipe *pipe,
|
||||||
u32 flags);
|
u64 flags);
|
||||||
int mdss_mdp_overlay_setup_scaling(struct mdss_mdp_pipe *pipe);
|
int mdss_mdp_overlay_setup_scaling(struct mdss_mdp_pipe *pipe);
|
||||||
struct mdss_mdp_pipe *mdss_mdp_pipe_assign(struct mdss_data_type *mdata,
|
struct mdss_mdp_pipe *mdss_mdp_pipe_assign(struct mdss_data_type *mdata,
|
||||||
struct mdss_mdp_mixer *mixer, u32 ndx,
|
struct mdss_mdp_mixer *mixer, u32 ndx,
|
||||||
|
@ -1841,7 +1858,7 @@ struct mult_factor *mdss_mdp_get_comp_factor(u32 format,
|
||||||
int mdss_mdp_data_map(struct mdss_mdp_data *data, bool rotator, int dir);
|
int mdss_mdp_data_map(struct mdss_mdp_data *data, bool rotator, int dir);
|
||||||
void mdss_mdp_data_free(struct mdss_mdp_data *data, bool rotator, int dir);
|
void mdss_mdp_data_free(struct mdss_mdp_data *data, bool rotator, int dir);
|
||||||
int mdss_mdp_data_get_and_validate_size(struct mdss_mdp_data *data,
|
int mdss_mdp_data_get_and_validate_size(struct mdss_mdp_data *data,
|
||||||
struct msmfb_data *planes, int num_planes, u32 flags,
|
struct msmfb_data *planes, int num_planes, u64 flags,
|
||||||
struct device *dev, bool rotator, int dir,
|
struct device *dev, bool rotator, int dir,
|
||||||
struct mdp_layer_buffer *buffer);
|
struct mdp_layer_buffer *buffer);
|
||||||
u32 mdss_get_panel_framerate(struct msm_fb_data_type *mfd);
|
u32 mdss_get_panel_framerate(struct msm_fb_data_type *mfd);
|
||||||
|
|
|
@ -1868,7 +1868,7 @@ static void __dump_pipe(struct seq_file *s, struct mdss_mdp_pipe *pipe)
|
||||||
int smps[4];
|
int smps[4];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
seq_printf(s, "\nSSPP #%d type=%s ndx=%x flags=0x%08x play_cnt=%u xin_id=%d\n",
|
seq_printf(s, "\nSSPP #%d type=%s ndx=%x flags=0x%16llx play_cnt=%u xin_id=%d\n",
|
||||||
pipe->num, mdss_mdp_pipetype2str(pipe->type),
|
pipe->num, mdss_mdp_pipetype2str(pipe->type),
|
||||||
pipe->ndx, pipe->flags, pipe->play_cnt, pipe->xin_id);
|
pipe->ndx, pipe->flags, pipe->play_cnt, pipe->xin_id);
|
||||||
seq_printf(s, "\tstage=%d alpha=0x%x transp=0x%x blend_op=%d\n",
|
seq_printf(s, "\tstage=%d alpha=0x%x transp=0x%x blend_op=%d\n",
|
||||||
|
|
|
@ -986,7 +986,7 @@ static int __configure_pipe_params(struct msm_fb_data_type *mfd,
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
u32 left_lm_w = left_lm_w_from_mfd(mfd);
|
u32 left_lm_w = left_lm_w_from_mfd(mfd);
|
||||||
u32 flags;
|
u64 flags;
|
||||||
|
|
||||||
struct mdss_mdp_mixer *mixer = NULL;
|
struct mdss_mdp_mixer *mixer = NULL;
|
||||||
struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
|
struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
|
||||||
|
@ -1028,6 +1028,8 @@ static int __configure_pipe_params(struct msm_fb_data_type *mfd,
|
||||||
pipe->flags |= MDP_BWC_EN;
|
pipe->flags |= MDP_BWC_EN;
|
||||||
if (layer->flags & MDP_LAYER_PP)
|
if (layer->flags & MDP_LAYER_PP)
|
||||||
pipe->flags |= MDP_OVERLAY_PP_CFG_EN;
|
pipe->flags |= MDP_OVERLAY_PP_CFG_EN;
|
||||||
|
if (layer->flags & MDP_LAYER_SECURE_CAMERA_SESSION)
|
||||||
|
pipe->flags |= MDP_SECURE_CAMERA_OVERLAY_SESSION;
|
||||||
|
|
||||||
pipe->scaler.enable = (layer->flags & SCALER_ENABLED);
|
pipe->scaler.enable = (layer->flags & SCALER_ENABLED);
|
||||||
pipe->is_fg = layer->flags & MDP_LAYER_FORGROUND;
|
pipe->is_fg = layer->flags & MDP_LAYER_FORGROUND;
|
||||||
|
@ -1399,7 +1401,7 @@ static struct mdss_mdp_data *__map_layer_buffer(struct msm_fb_data_type *mfd,
|
||||||
struct mdp_layer_buffer *buffer;
|
struct mdp_layer_buffer *buffer;
|
||||||
struct msmfb_data image;
|
struct msmfb_data image;
|
||||||
int i, ret;
|
int i, ret;
|
||||||
u32 flags;
|
u64 flags;
|
||||||
struct mdss_mdp_validate_info_t *vitem;
|
struct mdss_mdp_validate_info_t *vitem;
|
||||||
|
|
||||||
for (i = 0; i < layer_count; i++) {
|
for (i = 0; i < layer_count; i++) {
|
||||||
|
@ -1425,7 +1427,8 @@ static struct mdss_mdp_data *__map_layer_buffer(struct msm_fb_data_type *mfd,
|
||||||
}
|
}
|
||||||
|
|
||||||
flags = (pipe->flags & (MDP_SECURE_OVERLAY_SESSION |
|
flags = (pipe->flags & (MDP_SECURE_OVERLAY_SESSION |
|
||||||
MDP_SECURE_DISPLAY_OVERLAY_SESSION));
|
MDP_SECURE_DISPLAY_OVERLAY_SESSION |
|
||||||
|
MDP_SECURE_CAMERA_OVERLAY_SESSION));
|
||||||
|
|
||||||
if (buffer->planes[0].fd < 0) {
|
if (buffer->planes[0].fd < 0) {
|
||||||
pr_err("invalid file descriptor for layer buffer\n");
|
pr_err("invalid file descriptor for layer buffer\n");
|
||||||
|
@ -1636,34 +1639,48 @@ end:
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* __validate_secure_display() - validate secure display
|
* __validate_secure_session() - validate various secure sessions
|
||||||
*
|
*
|
||||||
* This function travers through used pipe list and checks if any pipe
|
* This function travers through used pipe list and checks if any pipe
|
||||||
* is with secure display enabled flag. It fails if client tries to stage
|
* is with secure display, secure video and secure camera enabled flag.
|
||||||
* unsecure content with secure display session.
|
* It fails if client tries to stage unsecure content with
|
||||||
|
* secure display session and secure camera with secure video sessions.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static int __validate_secure_display(struct mdss_overlay_private *mdp5_data)
|
static int __validate_secure_session(struct mdss_overlay_private *mdp5_data)
|
||||||
{
|
{
|
||||||
struct mdss_mdp_pipe *pipe, *tmp;
|
struct mdss_mdp_pipe *pipe, *tmp;
|
||||||
uint32_t sd_pipes = 0, nonsd_pipes = 0;
|
uint32_t sd_pipes = 0, nonsd_pipes = 0;
|
||||||
|
uint32_t secure_vid_pipes = 0, secure_cam_pipes = 0;
|
||||||
|
|
||||||
mutex_lock(&mdp5_data->list_lock);
|
mutex_lock(&mdp5_data->list_lock);
|
||||||
list_for_each_entry_safe(pipe, tmp, &mdp5_data->pipes_used, list) {
|
list_for_each_entry_safe(pipe, tmp, &mdp5_data->pipes_used, list) {
|
||||||
if (pipe->flags & MDP_SECURE_DISPLAY_OVERLAY_SESSION)
|
if (pipe->flags & MDP_SECURE_DISPLAY_OVERLAY_SESSION)
|
||||||
sd_pipes++;
|
sd_pipes++;
|
||||||
|
else if (pipe->flags & MDP_SECURE_OVERLAY_SESSION)
|
||||||
|
secure_vid_pipes++;
|
||||||
|
else if (pipe->flags & MDP_SECURE_CAMERA_OVERLAY_SESSION)
|
||||||
|
secure_cam_pipes++;
|
||||||
else
|
else
|
||||||
nonsd_pipes++;
|
nonsd_pipes++;
|
||||||
}
|
}
|
||||||
mutex_unlock(&mdp5_data->list_lock);
|
mutex_unlock(&mdp5_data->list_lock);
|
||||||
|
|
||||||
pr_debug("pipe count:: secure display:%d non-secure:%d\n",
|
pr_debug("pipe count:: secure display:%d non-secure:%d secure-vid:%d,secure-cam:%d\n",
|
||||||
sd_pipes, nonsd_pipes);
|
sd_pipes, nonsd_pipes, secure_vid_pipes, secure_cam_pipes);
|
||||||
|
|
||||||
if ((sd_pipes || mdss_get_sd_client_cnt()) && nonsd_pipes) {
|
if ((sd_pipes || mdss_get_sd_client_cnt()) &&
|
||||||
|
(nonsd_pipes || secure_vid_pipes ||
|
||||||
|
secure_cam_pipes)) {
|
||||||
pr_err("non-secure layer validation request during secure display session\n");
|
pr_err("non-secure layer validation request during secure display session\n");
|
||||||
pr_err(" secure client cnt:%d secure pipe cnt:%d non-secure pipe cnt:%d\n",
|
pr_err(" secure client cnt:%d secure pipe:%d non-secure pipe:%d, secure-vid:%d, secure-cam:%d\n",
|
||||||
mdss_get_sd_client_cnt(), sd_pipes, nonsd_pipes);
|
mdss_get_sd_client_cnt(), sd_pipes, nonsd_pipes,
|
||||||
|
secure_vid_pipes, secure_cam_pipes);
|
||||||
|
return -EINVAL;
|
||||||
|
} else if (secure_cam_pipes && (secure_vid_pipes || sd_pipes)) {
|
||||||
|
pr_err(" incompatible layers during secure camera session\n");
|
||||||
|
pr_err("secure-camera cnt:%d secure video:%d secure display:%d\n",
|
||||||
|
secure_cam_pipes, secure_vid_pipes, sd_pipes);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2439,7 +2456,7 @@ static int __validate_layers(struct msm_fb_data_type *mfd,
|
||||||
validate_skip:
|
validate_skip:
|
||||||
__handle_free_list(mdp5_data, validate_info_list, layer_count);
|
__handle_free_list(mdp5_data, validate_info_list, layer_count);
|
||||||
|
|
||||||
ret = __validate_secure_display(mdp5_data);
|
ret = __validate_secure_session(mdp5_data);
|
||||||
|
|
||||||
validate_exit:
|
validate_exit:
|
||||||
pr_debug("err=%d total_layer:%d left:%d right:%d rec0_rel_ndx=0x%x rec1_rel_ndx=0x%x rec0_destroy_ndx=0x%x rec1_destroy_ndx=0x%x processed=%d\n",
|
pr_debug("err=%d total_layer:%d left:%d right:%d rec0_rel_ndx=0x%x rec1_rel_ndx=0x%x rec0_destroy_ndx=0x%x rec1_destroy_ndx=0x%x processed=%d\n",
|
||||||
|
|
|
@ -396,7 +396,7 @@ int mdss_mdp_overlay_req_check(struct msm_fb_data_type *mfd,
|
||||||
}
|
}
|
||||||
|
|
||||||
int mdp_pipe_tune_perf(struct mdss_mdp_pipe *pipe,
|
int mdp_pipe_tune_perf(struct mdss_mdp_pipe *pipe,
|
||||||
u32 flags)
|
u64 flags)
|
||||||
{
|
{
|
||||||
struct mdss_data_type *mdata = pipe->mixer_left->ctl->mdata;
|
struct mdss_data_type *mdata = pipe->mixer_left->ctl->mdata;
|
||||||
struct mdss_mdp_perf_params perf;
|
struct mdss_mdp_perf_params perf;
|
||||||
|
@ -1188,11 +1188,10 @@ static void __overlay_pipe_cleanup(struct msm_fb_data_type *mfd,
|
||||||
list_move(&buf->buf_list, &mdp5_data->bufs_freelist);
|
list_move(&buf->buf_list, &mdp5_data->bufs_freelist);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* in case of secure UI, the buffer needs to be released as
|
* free the buffers on the same cycle instead of waiting for
|
||||||
* soon as session is closed.
|
* next kickoff
|
||||||
*/
|
*/
|
||||||
if (pipe->flags & MDP_SECURE_DISPLAY_OVERLAY_SESSION)
|
mdss_mdp_overlay_buf_free(mfd, buf);
|
||||||
mdss_mdp_overlay_buf_free(mfd, buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mdss_mdp_pipe_destroy(pipe);
|
mdss_mdp_pipe_destroy(pipe);
|
||||||
|
@ -1477,7 +1476,7 @@ static int __overlay_queue_pipes(struct msm_fb_data_type *mfd)
|
||||||
*/
|
*/
|
||||||
if (mdss_get_sd_client_cnt() &&
|
if (mdss_get_sd_client_cnt() &&
|
||||||
!(pipe->flags & MDP_SECURE_DISPLAY_OVERLAY_SESSION)) {
|
!(pipe->flags & MDP_SECURE_DISPLAY_OVERLAY_SESSION)) {
|
||||||
pr_warn("Non secure pipe during secure display: %u: %08X, skip\n",
|
pr_warn("Non secure pipe during secure display: %u: %16llx, skip\n",
|
||||||
pipe->num, pipe->flags);
|
pipe->num, pipe->flags);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -2110,6 +2109,92 @@ set_roi:
|
||||||
mdss_mdp_set_roi(ctl, &l_roi, &r_roi);
|
mdss_mdp_set_roi(ctl, &l_roi, &r_roi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enables/disable secure (display or camera) sessions
|
||||||
|
*/
|
||||||
|
static int __overlay_secure_ctrl(struct msm_fb_data_type *mfd)
|
||||||
|
{
|
||||||
|
struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
|
||||||
|
struct mdss_mdp_ctl *ctl = mfd_to_ctl(mfd);
|
||||||
|
struct mdss_mdp_pipe *pipe;
|
||||||
|
int ret = 0;
|
||||||
|
int sd_in_pipe = 0;
|
||||||
|
int sc_in_pipe = 0;
|
||||||
|
|
||||||
|
list_for_each_entry(pipe, &mdp5_data->pipes_used, list) {
|
||||||
|
if (pipe->flags & MDP_SECURE_DISPLAY_OVERLAY_SESSION) {
|
||||||
|
sd_in_pipe = 1;
|
||||||
|
pr_debug("Secure pipe: %u : %16llx\n",
|
||||||
|
pipe->num, pipe->flags);
|
||||||
|
} else if (pipe->flags & MDP_SECURE_CAMERA_OVERLAY_SESSION) {
|
||||||
|
sc_in_pipe = 1;
|
||||||
|
pr_debug("Secure camera: %u: %16llx\n",
|
||||||
|
pipe->num, pipe->flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((!sd_in_pipe && !mdp5_data->sd_enabled) ||
|
||||||
|
(sd_in_pipe && mdp5_data->sd_enabled) ||
|
||||||
|
(!sc_in_pipe && !mdp5_data->sc_enabled) ||
|
||||||
|
(sc_in_pipe && mdp5_data->sc_enabled))
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
/* Secure Display */
|
||||||
|
if (!mdp5_data->sd_enabled && sd_in_pipe) {
|
||||||
|
if (!mdss_get_sd_client_cnt()) {
|
||||||
|
/*wait for ping pong done */
|
||||||
|
if (ctl->ops.wait_pingpong)
|
||||||
|
mdss_mdp_display_wait4pingpong(ctl, true);
|
||||||
|
ret = mdss_mdp_secure_session_ctrl(1,
|
||||||
|
MDP_SECURE_DISPLAY_OVERLAY_SESSION);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
mdp5_data->sd_enabled = 1;
|
||||||
|
mdss_update_sd_client(mdp5_data->mdata, true);
|
||||||
|
} else if (mdp5_data->sd_enabled && !sd_in_pipe) {
|
||||||
|
/* disable the secure display on last client */
|
||||||
|
if (mdss_get_sd_client_cnt() == 1) {
|
||||||
|
if (ctl->ops.wait_pingpong)
|
||||||
|
mdss_mdp_display_wait4pingpong(ctl, true);
|
||||||
|
ret = mdss_mdp_secure_session_ctrl(0,
|
||||||
|
MDP_SECURE_DISPLAY_OVERLAY_SESSION);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
mdss_update_sd_client(mdp5_data->mdata, false);
|
||||||
|
mdp5_data->sd_enabled = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Secure Camera */
|
||||||
|
if (!mdp5_data->sc_enabled && sc_in_pipe) {
|
||||||
|
if (!mdss_get_sc_client_cnt()) {
|
||||||
|
if (ctl->ops.wait_pingpong)
|
||||||
|
mdss_mdp_display_wait4pingpong(ctl, true);
|
||||||
|
ret = mdss_mdp_secure_session_ctrl(1,
|
||||||
|
MDP_SECURE_CAMERA_OVERLAY_SESSION);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
mdp5_data->sc_enabled = 1;
|
||||||
|
mdss_update_sc_client(mdp5_data->mdata, true);
|
||||||
|
} else if (mdp5_data->sc_enabled && !sc_in_pipe) {
|
||||||
|
/* disable the secure camera on last client */
|
||||||
|
if (mdss_get_sc_client_cnt() == 1) {
|
||||||
|
if (ctl->ops.wait_pingpong)
|
||||||
|
mdss_mdp_display_wait4pingpong(ctl, true);
|
||||||
|
ret = mdss_mdp_secure_session_ctrl(0,
|
||||||
|
MDP_SECURE_CAMERA_OVERLAY_SESSION);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
mdss_update_sc_client(mdp5_data->mdata, false);
|
||||||
|
mdp5_data->sc_enabled = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,
|
int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,
|
||||||
struct mdp_display_commit *data)
|
struct mdp_display_commit *data)
|
||||||
{
|
{
|
||||||
|
@ -2117,7 +2202,6 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,
|
||||||
struct mdss_mdp_pipe *pipe, *tmp;
|
struct mdss_mdp_pipe *pipe, *tmp;
|
||||||
struct mdss_mdp_ctl *ctl = mfd_to_ctl(mfd);
|
struct mdss_mdp_ctl *ctl = mfd_to_ctl(mfd);
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int sd_in_pipe = 0;
|
|
||||||
struct mdss_mdp_commit_cb commit_cb;
|
struct mdss_mdp_commit_cb commit_cb;
|
||||||
|
|
||||||
if (!ctl)
|
if (!ctl)
|
||||||
|
@ -2148,30 +2232,12 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,
|
||||||
mutex_unlock(ctl->shared_lock);
|
mutex_unlock(ctl->shared_lock);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock(&mdp5_data->list_lock);
|
mutex_lock(&mdp5_data->list_lock);
|
||||||
|
ret = __overlay_secure_ctrl(mfd);
|
||||||
/*
|
if (IS_ERR_VALUE(ret)) {
|
||||||
* check if there is a secure display session
|
pr_err("secure operation failed %d\n", ret);
|
||||||
*/
|
goto commit_fail;
|
||||||
list_for_each_entry(pipe, &mdp5_data->pipes_used, list) {
|
|
||||||
if (pipe->flags & MDP_SECURE_DISPLAY_OVERLAY_SESSION) {
|
|
||||||
sd_in_pipe = 1;
|
|
||||||
pr_debug("Secure pipe: %u : %08X\n",
|
|
||||||
pipe->num, pipe->flags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* start secure display session if there is secure display session and
|
|
||||||
* sd_enabled is not true.
|
|
||||||
*/
|
|
||||||
if (!mdp5_data->sd_enabled && sd_in_pipe) {
|
|
||||||
if (!mdss_get_sd_client_cnt())
|
|
||||||
ret = mdss_mdp_secure_display_ctrl(1);
|
|
||||||
if (!ret) {
|
|
||||||
mdp5_data->sd_enabled = 1;
|
|
||||||
mdss_update_sd_client(mdp5_data->mdata, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ctl->shared_lock)
|
if (!ctl->shared_lock)
|
||||||
|
@ -2261,19 +2327,6 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd,
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock(&mdp5_data->ov_lock);
|
mutex_lock(&mdp5_data->ov_lock);
|
||||||
/*
|
|
||||||
* If there is no secure display session and sd_enabled, disable the
|
|
||||||
* secure display session
|
|
||||||
*/
|
|
||||||
if (mdp5_data->sd_enabled && !sd_in_pipe && !ret) {
|
|
||||||
/* disable the secure display on last client */
|
|
||||||
if (mdss_get_sd_client_cnt() == 1)
|
|
||||||
ret = mdss_mdp_secure_display_ctrl(0);
|
|
||||||
if (!ret) {
|
|
||||||
mdss_update_sd_client(mdp5_data->mdata, false);
|
|
||||||
mdp5_data->sd_enabled = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mdss_fb_update_notify_update(mfd);
|
mdss_fb_update_notify_update(mfd);
|
||||||
commit_fail:
|
commit_fail:
|
||||||
|
@ -2425,7 +2478,7 @@ static int mdss_mdp_overlay_queue(struct msm_fb_data_type *mfd,
|
||||||
struct mdss_mdp_data *src_data;
|
struct mdss_mdp_data *src_data;
|
||||||
struct mdp_layer_buffer buffer;
|
struct mdp_layer_buffer buffer;
|
||||||
int ret;
|
int ret;
|
||||||
u32 flags;
|
u64 flags;
|
||||||
|
|
||||||
pipe = __overlay_find_pipe(mfd, req->id);
|
pipe = __overlay_find_pipe(mfd, req->id);
|
||||||
if (!pipe) {
|
if (!pipe) {
|
||||||
|
@ -2451,7 +2504,8 @@ static int mdss_mdp_overlay_queue(struct msm_fb_data_type *mfd,
|
||||||
pr_warn("Unexpected buffer queue to a solid fill pipe\n");
|
pr_warn("Unexpected buffer queue to a solid fill pipe\n");
|
||||||
|
|
||||||
flags = (pipe->flags & (MDP_SECURE_OVERLAY_SESSION |
|
flags = (pipe->flags & (MDP_SECURE_OVERLAY_SESSION |
|
||||||
MDP_SECURE_DISPLAY_OVERLAY_SESSION));
|
MDP_SECURE_DISPLAY_OVERLAY_SESSION |
|
||||||
|
MDP_SECURE_CAMERA_OVERLAY_SESSION));
|
||||||
|
|
||||||
mutex_lock(&mdp5_data->list_lock);
|
mutex_lock(&mdp5_data->list_lock);
|
||||||
src_data = mdss_mdp_overlay_buf_alloc(mfd, pipe);
|
src_data = mdss_mdp_overlay_buf_alloc(mfd, pipe);
|
||||||
|
|
|
@ -1878,7 +1878,8 @@ static void mdss_mdp_pipe_stride_update(struct mdss_mdp_pipe *pipe)
|
||||||
if (pipe->multirect.mode == MDSS_MDP_PIPE_MULTIRECT_NONE) {
|
if (pipe->multirect.mode == MDSS_MDP_PIPE_MULTIRECT_NONE) {
|
||||||
memcpy(&ystride, &pipe->src_planes.ystride,
|
memcpy(&ystride, &pipe->src_planes.ystride,
|
||||||
sizeof(u32) * MAX_PLANES);
|
sizeof(u32) * MAX_PLANES);
|
||||||
if (pipe->flags & MDP_SECURE_OVERLAY_SESSION)
|
if (pipe->flags & (MDP_SECURE_OVERLAY_SESSION |
|
||||||
|
MDP_SECURE_CAMERA_OVERLAY_SESSION))
|
||||||
secure = 0xF;
|
secure = 0xF;
|
||||||
} else {
|
} else {
|
||||||
if (pipe->multirect.num == MDSS_MDP_PIPE_RECT0) {
|
if (pipe->multirect.num == MDSS_MDP_PIPE_RECT0) {
|
||||||
|
@ -1891,12 +1892,14 @@ static void mdss_mdp_pipe_stride_update(struct mdss_mdp_pipe *pipe)
|
||||||
|
|
||||||
ystride[0] = rec0_pipe->src_planes.ystride[0];
|
ystride[0] = rec0_pipe->src_planes.ystride[0];
|
||||||
ystride[2] = rec0_pipe->src_planes.ystride[2];
|
ystride[2] = rec0_pipe->src_planes.ystride[2];
|
||||||
if (rec0_pipe->flags & MDP_SECURE_OVERLAY_SESSION)
|
if (rec0_pipe->flags & (MDP_SECURE_OVERLAY_SESSION |
|
||||||
|
MDP_SECURE_CAMERA_OVERLAY_SESSION))
|
||||||
secure |= 0x5;
|
secure |= 0x5;
|
||||||
|
|
||||||
ystride[1] = rec1_pipe->src_planes.ystride[0];
|
ystride[1] = rec1_pipe->src_planes.ystride[0];
|
||||||
ystride[3] = rec1_pipe->src_planes.ystride[2];
|
ystride[3] = rec1_pipe->src_planes.ystride[2];
|
||||||
if (rec1_pipe->flags & MDP_SECURE_OVERLAY_SESSION)
|
if (rec1_pipe->flags & (MDP_SECURE_OVERLAY_SESSION |
|
||||||
|
MDP_SECURE_CAMERA_OVERLAY_SESSION))
|
||||||
secure |= 0xA;
|
secure |= 0xA;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2320,7 +2323,9 @@ static int mdss_mdp_pipe_solidfill_setup(struct mdss_mdp_pipe *pipe)
|
||||||
}
|
}
|
||||||
|
|
||||||
format = MDSS_MDP_FMT_SOLID_FILL;
|
format = MDSS_MDP_FMT_SOLID_FILL;
|
||||||
secure = (pipe->flags & MDP_SECURE_OVERLAY_SESSION ? 0xF : 0x0);
|
secure = (pipe->flags & (MDP_SECURE_OVERLAY_SESSION |
|
||||||
|
MDP_SECURE_CAMERA_OVERLAY_SESSION)
|
||||||
|
? 0xF : 0x0);
|
||||||
|
|
||||||
/* support ARGB color format only */
|
/* support ARGB color format only */
|
||||||
unpack = (C3_ALPHA << 24) | (C2_R_Cr << 16) |
|
unpack = (C3_ALPHA << 24) | (C2_R_Cr << 16) |
|
||||||
|
|
|
@ -971,16 +971,17 @@ static int mdss_mdp_put_img(struct mdss_mdp_img_data *data, bool rotator,
|
||||||
data->srcp_dma_buf = NULL;
|
data->srcp_dma_buf = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (data->flags & MDP_SECURE_DISPLAY_OVERLAY_SESSION) {
|
} else if ((data->flags & MDP_SECURE_DISPLAY_OVERLAY_SESSION) ||
|
||||||
|
(data->flags & MDP_SECURE_CAMERA_OVERLAY_SESSION)) {
|
||||||
/*
|
/*
|
||||||
* skip memory unmapping - secure display uses physical
|
* skip memory unmapping - secure display and camera uses
|
||||||
* address which does not require buffer unmapping
|
* physical address which does not require buffer unmapping
|
||||||
*
|
*
|
||||||
* For LT targets in secure display usecase, srcp_dma_buf will
|
* For LT targets in secure display usecase, srcp_dma_buf will
|
||||||
* be filled due to map call which will be unmapped above.
|
* be filled due to map call which will be unmapped above.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
pr_debug("skip memory unmapping for secure display content\n");
|
pr_debug("skip memory unmapping for secure display/camera content\n");
|
||||||
} else {
|
} else {
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
@ -1196,7 +1197,7 @@ err_unmap:
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mdss_mdp_data_get(struct mdss_mdp_data *data,
|
static int mdss_mdp_data_get(struct mdss_mdp_data *data,
|
||||||
struct msmfb_data *planes, int num_planes, u32 flags,
|
struct msmfb_data *planes, int num_planes, u64 flags,
|
||||||
struct device *dev, bool rotator, int dir)
|
struct device *dev, bool rotator, int dir)
|
||||||
{
|
{
|
||||||
int i, rc = 0;
|
int i, rc = 0;
|
||||||
|
@ -1209,7 +1210,7 @@ static int mdss_mdp_data_get(struct mdss_mdp_data *data,
|
||||||
rc = mdss_mdp_get_img(&planes[i], &data->p[i], dev, rotator,
|
rc = mdss_mdp_get_img(&planes[i], &data->p[i], dev, rotator,
|
||||||
dir);
|
dir);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
pr_err("failed to get buf p=%d flags=%x\n", i, flags);
|
pr_err("failed to get buf p=%d flags=%llx\n", i, flags);
|
||||||
while (i > 0) {
|
while (i > 0) {
|
||||||
i--;
|
i--;
|
||||||
mdss_mdp_put_img(&data->p[i], rotator, dir);
|
mdss_mdp_put_img(&data->p[i], rotator, dir);
|
||||||
|
@ -1259,7 +1260,7 @@ void mdss_mdp_data_free(struct mdss_mdp_data *data, bool rotator, int dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
int mdss_mdp_data_get_and_validate_size(struct mdss_mdp_data *data,
|
int mdss_mdp_data_get_and_validate_size(struct mdss_mdp_data *data,
|
||||||
struct msmfb_data *planes, int num_planes, u32 flags,
|
struct msmfb_data *planes, int num_planes, u64 flags,
|
||||||
struct device *dev, bool rotator, int dir,
|
struct device *dev, bool rotator, int dir,
|
||||||
struct mdp_layer_buffer *buffer)
|
struct mdp_layer_buffer *buffer)
|
||||||
{
|
{
|
||||||
|
|
|
@ -162,12 +162,15 @@ end:
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* mdss_smmu_v2_attach()
|
* mdss_smmu_attach_v2()
|
||||||
*
|
*
|
||||||
* Associates each configured VA range with the corresponding smmu context
|
* Associates each configured VA range with the corresponding smmu context
|
||||||
* bank device. Enables the clks as smmu_v2 requires voting it before the usage.
|
* bank device. Enables the clks as smmu_v2 requires voting it before the usage.
|
||||||
* And iommu attach is done only once during the initial attach and it is never
|
* And iommu attach is done only once during the initial attach and it is never
|
||||||
* detached as smmu v2 uses a feature called 'retention'.
|
* detached as smmu v2 uses a feature called 'retention'.
|
||||||
|
* Only detach the secure and non-secure contexts in case of secure display
|
||||||
|
* case and secure contexts for secure camera use cases for the platforms
|
||||||
|
* which have caps MDSS_CAPS_SEC_DETACH_SMMU enabled
|
||||||
*/
|
*/
|
||||||
static int mdss_smmu_attach_v2(struct mdss_data_type *mdata)
|
static int mdss_smmu_attach_v2(struct mdss_data_type *mdata)
|
||||||
{
|
{
|
||||||
|
@ -191,7 +194,9 @@ static int mdss_smmu_attach_v2(struct mdss_data_type *mdata)
|
||||||
}
|
}
|
||||||
mdss_smmu->handoff_pending = false;
|
mdss_smmu->handoff_pending = false;
|
||||||
|
|
||||||
if (!mdss_smmu->domain_attached) {
|
if (!mdss_smmu->domain_attached &&
|
||||||
|
mdss_smmu_is_valid_domain_condition(mdata,
|
||||||
|
i, true)) {
|
||||||
rc = arm_iommu_attach_device(mdss_smmu->dev,
|
rc = arm_iommu_attach_device(mdss_smmu->dev,
|
||||||
mdss_smmu->mmu_mapping);
|
mdss_smmu->mmu_mapping);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
|
@ -229,10 +234,11 @@ err:
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* mdss_smmu_v2_detach()
|
* mdss_smmu_detach_v2()
|
||||||
*
|
*
|
||||||
* Only disables the clks as it is not required to detach the iommu mapped
|
* Disables the clks only when it is not required to detach the iommu mapped
|
||||||
* VA range from the device in smmu_v2 as explained in the mdss_smmu_v2_attach
|
* VA range (as long as not in secure display use case)
|
||||||
|
* from the device in smmu_v2 as explained in the mdss_smmu_v2_attach
|
||||||
*/
|
*/
|
||||||
static int mdss_smmu_detach_v2(struct mdss_data_type *mdata)
|
static int mdss_smmu_detach_v2(struct mdss_data_type *mdata)
|
||||||
{
|
{
|
||||||
|
@ -245,8 +251,24 @@ static int mdss_smmu_detach_v2(struct mdss_data_type *mdata)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
mdss_smmu = mdss_smmu_get_cb(i);
|
mdss_smmu = mdss_smmu_get_cb(i);
|
||||||
if (mdss_smmu && mdss_smmu->dev && !mdss_smmu->handoff_pending)
|
if (mdss_smmu && mdss_smmu->dev) {
|
||||||
mdss_smmu_enable_power(mdss_smmu, false);
|
if (!mdss_smmu->handoff_pending &&
|
||||||
|
mdss_smmu->domain_attached &&
|
||||||
|
mdss_smmu_is_valid_domain_condition(mdata,
|
||||||
|
i, false)) {
|
||||||
|
/*
|
||||||
|
* if entering in secure display or
|
||||||
|
* secure camera use case(for secured contexts
|
||||||
|
* leave the smmu clocks on and only detach the
|
||||||
|
* smmu contexts
|
||||||
|
*/
|
||||||
|
arm_iommu_detach_device(mdss_smmu->dev);
|
||||||
|
mdss_smmu->domain_attached = false;
|
||||||
|
pr_debug("iommu v2 domain[%i] detached\n", i);
|
||||||
|
} else {
|
||||||
|
mdss_smmu_enable_power(mdss_smmu, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mutex_unlock(&mdp_iommu_lock);
|
mutex_unlock(&mdp_iommu_lock);
|
||||||
|
|
||||||
|
@ -609,6 +631,7 @@ int mdss_smmu_probe(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
mdss_smmu = &mdata->mdss_smmu[smmu_domain.domain];
|
mdss_smmu = &mdata->mdss_smmu[smmu_domain.domain];
|
||||||
|
mdss_smmu->domain = smmu_domain.domain;
|
||||||
mp = &mdss_smmu->mp;
|
mp = &mdss_smmu->mp;
|
||||||
memset(mp, 0, sizeof(struct dss_module_power));
|
memset(mp, 0, sizeof(struct dss_module_power));
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,38 @@ static inline bool mdss_smmu_is_valid_domain_type(struct mdss_data_type *mdata,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool mdss_smmu_is_valid_domain_condition(
|
||||||
|
struct mdss_data_type *mdata,
|
||||||
|
int domain_type,
|
||||||
|
bool is_attach)
|
||||||
|
{
|
||||||
|
if (is_attach) {
|
||||||
|
if (test_bit(MDSS_CAPS_SEC_DETACH_SMMU,
|
||||||
|
mdata->mdss_caps_map) &&
|
||||||
|
(mdata->sec_disp_en ||
|
||||||
|
(mdata->sec_cam_en &&
|
||||||
|
domain_type == MDSS_IOMMU_DOMAIN_SECURE))) {
|
||||||
|
pr_debug("SMMU attach not attempted, sd:%d, sc:%d\n",
|
||||||
|
mdata->sec_disp_en, mdata->sec_cam_en);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (test_bit(MDSS_CAPS_SEC_DETACH_SMMU,
|
||||||
|
mdata->mdss_caps_map) &&
|
||||||
|
(mdata->sec_disp_en ||
|
||||||
|
(mdata->sec_cam_en &&
|
||||||
|
domain_type == MDSS_IOMMU_DOMAIN_SECURE))) {
|
||||||
|
pr_debug("SMMU detach attempted, sd:%d, sc:%d\n",
|
||||||
|
mdata->sec_disp_en, mdata->sec_cam_en);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static inline struct mdss_smmu_client *mdss_smmu_get_cb(u32 domain)
|
static inline struct mdss_smmu_client *mdss_smmu_get_cb(u32 domain)
|
||||||
{
|
{
|
||||||
struct mdss_data_type *mdata = mdss_mdp_get_mdata();
|
struct mdss_data_type *mdata = mdss_mdp_get_mdata();
|
||||||
|
@ -96,7 +128,7 @@ static inline int is_mdss_iommu_attached(void)
|
||||||
return mdata ? mdata->iommu_attached : false;
|
return mdata ? mdata->iommu_attached : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int mdss_smmu_get_domain_type(u32 flags, bool rotator)
|
static inline int mdss_smmu_get_domain_type(u64 flags, bool rotator)
|
||||||
{
|
{
|
||||||
struct mdss_data_type *mdata = mdss_mdp_get_mdata();
|
struct mdss_data_type *mdata = mdss_mdp_get_mdata();
|
||||||
int type;
|
int type;
|
||||||
|
|
Loading…
Add table
Reference in a new issue