msm_fb: display: add 3D support at DSI video mode
Currently, only DSI command mode have 3D capability. Add 3D
support for DSI video mode also.
CRs-fixed: 294082
Signed-off-by: Kuogee Hsieh <khsieh@codeaurora.org>
diff --git a/drivers/video/msm/mdp4.h b/drivers/video/msm/mdp4.h
index 3b0244c..8e89b16 100644
--- a/drivers/video/msm/mdp4.h
+++ b/drivers/video/msm/mdp4.h
@@ -545,8 +545,10 @@
void mdp4_dsi_cmd_overlay_restore(void);
void mdp4_overlay_panel_3d(int mixer_num, uint32 panel_3d);
-int mdp4_overlay_3d(struct fb_info *info, struct msmfb_overlay_3d *req);
-void mdp4_dsi_cmd_3d(struct msm_fb_data_type *mfd,
+int mdp4_overlay_3d_sbys(struct fb_info *info, struct msmfb_overlay_3d *req);
+void mdp4_dsi_cmd_3d_sbys(struct msm_fb_data_type *mfd,
+ struct msmfb_overlay_3d *r3d);
+void mdp4_dsi_video_3d_sbys(struct msm_fb_data_type *mfd,
struct msmfb_overlay_3d *r3d);
void mdp_dmap_vsync_set(int enable);
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index b819f41..954f9f9 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -1730,7 +1730,8 @@
return ret;
}
-int mdp4_overlay_3d(struct fb_info *info, struct msmfb_overlay_3d *req)
+#ifdef CONFIG_FB_MSM_MIPI_DSI
+int mdp4_overlay_3d_sbys(struct fb_info *info, struct msmfb_overlay_3d *req)
{
struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
int ret = -EPERM;
@@ -1738,17 +1739,24 @@
if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
return -EINTR;
-#ifdef CONFIG_FB_MSM_MIPI_DSI
- /* Only dsi_cmd panel support 3D */
if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
- mdp4_dsi_cmd_3d(mfd, req);
+ mdp4_dsi_cmd_3d_sbys(mfd, req);
+ ret = 0;
+ } else if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO) {
+ mdp4_dsi_video_3d_sbys(mfd, req);
ret = 0;
}
-#endif
mutex_unlock(&mfd->dma->ov_mutex);
return ret;
}
+#else
+int mdp4_overlay_3d_sbys(struct fb_info *info, struct msmfb_overlay_3d *req)
+{
+ /* do nothing */
+ return -EPERM;
+}
+#endif
#ifdef CONFIG_FB_MSM_OVERLAY_WRITEBACK
int mdp4_overlay_blt(struct fb_info *info, struct msmfb_overlay_blt *req)
diff --git a/drivers/video/msm/mdp4_overlay_dsi_cmd.c b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
index 22d9d3b..a440ddf 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_cmd.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
@@ -226,7 +226,9 @@
wmb();
}
-void mdp4_dsi_cmd_3d(struct msm_fb_data_type *mfd, struct msmfb_overlay_3d *r3d)
+/* 3D side by side */
+void mdp4_dsi_cmd_3d_sbys(struct msm_fb_data_type *mfd,
+ struct msmfb_overlay_3d *r3d)
{
struct fb_info *fbi;
struct mdp4_overlay_pipe *pipe;
diff --git a/drivers/video/msm/mdp4_overlay_dsi_video.c b/drivers/video/msm/mdp4_overlay_dsi_video.c
index f7ceaac..6d8a43f 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_video.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_video.c
@@ -43,6 +43,21 @@
static cmd_fxn_t display_on;
+static __u32 msm_fb_line_length(__u32 fb_index, __u32 xres, int bpp)
+{
+ /*
+ * The adreno GPU hardware requires that the pitch be aligned to
+ * 32 pixels for color buffers, so for the cases where the GPU
+ * is writing directly to fb0, the framebuffer pitch
+ * also needs to be 32 pixel aligned
+ */
+
+ if (fb_index == 0)
+ return ALIGN(xres, 32) * bpp;
+ else
+ return xres * bpp;
+}
+
void mdp4_dsi_video_fxn_register(cmd_fxn_t fxn)
{
display_on = fxn;
@@ -277,6 +292,78 @@
return ret;
}
+/* 3D side by side */
+void mdp4_dsi_video_3d_sbys(struct msm_fb_data_type *mfd,
+ struct msmfb_overlay_3d *r3d)
+{
+ struct fb_info *fbi;
+ struct mdp4_overlay_pipe *pipe;
+ int bpp;
+ uint8 *buf = NULL;
+
+ if (dsi_pipe == NULL)
+ return;
+
+ dsi_pipe->is_3d = r3d->is_3d;
+ dsi_pipe->src_height_3d = r3d->height;
+ dsi_pipe->src_width_3d = r3d->width;
+
+ pipe = dsi_pipe;
+
+ if (pipe->is_3d)
+ mdp4_overlay_panel_3d(pipe->mixer_num, MDP4_3D_SIDE_BY_SIDE);
+ else
+ mdp4_overlay_panel_3d(pipe->mixer_num, MDP4_3D_NONE);
+
+ fbi = mfd->fbi;
+
+ bpp = fbi->var.bits_per_pixel / 8;
+ buf = (uint8 *) fbi->fix.smem_start;
+ buf += fbi->var.xoffset * bpp +
+ fbi->var.yoffset * fbi->fix.line_length;
+
+ if (pipe->is_3d) {
+ pipe->src_height = pipe->src_height_3d;
+ pipe->src_width = pipe->src_width_3d;
+ pipe->src_h = pipe->src_height_3d;
+ pipe->src_w = pipe->src_width_3d;
+ pipe->dst_h = pipe->src_height_3d;
+ pipe->dst_w = pipe->src_width_3d;
+ pipe->srcp0_ystride = msm_fb_line_length(0,
+ pipe->src_width, bpp);
+ } else {
+ /* 2D */
+ pipe->src_height = fbi->var.yres;
+ pipe->src_width = fbi->var.xres;
+ pipe->src_h = fbi->var.yres;
+ pipe->src_w = fbi->var.xres;
+ pipe->dst_h = fbi->var.yres;
+ pipe->dst_w = fbi->var.xres;
+ pipe->srcp0_ystride = fbi->fix.line_length;
+ }
+
+ pipe->src_y = 0;
+ pipe->src_x = 0;
+ pipe->dst_y = 0;
+ pipe->dst_x = 0;
+ pipe->srcp0_addr = (uint32)buf;
+
+ mdp4_overlay_rgb_setup(pipe);
+
+ mdp4_overlayproc_cfg(pipe);
+
+ mdp4_overlay_dmap_xy(pipe);
+
+ mdp4_overlay_dmap_cfg(mfd, 1);
+
+ mdp4_mixer_stage_up(pipe);
+
+ mb();
+
+ /* wait for vsycn */
+ mdp4_overlay_dsi_video_vsync_push(mfd, pipe);
+}
+
#ifdef CONFIG_FB_MSM_OVERLAY_WRITEBACK
int mdp4_dsi_video_overlay_blt_offset(struct msm_fb_data_type *mfd,
struct msmfb_overlay_blt *req)
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index 1c4cc72..b5cd46a3 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -2577,7 +2577,7 @@
}
#endif
-static int msmfb_overlay_3d(struct fb_info *info, unsigned long *argp)
+static int msmfb_overlay_3d_sbys(struct fb_info *info, unsigned long *argp)
{
int ret;
struct msmfb_overlay_3d req;
@@ -2589,7 +2589,7 @@
return ret;
}
- ret = mdp4_overlay_3d(info, &req);
+ ret = mdp4_overlay_3d_sbys(info, &req);
return ret;
}
@@ -2715,7 +2715,7 @@
break;
case MSMFB_OVERLAY_3D:
down(&msm_fb_ioctl_ppp_sem);
- ret = msmfb_overlay_3d(info, argp);
+ ret = msmfb_overlay_3d_sbys(info, argp);
up(&msm_fb_ioctl_ppp_sem);
break;
#endif