diff options
| author | Benet Clark <benetc@codeaurora.org> | 2014-10-14 18:45:44 -0700 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 20:35:07 -0700 |
| commit | 4c0f7dc9e9bd04b96ea2cf39338adca1ba7d9832 (patch) | |
| tree | 22b30133b44ab3f01077bef84e65c24423479896 /drivers/video/fbdev | |
| parent | d892b4e127f1177669acdd39bd98c1db80ce7e16 (diff) | |
msm: mdss: Add framework for MDP-version-based PP driver
With many updates coming the postprocessing driver, there needs to be
a way to manage the multiple versions of programming sequences and
interface structures, without adding to the hardware agnostic code path.
The pp_feature_ops structure will be used to decouple the PP driver from
the PP hardware, such that the hardware-specific code is separated to a
different file
Change-Id: I604850c082c32f5741905bd509ae0e819e334749
Signed-off-by: Benet Clark <benetc@codeaurora.org>
[cip@codeaurora.org: Moved mdss_mdp_pp_v1_7.c file location]
Signed-off-by: Clarence Ip <cip@codeaurora.org>
Diffstat (limited to 'drivers/video/fbdev')
| -rw-r--r-- | drivers/video/fbdev/msm/Makefile | 4 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_pp.c | 55 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_pp.h | 82 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_pp_v1_7.c | 83 |
4 files changed, 189 insertions, 35 deletions
diff --git a/drivers/video/fbdev/msm/Makefile b/drivers/video/fbdev/msm/Makefile index ffe14659ddec..78a9e625b63d 100644 --- a/drivers/video/fbdev/msm/Makefile +++ b/drivers/video/fbdev/msm/Makefile @@ -16,6 +16,10 @@ mdss-mdp-objs += mdss_mdp_wb.o obj-$(CONFIG_FB_MSM_MDSS) += mdss-mdp.o obj-$(CONFIG_FB_MSM_MDSS) += mdss_mdp_debug.o +ifeq ($(CONFIG_ARCH_MSMTHULIUM),y) +mdss-mdp-objs += mdss_mdp_pp_v1_7.o +endif + ifeq ($(CONFIG_FB_MSM_MDSS),y) obj-$(CONFIG_DEBUG_FS) += mdss_debug.o mdss_debug_xlog.o endif diff --git a/drivers/video/fbdev/msm/mdss_mdp_pp.c b/drivers/video/fbdev/msm/mdss_mdp_pp.c index 270e762c2438..ee6493e660ad 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_pp.c +++ b/drivers/video/fbdev/msm/mdss_mdp_pp.c @@ -233,7 +233,6 @@ static int mdss_mdp_hscl_filter[] = { #define PP_SSPP 0 #define PP_DSPP 1 -#define PP_STS_ENABLE 0x1 #define PP_STS_GAMUT_FIRST 0x2 #define PP_STS_PA_HUE_MASK 0x2 @@ -251,10 +250,6 @@ static int mdss_mdp_hscl_filter[] = { #define PP_AD_BAD_HW_NUM 255 -#define MDSS_SIDE_NONE 0 -#define MDSS_SIDE_LEFT 1 -#define MDSS_SIDE_RIGHT 2 - #define PP_AD_STATE_INIT 0x2 #define PP_AD_STATE_CFG 0x4 #define PP_AD_STATE_DATA 0x8 @@ -326,8 +321,18 @@ struct mdss_pp_res_type { struct pp_sts_type pp_disp_sts[MDSS_BLOCK_DISP_NUM]; /* physical info */ struct pp_hist_col_info *dspp_hist; + + /* + * The pp_data_res will be a pointer to newer MDP revisions of the + * pp_res, which will hold the cfg_payloads of each feature in a single + * struct. + */ + void *pp_data_res; }; +static struct mdp_pp_driver_ops pp_driver_ops; +static struct mdp_pp_feature_ops *pp_ops; + static DEFINE_MUTEX(mdss_pp_mutex); static struct mdss_pp_res_type *mdss_pp_res; @@ -420,8 +425,6 @@ static int pp_ad_linearize_bl(struct mdss_ad_info *ad, u32 bl, u32 *bl_out, static int pp_ad_calc_bl(struct msm_fb_data_type *mfd, int bl_in, int *bl_out, int *ad_bl_out); static int pp_num_to_side(struct mdss_mdp_ctl *ctl, u32 num); -static inline bool pp_sts_is_enabled(u32 sts, int side); -static inline void pp_sts_set_split_bits(u32 *sts, u32 bits); static u32 last_sts, last_state; @@ -2156,6 +2159,7 @@ int mdss_mdp_pp_init(struct device *dev) struct mdss_data_type *mdata = mdss_mdp_get_mdata(); struct mdss_mdp_pipe *vig; struct pp_hist_col_info *hist; + void *ret_ptr = NULL; if (!mdata) return -EPERM; @@ -2196,6 +2200,15 @@ int mdss_mdp_pp_init(struct device *dev) mdss_pp_res->dspp_hist = hist; } + ret_ptr = pp_get_driver_ops(&pp_driver_ops); + if (IS_ERR(ret_ptr)) { + pr_err("pp_get_driver_ops failed, ret=%d\n", + (int) PTR_ERR(ret_ptr)); + ret = PTR_ERR(ret_ptr); + } else { + mdss_pp_res->pp_data_res = ret_ptr; + pp_ops = pp_driver_ops.pp_ops; + } } } if (mdata && mdata->vig_pipes) { @@ -4390,34 +4403,6 @@ static int pp_num_to_side(struct mdss_mdp_ctl *ctl, u32 num) return -EINVAL; } -static inline void pp_sts_set_split_bits(u32 *sts, u32 bits) -{ - u32 tmp = *sts; - tmp &= ~MDSS_PP_SPLIT_MASK; - tmp |= bits & MDSS_PP_SPLIT_MASK; - *sts = tmp; -} - -static inline bool pp_sts_is_enabled(u32 sts, int side) -{ - bool ret = false; - /* - * If there are no sides, or if there are no split mode bits set, the - * side can't be disabled via split mode. - * - * Otherwise, if the side being checked opposes the split mode - * configuration, the side is disabled. - */ - if ((side == MDSS_SIDE_NONE) || !(sts & MDSS_PP_SPLIT_MASK)) - ret = true; - else if ((sts & MDSS_PP_SPLIT_RIGHT_ONLY) && (side == MDSS_SIDE_RIGHT)) - ret = true; - else if ((sts & MDSS_PP_SPLIT_LEFT_ONLY) && (side == MDSS_SIDE_LEFT)) - ret = true; - - return ret && (sts & PP_STS_ENABLE); -} - static int mdss_ad_init_checks(struct msm_fb_data_type *mfd) { u32 mixer_id[MDSS_MDP_INTF_MAX_LAYERMIXER]; diff --git a/drivers/video/fbdev/msm/mdss_mdp_pp.h b/drivers/video/fbdev/msm/mdss_mdp_pp.h index 0e3a7e3e37f6..d18fbd49b135 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_pp.h +++ b/drivers/video/fbdev/msm/mdss_mdp_pp.h @@ -17,6 +17,88 @@ #include <linux/msm_mdp.h> +/* PP STS related flags */ +#define PP_STS_ENABLE 0x1 + +/* Demo mode macros */ +#define MDSS_SIDE_NONE 0 +#define MDSS_SIDE_LEFT 1 +#define MDSS_SIDE_RIGHT 2 + +/* PP Feature Operations */ +enum pp_features { + IGC, + PCC, + GC, + PA, + GAMUT, + CSC, + DITHER, + QSEED, + HIST_LUT, + PP_FEATURE_MAX +}; + +enum pp_block_opmodes { + PP_OPMODE_VIG, + PP_OPMODE_DSPP, + PP_OPMODE_MAX +}; + +struct mdp_pp_feature_ops { + u32 feature; + int (*pp_get_config)(char __iomem *base_addr, void *cfg_data, + u32 block_type, u32 disp_num); + int (*pp_set_config)(char __iomem *base_addr, + struct pp_sts_type *pp_sts, void *cfg_data, + u32 block_type); +}; + +struct mdp_pp_driver_ops { + struct mdp_pp_feature_ops pp_ops[PP_FEATURE_MAX]; + void (*pp_opmode_config)(int location, struct pp_sts_type *pp_sts, + u32 *opmode, int side); +}; + +#ifdef CONFIG_ARCH_MSMTHULIUM +void *pp_get_driver_ops(struct mdp_pp_driver_ops *ops); +#else +static inline void *pp_get_driver_ops(struct mdp_pp_driver_ops *ops) +{ + memset(ops, 0, sizeof(struct mdp_pp_driver_ops)); + return NULL; +} +#endif + +static inline void pp_sts_set_split_bits(u32 *sts, u32 bits) +{ + u32 tmp = *sts; + tmp &= ~MDSS_PP_SPLIT_MASK; + tmp |= bits & MDSS_PP_SPLIT_MASK; + *sts = tmp; +} + +static inline bool pp_sts_is_enabled(u32 sts, int side) +{ + bool ret = false; + /* + * If there are no sides, or if there are no split mode bits set, the + * side can't be disabled via split mode. + * + * Otherwise, if the side being checked opposes the split mode + * configuration, the side is disabled. + */ + if ((side == MDSS_SIDE_NONE) || !(sts & MDSS_PP_SPLIT_MASK)) + ret = true; + else if ((sts & MDSS_PP_SPLIT_RIGHT_ONLY) && (side == MDSS_SIDE_RIGHT)) + ret = true; + else if ((sts & MDSS_PP_SPLIT_LEFT_ONLY) && (side == MDSS_SIDE_LEFT)) + ret = true; + + return ret && (sts & PP_STS_ENABLE); +} + +/* Debug related functions */ void pp_print_lut(void *data, int size, char *tab, uint32_t type); void pp_print_uint16_lut(uint16_t *data, int size, char *tab); void pp_print_pcc_coeff(struct mdp_pcc_coeff *pcc_coeff, int tab_depth); diff --git a/drivers/video/fbdev/msm/mdss_mdp_pp_v1_7.c b/drivers/video/fbdev/msm/mdss_mdp_pp_v1_7.c new file mode 100644 index 000000000000..35e7b0da6e55 --- /dev/null +++ b/drivers/video/fbdev/msm/mdss_mdp_pp_v1_7.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#define pr_fmt(fmt) "%s: " fmt, __func__ + +#include "mdss_fb.h" +#include "mdss_mdp.h" +#include "mdss_mdp_pp.h" +#include <linux/uaccess.h> + +static void pp_opmode_config(int location, struct pp_sts_type *pp_sts, + u32 *opmode, int side); + +void *pp_get_driver_ops(struct mdp_pp_driver_ops *ops) +{ + if (!ops) { + pr_err("PP driver ops invalid %p\n", ops); + return ERR_PTR(-EINVAL); + } + + /* IGC ops */ + ops->pp_ops[IGC].pp_set_config = NULL; + ops->pp_ops[IGC].pp_get_config = NULL; + + /* PCC ops */ + ops->pp_ops[PCC].pp_set_config = NULL; + ops->pp_ops[PCC].pp_get_config = NULL; + + /* GC ops */ + ops->pp_ops[GC].pp_set_config = NULL; + ops->pp_ops[GC].pp_get_config = NULL; + + /* PA ops */ + ops->pp_ops[PA].pp_set_config = NULL; + ops->pp_ops[PA].pp_get_config = NULL; + + /* Gamut ops */ + ops->pp_ops[GAMUT].pp_set_config = NULL; + ops->pp_ops[GAMUT].pp_get_config = NULL; + + /* CSC ops */ + ops->pp_ops[CSC].pp_set_config = NULL; + ops->pp_ops[CSC].pp_get_config = NULL; + + /* Dither ops */ + ops->pp_ops[DITHER].pp_set_config = NULL; + ops->pp_ops[DITHER].pp_get_config = NULL; + + /* QSEED ops */ + ops->pp_ops[QSEED].pp_set_config = NULL; + ops->pp_ops[QSEED].pp_get_config = NULL; + + /* PA_LUT ops */ + ops->pp_ops[HIST_LUT].pp_set_config = NULL; + ops->pp_ops[HIST_LUT].pp_get_config = NULL; + + /* Set opmode pointers */ + ops->pp_opmode_config = pp_opmode_config; + + return NULL; +} + +static void pp_opmode_config(int location, struct pp_sts_type *pp_sts, + u32 *opmode, int side) +{ + if (!pp_sts || !opmode) { + pr_err("Invalid pp_sts %p or opmode %p\n", pp_sts, opmode); + return; + } + + return; +} |
