static int mdp3_ctrl_off(struct msm_fb_data_type *mfd) { int rc = 0; struct mdp3_session_data *mdp3_session; struct mdss_panel_data *panel; pr_debug("mdp3_ctrl_off\n"); mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1; if (!mdp3_session || !mdp3_session->panel || !mdp3_session->dma || !mdp3_session->intf) { pr_err("mdp3_ctrl_on no device"); return -ENODEV; } mutex_lock(&mdp3_session->lock); if (!mdp3_session->status) { pr_debug("fb%d is off already", mfd->index); goto off_error; } pr_debug("mdp3_ctrl_off stop mdp3 dma engine\n"); rc = mdp3_session->dma->stop(mdp3_session->dma, mdp3_session->intf); if (rc) pr_err("fail to stop the MDP3 dma\n"); pr_debug("mdp3_ctrl_off stop dsi panel and controller\n"); panel = mdp3_session->panel; if (panel->event_handler) rc = panel->event_handler(panel, MDSS_EVENT_PANEL_OFF, NULL); if (rc) pr_err("fail to turn off the panel\n"); pr_debug("mdp3_ctrl_off release bus and clock\n"); rc = mdp3_ctrl_res_req_bus(mfd, 0); if (rc) pr_err("mdp bus resource release failed\n"); rc = mdp3_ctrl_res_req_clk(mfd, 0); if (rc) pr_err("mdp clock resource release failed\n"); rc = mdp3_iommu_disable(MDP3_CLIENT_DMA_P); if (rc) pr_err("fail to dettach MDP DMA SMMU\n"); off_error: mdp3_session->status = 0; mutex_unlock(&mdp3_session->lock); if (mdp3_session->overlay.id != MSMFB_NEW_REQUEST) mdp3_overlay_unset(mfd, mdp3_session->overlay.id); return 0; }
static int mdp3_ctrl_ioctl_handler(struct msm_fb_data_type *mfd, u32 cmd, void __user *argp) { int rc = -EINVAL; struct mdp3_session_data *mdp3_session; struct msmfb_metadata metadata; struct mdp_overlay *req = NULL; struct msmfb_overlay_data ov_data; int val; mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1; if (!mdp3_session) return -ENODEV; req = &mdp3_session->req_overlay; if (!mdp3_session->status && cmd != MSMFB_METADATA_GET && cmd != MSMFB_HISTOGRAM_STOP) { pr_err("mdp3_ctrl_ioctl_handler, display off!\n"); return -EPERM; } switch (cmd) { case MSMFB_MDP_PP: rc = mdp3_pp_ioctl(mfd, argp); break; case MSMFB_HISTOGRAM_START: case MSMFB_HISTOGRAM_STOP: case MSMFB_HISTOGRAM: rc = mdp3_histo_ioctl(mfd, cmd, argp); break; case MSMFB_VSYNC_CTRL: case MSMFB_OVERLAY_VSYNC_CTRL: if (!copy_from_user(&val, argp, sizeof(val))) { mutex_lock(&mdp3_session->lock); mdp3_session->vsync_enabled = val; rc = mdp3_ctrl_vsync_enable(mfd, val); mutex_unlock(&mdp3_session->lock); } else { pr_err("MSMFB_OVERLAY_VSYNC_CTRL failed\n"); rc = -EFAULT; } break; case MSMFB_ASYNC_BLIT: rc = mdp3_ctrl_async_blit_req(mfd, argp); break; case MSMFB_BLIT: rc = mdp3_ctrl_blit_req(mfd, argp); break; case MSMFB_METADATA_GET: rc = copy_from_user(&metadata, argp, sizeof(metadata)); if (!rc) rc = mdp3_get_metadata(mfd, &metadata); if (!rc) rc = copy_to_user(argp, &metadata, sizeof(metadata)); if (rc) pr_err("mdp3_get_metadata failed (%d)\n", rc); break; case MSMFB_METADATA_SET: rc = copy_from_user(&metadata, argp, sizeof(metadata)); if (!rc) rc = mdp3_set_metadata(mfd, &metadata); if (rc) pr_err("mdp3_set_metadata failed (%d)\n", rc); break; case MSMFB_OVERLAY_GET: rc = copy_from_user(req, argp, sizeof(*req)); if (!rc) { rc = mdp3_overlay_get(mfd, req); if (!IS_ERR_VALUE(rc)) rc = copy_to_user(argp, req, sizeof(*req)); } if (rc) pr_err("OVERLAY_GET failed (%d)\n", rc); break; case MSMFB_OVERLAY_SET: rc = copy_from_user(req, argp, sizeof(*req)); if (!rc) { rc = mdp3_overlay_set(mfd, req); if (!IS_ERR_VALUE(rc)) rc = copy_to_user(argp, req, sizeof(*req)); } if (rc) pr_err("OVERLAY_SET failed (%d)\n", rc); break; case MSMFB_OVERLAY_UNSET: if (!IS_ERR_VALUE(copy_from_user(&val, argp, sizeof(val)))) rc = mdp3_overlay_unset(mfd, val); break; case MSMFB_OVERLAY_PLAY: rc = copy_from_user(&ov_data, argp, sizeof(ov_data)); if (!rc) rc = mdp3_overlay_play(mfd, &ov_data); if (rc) pr_err("OVERLAY_PLAY failed (%d)\n", rc); break; case MSMFB_OVERLAY_PREPARE: rc = mdp3_overlay_prepare(mfd, argp); break; default: break; } return rc; }
static int mdp3_ctrl_ioctl_handler(struct msm_fb_data_type *mfd, u32 cmd, void __user *argp) { int rc = -EINVAL; struct mdp3_session_data *mdp3_session; struct msmfb_metadata metadata; struct mdp_overlay req; struct msmfb_overlay_data ov_data; int val; pr_debug("mdp3_ctrl_ioctl_handler\n"); mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1; if (!mdp3_session) return -ENODEV; if (!mdp3_session->status) { pr_err("mdp3_ctrl_ioctl_handler, display off!\n"); return -EINVAL; } switch (cmd) { case MSMFB_VSYNC_CTRL: case MSMFB_OVERLAY_VSYNC_CTRL: if (!copy_from_user(&val, argp, sizeof(val))) { rc = mdp3_ctrl_vsync_enable(mfd, val); } else { pr_err("MSMFB_OVERLAY_VSYNC_CTRL failed\n"); rc = -EFAULT; } break; case MSMFB_ASYNC_BLIT: rc = mdp3_ctrl_async_blit_req(mfd, argp); break; case MSMFB_BLIT: rc = mdp3_ctrl_blit_req(mfd, argp); break; case MSMFB_METADATA_GET: rc = copy_from_user(&metadata, argp, sizeof(metadata)); if (rc) return rc; rc = mdp3_get_metadata(mfd, &metadata); if (!rc) rc = copy_to_user(argp, &metadata, sizeof(metadata)); break; case MSMFB_OVERLAY_GET: rc = copy_from_user(&req, argp, sizeof(req)); if (!rc) { rc = mdp3_overlay_get(mfd, &req); if (!IS_ERR_VALUE(rc)) rc = copy_to_user(argp, &req, sizeof(req)); } if (rc) pr_err("OVERLAY_GET failed (%d)\n", rc); break; case MSMFB_OVERLAY_SET: rc = copy_from_user(&req, argp, sizeof(req)); if (!rc) { rc = mdp3_overlay_set(mfd, &req); if (!IS_ERR_VALUE(rc)) rc = copy_to_user(argp, &req, sizeof(req)); } if (rc) pr_err("OVERLAY_SET failed (%d)\n", rc); break; case MSMFB_OVERLAY_UNSET: if (!IS_ERR_VALUE(copy_from_user(&val, argp, sizeof(val)))) rc = mdp3_overlay_unset(mfd, val); break; case MSMFB_OVERLAY_PLAY: rc = copy_from_user(&ov_data, argp, sizeof(ov_data)); if (!rc) rc = mdp3_overlay_play(mfd, &ov_data); if (rc) pr_err("OVERLAY_PLAY failed (%d)\n", rc); break; default: break; } return rc; }
static int mdp3_ctrl_off(struct msm_fb_data_type *mfd) { int rc = 0; struct mdp3_session_data *mdp3_session; struct mdss_panel_data *panel; pr_debug("mdp3_ctrl_off\n"); mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1; if (!mdp3_session || !mdp3_session->panel || !mdp3_session->dma || !mdp3_session->intf) { pr_err("mdp3_ctrl_on no device"); return -ENODEV; } panel = mdp3_session->panel; mutex_lock(&mdp3_session->lock); if (!mdp3_session->status) { pr_debug("fb%d is off already", mfd->index); goto off_error; } mdp3_ctrl_clk_enable(mfd, 1); mdp3_histogram_stop(mdp3_session, MDP_BLOCK_DMA_P); rc = mdp3_session->dma->stop(mdp3_session->dma, mdp3_session->intf); if (rc) pr_debug("fail to stop the MDP3 dma\n"); if (panel->event_handler) rc = panel->event_handler(panel, MDSS_EVENT_PANEL_OFF, NULL); if (rc) pr_err("fail to turn off the panel\n"); mdp3_irq_deregister(); pr_debug("mdp3_ctrl_off stop clock\n"); if (mdp3_session->clk_on) { rc = mdp3_clk_enable(0, 1); if (rc) pr_err("mdp clock resource release failed\n"); pr_debug("mdp3_ctrl_off stop dsi controller\n"); if (panel->event_handler) rc = panel->event_handler(panel, MDSS_EVENT_BLANK, NULL); if (rc) pr_err("fail to turn off the panel\n"); } mdp3_clk_unprepare(); pr_debug("mdp3_ctrl_off release bus\n"); rc = mdp3_ctrl_res_req_bus(mfd, 0); if (rc) pr_err("mdp bus resource release failed\n"); rc = mdp3_iommu_disable(MDP3_CLIENT_DMA_P); if (rc) pr_err("fail to dettach MDP DMA SMMU\n"); mdp3_ctrl_notifier_unregister(mdp3_session, &mdp3_session->mfd->mdp_sync_pt_data.notifier); mdp3_batfet_ctrl(false); mdp3_session->vsync_enabled = 0; atomic_set(&mdp3_session->vsync_countdown, 0); mdp3_session->clk_on = 0; off_error: mdp3_session->status = 0; mdp3_bufq_deinit(&mdp3_session->bufq_out); mutex_unlock(&mdp3_session->lock); if (mdp3_session->overlay.id != MSMFB_NEW_REQUEST) mdp3_overlay_unset(mfd, mdp3_session->overlay.id); return 0; }