Merge "msm_fb: display: CSC Matrix update support is added" into msm-3.0
diff --git a/drivers/video/msm/mdp4.h b/drivers/video/msm/mdp4.h
index 0740f42..fd2f13e 100644
--- a/drivers/video/msm/mdp4.h
+++ b/drivers/video/msm/mdp4.h
@@ -143,7 +143,7 @@
};
/* 2 VG pipes can be shared by RGB and VIDEO */
-#define MDP4_MAX_PIPE (OVERLAY_PIPE_MAX + 2)
+#define MDP4_MAX_PIPE (OVERLAY_PIPE_MAX + 2)
#define OVERLAY_TYPE_RGB 0x01
#define OVERLAY_TYPE_VIDEO 0x02
@@ -343,6 +343,7 @@
ulong err_format;
};
+struct mdp4_overlay_pipe *mdp4_overlay_ndx2pipe(int ndx);
void mdp4_sw_reset(unsigned long bits);
void mdp4_display_intf_sel(int output, unsigned long intf);
void mdp4_overlay_cfg(int layer, int blt_mode, int refresh, int direct_out);
@@ -367,16 +368,9 @@
void mdp4_clear_lcdc(void);
void mdp4_mixer_blend_init(int mixer_num);
void mdp4_vg_qseed_init(int vg_num);
-void mdp4_vg_csc_mv_setup(int vp_num);
-void mdp4_vg_csc_pre_bv_setup(int vp_num);
-void mdp4_vg_csc_post_bv_setup(int vp_num);
-void mdp4_vg_csc_pre_lv_setup(int vp_num);
-void mdp4_vg_csc_post_lv_setup(int vp_num);
-void mdp4_mixer1_csc_mv_setup(void);
-void mdp4_mixer1_csc_pre_bv_setup(void);
-void mdp4_mixer1_csc_post_bv_setup(void);
-void mdp4_mixer1_csc_pre_lv_setup(void);
-void mdp4_mixer1_csc_post_lv_setup(void);
+void mdp4_vg_csc_setup(int vp_num);
+void mdp4_mixer1_csc_setup(void);
+void mdp4_vg_csc_update(struct mdp_csc *p);
irqreturn_t mdp4_isr(int irq, void *ptr);
void mdp4_overlay_format_to_pipe(uint32 format, struct mdp4_overlay_pipe *pipe);
uint32 mdp4_overlay_format(struct mdp4_overlay_pipe *pipe);
diff --git a/drivers/video/msm/mdp4_util.c b/drivers/video/msm/mdp4_util.c
index 00cffda..99607e7 100644
--- a/drivers/video/msm/mdp4_util.c
+++ b/drivers/video/msm/mdp4_util.c
@@ -265,24 +265,9 @@
mdp4_vg_qseed_init(0);
mdp4_vg_qseed_init(1);
- /* yuv2rgb */
- mdp4_vg_csc_mv_setup(0);
- mdp4_vg_csc_mv_setup(1);
- mdp4_vg_csc_pre_bv_setup(0);
- mdp4_vg_csc_pre_bv_setup(1);
- mdp4_vg_csc_post_bv_setup(0);
- mdp4_vg_csc_post_bv_setup(1);
- mdp4_vg_csc_pre_lv_setup(0);
- mdp4_vg_csc_pre_lv_setup(1);
- mdp4_vg_csc_post_lv_setup(0);
- mdp4_vg_csc_post_lv_setup(1);
-
- /* rgb2yuv */
- mdp4_mixer1_csc_mv_setup();
- mdp4_mixer1_csc_pre_bv_setup();
- mdp4_mixer1_csc_post_bv_setup();
- mdp4_mixer1_csc_pre_lv_setup();
- mdp4_mixer1_csc_post_lv_setup();
+ mdp4_vg_csc_setup(0);
+ mdp4_vg_csc_setup(1);
+ mdp4_mixer1_csc_setup();
if (mdp_rev <= MDP_REV_41) {
mdp4_mixer_gc_lut_setup(0);
@@ -1221,17 +1206,54 @@
}
-static uint32 csc_matrix_tab[9] = {
- 0x0254, 0x0000, 0x0331,
- 0x0254, 0xff37, 0xfe60,
- 0x0254, 0x0409, 0x0000
+struct mdp4_csc_matrix {
+uint32 csc_mv[9];
+uint32 csc_pre_bv[3];
+uint32 csc_post_bv[3];
+uint32 csc_pre_lv[6];
+uint32 csc_post_lv[6];
+} csc_matrix[2] = {
+ {
+ {
+ 0x0254, 0x0000, 0x0331,
+ 0x0254, 0xff37, 0xfe60,
+ 0x0254, 0x0409, 0x0000,
+ },
+ {
+ 0xfff0, 0xff80, 0xff80,
+ },
+ {
+ 0, 0, 0,
+ },
+ {
+ 0, 0xff, 0, 0xff, 0, 0xff,
+ },
+ {
+ 0, 0xff, 0, 0xff, 0, 0xff,
+ },
+ },
+ {
+ {
+ 0x0254, 0x0000, 0x0331,
+ 0x0254, 0xff37, 0xfe60,
+ 0x0254, 0x0409, 0x0000,
+ },
+ {
+ 0xfff0, 0xff80, 0xff80,
+ },
+ {
+ 0, 0, 0,
+ },
+ {
+ 0, 0xff, 0, 0xff, 0, 0xff,
+ },
+ {
+ 0, 0xff, 0, 0xff, 0, 0xff,
+ },
+ },
};
-static uint32 csc_pre_bv_tab[3] = {0xfff0, 0xff80, 0xff80 };
-static uint32 csc_post_bv_tab[3] = {0, 0, 0 };
-static uint32 csc_pre_lv_tab[6] = {0, 0xff, 0, 0xff, 0, 0xff };
-static uint32 csc_post_lv_tab[6] = {0, 0xff, 0, 0xff, 0, 0xff };
#define MDP4_CSC_MV_OFF 0x4400
#define MDP4_CSC_PRE_BV_OFF 0x4500
@@ -1250,7 +1272,7 @@
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
for (i = 0; i < 9; i++) {
- outpdw(off, csc_matrix_tab[i]);
+ outpdw(off, csc_matrix[vp_num].csc_mv[i]);
off++;
}
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
@@ -1267,7 +1289,7 @@
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
for (i = 0; i < 3; i++) {
- outpdw(off, csc_pre_bv_tab[i]);
+ outpdw(off, csc_matrix[vp_num].csc_pre_bv[i]);
off++;
}
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
@@ -1284,7 +1306,7 @@
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
for (i = 0; i < 3; i++) {
- outpdw(off, csc_post_bv_tab[i]);
+ outpdw(off, csc_matrix[vp_num].csc_post_bv[i]);
off++;
}
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
@@ -1301,7 +1323,7 @@
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
for (i = 0; i < 6; i++) {
- outpdw(off, csc_pre_lv_tab[i]);
+ outpdw(off, csc_matrix[vp_num].csc_pre_lv[i]);
off++;
}
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
@@ -1318,12 +1340,47 @@
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
for (i = 0; i < 6; i++) {
- outpdw(off, csc_post_lv_tab[i]);
+ outpdw(off, csc_matrix[vp_num].csc_post_lv[i]);
off++;
}
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
}
+void mdp4_vg_csc_setup(int vp_num)
+{
+ /* yuv2rgb */
+ mdp4_vg_csc_mv_setup(vp_num);
+ mdp4_vg_csc_pre_bv_setup(vp_num);
+ mdp4_vg_csc_post_bv_setup(vp_num);
+ mdp4_vg_csc_pre_lv_setup(vp_num);
+ mdp4_vg_csc_post_lv_setup(vp_num);
+}
+void mdp4_vg_csc_update(struct mdp_csc *p)
+{
+ struct mdp4_overlay_pipe *pipe;
+ int vp_num;
+
+ pipe = mdp4_overlay_ndx2pipe(p->id);
+ if (pipe == NULL) {
+ pr_err("%s: p->id = %d Error\n", __func__, p->id);
+ return;
+ }
+
+ vp_num = pipe->pipe_num - OVERLAY_PIPE_VG1;
+
+ if (vp_num == 0 || vp_num == 1) {
+ memcpy(csc_matrix[vp_num].csc_mv, p->csc_mv, sizeof(p->csc_mv));
+ memcpy(csc_matrix[vp_num].csc_pre_bv, p->csc_pre_bv,
+ sizeof(p->csc_pre_bv));
+ memcpy(csc_matrix[vp_num].csc_post_bv, p->csc_post_bv,
+ sizeof(p->csc_post_bv));
+ memcpy(csc_matrix[vp_num].csc_pre_lv, p->csc_pre_lv,
+ sizeof(p->csc_pre_lv));
+ memcpy(csc_matrix[vp_num].csc_post_lv, p->csc_post_lv,
+ sizeof(p->csc_post_lv));
+ mdp4_vg_csc_setup(vp_num);
+ }
+}
static uint32 csc_rgb2yuv_matrix_tab[9] = {
0x0083, 0x0102, 0x0032,
0x1fb5, 0x1f6c, 0x00e1,
@@ -1419,6 +1476,15 @@
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
}
+void mdp4_mixer1_csc_setup(void)
+{
+ /* rgb2yuv */
+ mdp4_mixer1_csc_mv_setup();
+ mdp4_mixer1_csc_pre_bv_setup();
+ mdp4_mixer1_csc_post_bv_setup();
+ mdp4_mixer1_csc_pre_lv_setup();
+ mdp4_mixer1_csc_post_lv_setup();
+}
char gc_lut[] = {
0x0, 0x1, 0x2, 0x2, 0x3, 0x4, 0x5, 0x6,
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index e5ec4cb..94c38ff 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -2690,6 +2690,11 @@
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
}
}
+#else
+static void msmfb_set_color_conv(struct mdp_csc *p)
+{
+ mdp4_vg_csc_update(p);
+}
#endif
static int msmfb_notify_update(struct fb_info *info, unsigned long *argp)
@@ -2726,6 +2731,8 @@
struct mdp_histogram hist;
#ifndef CONFIG_FB_MSM_MDP40
struct mdp_ccs ccs_matrix;
+#else
+ struct mdp_csc csc_matrix;
#endif
struct mdp_page_protection fb_page_protection;
int ret = 0;
@@ -2805,7 +2812,16 @@
msmfb_set_color_conv(&ccs_matrix) ;
up(&msm_fb_ioctl_ppp_sem);
#else
- ret = -EINVAL;
+ ret = copy_from_user(&csc_matrix, argp, sizeof(csc_matrix));
+ if (ret) {
+ pr_err("%s:MSMFB_SET_CSC_MATRIX ioctl failed\n",
+ __func__);
+ return ret;
+ }
+ down(&msm_fb_ioctl_ppp_sem);
+ msmfb_set_color_conv(&csc_matrix);
+ up(&msm_fb_ioctl_ppp_sem);
+
#endif
break;
diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h
index 144caa0..a739761 100644
--- a/include/linux/msm_mdp.h
+++ b/include/linux/msm_mdp.h
@@ -165,6 +165,15 @@
uint16_t bv[MDP_BV_SIZE]; /* 1x3 bias vector */
};
+struct mdp_csc {
+ int id;
+ uint32_t csc_mv[9];
+ uint32_t csc_pre_bv[3];
+ uint32_t csc_post_bv[3];
+ uint32_t csc_pre_lv[6];
+ uint32_t csc_post_lv[6];
+};
+
/* The version of the mdp_blit_req structure so that
* user applications can selectively decide which functionality
* to include