diff --git a/drivers/video/msm/lcdc.c b/drivers/video/msm/lcdc.c index 2170abe61321..1bd4302f4a00 100644 --- a/drivers/video/msm/lcdc.c +++ b/drivers/video/msm/lcdc.c @@ -84,8 +84,6 @@ static int lcdc_off(struct platform_device *pdev) } clk_disable_unprepare(mfd->ebi1_clk); } -#else - mdp_bus_scale_update_request(0); #endif return ret; @@ -108,9 +106,7 @@ static int lcdc_on(struct platform_device *pdev) if (!panel_pixclock_freq) panel_pixclock_freq = mfd->fbi->var.pixclock; -#ifdef CONFIG_MSM_BUS_SCALING - mdp_bus_scale_update_request(2); -#else +#ifndef CONFIG_MSM_BUS_SCALING if (panel_pixclock_freq > 65000000) /* pm_qos_rate should be in Khz */ pm_qos_rate = panel_pixclock_freq / 1000 ; diff --git a/drivers/video/msm/lvds.c b/drivers/video/msm/lvds.c index 13bb9e336733..e9bbceb1128a 100644 --- a/drivers/video/msm/lvds.c +++ b/drivers/video/msm/lvds.c @@ -254,10 +254,6 @@ static int lvds_off(struct platform_device *pdev) if (lvds_pdata && lvds_pdata->lcdc_gpio_config) ret = lvds_pdata->lcdc_gpio_config(0); -#ifdef CONFIG_MSM_BUS_SCALING - mdp_bus_scale_update_request(0); -#endif - return ret; } @@ -273,9 +269,6 @@ static int lvds_on(struct platform_device *pdev) if (!panel_pixclock_freq) panel_pixclock_freq = mfd->fbi->var.pixclock; -#ifdef CONFIG_MSM_BUS_SCALING - mdp_bus_scale_update_request(2); -#endif mfd = platform_get_drvdata(pdev); if (lvds_clk) { diff --git a/drivers/video/msm/mddi.c b/drivers/video/msm/mddi.c index 115491387f2f..b4c1e76e308f 100644 --- a/drivers/video/msm/mddi.c +++ b/drivers/video/msm/mddi.c @@ -212,9 +212,7 @@ static int mddi_off(struct platform_device *pdev) if (mddi_pdata && mddi_pdata->mddi_power_save) mddi_pdata->mddi_power_save(0); -#ifdef CONFIG_MSM_BUS_SCALING - mdp_bus_scale_update_request(0); -#else +#ifndef CONFIG_MSM_BUS_SCALING if (mfd->ebi1_clk) clk_disable_unprepare(mfd->ebi1_clk); #endif @@ -275,9 +273,7 @@ static int mddi_on(struct platform_device *pdev) printk(KERN_ERR "%s: clk_set_rate failed\n", __func__); -#ifdef CONFIG_MSM_BUS_SCALING - mdp_bus_scale_update_request(2); -#else +#ifndef CONFIG_MSM_BUS_SCALING if (mfd->ebi1_clk) clk_prepare_enable(mfd->ebi1_clk); #endif diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c index e2e2df675d94..b80bfdf0a360 100644 --- a/drivers/video/msm/mdp.c +++ b/drivers/video/msm/mdp.c @@ -51,6 +51,7 @@ static struct clk *mdp_lut_clk; int mdp_rev; int mdp_iommu_split_domain; u32 mdp_max_clk = 266667000; +u64 mdp_max_bw = 2000000000; static struct platform_device *mdp_init_pdev; static struct regulator *footswitch; @@ -1413,6 +1414,39 @@ int mdp_ppp_pipe_wait(void) return ret; } +#define DEFAULT_FRAME_RATE 60 + +u32 mdp_get_panel_framerate(struct msm_fb_data_type *mfd) +{ + u32 frame_rate = 0, total_pixel; + struct msm_panel_info *panel_info = &mfd->panel_info; + if (mfd->dest == DISPLAY_LCD) { + if (panel_info->type == MDDI_PANEL && panel_info->mddi.is_type1) + frame_rate = panel_info->lcd.refx100 / (100 * 2); + else + frame_rate = panel_info->lcd.refx100 / 100; + } else { + if (panel_info->type == MIPI_VIDEO_PANEL) { + frame_rate = panel_info->mipi.frame_rate; + } else { + total_pixel = (panel_info->lcdc.h_back_porch + + panel_info->lcdc.h_front_porch + + panel_info->lcdc.h_pulse_width + + panel_info->xres) * + (panel_info->lcdc.v_back_porch + + panel_info->lcdc.v_front_porch + + panel_info->lcdc.v_pulse_width + + panel_info->yres); + if (total_pixel) + frame_rate = panel_info->clk_rate / + total_pixel; + } + } + if (frame_rate == 0) + frame_rate = DEFAULT_FRAME_RATE; + return frame_rate; +} + static DEFINE_SPINLOCK(mdp_lock); static int mdp_irq_mask; static int mdp_irq_enabled; @@ -2169,7 +2203,9 @@ static int mdp_off(struct platform_device *pdev) ret = panel_next_off(pdev); mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); mdp_clk_ctrl(0); - +#ifdef CONFIG_MSM_BUS_SCALING + mdp_bus_scale_update_request(0, 0); +#endif if (mdp_rev >= MDP_REV_41 && mfd->panel.type == MIPI_CMD_PANEL) mdp_dsi_cmd_overlay_suspend(mfd); pr_debug("%s:-\n", __func__); @@ -2279,20 +2315,77 @@ void mdp_hw_version(void) } #ifdef CONFIG_MSM_BUS_SCALING + +#ifndef MDP_BUS_VECTOR_ENTRY +#define MDP_BUS_VECTOR_ENTRY(ab_val, ib_val) \ + { \ + .src = MSM_BUS_MASTER_MDP_PORT0, \ + .dst = MSM_BUS_SLAVE_EBI_CH0, \ + .ab = (ab_val), \ + .ib = (ib_val), \ + } +#endif +/* + * Entry 0 hold 0 request + * Entry 1 and 2 do ping pong request + */ +static struct msm_bus_vectors mdp_bus_vectors[] = { + MDP_BUS_VECTOR_ENTRY(0, 0), + MDP_BUS_VECTOR_ENTRY( 128000000, 160000000), + MDP_BUS_VECTOR_ENTRY( 128000000, 160000000), +}; + +static struct msm_bus_paths mdp_bus_usecases[ARRAY_SIZE(mdp_bus_vectors)]; +static struct msm_bus_scale_pdata mdp_bus_scale_table = { + .usecase = mdp_bus_usecases, + .num_usecases = ARRAY_SIZE(mdp_bus_usecases), + .name = "mdp", +}; static uint32_t mdp_bus_scale_handle; -int mdp_bus_scale_update_request(uint32_t index) +static int mdp_bus_scale_register(void) { - if (!mdp_pdata && (!mdp_pdata->mdp_bus_scale_table - || index > (mdp_pdata->mdp_bus_scale_table->num_usecases - 1))) { - printk(KERN_ERR "%s invalid table or index\n", __func__); - return -EINVAL; + struct msm_bus_scale_pdata *bus_pdata = &mdp_bus_scale_table; + int i; + for (i = 0; i < bus_pdata->num_usecases; i++) { + mdp_bus_usecases[i].num_paths = 1; + mdp_bus_usecases[i].vectors = &mdp_bus_vectors[i]; } + mdp_bus_scale_handle = msm_bus_scale_register_client(bus_pdata); + if (!mdp_bus_scale_handle) { + pr_err("%s: not able to get bus scale!\n", __func__); + return -ENOMEM; + } + return 0; +} + +int mdp_bus_scale_update_request(u64 ab, u64 ib) +{ + static int bus_index = 1; + if (mdp_bus_scale_handle < 1) { - pr_debug("%s invalid bus handle\n", __func__); + pr_err("%s invalid bus handle\n", __func__); return -EINVAL; } - return msm_bus_scale_client_update_request(mdp_bus_scale_handle, - index); + + if (!ab) + return msm_bus_scale_client_update_request + (mdp_bus_scale_handle, 0); + + /* ping pong bus_index between table entry 1 and 2 */ + bus_index++; + bus_index = (bus_index > 2) ? 1 : bus_index; + + mdp_bus_usecases[bus_index].vectors->ab = min(ab, mdp_max_bw); + ib = max(ib, ab); + mdp_bus_usecases[bus_index].vectors->ib = min(ib, mdp_max_bw); + + pr_debug("%s: handle=%d index=%d ab=%llu ib=%llu\n", __func__, + (u32)mdp_bus_scale_handle, bus_index, + mdp_bus_usecases[bus_index].vectors->ab, + mdp_bus_usecases[bus_index].vectors->ib); + + return msm_bus_scale_client_update_request + (mdp_bus_scale_handle, bus_index); } #endif DEFINE_MUTEX(mdp_clk_lock); @@ -2820,22 +2913,13 @@ static int mdp_probe(struct platform_device *pdev) mdp_clk_ctrl(0); #ifdef CONFIG_MSM_BUS_SCALING - if (!mdp_bus_scale_handle && mdp_pdata && - mdp_pdata->mdp_bus_scale_table) { - mdp_bus_scale_handle = - msm_bus_scale_register_client( - mdp_pdata->mdp_bus_scale_table); - if (!mdp_bus_scale_handle) { - printk(KERN_ERR "%s not able to get bus scale\n", - __func__); - return -ENOMEM; - } - } + if (mdp_bus_scale_register()) + return -ENOMEM; /* req bus bandwidth immediately */ if (!(mfd->cont_splash_done)) - mdp_bus_scale_update_request(5); - + mdp_bus_scale_update_request + (MDP_BUS_SCALE_INIT, MDP_BUS_SCALE_INIT); #endif /* set driver data */ @@ -2879,8 +2963,7 @@ static int mdp_probe(struct platform_device *pdev) mdp_probe_err: platform_device_put(msm_fb_dev); #ifdef CONFIG_MSM_BUS_SCALING - if (mdp_pdata && mdp_pdata->mdp_bus_scale_table && - mdp_bus_scale_handle > 0) + if (mdp_bus_scale_handle > 0) msm_bus_scale_unregister_client(mdp_bus_scale_handle); #endif return rc; @@ -2977,8 +3060,7 @@ static int mdp_remove(struct platform_device *pdev) iounmap(msm_mdp_base); pm_runtime_disable(&pdev->dev); #ifdef CONFIG_MSM_BUS_SCALING - if (mdp_pdata && mdp_pdata->mdp_bus_scale_table && - mdp_bus_scale_handle > 0) + if (mdp_bus_scale_handle > 0) msm_bus_scale_unregister_client(mdp_bus_scale_handle); #endif return 0; diff --git a/drivers/video/msm/mdp.h b/drivers/video/msm/mdp.h index 8f540aa7dc05..0653869a0622 100644 --- a/drivers/video/msm/mdp.h +++ b/drivers/video/msm/mdp.h @@ -830,12 +830,12 @@ int mdp_set_core_clk(u32 rate); int mdp_clk_round_rate(u32 rate); unsigned long mdp_get_core_clk(void); -unsigned long mdp_perf_level2clk_rate(uint32 perf_level); #ifdef CONFIG_MSM_BUS_SCALING -int mdp_bus_scale_update_request(uint32_t index); +int mdp_bus_scale_update_request(u64 ab, u64 ib); #else -static inline int mdp_bus_scale_update_request(uint32_t index) +static inline int mdp_bus_scale_update_request(u64 ab, + u64 ib) { return 0; } @@ -912,6 +912,8 @@ int mdp_ppp_v4l2_overlay_play(struct fb_info *info, unsigned long srcp0_addr, unsigned long srcp0_size, unsigned long srcp1_addr, unsigned long srcp1_size); +u32 mdp_get_panel_framerate(struct msm_fb_data_type *mfd); + #ifdef CONFIG_FB_MSM_DTV void mdp_vid_quant_set(void); #else diff --git a/drivers/video/msm/mdp4.h b/drivers/video/msm/mdp4.h index a40a0fb0ede7..ba099c3787b9 100644 --- a/drivers/video/msm/mdp4.h +++ b/drivers/video/msm/mdp4.h @@ -29,6 +29,12 @@ extern char *mmss_cc_base; /* mutimedia sub system clock control */ extern spinlock_t dsi_clk_lock; extern u32 mdp_max_clk; +extern u64 mdp_max_bw; +#define MDP4_BW_AB_FACTOR (115) /* 1.15 */ +#define MDP4_BW_IB_FACTOR (125) /* 1.25 */ +#define MDP_BUS_SCALE_AB_STEP (0x4000000) +#define MDP_BUS_SCALE_INIT (0x10000000) + #define MDP4_OVERLAYPROC0_BASE 0x10000 #define MDP4_OVERLAYPROC1_BASE 0x18000 #define MDP4_OVERLAYPROC2_BASE 0x88000 @@ -44,13 +50,6 @@ extern u32 mdp_max_clk; #define CS_CONTROLLER_0 0x0707ffff #define CS_CONTROLLER_1 0x03073f3f -enum { - OVERLAY_PERF_LEVEL1 = 1, - OVERLAY_PERF_LEVEL2, - OVERLAY_PERF_LEVEL3, - OVERLAY_PERF_LEVEL4 -}; - typedef int (*cmd_fxn_t)(struct platform_device *pdev); enum { /* display */ @@ -243,6 +242,12 @@ enum { #define MDP4_MAX_PLANE 4 #define VSYNC_PERIOD 16 +#ifdef BLT_RGB565 +#define BLT_BPP 2 +#else +#define BLT_BPP 3 +#endif + struct mdp4_hsic_regs { int32_t params[NUM_HSIC_PARAM]; int32_t conv_matrix[3][3]; @@ -368,7 +373,8 @@ struct mdp4_overlay_pipe { uint32 blt_dmap_done; uint32 blt_forced; uint32 req_clk; - uint32 req_bw; + uint64 bw_ab_quota; + uint64 bw_ib_quota; uint32 luma_align_size; struct mdp_overlay_pp_params pp_cfg; struct mdp_overlay req_data; @@ -932,7 +938,9 @@ int mdp4_v4l2_overlay_play(struct fb_info *info, struct mdp4_overlay_pipe *pipe, unsigned long srcp0_addr, unsigned long srcp1_addr, unsigned long srcp2_addr); int mdp4_overlay_mdp_pipe_req(struct mdp4_overlay_pipe *pipe, - struct msm_fb_data_type *mfd); + struct msm_fb_data_type *mfd); +int mdp4_calc_blt_mdp_bw(struct msm_fb_data_type *mfd, + struct mdp4_overlay_pipe *pipe); int mdp4_overlay_mdp_perf_req(struct msm_fb_data_type *mfd, struct mdp4_overlay_pipe *plist); void mdp4_overlay_mdp_perf_upd(struct msm_fb_data_type *mfd, int flag); diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c index ee40a71725f0..a2b32c81801d 100644 --- a/drivers/video/msm/mdp4_overlay.c +++ b/drivers/video/msm/mdp4_overlay.c @@ -106,17 +106,15 @@ static struct mdp4_overlay_ctrl *ctrl = &mdp4_overlay_db; struct mdp4_overlay_perf { u32 mdp_clk_rate; - u32 use_ov0_blt; - u32 use_ov1_blt; - u32 mdp_bw; + u32 use_ov_blt[MDP4_MIXER_MAX]; + u64 mdp_ov_ab_bw[MDP4_MIXER_MAX]; + u64 mdp_ov_ib_bw[MDP4_MIXER_MAX]; + u32 mdp_ab_bw; + u32 mdp_ib_bw; }; -struct mdp4_overlay_perf perf_request = { - .mdp_bw = OVERLAY_PERF_LEVEL4, -}; -struct mdp4_overlay_perf perf_current = { - .mdp_bw = OVERLAY_PERF_LEVEL4, -}; +struct mdp4_overlay_perf perf_request; +struct mdp4_overlay_perf perf_current; static struct ion_client *display_iclient; @@ -2439,12 +2437,10 @@ static int mdp4_calc_pipe_mdp_clk(struct msm_fb_data_type *mfd, if (!pipe) { pr_err("%s: pipe is null!\n", __func__); - pipe->req_bw = OVERLAY_PERF_LEVEL4; return ret; } if (!mfd) { pr_err("%s: mfd is null!\n", __func__); - pipe->req_bw = OVERLAY_PERF_LEVEL4; return ret; } @@ -2623,18 +2619,13 @@ static int mdp4_calc_pipe_mdp_clk(struct msm_fb_data_type *mfd, return 0; } -#define OVERLAY_VGA_SIZE 0x04B000 -#define OVERLAY_720P_TILE_SIZE 0x0E6000 -#define OVERLAY_WSVGA_SIZE 0x98000 /* 1024x608, align 600 to 32bit */ - -#define OVERLAY_BUS_SCALE_TABLE_BASE 6 - - static int mdp4_calc_pipe_mdp_bw(struct msm_fb_data_type *mfd, - struct mdp4_overlay_pipe *pipe) + struct mdp4_overlay_pipe *pipe) { - u32 res; + u32 fps; int ret = -EINVAL; + u32 quota; + u32 shift = 16; if (!pipe) { pr_err("%s: pipe is null!\n", __func__); @@ -2645,28 +2636,79 @@ static int mdp4_calc_pipe_mdp_bw(struct msm_fb_data_type *mfd, return ret; } - if (pipe->flags & MDP_DEINTERLACE) { - pr_info("%s deinterlace requires max mdp bw.\n", - __func__); - pipe->req_bw = OVERLAY_PERF_LEVEL1; - return 0; + fps = mdp_get_panel_framerate(mfd); + quota = pipe->src_w * pipe->src_h * fps * pipe->bpp; + + quota >>= shift; + /* factor 1.15 for ab */ + pipe->bw_ab_quota = quota * MDP4_BW_AB_FACTOR / 100; + /* factor 1.25 for ib */ + pipe->bw_ib_quota = quota * MDP4_BW_IB_FACTOR / 100; + /* down scaling factor for ib */ + if ((!pipe->dst_h) && (!pipe->src_h) && + (pipe->src_h > pipe->dst_h)) { + u64 ib = quota; + ib *= pipe->src_h; + ib /= pipe->dst_h; + pipe->bw_ib_quota = max(ib, pipe->bw_ib_quota); + pr_debug("%s: src_h=%d dst_h=%d mdp ib %llu, ib_quota=%llu\n", + __func__, pipe->src_h, pipe->dst_h, + ib<bw_ib_quota<pipe_type == OVERLAY_TYPE_BF) { - pipe->req_bw = OVERLAY_PERF_LEVEL4; - return 0; + pipe->bw_ab_quota <<= shift; + pipe->bw_ib_quota <<= shift; + + pr_debug("%s: pipe ndx=%d src(h,w)(%d, %d) fps=%d bpp=%d\n", + __func__, pipe->pipe_ndx, pipe->src_h, pipe->src_w, + fps, pipe->bpp); + pr_debug("%s: ab_quota=%llu ib_quota=%llu\n", __func__, + pipe->bw_ab_quota, pipe->bw_ib_quota); + + return 0; +} + +int mdp4_calc_blt_mdp_bw(struct msm_fb_data_type *mfd, + struct mdp4_overlay_pipe *pipe) +{ + struct mdp4_overlay_perf *perf_req = &perf_request; + u32 fps; + int bpp; + int ret = -EINVAL; + u32 quota; + u32 shift = 16; + if (!pipe) { + pr_err("%s: pipe is null!\n", __func__); + return ret; + } + if (!mfd) { + pr_err("%s: mfd is null!\n", __func__); + return ret; } - res = pipe->src_w * pipe->src_h; + bpp = BLT_BPP; + fps = mdp_get_panel_framerate(mfd); - if (res <= OVERLAY_WSVGA_SIZE) - pipe->req_bw = OVERLAY_PERF_LEVEL4; - else if (res <= OVERLAY_VGA_SIZE) - pipe->req_bw = OVERLAY_PERF_LEVEL3; - else if (res <= OVERLAY_720P_TILE_SIZE) - pipe->req_bw = OVERLAY_PERF_LEVEL2; - else - pipe->req_bw = OVERLAY_PERF_LEVEL1; + /* read and write bw*/ + quota = pipe->dst_w * pipe->dst_h * fps * bpp * 2; + quota >>= shift; + + perf_req->mdp_ov_ab_bw[pipe->mixer_num] = + quota * MDP4_BW_AB_FACTOR / 100; + + perf_req->mdp_ov_ib_bw[pipe->mixer_num] = + quota * MDP4_BW_IB_FACTOR / 100; + + perf_req->mdp_ov_ab_bw[pipe->mixer_num] <<= shift; + perf_req->mdp_ov_ib_bw[pipe->mixer_num] <<= shift; + + pr_debug("%s: pipe ndx=%d dst(h,w)(%d, %d) fps=%d bpp=%d\n", + __func__, pipe->pipe_ndx, pipe->dst_h, pipe->dst_w, + fps, bpp); + pr_debug("%s: overlay=%d ab_bw=%llu ib_bw=%llu\n", __func__, + pipe->mixer_num, + perf_req->mdp_ov_ab_bw[pipe->mixer_num], + perf_req->mdp_ov_ib_bw[pipe->mixer_num]); return 0; } @@ -2675,12 +2717,12 @@ int mdp4_overlay_mdp_perf_req(struct msm_fb_data_type *mfd, struct mdp4_overlay_pipe *plist) { u32 worst_mdp_clk = 0; - u32 worst_mdp_bw = OVERLAY_PERF_LEVEL4; int i; struct mdp4_overlay_perf *perf_req = &perf_request; struct mdp4_overlay_pipe *pipe = plist; u32 cnt = 0; int ret = -EINVAL; + u64 ab_quota_total = 0, ib_quota_total = 0; if (!mfd) { pr_err("%s: mfd is null!\n", __func__); @@ -2692,8 +2734,8 @@ int mdp4_overlay_mdp_perf_req(struct msm_fb_data_type *mfd, return ret; } - perf_req->use_ov0_blt = 0; - perf_req->use_ov1_blt = 0; + for (i = 0; i < MDP4_MIXER_MAX; i++) + perf_req->use_ov_blt[i] = 0; for (i = 0; i < OVERLAY_PIPE_MAX; i++, pipe++) { @@ -2705,25 +2747,17 @@ int mdp4_overlay_mdp_perf_req(struct msm_fb_data_type *mfd, cnt++; if (worst_mdp_clk < pipe->req_clk) worst_mdp_clk = pipe->req_clk; - if (pipe->req_clk > mdp_max_clk) { - if (pipe->mixer_num == MDP4_MIXER0) - perf_req->use_ov0_blt = 1; - if (pipe->mixer_num == MDP4_MIXER1) - perf_req->use_ov1_blt = 1; - } - if (!pipe->req_bw) { - pr_err("%s mdp pipe bw request should not be zero!\n", - __func__); - pr_debug("%s %d pid %d num %d idx %d mix %d bw %d\n", - __func__, __LINE__, current->pid, - pipe->pipe_num, pipe->pipe_ndx, - pipe->mixer_num, pipe->req_bw); - pipe->req_bw = OVERLAY_PERF_LEVEL4; - } + if (pipe->req_clk > mdp_max_clk) + perf_req->use_ov_blt[pipe->mixer_num] = 1; - if (pipe->req_bw < worst_mdp_bw) - worst_mdp_bw = pipe->req_bw; + if (pipe->mixer_num == MDP4_MIXER2) + perf_req->use_ov_blt[MDP4_MIXER2] = 1; + + if (pipe->pipe_type != OVERLAY_TYPE_BF) { + ab_quota_total += pipe->bw_ab_quota; + ib_quota_total += pipe->bw_ib_quota; + } if (mfd->mdp_rev == MDP_REV_41) { /* @@ -2732,32 +2766,45 @@ int mdp4_overlay_mdp_perf_req(struct msm_fb_data_type *mfd, */ if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) { if (pipe->dst_x != 0) - perf_req->use_ov0_blt = 1; + perf_req->use_ov_blt[MDP4_MIXER0] = 1; } if ((mfd->panel_info.xres > 1280) && (mfd->panel_info.type != DTV_PANEL)) { - perf_req->use_ov0_blt = 1; + perf_req->use_ov_blt[MDP4_MIXER0] = 1; } } } - perf_req->mdp_clk_rate = worst_mdp_clk; - if (perf_req->mdp_clk_rate > mdp_max_clk) - perf_req->mdp_clk_rate = mdp_max_clk; - + perf_req->mdp_clk_rate = min(worst_mdp_clk, mdp_max_clk); perf_req->mdp_clk_rate = mdp_clk_round_rate(perf_req->mdp_clk_rate); - perf_req->mdp_bw = worst_mdp_bw; + for (i = 0; i < MDP4_MIXER_MAX; i++) { + if (perf_req->use_ov_blt[i]) { + ab_quota_total += perf_req->mdp_ov_ab_bw[i]; + ib_quota_total += perf_req->mdp_ov_ib_bw[i]; + } + } - if (cnt >= 3) - perf_req->mdp_bw = OVERLAY_PERF_LEVEL1; + perf_req->mdp_ab_bw = roundup(ab_quota_total, MDP_BUS_SCALE_AB_STEP); + perf_req->mdp_ib_bw = roundup(ib_quota_total, MDP_BUS_SCALE_AB_STEP); - pr_debug("%s %d pid %d cnt %d clk %d ov0_blt %d, ov1_blt %d bw %d\n", + pr_debug("%s %d: ab_quota_total=(%llu, %d) ib_quota_total=(%llu, %d)\n", + __func__, __LINE__, + ab_quota_total, perf_req->mdp_ab_bw, + ib_quota_total, perf_req->mdp_ib_bw); + + if (ab_quota_total > mdp_max_bw) + pr_warn("%s: req ab bw=%llu is larger than max bw=%llu", + __func__, ab_quota_total, mdp_max_bw); + if (ib_quota_total > mdp_max_bw) + pr_warn("%s: req ib bw=%llu is larger than max bw=%llu", + __func__, ib_quota_total, mdp_max_bw); + + pr_debug("%s %d: pid %d cnt %d clk %d ov0_blt %d, ov1_blt %d\n", __func__, __LINE__, current->pid, cnt, perf_req->mdp_clk_rate, - perf_req->use_ov0_blt, - perf_req->use_ov1_blt, - perf_req->mdp_bw); + perf_req->use_ov_blt[0], + perf_req->use_ov_blt[1]); return 0; } @@ -2793,7 +2840,7 @@ void mdp4_overlay_mdp_perf_upd(struct msm_fb_data_type *mfd, flag); if (!mdp4_extn_disp) - perf_cur->use_ov1_blt = 0; + perf_cur->use_ov_blt[1] = 0; if (flag) { if (perf_req->mdp_clk_rate > perf_cur->mdp_clk_rate) { @@ -2806,19 +2853,26 @@ void mdp4_overlay_mdp_perf_upd(struct msm_fb_data_type *mfd, perf_cur->mdp_clk_rate = perf_req->mdp_clk_rate; } - if (perf_req->mdp_bw < perf_cur->mdp_bw) { + if ((perf_req->mdp_ab_bw > perf_cur->mdp_ab_bw) || + (perf_req->mdp_ib_bw > perf_cur->mdp_ib_bw)) { mdp_bus_scale_update_request - (OVERLAY_BUS_SCALE_TABLE_BASE - - perf_req->mdp_bw); - pr_info("%s mdp bw is changed [%d] from %d to %d\n", + (perf_req->mdp_ab_bw, perf_req->mdp_ib_bw); + pr_debug("%s mdp ab_bw is changed [%d] from %d to %d\n", __func__, flag, - perf_cur->mdp_bw, - perf_req->mdp_bw); - perf_cur->mdp_bw = perf_req->mdp_bw; + perf_cur->mdp_ab_bw, + perf_req->mdp_ab_bw); + pr_debug("%s mdp ib_bw is changed [%d] from %d to %d\n", + __func__, + flag, + perf_cur->mdp_ib_bw, + perf_req->mdp_ib_bw); + perf_cur->mdp_ab_bw = perf_req->mdp_ab_bw; + perf_cur->mdp_ib_bw = perf_req->mdp_ib_bw; } - if (mfd->panel_info.pdest == DISPLAY_1 && - perf_req->use_ov0_blt && !perf_cur->use_ov0_blt) { + + if ((mfd->panel_info.pdest == DISPLAY_1 && + perf_req->use_ov_blt[0] && !perf_cur->use_ov_blt[0])) { if (mfd->panel_info.type == LCDC_PANEL || mfd->panel_info.type == LVDS_PANEL) mdp4_lcdc_overlay_blt_start(mfd); @@ -2829,9 +2883,9 @@ void mdp4_overlay_mdp_perf_upd(struct msm_fb_data_type *mfd, pr_info("%s mixer0 start blt [%d] from %d to %d.\n", __func__, flag, - perf_cur->use_ov0_blt, - perf_req->use_ov0_blt); - perf_cur->use_ov0_blt = perf_req->use_ov0_blt; + perf_cur->use_ov_blt[0], + perf_req->use_ov_blt[0]); + perf_cur->use_ov_blt[0] = perf_req->use_ov_blt[0]; } } else { if (perf_req->mdp_clk_rate < perf_cur->mdp_clk_rate) { @@ -2844,19 +2898,26 @@ void mdp4_overlay_mdp_perf_upd(struct msm_fb_data_type *mfd, perf_cur->mdp_clk_rate = perf_req->mdp_clk_rate; } - if (perf_req->mdp_bw > perf_cur->mdp_bw) { - pr_info("%s mdp bw is changed [%d] from %d to %d\n", + if (perf_req->mdp_ab_bw < perf_cur->mdp_ab_bw || + perf_req->mdp_ib_bw < perf_cur->mdp_ib_bw) { + mdp_bus_scale_update_request + (perf_req->mdp_ab_bw, perf_req->mdp_ib_bw); + pr_debug("%s mdp ab bw is changed [%d] from %d to %d\n", __func__, flag, - perf_cur->mdp_bw, - perf_req->mdp_bw); - mdp_bus_scale_update_request - (OVERLAY_BUS_SCALE_TABLE_BASE - - perf_req->mdp_bw); - perf_cur->mdp_bw = perf_req->mdp_bw; + perf_cur->mdp_ab_bw, + perf_req->mdp_ab_bw); + pr_debug("%s mdp ib bw is changed [%d] from %d to %d\n", + __func__, + flag, + perf_cur->mdp_ib_bw, + perf_req->mdp_ib_bw); + perf_cur->mdp_ab_bw = perf_req->mdp_ab_bw; + perf_cur->mdp_ib_bw = perf_req->mdp_ib_bw; } - if (mfd->panel_info.pdest == DISPLAY_1 && - !perf_req->use_ov0_blt && perf_cur->use_ov0_blt) { + + if ((mfd->panel_info.pdest == DISPLAY_1 && + !perf_req->use_ov_blt[0] && perf_cur->use_ov_blt[0])) { if (mfd->panel_info.type == LCDC_PANEL || mfd->panel_info.type == LVDS_PANEL) mdp4_lcdc_overlay_blt_stop(mfd); @@ -2867,9 +2928,9 @@ void mdp4_overlay_mdp_perf_upd(struct msm_fb_data_type *mfd, pr_info("%s mixer0 stop blt [%d] from %d to %d.\n", __func__, flag, - perf_cur->use_ov0_blt, - perf_req->use_ov0_blt); - perf_cur->use_ov0_blt = perf_req->use_ov0_blt; + perf_cur->use_ov_blt[0], + perf_req->use_ov_blt[0]); + perf_cur->use_ov_blt[0] = perf_req->use_ov_blt[0]; } } return; @@ -3706,7 +3767,5 @@ int mdp4_overlay_reset() { memset(&perf_request, 0, sizeof(perf_request)); memset(&perf_current, 0, sizeof(perf_current)); - perf_request.mdp_bw = OVERLAY_PERF_LEVEL4; - perf_current.mdp_bw = OVERLAY_PERF_LEVEL4; return 0; } diff --git a/drivers/video/msm/mdp4_overlay_dsi_video.c b/drivers/video/msm/mdp4_overlay_dsi_video.c index 5076e11bf4de..1ab063df624c 100644 --- a/drivers/video/msm/mdp4_overlay_dsi_video.c +++ b/drivers/video/msm/mdp4_overlay_dsi_video.c @@ -575,6 +575,7 @@ int mdp4_dsi_video_on(struct platform_device *pdev) pipe->dst_w = fbi->var.xres; mdp4_overlay_mdp_pipe_req(pipe, mfd); + mdp4_calc_blt_mdp_bw(mfd, pipe); atomic_set(&vctrl->suspend, 0); diff --git a/drivers/video/msm/mdp4_overlay_dtv.c b/drivers/video/msm/mdp4_overlay_dtv.c index 20e769ae7501..d7daa05836d1 100644 --- a/drivers/video/msm/mdp4_overlay_dtv.c +++ b/drivers/video/msm/mdp4_overlay_dtv.c @@ -768,6 +768,7 @@ static void mdp4_overlay_dtv_alloc_pipe(struct msm_fb_data_type *mfd, pipe->srcp0_ystride = fbi->fix.line_length; mdp4_overlay_mdp_pipe_req(pipe, mfd); + mdp4_calc_blt_mdp_bw(mfd, pipe); ret = mdp4_overlay_format2pipe(pipe); if (ret < 0) diff --git a/drivers/video/msm/mdp4_overlay_lcdc.c b/drivers/video/msm/mdp4_overlay_lcdc.c index b67c59839d6b..c4e4ad949b2c 100644 --- a/drivers/video/msm/mdp4_overlay_lcdc.c +++ b/drivers/video/msm/mdp4_overlay_lcdc.c @@ -544,6 +544,7 @@ int mdp4_lcdc_on(struct platform_device *pdev) pipe->bpp = bpp; mdp4_overlay_mdp_pipe_req(pipe, mfd); + mdp4_calc_blt_mdp_bw(mfd, pipe); atomic_set(&vctrl->suspend, 0); diff --git a/drivers/video/msm/mdp4_overlay_writeback.c b/drivers/video/msm/mdp4_overlay_writeback.c index aa50d94b8889..42b748c93b98 100644 --- a/drivers/video/msm/mdp4_overlay_writeback.c +++ b/drivers/video/msm/mdp4_overlay_writeback.c @@ -260,6 +260,7 @@ static int mdp4_overlay_writeback_update(struct msm_fb_data_type *mfd) pipe->dst_x = 0; mdp4_overlay_mdp_pipe_req(pipe, mfd); + mdp4_calc_blt_mdp_bw(mfd, pipe); if (mfd->display_iova) pipe->srcp0_addr = mfd->display_iova + buf_offset; diff --git a/drivers/video/msm/mdp4_util.c b/drivers/video/msm/mdp4_util.c index d880be49e778..632354ba9a20 100644 --- a/drivers/video/msm/mdp4_util.c +++ b/drivers/video/msm/mdp4_util.c @@ -392,7 +392,8 @@ void mdp4_hw_init(void) /* MDP cmd block enable */ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); - mdp_bus_scale_update_request(5); + mdp_bus_scale_update_request + (MDP_BUS_SCALE_INIT, MDP_BUS_SCALE_INIT); #ifdef MDP4_ERROR /* diff --git a/drivers/video/msm/mipi_dsi.c b/drivers/video/msm/mipi_dsi.c index 493b102966e6..9a712f7977dd 100644 --- a/drivers/video/msm/mipi_dsi.c +++ b/drivers/video/msm/mipi_dsi.c @@ -106,11 +106,8 @@ static int mipi_dsi_off(struct platform_device *pdev) ret = panel_next_off(pdev); -#ifdef CONFIG_MSM_BUS_SCALING - mdp_bus_scale_update_request(0); -#endif - spin_lock_bh(&dsi_clk_lock); + mipi_dsi_clk_disable(); /* disbale dsi engine */ @@ -316,10 +313,6 @@ static int mipi_dsi_on(struct platform_device *pdev) mipi_dsi_unprepare_clocks(); } -#ifdef CONFIG_MSM_BUS_SCALING - mdp_bus_scale_update_request(2); -#endif - if (mdp_rev >= MDP_REV_41) mutex_unlock(&mfd->dma->ov_mutex); else