Loading drivers/video/msm/mdss/mdp3.h +1 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include "mdss_fb.h" #define MDP_VSYNC_CLK_RATE 19200000 #define KOFF_TIMEOUT msecs_to_jiffies(84) enum { MDP3_CLK_AHB, Loading drivers/video/msm/mdss/mdp3_ctrl.c +89 −8 Original line number Diff line number Diff line Loading @@ -91,6 +91,36 @@ static int mdp3_bufq_count(struct mdp3_buffer_queue *bufq) return bufq->count; } void mdp3_ctrl_notifier_register(struct mdp3_session_data *ses, struct notifier_block *notifier) { blocking_notifier_chain_register(&ses->notifier_head, notifier); } void mdp3_ctrl_notifier_unregister(struct mdp3_session_data *ses, struct notifier_block *notifier) { blocking_notifier_chain_unregister(&ses->notifier_head, notifier); } int mdp3_ctrl_notify(struct mdp3_session_data *ses, int event) { return blocking_notifier_call_chain(&ses->notifier_head, event, ses); } static void mdp3_dispatch_dma_done(struct work_struct *work) { struct mdp3_session_data *session; pr_debug("%s\n", __func__); session = container_of(work, struct mdp3_session_data, dma_done_work); if (!session) return; mdp3_ctrl_notify(session, MDP_NOTIFY_FRAME_DONE); } static void mdp3_dispatch_clk_off(struct work_struct *work) { struct mdp3_session_data *session; Loading Loading @@ -121,6 +151,12 @@ void vsync_notify_handler(void *arg) sysfs_notify_dirent(session->vsync_event_sd); } void dma_done_notify_handler(void *arg) { struct mdp3_session_data *session = (struct mdp3_session_data *)arg; schedule_work(&session->dma_done_work); } void vsync_count_down(void *arg) { struct mdp3_session_data *session = (struct mdp3_session_data *)arg; Loading @@ -140,8 +176,8 @@ void mdp3_ctrl_reset_countdown(struct mdp3_session_data *session, static int mdp3_ctrl_vsync_enable(struct msm_fb_data_type *mfd, int enable) { struct mdp3_session_data *mdp3_session; struct mdp3_vsync_notification vsync_client; struct mdp3_vsync_notification *arg = NULL; struct mdp3_notification vsync_client; struct mdp3_notification *arg = NULL; pr_debug("mdp3_ctrl_vsync_enable =%d\n", enable); mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1; Loading Loading @@ -464,6 +500,7 @@ static int mdp3_ctrl_dma_init(struct msm_fb_data_type *mfd, int frame_rate = mfd->panel_info->mipi.frame_rate; int vbp, vfp, vspw; int vtotal, vporch; struct mdp3_notification dma_done_callback; vbp = panel_info->lcdc.v_back_porch; vfp = panel_info->lcdc.v_front_porch; Loading Loading @@ -499,6 +536,13 @@ static int mdp3_ctrl_dma_init(struct msm_fb_data_type *mfd, rc = dma->dma_config(dma, &sourceConfig, &outputConfig); else rc = -EINVAL; if (outputConfig.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_CMD) { dma_done_callback.handler = dma_done_notify_handler; dma_done_callback.arg = mfd->mdp.private1; dma->dma_done_notifier(dma, &dma_done_callback); } return rc; } Loading Loading @@ -527,6 +571,8 @@ static int mdp3_ctrl_on(struct msm_fb_data_type *mfd) } mdp3_batfet_ctrl(true); mdp3_ctrl_notifier_register(mdp3_session, &mdp3_session->mfd->mdp_sync_pt_data.notifier); rc = mdp3_iommu_enable(MDP3_CLIENT_DMA_P); if (rc) { Loading Loading @@ -658,6 +704,8 @@ static int mdp3_ctrl_off(struct msm_fb_data_type *mfd) 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); Loading @@ -677,7 +725,7 @@ static int mdp3_ctrl_reset_cmd(struct msm_fb_data_type *mfd) struct mdp3_session_data *mdp3_session; struct mdp3_dma *mdp3_dma; struct mdss_panel_data *panel; struct mdp3_vsync_notification vsync_client; struct mdp3_notification vsync_client; pr_debug("mdp3_ctrl_reset_cmd\n"); mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1; Loading Loading @@ -728,7 +776,7 @@ static int mdp3_ctrl_reset(struct msm_fb_data_type *mfd) struct mdp3_session_data *mdp3_session; struct mdp3_dma *mdp3_dma; struct mdss_panel_data *panel; struct mdp3_vsync_notification vsync_client; struct mdp3_notification vsync_client; pr_debug("mdp3_ctrl_reset\n"); mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1; Loading Loading @@ -971,13 +1019,27 @@ static int mdp3_ctrl_display_commit_kickoff(struct msm_fb_data_type *mfd, return -EPERM; } mdp3_ctrl_notify(mdp3_session, MDP_NOTIFY_FRAME_BEGIN); data = mdp3_bufq_pop(&mdp3_session->bufq_in); if (data) { mdp3_ctrl_reset_countdown(mdp3_session, mfd); mdp3_ctrl_clk_enable(mfd, 1); mdp3_session->dma->update(mdp3_session->dma, rc = mdp3_session->dma->update(mdp3_session->dma, (void *)(int)data->addr, mdp3_session->intf); /* This is for the previous frame */ if (rc < 0) { mdp3_ctrl_notify(mdp3_session, MDP_NOTIFY_FRAME_TIMEOUT); } else { if (mdp3_ctrl_get_intf_type(mfd) == MDP3_DMA_OUTPUT_SEL_DSI_VIDEO) { mdp3_ctrl_notify(mdp3_session, MDP_NOTIFY_FRAME_DONE); } } mdp3_ctrl_notify(mdp3_session, MDP_NOTIFY_FRAME_FLUSHED); mdp3_bufq_push(&mdp3_session->bufq_out, data); } Loading @@ -1001,7 +1063,7 @@ static int mdp3_ctrl_display_commit_kickoff(struct msm_fb_data_type *mfd, mdss_fb_update_notify_update(mfd); return rc; return 0; } static void mdp3_ctrl_pan_display(struct msm_fb_data_type *mfd) Loading @@ -1011,6 +1073,7 @@ static void mdp3_ctrl_pan_display(struct msm_fb_data_type *mfd) u32 offset; int bpp; struct mdss_panel_info *panel_info; int rc; pr_debug("mdp3_ctrl_pan_display\n"); if (!mfd || !mfd->mdp.private1) Loading Loading @@ -1049,10 +1112,23 @@ static void mdp3_ctrl_pan_display(struct msm_fb_data_type *mfd) if (mfd->fbi->screen_base) { mdp3_ctrl_reset_countdown(mdp3_session, mfd); mdp3_ctrl_notify(mdp3_session, MDP_NOTIFY_FRAME_BEGIN); mdp3_ctrl_clk_enable(mfd, 1); mdp3_session->dma->update(mdp3_session->dma, rc = mdp3_session->dma->update(mdp3_session->dma, (void *)(int)(mfd->iova + offset), mdp3_session->intf); /* This is for the previous frame */ if (rc < 0) { mdp3_ctrl_notify(mdp3_session, MDP_NOTIFY_FRAME_TIMEOUT); } else { if (mdp3_ctrl_get_intf_type(mfd) == MDP3_DMA_OUTPUT_SEL_DSI_VIDEO) { mdp3_ctrl_notify(mdp3_session, MDP_NOTIFY_FRAME_DONE); } } mdp3_ctrl_notify(mdp3_session, MDP_NOTIFY_FRAME_FLUSHED); } else { pr_debug("mdp3_ctrl_pan_display no memory, stop interface"); mdp3_clk_enable(1, 0); Loading Loading @@ -1683,6 +1759,7 @@ int mdp3_ctrl_init(struct msm_fb_data_type *mfd) memset(mdp3_session, 0, sizeof(struct mdp3_session_data)); mutex_init(&mdp3_session->lock); INIT_WORK(&mdp3_session->clk_off_work, mdp3_dispatch_clk_off); INIT_WORK(&mdp3_session->dma_done_work, mdp3_dispatch_dma_done); atomic_set(&mdp3_session->vsync_countdown, 0); mutex_init(&mdp3_session->histo_lock); mdp3_session->dma = mdp3_get_dma_pipe(MDP3_DMA_CAP_ALL); Loading Loading @@ -1718,6 +1795,7 @@ int mdp3_ctrl_init(struct msm_fb_data_type *mfd) mdp3_bufq_init(&mdp3_session->bufq_out); mdp3_session->histo_status = 0; mdp3_session->lut_sel = 0; BLOCKING_INIT_NOTIFIER_HEAD(&mdp3_session->notifier_head); init_timer(&mdp3_session->vsync_timer); mdp3_session->vsync_timer.function = mdp3_vsync_timer_func; Loading Loading @@ -1746,8 +1824,11 @@ int mdp3_ctrl_init(struct msm_fb_data_type *mfd) kobject_uevent(&dev->kobj, KOBJ_ADD); pr_debug("vsync kobject_uevent(KOBJ_ADD)\n"); if (mdp3_get_cont_spash_en()) if (mdp3_get_cont_spash_en()) { mdp3_session->clk_on = 1; mdp3_ctrl_notifier_register(mdp3_session, &mdp3_session->mfd->mdp_sync_pt_data.notifier); } if (splash_mismatch) { pr_err("splash memory mismatch, stop splash\n"); Loading drivers/video/msm/mdss/mdp3_ctrl.h +2 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ struct mdp3_session_data { struct mdp3_buffer_queue bufq_in; struct mdp3_buffer_queue bufq_out; struct work_struct clk_off_work; struct work_struct dma_done_work; int histo_status; struct mutex histo_lock; int lut_sel; Loading @@ -56,6 +57,7 @@ struct mdp3_session_data { bool vsync_before_commit; bool first_commit; int clk_on; struct blocking_notifier_head notifier_head; int vsync_enabled; atomic_t vsync_countdown; /* Used to count down */ Loading drivers/video/msm/mdss/mdp3_dma.c +40 −7 Original line number Diff line number Diff line Loading @@ -27,7 +27,7 @@ static void mdp3_vsync_intr_handler(int type, void *arg) { struct mdp3_dma *dma = (struct mdp3_dma *)arg; struct mdp3_vsync_notification vsync_client; struct mdp3_notification vsync_client; unsigned int wait_for_next_vs; pr_debug("mdp3_vsync_intr_handler\n"); Loading @@ -49,10 +49,16 @@ static void mdp3_vsync_intr_handler(int type, void *arg) static void mdp3_dma_done_intr_handler(int type, void *arg) { struct mdp3_dma *dma = (struct mdp3_dma *)arg; struct mdp3_notification dma_client; pr_debug("mdp3_dma_done_intr_handler\n"); spin_lock(&dma->dma_lock); dma_client = dma->dma_notifier_client; complete(&dma->dma_comp); spin_unlock(&dma->dma_lock); mdp3_irq_disable_nosync(type); if (dma_client.handler) dma_client.handler(dma_client.arg); } static void mdp3_hist_done_intr_handler(int type, void *arg) Loading Loading @@ -195,7 +201,7 @@ static int mdp3_dma_callback_setup(struct mdp3_dma *dma) } static void mdp3_dma_vsync_enable(struct mdp3_dma *dma, struct mdp3_vsync_notification *vsync_client) struct mdp3_notification *vsync_client) { unsigned long flag; int updated = 0; Loading Loading @@ -226,6 +232,21 @@ static void mdp3_dma_vsync_enable(struct mdp3_dma *dma, } } static void mdp3_dma_done_notifier(struct mdp3_dma *dma, struct mdp3_notification *dma_client) { unsigned long flag; spin_lock_irqsave(&dma->dma_lock, flag); if (dma_client) { dma->dma_notifier_client = *dma_client; } else { dma->dma_notifier_client.handler = NULL; dma->dma_notifier_client.arg = NULL; } spin_unlock_irqrestore(&dma->dma_lock, flag); } static void mdp3_dma_clk_auto_gating(struct mdp3_dma *dma, int enable) { u32 cgc; Loading Loading @@ -552,13 +573,20 @@ static int mdp3_dmap_update(struct mdp3_dma *dma, void *buf, { unsigned long flag; int cb_type = MDP3_DMA_CALLBACK_TYPE_VSYNC; int rc = 0; pr_debug("mdp3_dmap_update\n"); if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_CMD) { cb_type = MDP3_DMA_CALLBACK_TYPE_DMA_DONE; if (intf->active) wait_for_completion_killable(&dma->dma_comp); if (intf->active) { rc = wait_for_completion_timeout(&dma->dma_comp, KOFF_TIMEOUT); if (rc <= 0) { WARN(1, "cmd kickoff timed out (%d)\n", rc); rc = -1; } } } spin_lock_irqsave(&dma->dma_lock, flag); MDP3_REG_WRITE(MDP3_REG_DMA_P_IBUF_ADDR, (u32)buf); Loading @@ -581,10 +609,14 @@ static int mdp3_dmap_update(struct mdp3_dma *dma, void *buf, mdp3_dma_callback_enable(dma, cb_type); pr_debug("mdp3_dmap_update wait for vsync_comp in\n"); if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_VIDEO) wait_for_completion_killable(&dma->vsync_comp); if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_VIDEO) { rc = wait_for_completion_timeout(&dma->vsync_comp, KOFF_TIMEOUT); if (rc <= 0) rc = -1; } pr_debug("mdp3_dmap_update wait for vsync_comp out\n"); return 0; return rc; } static int mdp3_dmas_update(struct mdp3_dma *dma, void *buf, Loading Loading @@ -878,6 +910,7 @@ int mdp3_dma_init(struct mdp3_dma *dma) dma->get_histo = mdp3_dmap_histo_get; dma->histo_op = mdp3_dmap_histo_op; dma->vsync_enable = mdp3_dma_vsync_enable; dma->dma_done_notifier = mdp3_dma_done_notifier; dma->start = mdp3_dma_start; dma->stop = mdp3_dma_stop; dma->config_stride = mdp3_dma_stride_config; Loading drivers/video/msm/mdss/mdp3_dma.h +8 −3 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ #ifndef MDP3_DMA_H #define MDP3_DMA_H #include <linux/notifier.h> #include <linux/sched.h> #define MDP_HISTOGRAM_BL_SCALE_MAX 1024 Loading Loading @@ -227,7 +228,7 @@ struct mdp3_dma_histogram_data { u32 extra[2]; }; struct mdp3_vsync_notification { struct mdp3_notification { void (*handler)(void *arg); void *arg; }; Loading @@ -245,7 +246,8 @@ struct mdp3_dma { struct completion vsync_comp; struct completion dma_comp; struct completion histo_comp; struct mdp3_vsync_notification vsync_client; struct mdp3_notification vsync_client; struct mdp3_notification dma_notifier_client; struct mdp3_dma_output_config output_config; struct mdp3_dma_source source_config; Loading Loading @@ -291,7 +293,10 @@ struct mdp3_dma { void (*config_stride)(struct mdp3_dma *dma, int stride); void (*vsync_enable)(struct mdp3_dma *dma, struct mdp3_vsync_notification *vsync_client); struct mdp3_notification *vsync_client); void (*dma_done_notifier)(struct mdp3_dma *dma, struct mdp3_notification *dma_client); }; struct mdp3_video_intf_cfg { Loading Loading
drivers/video/msm/mdss/mdp3.h +1 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include "mdss_fb.h" #define MDP_VSYNC_CLK_RATE 19200000 #define KOFF_TIMEOUT msecs_to_jiffies(84) enum { MDP3_CLK_AHB, Loading
drivers/video/msm/mdss/mdp3_ctrl.c +89 −8 Original line number Diff line number Diff line Loading @@ -91,6 +91,36 @@ static int mdp3_bufq_count(struct mdp3_buffer_queue *bufq) return bufq->count; } void mdp3_ctrl_notifier_register(struct mdp3_session_data *ses, struct notifier_block *notifier) { blocking_notifier_chain_register(&ses->notifier_head, notifier); } void mdp3_ctrl_notifier_unregister(struct mdp3_session_data *ses, struct notifier_block *notifier) { blocking_notifier_chain_unregister(&ses->notifier_head, notifier); } int mdp3_ctrl_notify(struct mdp3_session_data *ses, int event) { return blocking_notifier_call_chain(&ses->notifier_head, event, ses); } static void mdp3_dispatch_dma_done(struct work_struct *work) { struct mdp3_session_data *session; pr_debug("%s\n", __func__); session = container_of(work, struct mdp3_session_data, dma_done_work); if (!session) return; mdp3_ctrl_notify(session, MDP_NOTIFY_FRAME_DONE); } static void mdp3_dispatch_clk_off(struct work_struct *work) { struct mdp3_session_data *session; Loading Loading @@ -121,6 +151,12 @@ void vsync_notify_handler(void *arg) sysfs_notify_dirent(session->vsync_event_sd); } void dma_done_notify_handler(void *arg) { struct mdp3_session_data *session = (struct mdp3_session_data *)arg; schedule_work(&session->dma_done_work); } void vsync_count_down(void *arg) { struct mdp3_session_data *session = (struct mdp3_session_data *)arg; Loading @@ -140,8 +176,8 @@ void mdp3_ctrl_reset_countdown(struct mdp3_session_data *session, static int mdp3_ctrl_vsync_enable(struct msm_fb_data_type *mfd, int enable) { struct mdp3_session_data *mdp3_session; struct mdp3_vsync_notification vsync_client; struct mdp3_vsync_notification *arg = NULL; struct mdp3_notification vsync_client; struct mdp3_notification *arg = NULL; pr_debug("mdp3_ctrl_vsync_enable =%d\n", enable); mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1; Loading Loading @@ -464,6 +500,7 @@ static int mdp3_ctrl_dma_init(struct msm_fb_data_type *mfd, int frame_rate = mfd->panel_info->mipi.frame_rate; int vbp, vfp, vspw; int vtotal, vporch; struct mdp3_notification dma_done_callback; vbp = panel_info->lcdc.v_back_porch; vfp = panel_info->lcdc.v_front_porch; Loading Loading @@ -499,6 +536,13 @@ static int mdp3_ctrl_dma_init(struct msm_fb_data_type *mfd, rc = dma->dma_config(dma, &sourceConfig, &outputConfig); else rc = -EINVAL; if (outputConfig.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_CMD) { dma_done_callback.handler = dma_done_notify_handler; dma_done_callback.arg = mfd->mdp.private1; dma->dma_done_notifier(dma, &dma_done_callback); } return rc; } Loading Loading @@ -527,6 +571,8 @@ static int mdp3_ctrl_on(struct msm_fb_data_type *mfd) } mdp3_batfet_ctrl(true); mdp3_ctrl_notifier_register(mdp3_session, &mdp3_session->mfd->mdp_sync_pt_data.notifier); rc = mdp3_iommu_enable(MDP3_CLIENT_DMA_P); if (rc) { Loading Loading @@ -658,6 +704,8 @@ static int mdp3_ctrl_off(struct msm_fb_data_type *mfd) 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); Loading @@ -677,7 +725,7 @@ static int mdp3_ctrl_reset_cmd(struct msm_fb_data_type *mfd) struct mdp3_session_data *mdp3_session; struct mdp3_dma *mdp3_dma; struct mdss_panel_data *panel; struct mdp3_vsync_notification vsync_client; struct mdp3_notification vsync_client; pr_debug("mdp3_ctrl_reset_cmd\n"); mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1; Loading Loading @@ -728,7 +776,7 @@ static int mdp3_ctrl_reset(struct msm_fb_data_type *mfd) struct mdp3_session_data *mdp3_session; struct mdp3_dma *mdp3_dma; struct mdss_panel_data *panel; struct mdp3_vsync_notification vsync_client; struct mdp3_notification vsync_client; pr_debug("mdp3_ctrl_reset\n"); mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1; Loading Loading @@ -971,13 +1019,27 @@ static int mdp3_ctrl_display_commit_kickoff(struct msm_fb_data_type *mfd, return -EPERM; } mdp3_ctrl_notify(mdp3_session, MDP_NOTIFY_FRAME_BEGIN); data = mdp3_bufq_pop(&mdp3_session->bufq_in); if (data) { mdp3_ctrl_reset_countdown(mdp3_session, mfd); mdp3_ctrl_clk_enable(mfd, 1); mdp3_session->dma->update(mdp3_session->dma, rc = mdp3_session->dma->update(mdp3_session->dma, (void *)(int)data->addr, mdp3_session->intf); /* This is for the previous frame */ if (rc < 0) { mdp3_ctrl_notify(mdp3_session, MDP_NOTIFY_FRAME_TIMEOUT); } else { if (mdp3_ctrl_get_intf_type(mfd) == MDP3_DMA_OUTPUT_SEL_DSI_VIDEO) { mdp3_ctrl_notify(mdp3_session, MDP_NOTIFY_FRAME_DONE); } } mdp3_ctrl_notify(mdp3_session, MDP_NOTIFY_FRAME_FLUSHED); mdp3_bufq_push(&mdp3_session->bufq_out, data); } Loading @@ -1001,7 +1063,7 @@ static int mdp3_ctrl_display_commit_kickoff(struct msm_fb_data_type *mfd, mdss_fb_update_notify_update(mfd); return rc; return 0; } static void mdp3_ctrl_pan_display(struct msm_fb_data_type *mfd) Loading @@ -1011,6 +1073,7 @@ static void mdp3_ctrl_pan_display(struct msm_fb_data_type *mfd) u32 offset; int bpp; struct mdss_panel_info *panel_info; int rc; pr_debug("mdp3_ctrl_pan_display\n"); if (!mfd || !mfd->mdp.private1) Loading Loading @@ -1049,10 +1112,23 @@ static void mdp3_ctrl_pan_display(struct msm_fb_data_type *mfd) if (mfd->fbi->screen_base) { mdp3_ctrl_reset_countdown(mdp3_session, mfd); mdp3_ctrl_notify(mdp3_session, MDP_NOTIFY_FRAME_BEGIN); mdp3_ctrl_clk_enable(mfd, 1); mdp3_session->dma->update(mdp3_session->dma, rc = mdp3_session->dma->update(mdp3_session->dma, (void *)(int)(mfd->iova + offset), mdp3_session->intf); /* This is for the previous frame */ if (rc < 0) { mdp3_ctrl_notify(mdp3_session, MDP_NOTIFY_FRAME_TIMEOUT); } else { if (mdp3_ctrl_get_intf_type(mfd) == MDP3_DMA_OUTPUT_SEL_DSI_VIDEO) { mdp3_ctrl_notify(mdp3_session, MDP_NOTIFY_FRAME_DONE); } } mdp3_ctrl_notify(mdp3_session, MDP_NOTIFY_FRAME_FLUSHED); } else { pr_debug("mdp3_ctrl_pan_display no memory, stop interface"); mdp3_clk_enable(1, 0); Loading Loading @@ -1683,6 +1759,7 @@ int mdp3_ctrl_init(struct msm_fb_data_type *mfd) memset(mdp3_session, 0, sizeof(struct mdp3_session_data)); mutex_init(&mdp3_session->lock); INIT_WORK(&mdp3_session->clk_off_work, mdp3_dispatch_clk_off); INIT_WORK(&mdp3_session->dma_done_work, mdp3_dispatch_dma_done); atomic_set(&mdp3_session->vsync_countdown, 0); mutex_init(&mdp3_session->histo_lock); mdp3_session->dma = mdp3_get_dma_pipe(MDP3_DMA_CAP_ALL); Loading Loading @@ -1718,6 +1795,7 @@ int mdp3_ctrl_init(struct msm_fb_data_type *mfd) mdp3_bufq_init(&mdp3_session->bufq_out); mdp3_session->histo_status = 0; mdp3_session->lut_sel = 0; BLOCKING_INIT_NOTIFIER_HEAD(&mdp3_session->notifier_head); init_timer(&mdp3_session->vsync_timer); mdp3_session->vsync_timer.function = mdp3_vsync_timer_func; Loading Loading @@ -1746,8 +1824,11 @@ int mdp3_ctrl_init(struct msm_fb_data_type *mfd) kobject_uevent(&dev->kobj, KOBJ_ADD); pr_debug("vsync kobject_uevent(KOBJ_ADD)\n"); if (mdp3_get_cont_spash_en()) if (mdp3_get_cont_spash_en()) { mdp3_session->clk_on = 1; mdp3_ctrl_notifier_register(mdp3_session, &mdp3_session->mfd->mdp_sync_pt_data.notifier); } if (splash_mismatch) { pr_err("splash memory mismatch, stop splash\n"); Loading
drivers/video/msm/mdss/mdp3_ctrl.h +2 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ struct mdp3_session_data { struct mdp3_buffer_queue bufq_in; struct mdp3_buffer_queue bufq_out; struct work_struct clk_off_work; struct work_struct dma_done_work; int histo_status; struct mutex histo_lock; int lut_sel; Loading @@ -56,6 +57,7 @@ struct mdp3_session_data { bool vsync_before_commit; bool first_commit; int clk_on; struct blocking_notifier_head notifier_head; int vsync_enabled; atomic_t vsync_countdown; /* Used to count down */ Loading
drivers/video/msm/mdss/mdp3_dma.c +40 −7 Original line number Diff line number Diff line Loading @@ -27,7 +27,7 @@ static void mdp3_vsync_intr_handler(int type, void *arg) { struct mdp3_dma *dma = (struct mdp3_dma *)arg; struct mdp3_vsync_notification vsync_client; struct mdp3_notification vsync_client; unsigned int wait_for_next_vs; pr_debug("mdp3_vsync_intr_handler\n"); Loading @@ -49,10 +49,16 @@ static void mdp3_vsync_intr_handler(int type, void *arg) static void mdp3_dma_done_intr_handler(int type, void *arg) { struct mdp3_dma *dma = (struct mdp3_dma *)arg; struct mdp3_notification dma_client; pr_debug("mdp3_dma_done_intr_handler\n"); spin_lock(&dma->dma_lock); dma_client = dma->dma_notifier_client; complete(&dma->dma_comp); spin_unlock(&dma->dma_lock); mdp3_irq_disable_nosync(type); if (dma_client.handler) dma_client.handler(dma_client.arg); } static void mdp3_hist_done_intr_handler(int type, void *arg) Loading Loading @@ -195,7 +201,7 @@ static int mdp3_dma_callback_setup(struct mdp3_dma *dma) } static void mdp3_dma_vsync_enable(struct mdp3_dma *dma, struct mdp3_vsync_notification *vsync_client) struct mdp3_notification *vsync_client) { unsigned long flag; int updated = 0; Loading Loading @@ -226,6 +232,21 @@ static void mdp3_dma_vsync_enable(struct mdp3_dma *dma, } } static void mdp3_dma_done_notifier(struct mdp3_dma *dma, struct mdp3_notification *dma_client) { unsigned long flag; spin_lock_irqsave(&dma->dma_lock, flag); if (dma_client) { dma->dma_notifier_client = *dma_client; } else { dma->dma_notifier_client.handler = NULL; dma->dma_notifier_client.arg = NULL; } spin_unlock_irqrestore(&dma->dma_lock, flag); } static void mdp3_dma_clk_auto_gating(struct mdp3_dma *dma, int enable) { u32 cgc; Loading Loading @@ -552,13 +573,20 @@ static int mdp3_dmap_update(struct mdp3_dma *dma, void *buf, { unsigned long flag; int cb_type = MDP3_DMA_CALLBACK_TYPE_VSYNC; int rc = 0; pr_debug("mdp3_dmap_update\n"); if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_CMD) { cb_type = MDP3_DMA_CALLBACK_TYPE_DMA_DONE; if (intf->active) wait_for_completion_killable(&dma->dma_comp); if (intf->active) { rc = wait_for_completion_timeout(&dma->dma_comp, KOFF_TIMEOUT); if (rc <= 0) { WARN(1, "cmd kickoff timed out (%d)\n", rc); rc = -1; } } } spin_lock_irqsave(&dma->dma_lock, flag); MDP3_REG_WRITE(MDP3_REG_DMA_P_IBUF_ADDR, (u32)buf); Loading @@ -581,10 +609,14 @@ static int mdp3_dmap_update(struct mdp3_dma *dma, void *buf, mdp3_dma_callback_enable(dma, cb_type); pr_debug("mdp3_dmap_update wait for vsync_comp in\n"); if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_VIDEO) wait_for_completion_killable(&dma->vsync_comp); if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_VIDEO) { rc = wait_for_completion_timeout(&dma->vsync_comp, KOFF_TIMEOUT); if (rc <= 0) rc = -1; } pr_debug("mdp3_dmap_update wait for vsync_comp out\n"); return 0; return rc; } static int mdp3_dmas_update(struct mdp3_dma *dma, void *buf, Loading Loading @@ -878,6 +910,7 @@ int mdp3_dma_init(struct mdp3_dma *dma) dma->get_histo = mdp3_dmap_histo_get; dma->histo_op = mdp3_dmap_histo_op; dma->vsync_enable = mdp3_dma_vsync_enable; dma->dma_done_notifier = mdp3_dma_done_notifier; dma->start = mdp3_dma_start; dma->stop = mdp3_dma_stop; dma->config_stride = mdp3_dma_stride_config; Loading
drivers/video/msm/mdss/mdp3_dma.h +8 −3 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ #ifndef MDP3_DMA_H #define MDP3_DMA_H #include <linux/notifier.h> #include <linux/sched.h> #define MDP_HISTOGRAM_BL_SCALE_MAX 1024 Loading Loading @@ -227,7 +228,7 @@ struct mdp3_dma_histogram_data { u32 extra[2]; }; struct mdp3_vsync_notification { struct mdp3_notification { void (*handler)(void *arg); void *arg; }; Loading @@ -245,7 +246,8 @@ struct mdp3_dma { struct completion vsync_comp; struct completion dma_comp; struct completion histo_comp; struct mdp3_vsync_notification vsync_client; struct mdp3_notification vsync_client; struct mdp3_notification dma_notifier_client; struct mdp3_dma_output_config output_config; struct mdp3_dma_source source_config; Loading Loading @@ -291,7 +293,10 @@ struct mdp3_dma { void (*config_stride)(struct mdp3_dma *dma, int stride); void (*vsync_enable)(struct mdp3_dma *dma, struct mdp3_vsync_notification *vsync_client); struct mdp3_notification *vsync_client); void (*dma_done_notifier)(struct mdp3_dma *dma, struct mdp3_notification *dma_client); }; struct mdp3_video_intf_cfg { Loading