Loading drivers/video/msm/mdss/mdp3.c +49 −10 Original line number Diff line number Diff line Loading @@ -159,7 +159,6 @@ static irqreturn_t mdp3_irq_handler(int irq, void *ptr) spin_unlock(&mdata->irq_lock); return IRQ_HANDLED; } mdp_status = MDP3_REG_READ(MDP3_REG_INTR_STATUS); mdp_interrupt = mdp_status; pr_debug("mdp3_irq_handler irq=%d\n", mdp_interrupt); Loading Loading @@ -1072,6 +1071,17 @@ u64 mdp3_get_panic_lut_cfg(u32 panel_width) return panic_config; } int mdp3_enable_panic_ctrl(void) { int rc = 0; if (MDP3_REG_READ(MDP3_PANIC_ROBUST_CTRL) == 0) { pr_err("%s: Enable Panic Control\n", __func__); MDP3_REG_WRITE(MDP3_PANIC_ROBUST_CTRL, BIT(0)); } return rc; } int mdp3_qos_remapper_setup(struct mdss_panel_data *panel) { int rc = 0; Loading Loading @@ -2196,9 +2206,10 @@ static int mdp3_is_display_on(struct mdss_panel_data *pdata) mdp3_res->splash_mem_addr = MDP3_REG_READ(MDP3_REG_DMA_P_IBUF_ADDR); rc = mdp3_clk_enable(0, 0); if (rc) if (pdata->panel_info.type == MIPI_CMD_PANEL) { if (mdp3_clk_enable(0, 0)) pr_err("fail to turn off MDP core clks\n"); } return rc; } Loading Loading @@ -2293,10 +2304,30 @@ static int mdp3_panel_register_done(struct mdss_panel_data *pdata) return rc; } /* mdp3_clear_irq() - Clear interrupt * @ interrupt_mask : interrupt mask * * This function clear sync irq for command mode panel. * When system is entering in idle screen state. */ void mdp3_clear_irq(u32 interrupt_mask) { unsigned long flag; u32 irq_status = 0; spin_lock_irqsave(&mdp3_res->irq_lock, flag); irq_status = interrupt_mask & MDP3_REG_READ(MDP3_REG_INTR_STATUS); if (irq_status) MDP3_REG_WRITE(MDP3_REG_INTR_CLEAR, irq_status); spin_unlock_irqrestore(&mdp3_res->irq_lock, flag); } /* mdp3_autorefresh_disable() - Disable Auto refresh * @ panel_info : pointer to panel configuration structure * * This function displable Auto refresh block for command mode panel. * This function disable Auto refresh block for command mode panel. */ int mdp3_autorefresh_disable(struct mdss_panel_info *panel_info) { Loading Loading @@ -2598,10 +2629,12 @@ int mdp3_footswitch_ctrl(int enable) int rc = 0; int active_cnt = 0; mutex_lock(&mdp3_res->fs_idle_pc_lock); if (!mdp3_res->fs_ena && enable) { rc = regulator_enable(mdp3_res->fs); if (rc) { pr_err("mdp footswitch ctrl enable failed\n"); mutex_unlock(&mdp3_res->fs_idle_pc_lock); return -EINVAL; } pr_debug("mdp footswitch ctrl enable success\n"); Loading @@ -2622,13 +2655,16 @@ int mdp3_footswitch_ctrl(int enable) rc = regulator_disable(mdp3_res->fs); if (rc) { pr_err("mdp footswitch ctrl disable failed\n"); mutex_unlock(&mdp3_res->fs_idle_pc_lock); return -EINVAL; } mdp3_res->fs_ena = false; pr_debug("mdp3 footswitch ctrl disable configured\n"); } else { pr_debug("mdp3 footswitch ctrl already configured\n"); } mutex_unlock(&mdp3_res->fs_idle_pc_lock); return rc; } Loading @@ -2649,9 +2685,11 @@ int mdp3_panel_get_intf_status(u32 disp_num, u32 intf_type) /* DSI video mode or command mode */ rc = (status == 0x180000) || (status == 0x080000); rc = mdp3_clk_enable(0, 0); if (rc) /* For Video mode panel do not disable clock */ if (status == 0x80000) { if (mdp3_clk_enable(0, 0)) pr_err("fail to turn off MDP core clks\n"); } return rc; } Loading Loading @@ -2690,6 +2728,7 @@ static int mdp3_probe(struct platform_device *pdev) pdev->id = 0; mdp3_res->pdev = pdev; mutex_init(&mdp3_res->res_mutex); mutex_init(&mdp3_res->fs_idle_pc_lock); spin_lock_init(&mdp3_res->irq_lock); platform_set_drvdata(pdev, mdp3_res); atomic_set(&mdp3_res->active_intf_cnt, 0); Loading drivers/video/msm/mdss/mdp3.h +3 −1 Original line number Diff line number Diff line Loading @@ -169,6 +169,7 @@ struct mdp3_hw_resource { bool allow_iommu_update; struct ion_handle *ion_handle; struct mutex iommu_lock; struct mutex fs_idle_pc_lock; struct mdp3_dma dma[MDP3_DMA_MAX]; struct mdp3_intf intf[MDP3_DMA_OUTPUT_SEL_MAX]; Loading Loading @@ -265,7 +266,8 @@ u64 mdp3_clk_round_off(u64 clk_rate); void mdp3_calc_dma_res(struct mdss_panel_info *panel_info, u64 *clk_rate, u64 *ab, u64 *ib, uint32_t bpp); void mdp3_clear_irq(u32 interrupt_mask); int mdp3_enable_panic_ctrl(void); #define MDP3_REG_WRITE(addr, val) writel_relaxed(val, mdp3_res->mdp_base + addr) #define MDP3_REG_READ(addr) readl_relaxed(mdp3_res->mdp_base + addr) Loading drivers/video/msm/mdss/mdp3_ctrl.c +83 −23 Original line number Diff line number Diff line Loading @@ -172,9 +172,9 @@ static void mdp3_dispatch_clk_off(struct work_struct *work) mutex_lock(&session->lock); if (session->vsync_enabled || atomic_read(&session->vsync_countdown) != 0) { atomic_read(&session->vsync_countdown) > 0) { mutex_unlock(&session->lock); pr_debug("Ignoring clk shut down\n"); pr_debug("%s: Ignoring clk shut down\n", __func__); return; } Loading @@ -201,7 +201,6 @@ retry_dma_done: } } } mdp3_ctrl_vsync_enable(session->mfd, 0); mdp3_ctrl_clk_enable(session->mfd, 0); mutex_unlock(&session->lock); Loading @@ -226,6 +225,7 @@ void vsync_count_down(void *arg) { struct mdp3_session_data *session = (struct mdp3_session_data *)arg; /* We are counting down to turn off clocks */ if (atomic_read(&session->vsync_countdown) > 0) atomic_dec(&session->vsync_countdown); if (atomic_read(&session->vsync_countdown) == 0) schedule_work(&session->clk_off_work); Loading @@ -243,6 +243,7 @@ static int mdp3_ctrl_vsync_enable(struct msm_fb_data_type *mfd, int enable) struct mdp3_session_data *mdp3_session; struct mdp3_notification vsync_client; struct mdp3_notification *arg = NULL; bool mod_vsync_timer = false; pr_debug("mdp3_ctrl_vsync_enable =%d\n", enable); mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1; Loading @@ -258,7 +259,7 @@ static int mdp3_ctrl_vsync_enable(struct msm_fb_data_type *mfd, int enable) vsync_client.handler = vsync_notify_handler; vsync_client.arg = mdp3_session; arg = &vsync_client; } else if (atomic_read(&mdp3_session->vsync_countdown)) { } else if (atomic_read(&mdp3_session->vsync_countdown) > 0) { /* * Now that vsync is no longer needed we will * shutdown dsi clocks as soon as cnt down == 0 Loading @@ -270,6 +271,18 @@ static int mdp3_ctrl_vsync_enable(struct msm_fb_data_type *mfd, int enable) enable = 1; } if (enable) { if (mdp3_session->status == 1 && (mdp3_session->vsync_before_commit || !mdp3_session->intf->active)) { mod_vsync_timer = true; } else if (!mdp3_session->clk_on) { /* Enable clocks before enabling the vsync interrupt */ mdp3_ctrl_reset_countdown(mdp3_session, mfd); mdp3_ctrl_clk_enable(mfd, 1); } } mdp3_clk_enable(1, 0); mdp3_session->dma->vsync_enable(mdp3_session->dma, arg); mdp3_clk_enable(0, 0); Loading @@ -278,14 +291,9 @@ static int mdp3_ctrl_vsync_enable(struct msm_fb_data_type *mfd, int enable) * Need to fake vsync whenever dsi interface is not * active or when dsi clocks are currently off */ if (enable && mdp3_session->status == 1 && (mdp3_session->vsync_before_commit || !mdp3_session->intf->active)) { if (mod_vsync_timer) { mod_timer(&mdp3_session->vsync_timer, jiffies + msecs_to_jiffies(mdp3_session->vsync_period)); } else if (enable && !mdp3_session->clk_on) { mdp3_ctrl_reset_countdown(mdp3_session, mfd); mdp3_ctrl_clk_enable(mfd, 1); } else if (!enable) { del_timer(&mdp3_session->vsync_timer); } Loading Loading @@ -750,8 +758,6 @@ static int mdp3_ctrl_on(struct msm_fb_data_type *mfd) mutex_lock(&mdp3_session->lock); panel = mdp3_session->panel; pr_err("%s %d in_splash_screen %d\n", __func__, __LINE__, mdp3_session->in_splash_screen); /* make sure DSI host is initialized properly */ if (panel) { pr_debug("%s : dsi host init, power state = %d Splash %d\n", Loading @@ -760,7 +766,6 @@ static int mdp3_ctrl_on(struct msm_fb_data_type *mfd) if (mdss_fb_is_power_on_lp(mfd) || mdp3_session->in_splash_screen) { /* Turn on panel so that it can exit low power mode */ pr_err("%s %d\n", __func__, __LINE__); mdp3_clk_enable(1, 0); rc = panel->event_handler(panel, MDSS_EVENT_LINK_READY, NULL); Loading @@ -768,12 +773,14 @@ static int mdp3_ctrl_on(struct msm_fb_data_type *mfd) MDSS_EVENT_UNBLANK, NULL); rc |= panel->event_handler(panel, MDSS_EVENT_PANEL_ON, NULL); if (mdss_fb_is_power_on_ulp(mfd)) rc |= mdp3_enable_panic_ctrl(); mdp3_clk_enable(0, 0); } } if (mdp3_session->status) { pr_err("fb%d is on already\n", mfd->index); pr_debug("fb%d is on already\n", mfd->index); goto end; } Loading Loading @@ -1011,6 +1018,32 @@ static int mdp3_ctrl_off(struct msm_fb_data_type *mfd) mdp3_bufq_deinit(&mdp3_session->bufq_in); } } if (mdss_fb_is_power_on_ulp(mfd) && (mfd->panel.type == MIPI_CMD_PANEL)) { pr_debug("%s: Disable MDP3 clocks in ULP\n", __func__); if (!mdp3_session->clk_on) mdp3_ctrl_clk_enable(mfd, 1); /* * STOP DMA transfer first and signal vsync notification * Before releasing the resource in ULP state. */ rc = mdp3_session->dma->stop(mdp3_session->dma, mdp3_session->intf); if (rc) pr_warn("fail to stop the MDP3 dma in ULP\n"); /* Wait to ensure TG to turn off */ msleep(20); /* * Handle ULP request initiated from fb_pm_suspend. * For ULP panel power state disabling vsync and set * vsync_count to zero and Turn off MDP3 clocks */ atomic_set(&mdp3_session->vsync_countdown, 0); mdp3_session->vsync_enabled = 0; mdp3_ctrl_vsync_enable(mdp3_session->mfd, 0); mdp3_ctrl_clk_enable(mdp3_session->mfd, 0); } off_error: mutex_unlock(&mdp3_session->lock); /* Release the last reference to the runtime device */ Loading Loading @@ -1038,7 +1071,10 @@ static int mdp3_ctrl_reset(struct msm_fb_data_type *mfd) panel = mdp3_session->panel; mdp3_dma = mdp3_session->dma; mutex_lock(&mdp3_session->lock); if (mdp3_res->idle_pc) { pr_debug("mdp3_ctrl_reset idle_pc %s FS_EN %s\n", mdp3_res->idle_pc ? "True":"False", mdp3_res->fs_ena ? "True":"False"); if (mdp3_res->idle_pc || mdp3_res->fs_ena) { mdp3_clk_enable(1, 0); mdp3_dynamic_clock_gating_ctrl(0); mdp3_qos_remapper_setup(panel); Loading @@ -1047,7 +1083,7 @@ static int mdp3_ctrl_reset(struct msm_fb_data_type *mfd) rc = mdp3_iommu_enable(MDP3_CLIENT_DMA_P); if (rc) { pr_err("fail to attach dma iommu\n"); if (mdp3_res->idle_pc) if (mdp3_res->idle_pc || mdp3_res->fs_ena) mdp3_clk_enable(0, 0); goto reset_error; } Loading Loading @@ -1166,16 +1202,26 @@ static int mdp3_overlay_queue_buffer(struct msm_fb_data_type *mfd, struct msmfb_overlay_data *req) { int rc; bool is_panel_type_cmd = false; struct mdp3_session_data *mdp3_session = mfd->mdp.private1; struct msmfb_data *img = &req->data; struct mdp3_img_data data; struct mdp3_dma *dma = mdp3_session->dma; memset(&data, 0, sizeof(struct mdp3_img_data)); if (mfd->panel.type == MIPI_CMD_PANEL) is_panel_type_cmd = true; if (is_panel_type_cmd) { rc = mdp3_iommu_enable(MDP3_CLIENT_DMA_P); if (rc) { pr_err("fail to enable iommu\n"); return rc; } } rc = mdp3_get_img(img, &data, MDP3_CLIENT_DMA_P); if (rc) { pr_err("fail to get overlay buffer\n"); return rc; goto err; } if (data.len < dma->source_config.stride * dma->source_config.height) { Loading @@ -1183,16 +1229,20 @@ static int mdp3_overlay_queue_buffer(struct msm_fb_data_type *mfd, data.len, (dma->source_config.stride * dma->source_config.height)); mdp3_put_img(&data, MDP3_CLIENT_DMA_P); return -EINVAL; rc = -EINVAL; goto err; } rc = mdp3_bufq_push(&mdp3_session->bufq_in, &data); if (rc) { pr_err("fail to queue the overlay buffer, buffer drop\n"); mdp3_put_img(&data, MDP3_CLIENT_DMA_P); return rc; goto err; } return 0; rc = 0; err: if (is_panel_type_cmd) mdp3_iommu_disable(MDP3_CLIENT_DMA_P); return rc; } static int mdp3_overlay_play(struct msm_fb_data_type *mfd, Loading Loading @@ -1276,6 +1326,7 @@ static int mdp3_ctrl_display_commit_kickoff(struct msm_fb_data_type *mfd, } panel = mdp3_session->panel; mutex_lock(&mdp3_res->fs_idle_pc_lock); if (mdp3_session->in_splash_screen || mdp3_res->idle_pc) { pr_debug("%s: reset- in_splash = %d, idle_pc = %d", __func__, Loading @@ -1283,9 +1334,11 @@ static int mdp3_ctrl_display_commit_kickoff(struct msm_fb_data_type *mfd, rc = mdp3_ctrl_reset(mfd); if (rc) { pr_err("fail to reset display\n"); mutex_unlock(&mdp3_res->fs_idle_pc_lock); return -EINVAL; } } mutex_unlock(&mdp3_res->fs_idle_pc_lock); mutex_lock(&mdp3_session->lock); Loading Loading @@ -1418,6 +1471,7 @@ static void mdp3_ctrl_pan_display(struct msm_fb_data_type *mfd) if (!mdp3_session || !mdp3_session->dma) return; mutex_lock(&mdp3_res->fs_idle_pc_lock); if (mdp3_session->in_splash_screen || mdp3_res->idle_pc) { pr_debug("%s: reset- in_splash = %d, idle_pc = %d", __func__, Loading @@ -1425,9 +1479,11 @@ static void mdp3_ctrl_pan_display(struct msm_fb_data_type *mfd) rc = mdp3_ctrl_reset(mfd); if (rc) { pr_err("fail to reset display\n"); mutex_unlock(&mdp3_res->fs_idle_pc_lock); return; } } mutex_unlock(&mdp3_res->fs_idle_pc_lock); mutex_lock(&mdp3_session->lock); Loading Loading @@ -2493,17 +2549,21 @@ static int mdp3_ctrl_ioctl_handler(struct msm_fb_data_type *mfd, } break; case MSMFB_ASYNC_BLIT: mutex_lock(&mdp3_res->fs_idle_pc_lock); if (mdp3_session->in_splash_screen || mdp3_res->idle_pc) { pr_err("%s: reset- in_splash = %d, idle_pc = %d", pr_debug("%s: reset- in_splash = %d, idle_pc = %d", __func__, mdp3_session->in_splash_screen, mdp3_res->idle_pc); mdp3_ctrl_reset(mfd); } mutex_unlock(&mdp3_res->fs_idle_pc_lock); rc = mdp3_ctrl_async_blit_req(mfd, argp); break; case MSMFB_BLIT: mutex_lock(&mdp3_res->fs_idle_pc_lock); if (mdp3_session->in_splash_screen) mdp3_ctrl_reset(mfd); mutex_unlock(&mdp3_res->fs_idle_pc_lock); rc = mdp3_ctrl_blit_req(mfd, argp); break; case MSMFB_METADATA_GET: Loading drivers/video/msm/mdss/mdp3_dma.c +6 −1 Original line number Diff line number Diff line Loading @@ -153,6 +153,12 @@ void mdp3_dma_callback_disable(struct mdp3_dma *dma, int type) irq_bit = MDP3_INTR_SYNC_PRIMARY_LINE; irq_bit += dma->dma_sel; mdp3_irq_disable(irq_bit); /* * Clear read pointer interrupt before disabling clocks. * Else pending ISR handling will result in NOC error * since the clock will be disable after this point. */ mdp3_clear_irq(irq_bit); } if (type & MDP3_DMA_CALLBACK_TYPE_DMA_DONE) { Loading Loading @@ -721,7 +727,6 @@ retry_dma_done: retry_vsync: rc = wait_for_completion_timeout(&dma->vsync_comp, KOFF_TIMEOUT); pr_err("%s VID DMA Buff Addr %pK\n", __func__, buf); if (rc <= 0 && --retry_count) { int vsync = MDP3_REG_READ(MDP3_REG_INTR_STATUS) & (1 << MDP3_INTR_LCDC_START_OF_FRAME); Loading drivers/video/msm/mdss/mdp3_ppp.c +7 −3 Original line number Diff line number Diff line Loading @@ -530,6 +530,8 @@ int mdp3_calc_ppp_res(struct msm_fb_data_type *mfd, int i, lcount = 0; struct mdp_blit_req *req; struct bpp_info bpp; u64 old_solid_fill_pixel = 0; u64 new_solid_fill_pixel = 0; u64 src_read_bw = 0; u32 bg_read_bw = 0; u32 dst_write_bw = 0; Loading @@ -548,12 +550,14 @@ int mdp3_calc_ppp_res(struct msm_fb_data_type *mfd, if (lreq->req_list[0].flags & MDP_SOLID_FILL) { req = &(lreq->req_list[0]); mdp3_get_bpp_info(req->dst.format, &bpp); ppp_res.solid_fill_pixel += req->dst_rect.w * req->dst_rect.h; old_solid_fill_pixel = ppp_res.solid_fill_pixel; new_solid_fill_pixel = req->dst_rect.w * req->dst_rect.h; ppp_res.solid_fill_pixel += new_solid_fill_pixel; ppp_res.solid_fill_byte += req->dst_rect.w * req->dst_rect.h * bpp.bpp_num / bpp.bpp_den; if ((panel_info->yres/2 > req->dst_rect.h) || if ((old_solid_fill_pixel >= new_solid_fill_pixel) || (mdp3_res->solid_fill_vote_en)) { pr_debug("Solid fill less than H/2 or fill vote %d\n", pr_debug("Last fill pixels are higher or fill_en %d\n", mdp3_res->solid_fill_vote_en); ATRACE_END(__func__); return 0; Loading Loading
drivers/video/msm/mdss/mdp3.c +49 −10 Original line number Diff line number Diff line Loading @@ -159,7 +159,6 @@ static irqreturn_t mdp3_irq_handler(int irq, void *ptr) spin_unlock(&mdata->irq_lock); return IRQ_HANDLED; } mdp_status = MDP3_REG_READ(MDP3_REG_INTR_STATUS); mdp_interrupt = mdp_status; pr_debug("mdp3_irq_handler irq=%d\n", mdp_interrupt); Loading Loading @@ -1072,6 +1071,17 @@ u64 mdp3_get_panic_lut_cfg(u32 panel_width) return panic_config; } int mdp3_enable_panic_ctrl(void) { int rc = 0; if (MDP3_REG_READ(MDP3_PANIC_ROBUST_CTRL) == 0) { pr_err("%s: Enable Panic Control\n", __func__); MDP3_REG_WRITE(MDP3_PANIC_ROBUST_CTRL, BIT(0)); } return rc; } int mdp3_qos_remapper_setup(struct mdss_panel_data *panel) { int rc = 0; Loading Loading @@ -2196,9 +2206,10 @@ static int mdp3_is_display_on(struct mdss_panel_data *pdata) mdp3_res->splash_mem_addr = MDP3_REG_READ(MDP3_REG_DMA_P_IBUF_ADDR); rc = mdp3_clk_enable(0, 0); if (rc) if (pdata->panel_info.type == MIPI_CMD_PANEL) { if (mdp3_clk_enable(0, 0)) pr_err("fail to turn off MDP core clks\n"); } return rc; } Loading Loading @@ -2293,10 +2304,30 @@ static int mdp3_panel_register_done(struct mdss_panel_data *pdata) return rc; } /* mdp3_clear_irq() - Clear interrupt * @ interrupt_mask : interrupt mask * * This function clear sync irq for command mode panel. * When system is entering in idle screen state. */ void mdp3_clear_irq(u32 interrupt_mask) { unsigned long flag; u32 irq_status = 0; spin_lock_irqsave(&mdp3_res->irq_lock, flag); irq_status = interrupt_mask & MDP3_REG_READ(MDP3_REG_INTR_STATUS); if (irq_status) MDP3_REG_WRITE(MDP3_REG_INTR_CLEAR, irq_status); spin_unlock_irqrestore(&mdp3_res->irq_lock, flag); } /* mdp3_autorefresh_disable() - Disable Auto refresh * @ panel_info : pointer to panel configuration structure * * This function displable Auto refresh block for command mode panel. * This function disable Auto refresh block for command mode panel. */ int mdp3_autorefresh_disable(struct mdss_panel_info *panel_info) { Loading Loading @@ -2598,10 +2629,12 @@ int mdp3_footswitch_ctrl(int enable) int rc = 0; int active_cnt = 0; mutex_lock(&mdp3_res->fs_idle_pc_lock); if (!mdp3_res->fs_ena && enable) { rc = regulator_enable(mdp3_res->fs); if (rc) { pr_err("mdp footswitch ctrl enable failed\n"); mutex_unlock(&mdp3_res->fs_idle_pc_lock); return -EINVAL; } pr_debug("mdp footswitch ctrl enable success\n"); Loading @@ -2622,13 +2655,16 @@ int mdp3_footswitch_ctrl(int enable) rc = regulator_disable(mdp3_res->fs); if (rc) { pr_err("mdp footswitch ctrl disable failed\n"); mutex_unlock(&mdp3_res->fs_idle_pc_lock); return -EINVAL; } mdp3_res->fs_ena = false; pr_debug("mdp3 footswitch ctrl disable configured\n"); } else { pr_debug("mdp3 footswitch ctrl already configured\n"); } mutex_unlock(&mdp3_res->fs_idle_pc_lock); return rc; } Loading @@ -2649,9 +2685,11 @@ int mdp3_panel_get_intf_status(u32 disp_num, u32 intf_type) /* DSI video mode or command mode */ rc = (status == 0x180000) || (status == 0x080000); rc = mdp3_clk_enable(0, 0); if (rc) /* For Video mode panel do not disable clock */ if (status == 0x80000) { if (mdp3_clk_enable(0, 0)) pr_err("fail to turn off MDP core clks\n"); } return rc; } Loading Loading @@ -2690,6 +2728,7 @@ static int mdp3_probe(struct platform_device *pdev) pdev->id = 0; mdp3_res->pdev = pdev; mutex_init(&mdp3_res->res_mutex); mutex_init(&mdp3_res->fs_idle_pc_lock); spin_lock_init(&mdp3_res->irq_lock); platform_set_drvdata(pdev, mdp3_res); atomic_set(&mdp3_res->active_intf_cnt, 0); Loading
drivers/video/msm/mdss/mdp3.h +3 −1 Original line number Diff line number Diff line Loading @@ -169,6 +169,7 @@ struct mdp3_hw_resource { bool allow_iommu_update; struct ion_handle *ion_handle; struct mutex iommu_lock; struct mutex fs_idle_pc_lock; struct mdp3_dma dma[MDP3_DMA_MAX]; struct mdp3_intf intf[MDP3_DMA_OUTPUT_SEL_MAX]; Loading Loading @@ -265,7 +266,8 @@ u64 mdp3_clk_round_off(u64 clk_rate); void mdp3_calc_dma_res(struct mdss_panel_info *panel_info, u64 *clk_rate, u64 *ab, u64 *ib, uint32_t bpp); void mdp3_clear_irq(u32 interrupt_mask); int mdp3_enable_panic_ctrl(void); #define MDP3_REG_WRITE(addr, val) writel_relaxed(val, mdp3_res->mdp_base + addr) #define MDP3_REG_READ(addr) readl_relaxed(mdp3_res->mdp_base + addr) Loading
drivers/video/msm/mdss/mdp3_ctrl.c +83 −23 Original line number Diff line number Diff line Loading @@ -172,9 +172,9 @@ static void mdp3_dispatch_clk_off(struct work_struct *work) mutex_lock(&session->lock); if (session->vsync_enabled || atomic_read(&session->vsync_countdown) != 0) { atomic_read(&session->vsync_countdown) > 0) { mutex_unlock(&session->lock); pr_debug("Ignoring clk shut down\n"); pr_debug("%s: Ignoring clk shut down\n", __func__); return; } Loading @@ -201,7 +201,6 @@ retry_dma_done: } } } mdp3_ctrl_vsync_enable(session->mfd, 0); mdp3_ctrl_clk_enable(session->mfd, 0); mutex_unlock(&session->lock); Loading @@ -226,6 +225,7 @@ void vsync_count_down(void *arg) { struct mdp3_session_data *session = (struct mdp3_session_data *)arg; /* We are counting down to turn off clocks */ if (atomic_read(&session->vsync_countdown) > 0) atomic_dec(&session->vsync_countdown); if (atomic_read(&session->vsync_countdown) == 0) schedule_work(&session->clk_off_work); Loading @@ -243,6 +243,7 @@ static int mdp3_ctrl_vsync_enable(struct msm_fb_data_type *mfd, int enable) struct mdp3_session_data *mdp3_session; struct mdp3_notification vsync_client; struct mdp3_notification *arg = NULL; bool mod_vsync_timer = false; pr_debug("mdp3_ctrl_vsync_enable =%d\n", enable); mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1; Loading @@ -258,7 +259,7 @@ static int mdp3_ctrl_vsync_enable(struct msm_fb_data_type *mfd, int enable) vsync_client.handler = vsync_notify_handler; vsync_client.arg = mdp3_session; arg = &vsync_client; } else if (atomic_read(&mdp3_session->vsync_countdown)) { } else if (atomic_read(&mdp3_session->vsync_countdown) > 0) { /* * Now that vsync is no longer needed we will * shutdown dsi clocks as soon as cnt down == 0 Loading @@ -270,6 +271,18 @@ static int mdp3_ctrl_vsync_enable(struct msm_fb_data_type *mfd, int enable) enable = 1; } if (enable) { if (mdp3_session->status == 1 && (mdp3_session->vsync_before_commit || !mdp3_session->intf->active)) { mod_vsync_timer = true; } else if (!mdp3_session->clk_on) { /* Enable clocks before enabling the vsync interrupt */ mdp3_ctrl_reset_countdown(mdp3_session, mfd); mdp3_ctrl_clk_enable(mfd, 1); } } mdp3_clk_enable(1, 0); mdp3_session->dma->vsync_enable(mdp3_session->dma, arg); mdp3_clk_enable(0, 0); Loading @@ -278,14 +291,9 @@ static int mdp3_ctrl_vsync_enable(struct msm_fb_data_type *mfd, int enable) * Need to fake vsync whenever dsi interface is not * active or when dsi clocks are currently off */ if (enable && mdp3_session->status == 1 && (mdp3_session->vsync_before_commit || !mdp3_session->intf->active)) { if (mod_vsync_timer) { mod_timer(&mdp3_session->vsync_timer, jiffies + msecs_to_jiffies(mdp3_session->vsync_period)); } else if (enable && !mdp3_session->clk_on) { mdp3_ctrl_reset_countdown(mdp3_session, mfd); mdp3_ctrl_clk_enable(mfd, 1); } else if (!enable) { del_timer(&mdp3_session->vsync_timer); } Loading Loading @@ -750,8 +758,6 @@ static int mdp3_ctrl_on(struct msm_fb_data_type *mfd) mutex_lock(&mdp3_session->lock); panel = mdp3_session->panel; pr_err("%s %d in_splash_screen %d\n", __func__, __LINE__, mdp3_session->in_splash_screen); /* make sure DSI host is initialized properly */ if (panel) { pr_debug("%s : dsi host init, power state = %d Splash %d\n", Loading @@ -760,7 +766,6 @@ static int mdp3_ctrl_on(struct msm_fb_data_type *mfd) if (mdss_fb_is_power_on_lp(mfd) || mdp3_session->in_splash_screen) { /* Turn on panel so that it can exit low power mode */ pr_err("%s %d\n", __func__, __LINE__); mdp3_clk_enable(1, 0); rc = panel->event_handler(panel, MDSS_EVENT_LINK_READY, NULL); Loading @@ -768,12 +773,14 @@ static int mdp3_ctrl_on(struct msm_fb_data_type *mfd) MDSS_EVENT_UNBLANK, NULL); rc |= panel->event_handler(panel, MDSS_EVENT_PANEL_ON, NULL); if (mdss_fb_is_power_on_ulp(mfd)) rc |= mdp3_enable_panic_ctrl(); mdp3_clk_enable(0, 0); } } if (mdp3_session->status) { pr_err("fb%d is on already\n", mfd->index); pr_debug("fb%d is on already\n", mfd->index); goto end; } Loading Loading @@ -1011,6 +1018,32 @@ static int mdp3_ctrl_off(struct msm_fb_data_type *mfd) mdp3_bufq_deinit(&mdp3_session->bufq_in); } } if (mdss_fb_is_power_on_ulp(mfd) && (mfd->panel.type == MIPI_CMD_PANEL)) { pr_debug("%s: Disable MDP3 clocks in ULP\n", __func__); if (!mdp3_session->clk_on) mdp3_ctrl_clk_enable(mfd, 1); /* * STOP DMA transfer first and signal vsync notification * Before releasing the resource in ULP state. */ rc = mdp3_session->dma->stop(mdp3_session->dma, mdp3_session->intf); if (rc) pr_warn("fail to stop the MDP3 dma in ULP\n"); /* Wait to ensure TG to turn off */ msleep(20); /* * Handle ULP request initiated from fb_pm_suspend. * For ULP panel power state disabling vsync and set * vsync_count to zero and Turn off MDP3 clocks */ atomic_set(&mdp3_session->vsync_countdown, 0); mdp3_session->vsync_enabled = 0; mdp3_ctrl_vsync_enable(mdp3_session->mfd, 0); mdp3_ctrl_clk_enable(mdp3_session->mfd, 0); } off_error: mutex_unlock(&mdp3_session->lock); /* Release the last reference to the runtime device */ Loading Loading @@ -1038,7 +1071,10 @@ static int mdp3_ctrl_reset(struct msm_fb_data_type *mfd) panel = mdp3_session->panel; mdp3_dma = mdp3_session->dma; mutex_lock(&mdp3_session->lock); if (mdp3_res->idle_pc) { pr_debug("mdp3_ctrl_reset idle_pc %s FS_EN %s\n", mdp3_res->idle_pc ? "True":"False", mdp3_res->fs_ena ? "True":"False"); if (mdp3_res->idle_pc || mdp3_res->fs_ena) { mdp3_clk_enable(1, 0); mdp3_dynamic_clock_gating_ctrl(0); mdp3_qos_remapper_setup(panel); Loading @@ -1047,7 +1083,7 @@ static int mdp3_ctrl_reset(struct msm_fb_data_type *mfd) rc = mdp3_iommu_enable(MDP3_CLIENT_DMA_P); if (rc) { pr_err("fail to attach dma iommu\n"); if (mdp3_res->idle_pc) if (mdp3_res->idle_pc || mdp3_res->fs_ena) mdp3_clk_enable(0, 0); goto reset_error; } Loading Loading @@ -1166,16 +1202,26 @@ static int mdp3_overlay_queue_buffer(struct msm_fb_data_type *mfd, struct msmfb_overlay_data *req) { int rc; bool is_panel_type_cmd = false; struct mdp3_session_data *mdp3_session = mfd->mdp.private1; struct msmfb_data *img = &req->data; struct mdp3_img_data data; struct mdp3_dma *dma = mdp3_session->dma; memset(&data, 0, sizeof(struct mdp3_img_data)); if (mfd->panel.type == MIPI_CMD_PANEL) is_panel_type_cmd = true; if (is_panel_type_cmd) { rc = mdp3_iommu_enable(MDP3_CLIENT_DMA_P); if (rc) { pr_err("fail to enable iommu\n"); return rc; } } rc = mdp3_get_img(img, &data, MDP3_CLIENT_DMA_P); if (rc) { pr_err("fail to get overlay buffer\n"); return rc; goto err; } if (data.len < dma->source_config.stride * dma->source_config.height) { Loading @@ -1183,16 +1229,20 @@ static int mdp3_overlay_queue_buffer(struct msm_fb_data_type *mfd, data.len, (dma->source_config.stride * dma->source_config.height)); mdp3_put_img(&data, MDP3_CLIENT_DMA_P); return -EINVAL; rc = -EINVAL; goto err; } rc = mdp3_bufq_push(&mdp3_session->bufq_in, &data); if (rc) { pr_err("fail to queue the overlay buffer, buffer drop\n"); mdp3_put_img(&data, MDP3_CLIENT_DMA_P); return rc; goto err; } return 0; rc = 0; err: if (is_panel_type_cmd) mdp3_iommu_disable(MDP3_CLIENT_DMA_P); return rc; } static int mdp3_overlay_play(struct msm_fb_data_type *mfd, Loading Loading @@ -1276,6 +1326,7 @@ static int mdp3_ctrl_display_commit_kickoff(struct msm_fb_data_type *mfd, } panel = mdp3_session->panel; mutex_lock(&mdp3_res->fs_idle_pc_lock); if (mdp3_session->in_splash_screen || mdp3_res->idle_pc) { pr_debug("%s: reset- in_splash = %d, idle_pc = %d", __func__, Loading @@ -1283,9 +1334,11 @@ static int mdp3_ctrl_display_commit_kickoff(struct msm_fb_data_type *mfd, rc = mdp3_ctrl_reset(mfd); if (rc) { pr_err("fail to reset display\n"); mutex_unlock(&mdp3_res->fs_idle_pc_lock); return -EINVAL; } } mutex_unlock(&mdp3_res->fs_idle_pc_lock); mutex_lock(&mdp3_session->lock); Loading Loading @@ -1418,6 +1471,7 @@ static void mdp3_ctrl_pan_display(struct msm_fb_data_type *mfd) if (!mdp3_session || !mdp3_session->dma) return; mutex_lock(&mdp3_res->fs_idle_pc_lock); if (mdp3_session->in_splash_screen || mdp3_res->idle_pc) { pr_debug("%s: reset- in_splash = %d, idle_pc = %d", __func__, Loading @@ -1425,9 +1479,11 @@ static void mdp3_ctrl_pan_display(struct msm_fb_data_type *mfd) rc = mdp3_ctrl_reset(mfd); if (rc) { pr_err("fail to reset display\n"); mutex_unlock(&mdp3_res->fs_idle_pc_lock); return; } } mutex_unlock(&mdp3_res->fs_idle_pc_lock); mutex_lock(&mdp3_session->lock); Loading Loading @@ -2493,17 +2549,21 @@ static int mdp3_ctrl_ioctl_handler(struct msm_fb_data_type *mfd, } break; case MSMFB_ASYNC_BLIT: mutex_lock(&mdp3_res->fs_idle_pc_lock); if (mdp3_session->in_splash_screen || mdp3_res->idle_pc) { pr_err("%s: reset- in_splash = %d, idle_pc = %d", pr_debug("%s: reset- in_splash = %d, idle_pc = %d", __func__, mdp3_session->in_splash_screen, mdp3_res->idle_pc); mdp3_ctrl_reset(mfd); } mutex_unlock(&mdp3_res->fs_idle_pc_lock); rc = mdp3_ctrl_async_blit_req(mfd, argp); break; case MSMFB_BLIT: mutex_lock(&mdp3_res->fs_idle_pc_lock); if (mdp3_session->in_splash_screen) mdp3_ctrl_reset(mfd); mutex_unlock(&mdp3_res->fs_idle_pc_lock); rc = mdp3_ctrl_blit_req(mfd, argp); break; case MSMFB_METADATA_GET: Loading
drivers/video/msm/mdss/mdp3_dma.c +6 −1 Original line number Diff line number Diff line Loading @@ -153,6 +153,12 @@ void mdp3_dma_callback_disable(struct mdp3_dma *dma, int type) irq_bit = MDP3_INTR_SYNC_PRIMARY_LINE; irq_bit += dma->dma_sel; mdp3_irq_disable(irq_bit); /* * Clear read pointer interrupt before disabling clocks. * Else pending ISR handling will result in NOC error * since the clock will be disable after this point. */ mdp3_clear_irq(irq_bit); } if (type & MDP3_DMA_CALLBACK_TYPE_DMA_DONE) { Loading Loading @@ -721,7 +727,6 @@ retry_dma_done: retry_vsync: rc = wait_for_completion_timeout(&dma->vsync_comp, KOFF_TIMEOUT); pr_err("%s VID DMA Buff Addr %pK\n", __func__, buf); if (rc <= 0 && --retry_count) { int vsync = MDP3_REG_READ(MDP3_REG_INTR_STATUS) & (1 << MDP3_INTR_LCDC_START_OF_FRAME); Loading
drivers/video/msm/mdss/mdp3_ppp.c +7 −3 Original line number Diff line number Diff line Loading @@ -530,6 +530,8 @@ int mdp3_calc_ppp_res(struct msm_fb_data_type *mfd, int i, lcount = 0; struct mdp_blit_req *req; struct bpp_info bpp; u64 old_solid_fill_pixel = 0; u64 new_solid_fill_pixel = 0; u64 src_read_bw = 0; u32 bg_read_bw = 0; u32 dst_write_bw = 0; Loading @@ -548,12 +550,14 @@ int mdp3_calc_ppp_res(struct msm_fb_data_type *mfd, if (lreq->req_list[0].flags & MDP_SOLID_FILL) { req = &(lreq->req_list[0]); mdp3_get_bpp_info(req->dst.format, &bpp); ppp_res.solid_fill_pixel += req->dst_rect.w * req->dst_rect.h; old_solid_fill_pixel = ppp_res.solid_fill_pixel; new_solid_fill_pixel = req->dst_rect.w * req->dst_rect.h; ppp_res.solid_fill_pixel += new_solid_fill_pixel; ppp_res.solid_fill_byte += req->dst_rect.w * req->dst_rect.h * bpp.bpp_num / bpp.bpp_den; if ((panel_info->yres/2 > req->dst_rect.h) || if ((old_solid_fill_pixel >= new_solid_fill_pixel) || (mdp3_res->solid_fill_vote_en)) { pr_debug("Solid fill less than H/2 or fill vote %d\n", pr_debug("Last fill pixels are higher or fill_en %d\n", mdp3_res->solid_fill_vote_en); ATRACE_END(__func__); return 0; Loading