video: msm: Writeback support in mdp for WFD.
Adds writeback mode in mdp for wifi-display(WFD).
This mode can be used to get the captured
frames from mdp. This is added to support
wifi-display capture device.
Change-Id: Iae30cac65af181d8df4b514a128cd876fe7dda1c
Signed-off-by: Vinay Kalia <vkalia@codeaurora.org>
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index d21910b..7595838 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -2630,6 +2630,136 @@
}
#endif
+#ifdef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
+static int msmfb_overlay_ioctl_writeback_init(struct fb_info *info)
+{
+ return mdp4_writeback_init(info);
+}
+static int msmfb_overlay_ioctl_writeback_register_buffer(
+ struct fb_info *info, unsigned long *argp)
+{
+ int ret = 0;
+ struct msmfb_writeback_data data;
+
+ ret = copy_from_user(&data, argp, sizeof(data));
+ if (ret)
+ goto error;
+
+ ret = mdp4_writeback_register_buffer(info, &data);
+ if (ret)
+ goto error;
+error:
+ if (ret)
+ pr_err("%s:msmfb_writeback_register_buffer "
+ " ioctl failed\n", __func__);
+ return ret;
+}
+
+static int msmfb_overlay_ioctl_writeback_unregister_buffer(
+ struct fb_info *info, unsigned long *argp)
+{
+ int ret = 0;
+ struct msmfb_writeback_data data;
+
+ ret = copy_from_user(&data, argp, sizeof(data));
+ if (ret)
+ goto error;
+
+ ret = mdp4_writeback_unregister_buffer(info, &data);
+ if (ret)
+ goto error;
+
+error:
+ if (ret)
+ pr_err("%s:msmfb_writeback_unregister_buffer ioctl failed\n",
+ __func__);
+ return ret;
+}
+
+static int msmfb_overlay_ioctl_writeback_queue_buffer(
+ struct fb_info *info, unsigned long *argp)
+{
+ int ret = 0;
+ struct msmfb_data data;
+
+ ret = copy_from_user(&data, argp, sizeof(data));
+ if (ret)
+ goto error;
+
+ ret = mdp4_writeback_queue_buffer(info, &data);
+ if (ret)
+ goto error;
+
+error:
+ if (ret)
+ pr_err("%s:msmfb_writeback_queue_buffer ioctl failed\n",
+ __func__);
+ return ret;
+}
+
+static int msmfb_overlay_ioctl_writeback_dequeue_buffer(
+ struct fb_info *info, unsigned long *argp)
+{
+ int ret = 0;
+ struct msmfb_data data;
+
+ ret = copy_from_user(&data, argp, sizeof(data));
+ if (ret)
+ goto error;
+
+ ret = mdp4_writeback_dequeue_buffer(info, &data);
+ if (ret)
+ goto error;
+
+ ret = copy_to_user(argp, &data, sizeof(data));
+ if (ret)
+ goto error;
+
+error:
+ if (ret)
+ pr_err("%s:msmfb_writeback_dequeue_buffer ioctl failed\n",
+ __func__);
+ return ret;
+}
+static int msmfb_overlay_ioctl_writeback_terminate(struct fb_info *info)
+{
+ return mdp4_writeback_terminate(info);
+}
+
+#else
+static int msmfb_overlay_ioctl_writeback_init(struct fb_info *info)
+{
+ return -ENOTSUPP;
+}
+static int msmfb_overlay_ioctl_writeback_register_buffer(
+ struct fb_info *info, unsigned long *argp)
+{
+ return -ENOTSUPP;
+}
+
+static int msmfb_overlay_ioctl_writeback_unregister_buffer(
+ struct fb_info *info, unsigned long *argp)
+{
+ return -ENOTSUPP;
+}
+
+static int msmfb_overlay_ioctl_writeback_queue_buffer(
+ struct fb_info *info, unsigned long *argp)
+{
+ return -ENOTSUPP;
+}
+
+static int msmfb_overlay_ioctl_writeback_dequeue_buffer(
+ struct fb_info *info, unsigned long *argp)
+{
+ return -ENOTSUPP;
+}
+static int msmfb_overlay_ioctl_writeback_terminate(struct fb_info *info)
+{
+ return -ENOTSUPP;
+}
+#endif
+
static int msmfb_overlay_3d_sbys(struct fb_info *info, unsigned long *argp)
{
int ret;
@@ -2809,6 +2939,28 @@
ret = msmfb_mixer_info(info, argp);
up(&msm_fb_ioctl_ppp_sem);
break;
+ case MSMFB_WRITEBACK_INIT:
+ ret = msmfb_overlay_ioctl_writeback_init(info);
+ break;
+ case MSMFB_WRITEBACK_REGISTER_BUFFER:
+ ret = msmfb_overlay_ioctl_writeback_register_buffer(
+ info, argp);
+ break;
+ case MSMFB_WRITEBACK_UNREGISTER_BUFFER:
+ ret = msmfb_overlay_ioctl_writeback_unregister_buffer(
+ info, argp);
+ break;
+ case MSMFB_WRITEBACK_QUEUE_BUFFER:
+ ret = msmfb_overlay_ioctl_writeback_queue_buffer(
+ info, argp);
+ break;
+ case MSMFB_WRITEBACK_DEQUEUE_BUFFER:
+ ret = msmfb_overlay_ioctl_writeback_dequeue_buffer(
+ info, argp);
+ break;
+ case MSMFB_WRITEBACK_TERMINATE:
+ ret = msmfb_overlay_ioctl_writeback_terminate(info);
+ break;
#endif
case MSMFB_BLIT:
down(&msm_fb_ioctl_ppp_sem);
@@ -3023,6 +3175,60 @@
return platform_driver_register(&msm_fb_driver);
}
+#ifdef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
+struct fb_info *msm_fb_get_writeback_fb(void)
+{
+ int c = 0;
+ for (c = 0; c < fbi_list_index; ++c) {
+ struct msm_fb_data_type *mfd;
+ mfd = (struct msm_fb_data_type *)fbi_list[c]->par;
+ if (mfd->panel.type == WRITEBACK_PANEL)
+ return fbi_list[c];
+ }
+
+ return NULL;
+}
+EXPORT_SYMBOL(msm_fb_get_writeback_fb);
+
+int msm_fb_writeback_register_buffer(struct fb_info *info,
+ struct msmfb_writeback_data *data)
+{
+ return mdp4_writeback_register_buffer(info, data);
+}
+EXPORT_SYMBOL(msm_fb_writeback_register_buffer);
+
+int msm_fb_writeback_queue_buffer(struct fb_info *info,
+ struct msmfb_data *data)
+{
+ return mdp4_writeback_queue_buffer(info, data);
+}
+EXPORT_SYMBOL(msm_fb_writeback_queue_buffer);
+
+int msm_fb_writeback_dequeue_buffer(struct fb_info *info,
+ struct msmfb_data *data)
+{
+ return mdp4_writeback_dequeue_buffer(info, data);
+}
+EXPORT_SYMBOL(msm_fb_writeback_dequeue_buffer);
+
+int msm_fb_writeback_unregister_buffer(struct fb_info *info,
+ struct msmfb_writeback_data *data)
+{
+ return mdp4_writeback_unregister_buffer(info, data);
+}
+EXPORT_SYMBOL(msm_fb_writeback_unregister_buffer);
+int msm_fb_writeback_init(struct fb_info *info)
+{
+ return mdp4_writeback_init(info);
+}
+EXPORT_SYMBOL(msm_fb_writeback_init);
+int msm_fb_writeback_terminate(struct fb_info *info)
+{
+ return mdp4_writeback_terminate(info);
+}
+EXPORT_SYMBOL(msm_fb_writeback_terminate);
+#endif
+
struct platform_device *msm_fb_add_device(struct platform_device *pdev)
{
struct msm_fb_panel_data *pdata;
@@ -3046,7 +3252,8 @@
* at panel_info
*
*/
- if (type == HDMI_PANEL || type == DTV_PANEL || type == TV_PANEL) {
+ if (type == HDMI_PANEL || type == DTV_PANEL ||
+ type == TV_PANEL || type == WRITEBACK_PANEL) {
#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
pdata->panel_info.fb_num = 2;
#else