summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenet Clark <benetc@codeaurora.org>2015-01-07 16:39:40 -0800
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 20:37:30 -0700
commit7d9384c459f82bbc28867f9df9e8facf3be88a6c (patch)
tree4e48be6968d262feda422af3774d624267b6c3ea
parentc8dae70deaaf130af1b6343c0825178c3fd1f8cc (diff)
msm: mdss: compat ioctl support for DSPP PA in thulium
Picture adjustment (PA) feature can be enabled by the 32/64 bit user-space clients. 32 bit user-space client will take the compat ioctl path. Change adds support for 32 bit clients for PA feature in DSPP. Change-Id: Idbef740f10df0dd3e32003bfd441ff436ee072fa Signed-off-by: Benet Clark <benetc@codeaurora.org>
-rw-r--r--drivers/video/fbdev/msm/mdss_compat_utils.c227
-rw-r--r--drivers/video/fbdev/msm/mdss_compat_utils.h34
2 files changed, 252 insertions, 9 deletions
diff --git a/drivers/video/fbdev/msm/mdss_compat_utils.c b/drivers/video/fbdev/msm/mdss_compat_utils.c
index c0d733d14fc9..0a7ee25e3b3c 100644
--- a/drivers/video/fbdev/msm/mdss_compat_utils.c
+++ b/drivers/video/fbdev/msm/mdss_compat_utils.c
@@ -1516,19 +1516,169 @@ static int __to_user_pa_v2_data(
return 0;
}
+static inline void __from_user_pa_mem_col_data_v1_7(
+ struct mdp_pa_mem_col_data_v1_7_32 *mem_col_data32,
+ struct mdp_pa_mem_col_data_v1_7 *mem_col_data)
+{
+ mem_col_data->color_adjust_p0 = mem_col_data32->color_adjust_p0;
+ mem_col_data->color_adjust_p1 = mem_col_data32->color_adjust_p1;
+ mem_col_data->color_adjust_p2 = mem_col_data32->color_adjust_p2;
+ mem_col_data->blend_gain = mem_col_data32->blend_gain;
+ mem_col_data->sat_hold = mem_col_data32->sat_hold;
+ mem_col_data->val_hold = mem_col_data32->val_hold;
+ mem_col_data->hue_region = mem_col_data32->hue_region;
+ mem_col_data->sat_region = mem_col_data32->sat_region;
+ mem_col_data->val_region = mem_col_data32->val_region;
+}
+
+
+static int __from_user_pa_data_v1_7(
+ struct mdp_pa_v2_cfg_data32 __user *pa_v2_cfg32,
+ struct mdp_pa_v2_cfg_data __user *pa_v2_cfg)
+{
+ struct mdp_pa_data_v1_7_32 pa_cfg_payload32;
+ struct mdp_pa_data_v1_7 pa_cfg_payload;
+
+ if (copy_from_user(&pa_cfg_payload32,
+ compat_ptr(pa_v2_cfg32->cfg_payload),
+ sizeof(pa_cfg_payload32))) {
+ pr_err("failed to copy the PA payload from userspace\n");
+ return -EFAULT;
+ }
+
+ pa_cfg_payload.mode = pa_cfg_payload32.mode;
+ pa_cfg_payload.global_hue_adj = pa_cfg_payload32.global_hue_adj;
+ pa_cfg_payload.global_sat_adj = pa_cfg_payload32.global_sat_adj;
+ pa_cfg_payload.global_val_adj = pa_cfg_payload32.global_val_adj;
+ pa_cfg_payload.global_cont_adj = pa_cfg_payload32.global_cont_adj;
+
+ __from_user_pa_mem_col_data_v1_7(&pa_cfg_payload32.skin_cfg,
+ &pa_cfg_payload.skin_cfg);
+ __from_user_pa_mem_col_data_v1_7(&pa_cfg_payload32.sky_cfg,
+ &pa_cfg_payload.sky_cfg);
+ __from_user_pa_mem_col_data_v1_7(&pa_cfg_payload32.fol_cfg,
+ &pa_cfg_payload.fol_cfg);
+
+ pa_cfg_payload.six_zone_thresh = pa_cfg_payload32.six_zone_thresh;
+ pa_cfg_payload.six_zone_adj_p0 = pa_cfg_payload32.six_zone_adj_p0;
+ pa_cfg_payload.six_zone_adj_p1 = pa_cfg_payload32.six_zone_adj_p1;
+ pa_cfg_payload.six_zone_sat_hold = pa_cfg_payload32.six_zone_sat_hold;
+ pa_cfg_payload.six_zone_val_hold = pa_cfg_payload32.six_zone_val_hold;
+ pa_cfg_payload.six_zone_len = pa_cfg_payload32.six_zone_len;
+
+ pa_cfg_payload.six_zone_curve_p0 =
+ compat_ptr(pa_cfg_payload32.six_zone_curve_p0);
+ pa_cfg_payload.six_zone_curve_p1 =
+ compat_ptr(pa_cfg_payload32.six_zone_curve_p1);
+
+ if (copy_to_user(pa_v2_cfg->cfg_payload, &pa_cfg_payload,
+ sizeof(pa_cfg_payload))) {
+ pr_err("Failed to copy to user pa cfg payload\n");
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
static int __from_user_pa_v2_cfg_data(
struct mdp_pa_v2_cfg_data32 __user *pa_v2_cfg32,
struct mdp_pa_v2_cfg_data __user *pa_v2_cfg)
{
+ uint32_t version;
+
if (copy_in_user(&pa_v2_cfg->block,
&pa_v2_cfg32->block,
+ sizeof(uint32_t)) ||
+ copy_in_user(&pa_v2_cfg->version,
+ &pa_v2_cfg32->version,
+ sizeof(uint32_t)) ||
+ copy_in_user(&pa_v2_cfg->flags,
+ &pa_v2_cfg32->flags,
sizeof(uint32_t)))
return -EFAULT;
- if (__from_user_pa_v2_data(
- compat_ptr((uintptr_t)&pa_v2_cfg32->pa_v2_data),
- &pa_v2_cfg->pa_v2_data))
+ if (copy_from_user(&version,
+ &pa_v2_cfg32->version,
+ sizeof(uint32_t))) {
+ pr_err("failed to copy the version info\n");
return -EFAULT;
+ }
+
+ switch (version) {
+ case mdp_pa_v1_7:
+ if (__from_user_pa_data_v1_7(pa_v2_cfg32, pa_v2_cfg)) {
+ pr_err("failed to get pa data for version %d\n",
+ version);
+ return -EFAULT;
+ }
+ break;
+ default:
+ pr_debug("version invalid, fallback to legacy\n");
+ if (__from_user_pa_v2_data(
+ compat_ptr((uintptr_t)&pa_v2_cfg32->pa_v2_data),
+ &pa_v2_cfg->pa_v2_data))
+ return -EFAULT;
+ break;
+ }
+
+ return 0;
+}
+
+static inline void __to_user_pa_mem_col_data_v1_7(
+ struct mdp_pa_mem_col_data_v1_7_32 *mem_col_data32,
+ struct mdp_pa_mem_col_data_v1_7 *mem_col_data)
+{
+ mem_col_data32->color_adjust_p0 = mem_col_data->color_adjust_p0;
+ mem_col_data32->color_adjust_p1 = mem_col_data->color_adjust_p1;
+ mem_col_data32->color_adjust_p2 = mem_col_data->color_adjust_p2;
+ mem_col_data32->blend_gain = mem_col_data->blend_gain;
+ mem_col_data32->sat_hold = mem_col_data->sat_hold;
+ mem_col_data32->val_hold = mem_col_data->val_hold;
+ mem_col_data32->hue_region = mem_col_data->hue_region;
+ mem_col_data32->sat_region = mem_col_data->sat_region;
+ mem_col_data32->val_region = mem_col_data->val_region;
+}
+
+static int __to_user_pa_data_v1_7(
+ struct mdp_pa_v2_cfg_data32 __user *pa_v2_cfg32,
+ struct mdp_pa_v2_cfg_data __user *pa_v2_cfg)
+{
+ struct mdp_pa_data_v1_7_32 pa_cfg_payload32;
+ struct mdp_pa_data_v1_7 pa_cfg_payload;
+
+ if (copy_from_user(&pa_cfg_payload,
+ pa_v2_cfg->cfg_payload,
+ sizeof(pa_cfg_payload))) {
+ pr_err("failed to copy the PA payload from userspace\n");
+ return -EFAULT;
+ }
+
+ pa_cfg_payload32.mode = pa_cfg_payload.mode;
+ pa_cfg_payload32.global_hue_adj = pa_cfg_payload.global_hue_adj;
+ pa_cfg_payload32.global_sat_adj = pa_cfg_payload.global_sat_adj;
+ pa_cfg_payload32.global_val_adj = pa_cfg_payload.global_val_adj;
+ pa_cfg_payload32.global_cont_adj = pa_cfg_payload.global_cont_adj;
+
+ __to_user_pa_mem_col_data_v1_7(&pa_cfg_payload32.skin_cfg,
+ &pa_cfg_payload.skin_cfg);
+ __to_user_pa_mem_col_data_v1_7(&pa_cfg_payload32.sky_cfg,
+ &pa_cfg_payload.sky_cfg);
+ __to_user_pa_mem_col_data_v1_7(&pa_cfg_payload32.fol_cfg,
+ &pa_cfg_payload.fol_cfg);
+
+ pa_cfg_payload32.six_zone_thresh = pa_cfg_payload.six_zone_thresh;
+ pa_cfg_payload32.six_zone_adj_p0 = pa_cfg_payload.six_zone_adj_p0;
+ pa_cfg_payload32.six_zone_adj_p1 = pa_cfg_payload.six_zone_adj_p1;
+ pa_cfg_payload32.six_zone_sat_hold = pa_cfg_payload.six_zone_sat_hold;
+ pa_cfg_payload32.six_zone_val_hold = pa_cfg_payload.six_zone_val_hold;
+ pa_cfg_payload32.six_zone_len = pa_cfg_payload.six_zone_len;
+
+ if (copy_to_user(compat_ptr(pa_v2_cfg32->cfg_payload),
+ &pa_cfg_payload32,
+ sizeof(pa_cfg_payload32))) {
+ pr_err("Failed to copy to user pa cfg payload\n");
+ return -EFAULT;
+ }
return 0;
}
@@ -1537,15 +1687,55 @@ static int __to_user_pa_v2_cfg_data(
struct mdp_pa_v2_cfg_data32 __user *pa_v2_cfg32,
struct mdp_pa_v2_cfg_data __user *pa_v2_cfg)
{
- if (copy_in_user(&pa_v2_cfg32->block,
- &pa_v2_cfg->block,
+ uint32_t version = 0;
+ uint32_t flags = 0;
+
+ if (copy_from_user(&version,
+ &pa_v2_cfg32->version,
sizeof(uint32_t)))
return -EFAULT;
- if (__to_user_pa_v2_data(
- compat_ptr((uintptr_t)&pa_v2_cfg32->pa_v2_data),
- &pa_v2_cfg->pa_v2_data))
- return -EFAULT;
+ switch (version) {
+ case mdp_pa_v1_7:
+ if (copy_from_user(&flags,
+ &pa_v2_cfg32->flags,
+ sizeof(uint32_t))) {
+ pr_err("failed to get PA v1_7 flags\n");
+ return -EFAULT;
+ }
+
+ if (!(flags & MDP_PP_OPS_READ)) {
+ pr_debug("Read op not set. Skipping compat copyback\n");
+ return 0;
+ }
+
+ if (__to_user_pa_data_v1_7(pa_v2_cfg32, pa_v2_cfg)) {
+ pr_err("failed to set pa data for version %d\n",
+ version);
+ return -EFAULT;
+ }
+ break;
+ default:
+ pr_debug("version invalid, fallback to legacy\n");
+
+ if (copy_from_user(&flags,
+ &pa_v2_cfg32->pa_v2_data.flags,
+ sizeof(uint32_t))) {
+ pr_err("failed to get PAv2 flags\n");
+ return -EFAULT;
+ }
+
+ if (!(flags & MDP_PP_OPS_READ)) {
+ pr_debug("Read op not set. Skipping compat copyback\n");
+ return 0;
+ }
+
+ if (__to_user_pa_v2_data(
+ compat_ptr((uintptr_t)&pa_v2_cfg32->pa_v2_data),
+ &pa_v2_cfg->pa_v2_data))
+ return -EFAULT;
+ break;
+ }
return 0;
}
@@ -2134,6 +2324,12 @@ static u32 __pp_compat_size_pcc(void)
return sizeof(struct mdp_pcc_data_v1_7);
}
+static u32 __pp_compat_size_pa(void)
+{
+ /* if new version of PA is added return max struct size */
+ return sizeof(struct mdp_pa_data_v1_7);
+}
+
static u32 __pp_compat_size_gamut(void)
{
return sizeof(struct mdp_gamut_data_v1_7);
@@ -2234,6 +2430,19 @@ static int __pp_compat_alloc(struct msmfb_mdp_pp32 __user *pp32,
(void *)((unsigned long)(*pp) +
sizeof(struct msmfb_mdp_pp));
break;
+ case mdp_op_pa_v2_cfg:
+ alloc_size += __pp_compat_size_pa();
+ *pp = compat_alloc_user_space(alloc_size);
+ if (NULL == *pp) {
+ pr_err("alloc from user size %d for pcc fail\n",
+ alloc_size);
+ return -ENOMEM;
+ }
+ memset(*pp, 0, alloc_size);
+ (*pp)->data.pa_v2_cfg_data.cfg_payload =
+ (void *)((unsigned long)(*pp) +
+ sizeof(struct msmfb_mdp_pp));
+ break;
default:
*pp = compat_alloc_user_space(alloc_size);
if (NULL == *pp)
diff --git a/drivers/video/fbdev/msm/mdss_compat_utils.h b/drivers/video/fbdev/msm/mdss_compat_utils.h
index c84bb1a8d0cc..a07de0a09bcf 100644
--- a/drivers/video/fbdev/msm/mdss_compat_utils.h
+++ b/drivers/video/fbdev/msm/mdss_compat_utils.h
@@ -159,9 +159,43 @@ struct mdp_pa_v2_data32 {
compat_caddr_t six_zone_curve_p1;
};
+struct mdp_pa_mem_col_data_v1_7_32 {
+ uint32_t color_adjust_p0;
+ uint32_t color_adjust_p1;
+ uint32_t color_adjust_p2;
+ uint32_t blend_gain;
+ uint8_t sat_hold;
+ uint8_t val_hold;
+ uint32_t hue_region;
+ uint32_t sat_region;
+ uint32_t val_region;
+};
+
+struct mdp_pa_data_v1_7_32 {
+ uint32_t mode;
+ uint32_t global_hue_adj;
+ uint32_t global_sat_adj;
+ uint32_t global_val_adj;
+ uint32_t global_cont_adj;
+ struct mdp_pa_mem_col_data_v1_7_32 skin_cfg;
+ struct mdp_pa_mem_col_data_v1_7_32 sky_cfg;
+ struct mdp_pa_mem_col_data_v1_7_32 fol_cfg;
+ uint32_t six_zone_thresh;
+ uint32_t six_zone_adj_p0;
+ uint32_t six_zone_adj_p1;
+ uint8_t six_zone_sat_hold;
+ uint8_t six_zone_val_hold;
+ uint32_t six_zone_len;
+ compat_caddr_t six_zone_curve_p0;
+ compat_caddr_t six_zone_curve_p1;
+};
+
struct mdp_pa_v2_cfg_data32 {
+ uint32_t version;
uint32_t block;
+ uint32_t flags;
struct mdp_pa_v2_data32 pa_v2_data;
+ compat_caddr_t cfg_payload;
};
struct mdp_pa_cfg32 {