summaryrefslogtreecommitdiff
path: root/drivers/video/fbdev
diff options
context:
space:
mode:
authorBenet Clark <benetc@codeaurora.org>2014-10-14 18:45:44 -0700
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 20:35:07 -0700
commit4c0f7dc9e9bd04b96ea2cf39338adca1ba7d9832 (patch)
tree22b30133b44ab3f01077bef84e65c24423479896 /drivers/video/fbdev
parentd892b4e127f1177669acdd39bd98c1db80ce7e16 (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/Makefile4
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_pp.c55
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_pp.h82
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_pp_v1_7.c83
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;
+}