msm_fb: display: add mdp bandwidth runtime calculation

Currently mdp bandwidth request logic is based on source image size
and number of layers. This logic can not support complicated mdp
usecases and it is not power efficient. The logic is improved by
calculating mdp bandwidth request at runtime from all pipes and mixers.

Conflicts:

	drivers/video/msm/mdp.c
	drivers/video/msm/mdp4_overlay.c
	drivers/video/msm/mipi_dsi.c

CRs-fixed: 425823
Change-Id: I63206f00f8d3017a2449f8ac617fce3ba2a4d36c
Signed-off-by: Huaibin Yang <huaibiny@codeaurora.org>
This commit is contained in:
Huaibin Yang 2012-12-07 20:23:53 -08:00 committed by Stephen Boyd
parent 1ddd0948c3
commit 586da5d998
13 changed files with 297 additions and 163 deletions

View file

@ -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 ;

View file

@ -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) {

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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);

View file

@ -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<<shift, pipe->bw_ib_quota<<shift);
}
if (pipe->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;
}

View file

@ -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);

View file

@ -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)

View file

@ -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);

View file

@ -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;

View file

@ -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
/*

View file

@ -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