msm_fb: display: change implementation of updating mdp_clk and blt mode
Currently mdp clk and bw requests are predefined in a 4-entry table
passed from the board file, and the logic to decide which level to use
is mainly based on source resolution. This patch is intended to
address several issues with this approach.
One major issue is clk and bandwidth depends on seperate things, and
need to be considered seperately. e.g. with mdp composition of
multiple pipes, bw request may be high but clk requirement may still
be low. The current approach that binds these two things together
causes inefficiency of power.
Another major issue is that there is no logic to calculate mdp clk
requirement of a single pipe based upon panel clk and downscale
parameters. Further the worst case of mdp clk should be determined by
all pipe usage. Without proper logic, many underrun have been
experienced, and blt mode may not be enalbed properly.
Also mdp_clk or blt mode update must be on right timing especially
between these two pathes: overlay play and pan display. In the
situations of performance from high to low or from low to high clk and
blt must be handled properly to avoid underruns.
In a summary, to support many different panels and targets and
complicated mdp pipe usage(mdp composition), mdp driver related to clk
and bw needs to be implemented differently. This patch is to seperate
clk and bw, and maily to deal with mdp clk and blt. Later increasing
granuity of bw will be added.
Change-Id: I678fbf86d6997ed7b602ce81cf2e0fff6164d129
Signed-off-by: Siddhartha Agrawal <agrawals@codeaurora.org>
diff --git a/arch/arm/mach-msm/board-8064-display.c b/arch/arm/mach-msm/board-8064-display.c
index da0fd31..5780ca1 100644
--- a/arch/arm/mach-msm/board-8064-display.c
+++ b/arch/arm/mach-msm/board-8064-display.c
@@ -236,18 +236,9 @@
.name = "mdp",
};
-static int mdp_core_clk_rate_table[] = {
- 59080000,
- 128000000,
- 160000000,
- 200000000,
-};
-
static struct msm_panel_common_pdata mdp_pdata = {
.gpio = MDP_VSYNC_GPIO,
- .mdp_core_clk_rate = 59080000,
- .mdp_core_clk_table = mdp_core_clk_rate_table,
- .num_mdp_clk = ARRAY_SIZE(mdp_core_clk_rate_table),
+ .mdp_max_clk = 200000000,
.mdp_bus_scale_table = &mdp_bus_scale_pdata,
.mdp_rev = MDP_REV_44,
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
@@ -1026,8 +1017,6 @@
*/
static void set_mdp_clocks_for_wuxga(void)
{
- int i;
-
mdp_ui_vectors[0].ab = 2000000000;
mdp_ui_vectors[0].ib = 2000000000;
mdp_vga_vectors[0].ab = 2000000000;
@@ -1037,11 +1026,6 @@
mdp_1080p_vectors[0].ab = 2000000000;
mdp_1080p_vectors[0].ib = 2000000000;
- mdp_pdata.mdp_core_clk_rate = 200000000;
-
- for (i = 0; i < ARRAY_SIZE(mdp_core_clk_rate_table); i++)
- mdp_core_clk_rate_table[i] = 200000000;
-
if (apq8064_hdmi_as_primary_selected()) {
dtv_bus_def_vectors[0].ab = 2000000000;
dtv_bus_def_vectors[0].ib = 2000000000;
diff --git a/arch/arm/mach-msm/board-8930-display.c b/arch/arm/mach-msm/board-8930-display.c
index d975997..2a8e918 100644
--- a/arch/arm/mach-msm/board-8930-display.c
+++ b/arch/arm/mach-msm/board-8930-display.c
@@ -413,31 +413,9 @@
#endif
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
-static int mdp_core_clk_rate_table[] = {
- 200000000,
- 200000000,
- 200000000,
- 200000000,
-};
-#else
-static int mdp_core_clk_rate_table[] = {
- 85330000,
- 128000000,
- 160000000,
- 200000000,
-};
-#endif
-
static struct msm_panel_common_pdata mdp_pdata = {
.gpio = MDP_VSYNC_GPIO,
-#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
- .mdp_core_clk_rate = 200000000,
-#else
- .mdp_core_clk_rate = 85330000,
-#endif
- .mdp_core_clk_table = mdp_core_clk_rate_table,
- .num_mdp_clk = ARRAY_SIZE(mdp_core_clk_rate_table),
+ .mdp_max_clk = 200000000,
#ifdef CONFIG_MSM_BUS_SCALING
.mdp_bus_scale_table = &mdp_bus_scale_pdata,
#endif
diff --git a/arch/arm/mach-msm/board-8960-display.c b/arch/arm/mach-msm/board-8960-display.c
index ddeba32..f993ed8 100644
--- a/arch/arm/mach-msm/board-8960-display.c
+++ b/arch/arm/mach-msm/board-8960-display.c
@@ -573,18 +573,9 @@
#endif
-static int mdp_core_clk_rate_table[] = {
- 85330000,
- 128000000,
- 160000000,
- 200000000,
-};
-
static struct msm_panel_common_pdata mdp_pdata = {
.gpio = MDP_VSYNC_GPIO,
- .mdp_core_clk_rate = 85330000,
- .mdp_core_clk_table = mdp_core_clk_rate_table,
- .num_mdp_clk = ARRAY_SIZE(mdp_core_clk_rate_table),
+ .mdp_max_clk = 200000000,
#ifdef CONFIG_MSM_BUS_SCALING
.mdp_bus_scale_table = &mdp_bus_scale_pdata,
#endif
@@ -1043,8 +1034,6 @@
*/
static void set_mdp_clocks_for_wuxga(void)
{
- int i;
-
mdp_ui_vectors[0].ab = 2000000000;
mdp_ui_vectors[0].ib = 2000000000;
mdp_vga_vectors[0].ab = 2000000000;
@@ -1054,11 +1043,6 @@
mdp_1080p_vectors[0].ab = 2000000000;
mdp_1080p_vectors[0].ib = 2000000000;
- mdp_pdata.mdp_core_clk_rate = 200000000;
-
- for (i = 0; i < ARRAY_SIZE(mdp_core_clk_rate_table); i++)
- mdp_core_clk_rate_table[i] = 200000000;
-
if (hdmi_is_primary) {
dtv_bus_def_vectors[0].ab = 2000000000;
dtv_bus_def_vectors[0].ib = 2000000000;
diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c
index 8adfdab..4524f43 100644
--- a/arch/arm/mach-msm/board-msm7x30.c
+++ b/arch/arm/mach-msm/board-msm7x30.c
@@ -4539,19 +4539,10 @@
.mddi_client_power = msm_fb_mddi_client_power,
};
-int mdp_core_clk_rate_table[] = {
- 122880000,
- 122880000,
- 192000000,
- 192000000,
-};
-
static struct msm_panel_common_pdata mdp_pdata = {
.hw_revision_addr = 0xac001270,
.gpio = 30,
- .mdp_core_clk_rate = 122880000,
- .mdp_core_clk_table = mdp_core_clk_rate_table,
- .num_mdp_clk = ARRAY_SIZE(mdp_core_clk_rate_table),
+ .mdp_max_clk = 192000000,
.mdp_rev = MDP_REV_40,
.mem_hid = MEMTYPE_EBI0,
};
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index 7ddf88e..47d847e 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -9651,27 +9651,9 @@
}
#endif
-#ifdef CONFIG_FB_MSM_MIPI_DSI
-int mdp_core_clk_rate_table[] = {
- 85330000,
- 128000000,
- 160000000,
- 200000000,
-};
-#else
-int mdp_core_clk_rate_table[] = {
- 59080000,
- 128000000,
- 128000000,
- 200000000,
-};
-#endif
-
static struct msm_panel_common_pdata mdp_pdata = {
.gpio = MDP_VSYNC_GPIO,
- .mdp_core_clk_rate = 59080000,
- .mdp_core_clk_table = mdp_core_clk_rate_table,
- .num_mdp_clk = ARRAY_SIZE(mdp_core_clk_rate_table),
+ .mdp_max_clk = 200000000,
#ifdef CONFIG_MSM_BUS_SCALING
.mdp_bus_scale_table = &mdp_bus_scale_pdata,
#endif
@@ -9764,9 +9746,7 @@
static void __init msm_fb_add_devices(void)
{
#ifdef CONFIG_FB_MSM_LCDC_DSUB
- mdp_pdata.mdp_core_clk_table = NULL;
- mdp_pdata.num_mdp_clk = 0;
- mdp_pdata.mdp_core_clk_rate = 200000000;
+ mdp_pdata.mdp_max_clk = 200000000;
#endif
msm_fb_register_device("mdp", &mdp_pdata);
@@ -9790,8 +9770,6 @@
*/
static void set_mdp_clocks_for_wuxga(void)
{
- int i;
-
mdp_sd_smi_vectors[0].ab = 2000000000;
mdp_sd_smi_vectors[0].ib = 2000000000;
mdp_sd_smi_vectors[1].ab = 2000000000;
@@ -9817,10 +9795,7 @@
mdp_1080p_vectors[1].ab = 2000000000;
mdp_1080p_vectors[1].ib = 2000000000;
- mdp_pdata.mdp_core_clk_rate = 200000000;
-
- for (i = 0; i < ARRAY_SIZE(mdp_core_clk_rate_table); i++)
- mdp_core_clk_rate_table[i] = 200000000;
+ mdp_pdata.mdp_max_clk = 200000000;
}
#if (defined(CONFIG_MARIMBA_CORE)) && \
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index f53ee09..f529522 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -391,9 +391,7 @@
void (*panel_config_gpio)(int);
int (*vga_switch)(int select_vga);
int *gpio_num;
- int mdp_core_clk_rate;
- unsigned num_mdp_clk;
- int *mdp_core_clk_table;
+ u32 mdp_max_clk;
#ifdef CONFIG_MSM_BUS_SCALING
struct msm_bus_scale_pdata *mdp_bus_scale_table;
#endif
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index d911b62..6d14ec1 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -50,6 +50,7 @@
static struct clk *mdp_lut_clk;
int mdp_rev;
int mdp_iommu_split_domain;
+u32 mdp_max_clk = 200000000;
static struct platform_device *mdp_init_pdev;
static struct regulator *footswitch;
@@ -2178,33 +2179,6 @@
__func__, mdp_hw_revision);
}
-#ifdef CONFIG_FB_MSM_MDP40
-static void configure_mdp_core_clk_table(uint32 min_clk_rate)
-{
- uint8 count;
- uint32 current_rate;
- if (mdp_clk && mdp_pdata && mdp_pdata->mdp_core_clk_table) {
- min_clk_rate = clk_round_rate(mdp_clk, min_clk_rate);
- if (clk_set_rate(mdp_clk, min_clk_rate) < 0)
- printk(KERN_ERR "%s: clk_set_rate failed\n",
- __func__);
- else {
- count = 0;
- current_rate = clk_get_rate(mdp_clk);
- while (count < mdp_pdata->num_mdp_clk) {
- if (mdp_pdata->mdp_core_clk_table[count]
- < current_rate) {
- mdp_pdata->
- mdp_core_clk_table[count] =
- current_rate;
- }
- count++;
- }
- }
- }
-}
-#endif
-
#ifdef CONFIG_MSM_BUS_SCALING
static uint32_t mdp_bus_scale_handle;
int mdp_bus_scale_update_request(uint32_t index)
@@ -2223,29 +2197,24 @@
}
#endif
DEFINE_MUTEX(mdp_clk_lock);
-int mdp_set_core_clk(uint16 perf_level)
+int mdp_set_core_clk(u32 rate)
{
int ret = -EINVAL;
- if (mdp_clk && mdp_pdata
- && mdp_pdata->mdp_core_clk_table) {
- if (perf_level > mdp_pdata->num_mdp_clk)
- printk(KERN_ERR "%s invalid perf level\n", __func__);
- else {
- mutex_lock(&mdp_clk_lock);
- ret = clk_set_rate(mdp_clk,
- mdp_pdata->
- mdp_core_clk_table[mdp_pdata->num_mdp_clk
- - perf_level]);
- mutex_unlock(&mdp_clk_lock);
- if (ret) {
- printk(KERN_ERR "%s unable to set mdp_core_clk rate\n",
- __func__);
- }
- }
- }
+ if (mdp_clk)
+ ret = clk_set_rate(mdp_clk, rate);
+ if (ret)
+ pr_err("%s unable to set mdp clk rate", __func__);
+ else
+ pr_debug("%s mdp clk rate to be set %d: actual rate %ld\n",
+ __func__, rate, clk_get_rate(mdp_clk));
return ret;
}
+int mdp_clk_round_rate(u32 rate)
+{
+ return clk_round_rate(mdp_clk, rate);
+}
+
unsigned long mdp_get_core_clk(void)
{
unsigned long clk_rate = 0;
@@ -2258,25 +2227,6 @@
return clk_rate;
}
-unsigned long mdp_perf_level2clk_rate(uint32 perf_level)
-{
- unsigned long clk_rate = 0;
-
- if (mdp_pdata && mdp_pdata->mdp_core_clk_table) {
- if (perf_level > mdp_pdata->num_mdp_clk) {
- printk(KERN_ERR "%s invalid perf level\n", __func__);
- clk_rate = mdp_get_core_clk();
- } else {
- clk_rate = mdp_pdata->
- mdp_core_clk_table[mdp_pdata->num_mdp_clk
- - perf_level];
- }
- } else
- clk_rate = mdp_get_core_clk();
-
- return clk_rate;
-}
-
static int mdp_irq_clk_setup(struct platform_device *pdev,
char cont_splashScreen)
{
@@ -2333,21 +2283,25 @@
}
#ifdef CONFIG_FB_MSM_MDP40
- /*
- * mdp_clk should greater than mdp_pclk always
- */
- if (mdp_pdata && mdp_pdata->mdp_core_clk_rate) {
- if (cont_splashScreen)
- mdp_clk_rate = clk_get_rate(mdp_clk);
- else
- mdp_clk_rate = mdp_pdata->mdp_core_clk_rate;
- mutex_lock(&mdp_clk_lock);
- clk_set_rate(mdp_clk, mdp_clk_rate);
- if (mdp_lut_clk != NULL)
- clk_set_rate(mdp_lut_clk, mdp_clk_rate);
- mutex_unlock(&mdp_clk_lock);
- }
+ if (mdp_pdata)
+ mdp_max_clk = mdp_pdata->mdp_max_clk;
+ else
+ pr_err("%s cannot get mdp max clk!\n", __func__);
+
+ if (!mdp_max_clk)
+ pr_err("%s mdp max clk is zero!\n", __func__);
+
+ if (cont_splashScreen)
+ mdp_clk_rate = clk_get_rate(mdp_clk);
+ else
+ mdp_clk_rate = mdp_max_clk;
+
+ mutex_lock(&mdp_clk_lock);
+ clk_set_rate(mdp_clk, mdp_clk_rate);
+ if (mdp_lut_clk != NULL)
+ clk_set_rate(mdp_lut_clk, mdp_clk_rate);
+ mutex_unlock(&mdp_clk_lock);
MSM_FB_DEBUG("mdp_clk: mdp_clk=%d\n", (int)clk_get_rate(mdp_clk));
#endif
@@ -2468,8 +2422,6 @@
mfd->ov1_wb_buf->size = 0;
mfd->mem_hid = 0;
}
- mfd->ov0_blt_state = 0;
- mfd->use_ov0_blt = 0 ;
/* initialize Post Processing data*/
mdp_hist_lut_init();
@@ -2568,7 +2520,6 @@
case MIPI_VIDEO_PANEL:
#ifndef CONFIG_FB_MSM_MDP303
mipi = &mfd->panel_info.mipi;
- configure_mdp_core_clk_table((mipi->dsi_pclk_rate) * 23 / 20);
mdp4_dsi_vsync_init(0);
mfd->hw_refresh = TRUE;
mfd->dma_fnc = mdp4_dsi_video_overlay;
@@ -2613,7 +2564,6 @@
#ifndef CONFIG_FB_MSM_MDP303
mfd->dma_fnc = mdp4_dsi_cmd_overlay;
mipi = &mfd->panel_info.mipi;
- configure_mdp_core_clk_table((mipi->dsi_pclk_rate) * 3 / 2);
mdp4_dsi_rdptr_init(0);
if (mfd->panel_info.pdest == DISPLAY_1) {
if_no = PRIMARY_INTF_SEL;
@@ -2698,8 +2648,6 @@
#ifdef CONFIG_FB_MSM_MDP40
mdp4_lcdc_vsync_init(0);
- configure_mdp_core_clk_table((mfd->panel_info.clk_rate)
- * 23 / 20);
if (mfd->panel.type == HDMI_PANEL) {
mfd->dma = &dma_e_data;
mdp4_display_intf_sel(EXTERNAL_INTF_SEL, LCDC_RGB_INTF);
diff --git a/drivers/video/msm/mdp.h b/drivers/video/msm/mdp.h
index 76d06a0..293bd9b 100644
--- a/drivers/video/msm/mdp.h
+++ b/drivers/video/msm/mdp.h
@@ -812,7 +812,9 @@
void mdp_disable_irq_nosync(uint32 term);
int mdp_get_bytes_per_pixel(uint32_t format,
struct msm_fb_data_type *mfd);
-int mdp_set_core_clk(uint16 perf_level);
+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);
diff --git a/drivers/video/msm/mdp4.h b/drivers/video/msm/mdp4.h
index cf8a9b2..cc4eae5 100644
--- a/drivers/video/msm/mdp4.h
+++ b/drivers/video/msm/mdp4.h
@@ -27,6 +27,7 @@
extern uint32 mdp4_extn_disp;
extern char *mmss_cc_base; /* mutimedia sub system clock control */
extern spinlock_t dsi_clk_lock;
+extern u32 mdp_max_clk;
#define MDP4_OVERLAYPROC0_BASE 0x10000
#define MDP4_OVERLAYPROC1_BASE 0x18000
@@ -361,6 +362,8 @@
uint32 blt_ov_done;
uint32 blt_dmap_koff;
uint32 blt_dmap_done;
+ uint32 req_clk;
+ uint32 req_bw;
uint32 luma_align_size;
struct mdp_overlay_pp_params pp_cfg;
struct mdp_overlay req_data;
@@ -610,9 +613,6 @@
void mdp4_lcdc_wait4vsync(int cndx, long long *vtime);
void mdp4_overlay_lcdc_vsync_push(struct msm_fb_data_type *mfd,
struct mdp4_overlay_pipe *pipe);
-void mdp4_overlay_dtv_set_perf(struct msm_fb_data_type *mfd);
-void mdp4_update_perf_level(u32 perf_level);
-void mdp4_set_perf_level(void);
void mdp4_mddi_overlay_dmas_restore(void);
#ifndef CONFIG_FB_MSM_MIPI_DSI
@@ -728,6 +728,12 @@
{
/* empty */
}
+static inline void mdp4_dsi_cmd_blt_start(struct msm_fb_data_type *mfd)
+{
+}
+static inline void mdp4_dsi_cmd_blt_stop(struct msm_fb_data_type *mfd)
+{
+}
#endif /* CONFIG_FB_MSM_MIPI_DSI */
void mdp4_lcdc_overlay_blt(struct msm_fb_data_type *mfd,
@@ -914,6 +920,11 @@
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);
+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);
#ifndef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
static inline void mdp4_writeback_dma_busy_wait(struct msm_fb_data_type *mfd)
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index a6ffe82..f0a3639 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -104,7 +104,21 @@
static DEFINE_MUTEX(iommu_mutex);
static struct mdp4_overlay_ctrl *ctrl = &mdp4_overlay_db;
-static int new_perf_level;
+
+struct mdp4_overlay_perf {
+ u32 mdp_clk_rate;
+ u32 use_ov0_blt;
+ u32 use_ov1_blt;
+ u32 mdp_bw;
+};
+
+struct mdp4_overlay_perf perf_request = {
+ .mdp_bw = OVERLAY_PERF_LEVEL4,
+};
+struct mdp4_overlay_perf perf_current = {
+ .mdp_bw = OVERLAY_PERF_LEVEL4,
+};
+
static struct ion_client *display_iclient;
@@ -2114,79 +2128,6 @@
}
-static int mdp4_overlay_validate_downscale(struct mdp_overlay *req,
- struct msm_fb_data_type *mfd, uint32 perf_level, uint32 pclk_rate)
-{
- __u32 panel_clk_khz, mdp_clk_khz;
- __u32 num_hsync_pix_clks, mdp_clks_per_hsync, src_wh;
- __u32 hsync_period_ps, mdp_period_ps, total_hsync_period_ps;
- unsigned long fill_rate_y_dir, fill_rate_x_dir;
- unsigned long fillratex100, mdp_pixels_produced;
- unsigned long mdp_clk_hz;
-
- pr_debug("%s: LCDC Mode Downscale validation with MDP Core"
- " Clk rate\n", __func__);
- pr_debug("src_w %u, src_h %u, dst_w %u, dst_h %u\n",
- req->src_rect.w, req->src_rect.h, req->dst_rect.w,
- req->dst_rect.h);
-
-
- panel_clk_khz = pclk_rate/1000;
- mdp_clk_hz = mdp_perf_level2clk_rate(perf_level);
-
- if (!mdp_clk_hz || !req->dst_rect.w || !req->dst_rect.h) {
- pr_debug("mdp_perf_level2clk_rate returned 0,"
- "or dst_rect height/width is 0,"
- "Downscale Validation incomplete\n");
- return 0;
- }
-
- mdp_clk_khz = mdp_clk_hz/1000;
-
- num_hsync_pix_clks = mfd->panel_info.lcdc.h_back_porch +
- mfd->panel_info.lcdc.h_front_porch +
- mfd->panel_info.lcdc.h_pulse_width +
- mfd->panel_info.xres;
-
- hsync_period_ps = 1000000000/panel_clk_khz;
- mdp_period_ps = 1000000000/mdp_clk_khz;
-
- total_hsync_period_ps = num_hsync_pix_clks * hsync_period_ps;
- mdp_clks_per_hsync = total_hsync_period_ps/mdp_period_ps;
-
- pr_debug("hsync_period_ps %u, mdp_period_ps %u,"
- "total_hsync_period_ps %u\n", hsync_period_ps,
- mdp_period_ps, total_hsync_period_ps);
-
- src_wh = req->src_rect.w * req->src_rect.h;
- if (src_wh % req->dst_rect.h)
- fill_rate_y_dir = (src_wh / req->dst_rect.h) + 1;
- else
- fill_rate_y_dir = (src_wh / req->dst_rect.h);
-
- fill_rate_x_dir = (mfd->panel_info.xres - req->dst_rect.w)
- + req->src_rect.w;
-
- if (fill_rate_y_dir >= fill_rate_x_dir)
- fillratex100 = 100 * fill_rate_y_dir / mfd->panel_info.xres;
- else
- fillratex100 = 100 * fill_rate_x_dir / mfd->panel_info.xres;
-
- pr_debug("mdp_clks_per_hsync %u, fill_rate_y_dir %lu,"
- "fill_rate_x_dir %lu\n", mdp_clks_per_hsync,
- fill_rate_y_dir, fill_rate_x_dir);
-
- mdp_pixels_produced = 100 * mdp_clks_per_hsync/fillratex100;
- pr_debug("fillratex100 %lu, mdp_pixels_produced %lu\n",
- fillratex100, mdp_pixels_produced);
- if (mdp_pixels_produced <= mfd->panel_info.xres) {
- mdp4_stat.err_underflow++;
- return -ERANGE;
- }
-
- return 0;
-}
-
static int mdp4_overlay_req2pipe(struct mdp_overlay *req, int mixer,
struct mdp4_overlay_pipe **ppipe,
struct msm_fb_data_type *mfd)
@@ -2428,11 +2369,451 @@
pipe->transp = req->transp_mask;
+ pipe->flags = req->flags;
+
*ppipe = pipe;
return 0;
}
+static int mdp4_calc_pipe_mdp_clk(struct msm_fb_data_type *mfd,
+ struct mdp4_overlay_pipe *pipe)
+{
+ u32 pclk;
+ u32 xscale, yscale;
+ u32 hsync = 0;
+ u32 shift = 16;
+ u64 rst;
+ int ret = -EINVAL;
+
+ 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;
+ }
+
+ /*
+ * Serveral special cases require the max mdp clk but cannot
+ * be explained by mdp clk equation.
+ */
+ if (pipe->flags & MDP_DEINTERLACE) {
+ pr_info("%s deinterlace requires max mdp clk.\n",
+ __func__);
+ pipe->req_clk = mdp_max_clk;
+ return 0;
+ }
+
+ pr_debug("%s: pipe sets: panel res(x,y)=(%d,%d)\n",
+ __func__, mfd->panel_info.xres, mfd->panel_info.yres);
+ pr_debug("%s: src(w,h)(%d,%d),src(x,y)(%d,%d)\n",
+ __func__, pipe->src_w, pipe->src_h, pipe->src_x, pipe->src_y);
+ pr_debug("%s: dst(w,h)(%d,%d),dst(x,y)(%d,%d)\n",
+ __func__, pipe->dst_w, pipe->dst_h, pipe->dst_x, pipe->dst_y);
+
+ pclk = (mfd->panel_info.type == MIPI_VIDEO_PANEL ||
+ mfd->panel_info.type == MIPI_CMD_PANEL) ?
+ mfd->panel_info.mipi.dsi_pclk_rate :
+ mfd->panel_info.clk_rate;
+ if (!pclk) {
+ pipe->req_clk = mdp_max_clk;
+ pr_err("%s panel pixel clk is zero!\n", __func__);
+ return ret;
+ }
+ pr_debug("%s: mdp panel pixel clk is %d.\n",
+ __func__, pclk);
+
+ if (!pipe->dst_h) {
+ pr_err("%s: pipe dst_h is zero!\n", __func__);
+ pipe->req_clk = mdp_max_clk;
+ return ret;
+ }
+
+ if (!pipe->src_h) {
+ pr_err("%s: pipe src_h is zero!\n", __func__);
+ pipe->req_clk = mdp_max_clk;
+ return ret;
+ }
+
+ if (!pipe->dst_w) {
+ pr_err("%s: pipe dst_w is zero!\n", __func__);
+ pipe->req_clk = mdp_max_clk;
+ return ret;
+ }
+
+ if (!pipe->dst_h) {
+ pr_err("%s: pipe dst_h is zero!\n", __func__);
+ pipe->req_clk = mdp_max_clk;
+ return ret;
+ }
+
+ /*
+ * For the scaling cases, make more margin by removing porch
+ * values and adding extra 20%.
+ */
+ if ((pipe->src_h != pipe->dst_h) ||
+ (pipe->src_w != pipe->dst_w)) {
+ hsync = mfd->panel_info.xres;
+ hsync *= 100;
+ hsync /= 120;
+ pr_debug("%s: panel hsync is %d. with scaling\n",
+ __func__, hsync);
+
+ } else {
+ hsync = mfd->panel_info.lcdc.h_back_porch +
+ mfd->panel_info.lcdc.h_front_porch +
+ mfd->panel_info.lcdc.h_pulse_width +
+ mfd->panel_info.xres;
+ pr_debug("%s: panel hsync is %d.\n",
+ __func__, hsync);
+ }
+
+ if (!hsync) {
+ pipe->req_clk = mdp_max_clk;
+ pr_err("%s: panel hsync is zero!\n", __func__);
+ return 0;
+ }
+
+ xscale = mfd->panel_info.xres;
+ xscale += pipe->src_w;
+
+ if (xscale < pipe->dst_w) {
+ pipe->req_clk = mdp_max_clk;
+ pr_err("%s: xres+src_w cannot be less than dst_w!\n",
+ __func__);
+ return ret;
+ }
+
+ xscale -= pipe->dst_w;
+ xscale <<= shift;
+ xscale /= hsync;
+ pr_debug("%s: the right %d shifted xscale is %d.\n",
+ __func__, shift, xscale);
+
+ if (pipe->src_h > pipe->dst_h) {
+ yscale = pipe->src_h;
+ yscale <<= shift;
+ yscale /= pipe->dst_h;
+ } else { /* upscale */
+ yscale = pipe->dst_h;
+ yscale <<= shift;
+ yscale /= pipe->src_h;
+ }
+
+ yscale *= pipe->src_w;
+ yscale /= hsync;
+
+ pr_debug("%s: the right %d shifted yscale is %d.\n",
+ __func__, shift, yscale);
+
+ rst = pclk;
+ if (yscale > xscale)
+ rst *= yscale;
+ else
+ rst *= xscale;
+
+ rst >>= shift;
+
+ /*
+ * If the calculated mdp clk is less than panel pixel clk,
+ * most likely due to upscaling, mdp clk rate will be set to
+ * greater than pclk. Now the driver uses 1.15 as the
+ * factor. Ideally this factor is passed from board file.
+ */
+ if (rst < pclk) {
+ rst = ((pclk >> shift) * 23 / 20) << shift;
+ pr_debug("%s calculated mdp clk is less than pclk.\n",
+ __func__);
+ }
+
+ pipe->req_clk = (u32) rst;
+
+ pr_debug("%s: required mdp clk %d mixer %d pipe ndx %d\n",
+ __func__, pipe->req_clk, pipe->mixer_num, pipe->pipe_ndx);
+
+ 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)
+{
+ u32 res;
+ int ret = -EINVAL;
+
+ if (!pipe) {
+ pr_err("%s: pipe is null!\n", __func__);
+ return ret;
+ }
+ if (!mfd) {
+ pr_err("%s: mfd is null!\n", __func__);
+ 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;
+ }
+
+ if (pipe->pipe_type == OVERLAY_TYPE_BF) {
+ pipe->req_bw = OVERLAY_PERF_LEVEL4;
+ return 0;
+ }
+
+ res = pipe->src_w * pipe->src_h;
+
+ 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;
+
+ return 0;
+}
+
+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;
+
+ if (!mfd) {
+ pr_err("%s: mfd is null!\n", __func__);
+ return ret;
+ }
+
+ if (!plist) {
+ pr_err("%s: plist is null!\n", __func__);
+ return ret;
+ }
+
+ perf_req->use_ov0_blt = 0;
+ perf_req->use_ov1_blt = 0;
+
+ for (i = 0; i < OVERLAY_PIPE_MAX; i++, pipe++) {
+
+ if (!pipe)
+ return ret;
+
+ if (!pipe->pipe_used)
+ continue;
+ 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_bw < worst_mdp_bw)
+ worst_mdp_bw = pipe->req_bw;
+
+ if (mfd->mdp_rev == MDP_REV_41) {
+ /*
+ * writeback (blt) mode to provide work around
+ * for dsi cmd mode interface hardware bug.
+ */
+ if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
+ if (pipe->dst_x != 0)
+ perf_req->use_ov0_blt = 1;
+ }
+ if ((mfd->panel_info.xres > 1280) &&
+ (mfd->panel_info.type != DTV_PANEL)) {
+ perf_req->use_ov0_blt = 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 = mdp_clk_round_rate(perf_req->mdp_clk_rate);
+
+ perf_req->mdp_bw = worst_mdp_bw;
+
+ if (cnt >= 3)
+ perf_req->mdp_bw = OVERLAY_PERF_LEVEL1;
+
+ pr_debug("%s %d pid %d cnt %d clk %d ov0_blt %d, ov1_blt %d bw %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);
+
+ return 0;
+}
+
+int mdp4_overlay_mdp_pipe_req(struct mdp4_overlay_pipe *pipe,
+ struct msm_fb_data_type *mfd)
+{
+ int ret = 0;
+
+ if (mdp4_calc_pipe_mdp_clk(mfd, pipe)) {
+ pr_err("%s unable to calc mdp pipe clk rate ret=%d\n",
+ __func__, ret);
+ ret = -EINVAL;
+ }
+ if (mdp4_calc_pipe_mdp_bw(mfd, pipe)) {
+ pr_err("%s unable to calc mdp pipe bandwidth ret=%d\n",
+ __func__, ret);
+ ret = -EINVAL;
+ }
+ return ret;
+}
+
+void mdp4_overlay_mdp_perf_upd(struct msm_fb_data_type *mfd,
+ int flag)
+{
+ struct mdp4_overlay_perf *perf_req = &perf_request;
+ struct mdp4_overlay_perf *perf_cur = &perf_current;
+
+ pr_debug("%s %d: req mdp clk %d, cur mdp clk %d flag %d\n",
+ __func__, __LINE__,
+ perf_req->mdp_clk_rate,
+ perf_cur->mdp_clk_rate,
+ flag);
+
+ if (!mdp4_extn_disp)
+ perf_cur->use_ov1_blt = 0;
+
+ if (flag) {
+ if (perf_req->mdp_clk_rate > perf_cur->mdp_clk_rate) {
+ mdp_set_core_clk(perf_req->mdp_clk_rate);
+ pr_info("%s mdp clk is changed [%d] from %d to %d\n",
+ __func__,
+ flag,
+ perf_cur->mdp_clk_rate,
+ perf_req->mdp_clk_rate);
+ perf_cur->mdp_clk_rate =
+ perf_req->mdp_clk_rate;
+ }
+ if (perf_req->mdp_bw < perf_cur->mdp_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",
+ __func__,
+ flag,
+ perf_cur->mdp_bw,
+ perf_req->mdp_bw);
+ perf_cur->mdp_bw = perf_req->mdp_bw;
+ }
+ if (mfd->panel_info.pdest == DISPLAY_1 &&
+ perf_req->use_ov0_blt && !perf_cur->use_ov0_blt) {
+ mdp4_allocate_writeback_buf(mfd, MDP4_MIXER0);
+ if (mfd->panel_info.type == LCDC_PANEL ||
+ mfd->panel_info.type == LVDS_PANEL)
+ mdp4_lcdc_overlay_blt_start(mfd);
+ else if (mfd->panel_info.type == MIPI_VIDEO_PANEL)
+ mdp4_dsi_video_blt_start(mfd);
+ else if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD)
+ mdp4_dsi_cmd_blt_start(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;
+ }
+ if (mfd->panel_info.pdest == DISPLAY_2 &&
+ perf_req->use_ov1_blt && !perf_cur->use_ov1_blt) {
+ mdp4_allocate_writeback_buf(mfd, MDP4_MIXER1);
+ mdp4_dtv_overlay_blt_start(mfd);
+ pr_info("%s mixer1 start blt [%d] from %d to %d.\n",
+ __func__,
+ flag,
+ perf_cur->use_ov1_blt,
+ perf_req->use_ov1_blt);
+ perf_cur->use_ov1_blt = perf_req->use_ov1_blt;
+ }
+ } else {
+ if (perf_req->mdp_clk_rate < perf_cur->mdp_clk_rate) {
+ pr_info("%s mdp clk is changed [%d] from %d to %d\n",
+ __func__,
+ flag,
+ perf_cur->mdp_clk_rate,
+ perf_req->mdp_clk_rate);
+ mdp_set_core_clk(perf_req->mdp_clk_rate);
+ 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",
+ __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;
+ }
+ if (mfd->panel_info.pdest == DISPLAY_1 &&
+ !perf_req->use_ov0_blt && perf_cur->use_ov0_blt) {
+ if (mfd->panel_info.type == LCDC_PANEL ||
+ mfd->panel_info.type == LVDS_PANEL)
+ mdp4_lcdc_overlay_blt_stop(mfd);
+ else if (mfd->panel_info.type == MIPI_VIDEO_PANEL)
+ mdp4_dsi_video_blt_stop(mfd);
+ else if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD)
+ mdp4_dsi_cmd_blt_stop(mfd);
+ mdp4_free_writeback_buf(mfd, MDP4_MIXER0);
+ 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;
+ }
+ if (mfd->panel_info.pdest == DISPLAY_2 &&
+ !perf_req->use_ov1_blt && perf_cur->use_ov1_blt) {
+ mdp4_dtv_overlay_blt_stop(mfd);
+ mdp4_free_writeback_buf(mfd, MDP4_MIXER1);
+ pr_info("%s mixer1 stop blt [%d] from %d to %d.\n",
+ __func__,
+ flag,
+ perf_cur->use_ov1_blt,
+ perf_req->use_ov1_blt);
+ perf_cur->use_ov1_blt = perf_req->use_ov1_blt;
+ }
+ }
+ return;
+}
+
static int get_img(struct msmfb_data *img, struct fb_info *info,
struct mdp4_overlay_pipe *pipe, unsigned int plane,
unsigned long *start, unsigned long *len, struct file **srcp_file,
@@ -2555,154 +2936,10 @@
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_overlay_is_rgb_type(int format)
-{
- switch (format) {
- case MDP_RGB_565:
- case MDP_RGB_888:
- case MDP_BGR_565:
- case MDP_XRGB_8888:
- case MDP_ARGB_8888:
- case MDP_RGBA_8888:
- case MDP_BGRA_8888:
- case MDP_RGBX_8888:
- return 1;
- default:
- return 0;
- }
-}
-
-static uint32 mdp4_overlay_get_perf_level(struct mdp_overlay *req,
- struct msm_fb_data_type *mfd)
-{
- int is_fg = 0, i, cnt;
-
- if (req->is_fg && ((req->alpha & 0x0ff) == 0xff))
- is_fg = 1;
-
- if (mdp4_extn_disp)
- return OVERLAY_PERF_LEVEL1;
-
- if (req->flags & (MDP_DEINTERLACE | MDP_BACKEND_COMPOSITION))
- return OVERLAY_PERF_LEVEL1;
-
- for (i = 0, cnt = 0; i < OVERLAY_PIPE_MAX; i++) {
- if (ctrl->plist[i].pipe_used && ++cnt > 2)
- return OVERLAY_PERF_LEVEL1;
- }
-
- if (mdp4_overlay_is_rgb_type(req->src.format) && is_fg &&
- ((req->src.width * req->src.height) <= OVERLAY_WSVGA_SIZE))
- return OVERLAY_PERF_LEVEL4;
- else if (mdp4_overlay_is_rgb_type(req->src.format))
- return OVERLAY_PERF_LEVEL1;
-
- if (req->src.width*req->src.height <= OVERLAY_VGA_SIZE) {
- if (mfd->mdp_rev >= MDP_REV_42)
- return OVERLAY_PERF_LEVEL4;
- else
- return OVERLAY_PERF_LEVEL3;
-
- } else if (req->src.width*req->src.height <= OVERLAY_720P_TILE_SIZE) {
- u32 max, min;
- max = (req->dst_rect.h > req->dst_rect.w) ?
- req->dst_rect.h : req->dst_rect.w;
- min = (mfd->panel_info.yres > mfd->panel_info.xres) ?
- mfd->panel_info.xres : mfd->panel_info.yres;
- if (max > min) /* landscape mode */
- return OVERLAY_PERF_LEVEL3;
- else /* potrait mode */
- return OVERLAY_PERF_LEVEL2;
- }
- else
- return OVERLAY_PERF_LEVEL1;
-}
-
-void mdp4_update_perf_level(u32 perf_level)
-{
- static int first = 1;
-
- new_perf_level = perf_level;
-
- if (first) {
- first = 0;
- mdp4_set_perf_level();
- }
-}
-
-void mdp4_set_perf_level(void)
-{
- static int old_perf_level;
- int cur_perf_level;
-
- if (mdp4_extn_disp)
- cur_perf_level = OVERLAY_PERF_LEVEL1;
- else
- cur_perf_level = new_perf_level;
-
- if (old_perf_level != cur_perf_level) {
- mdp_set_core_clk(cur_perf_level);
- old_perf_level = cur_perf_level;
- mdp_bus_scale_update_request(OVERLAY_BUS_SCALE_TABLE_BASE
- - cur_perf_level);
- }
-}
-
-static u32 mdp4_overlay_blt_enable(struct mdp_overlay *req,
- struct msm_fb_data_type *mfd, uint32 perf_level)
-{
- u32 clk_rate = mfd->panel_info.clk_rate;
- u32 blt_chq_req = 0, use_blt = 0;
-
- if ((mfd->panel_info.type == MIPI_VIDEO_PANEL) ||
- (mfd->panel_info.type == MIPI_CMD_PANEL))
- clk_rate = (&mfd->panel_info.mipi)->dsi_pclk_rate;
-
- if ((mfd->panel_info.type == LCDC_PANEL) ||
- (mfd->panel_info.type == MIPI_VIDEO_PANEL) ||
- (mfd->panel_info.type == DTV_PANEL) ||
- (mfd->panel_info.type == MIPI_CMD_PANEL))
- blt_chq_req = 1;
-
- if (blt_chq_req && (req->src_rect.h > req->dst_rect.h ||
- req->src_rect.w > req->dst_rect.w)) {
- if (mdp4_overlay_validate_downscale(req, mfd, perf_level,
- clk_rate))
- use_blt = 1;
- }
-
- if (mfd->panel_info.type == MDDI_PANEL) {
- if ((req->src_rect.h/2) >= req->dst_rect.h ||
- (req->src_rect.w/2) >= req->dst_rect.w)
- use_blt = 1;
- }
-
- if (mfd->mdp_rev == MDP_REV_41) {
- /*
- * writeback (blt) mode to provide work around for
- * dsi cmd mode interface hardware bug.
- */
- if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
- if (req->dst_rect.x != 0)
- use_blt = 1;
- }
- if ((mfd->panel_info.xres > 1280) &&
- (mfd->panel_info.type != DTV_PANEL))
- use_blt = 1;
- }
- return use_blt;
-}
-
int mdp4_overlay_set(struct fb_info *info, struct mdp_overlay *req)
{
struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
- int ret, mixer, perf_level;
+ int ret, mixer;
struct mdp4_overlay_pipe *pipe;
if (mfd == NULL) {
@@ -2732,20 +2969,10 @@
return ret;
}
- perf_level = mdp4_overlay_get_perf_level(req, mfd);
-
- if (mixer == MDP4_MIXER0) {
- u32 use_blt = mdp4_overlay_blt_enable(req, mfd, perf_level);
- mfd->use_ov0_blt &= ~(1 << (pipe->pipe_ndx-1));
- mfd->use_ov0_blt |= (use_blt << (pipe->pipe_ndx-1));
- }
-
/* return id back to user */
req->id = pipe->pipe_ndx; /* pipe_ndx start from 1 */
pipe->req_data = *req; /* keep original req */
- pipe->flags = req->flags;
-
if (!IS_ERR_OR_NULL(mfd->iclient)) {
pr_debug("pipe->flags 0x%x\n", pipe->flags);
if (pipe->flags & MDP_SECURE_OVERLAY_SESSION) {
@@ -2768,47 +2995,8 @@
__func__);
}
- if (ctrl->panel_mode & MDP4_PANEL_DTV &&
- pipe->mixer_num == MDP4_MIXER1) {
- u32 use_blt = mdp4_overlay_blt_enable(req, mfd, perf_level);
+ mdp4_overlay_mdp_pipe_req(pipe, mfd);
- if (hdmi_prim_display) {
- if (!mdp4_overlay_is_rgb_type(req->src.format) &&
- pipe->pipe_type == OVERLAY_TYPE_VIDEO &&
- (req->src_rect.h > req->dst_rect.h ||
- req->src_rect.w > req->dst_rect.w))
- use_blt = 1;
- }
-
- mdp4_overlay_dtv_set(mfd, pipe);
- mfd->use_ov1_blt &= ~(1 << (pipe->pipe_ndx-1));
- mfd->use_ov1_blt |= (use_blt << (pipe->pipe_ndx-1));
- }
-
- if (new_perf_level != perf_level) {
- u32 old_level = new_perf_level;
- mdp4_update_perf_level(perf_level);
-
- /* change clck base on perf level */
- if (pipe->mixer_num == MDP4_MIXER0) {
- if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO) {
- if (old_level > perf_level)
- mdp4_set_perf_level();
- } else if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
- mdp4_set_perf_level();
- } else if (ctrl->panel_mode & MDP4_PANEL_LCDC) {
- if (old_level > perf_level)
- mdp4_set_perf_level();
- } else if (ctrl->panel_mode & MDP4_PANEL_MDDI) {
- mdp4_mddi_dma_busy_wait(mfd);
- mdp4_mddi_blt_dmap_busy_wait(mfd);
- mdp4_set_perf_level();
- }
- } else {
- if (ctrl->panel_mode & MDP4_PANEL_DTV)
- mdp4_overlay_dtv_set_perf(mfd);
- }
- }
mutex_unlock(&mfd->dma->ov_mutex);
return 0;
@@ -2864,7 +3052,6 @@
else {
/* mixer 0 */
ctrl->mixer0_played = 0;
-
if (ctrl->panel_mode & MDP4_PANEL_MDDI) {
if (mfd->panel_power_on)
mdp4_mddi_blt_dmap_busy_wait(mfd);
@@ -2879,13 +3066,9 @@
if (mfd->panel_power_on)
mdp4_mddi_overlay_restore();
}
-
- mfd->use_ov0_blt &= ~(1 << (pipe->pipe_ndx-1));
} else { /* mixer1, DTV, ATV */
- if (ctrl->panel_mode & MDP4_PANEL_DTV) {
+ if (ctrl->panel_mode & MDP4_PANEL_DTV)
mdp4_overlay_dtv_unset(mfd, pipe);
- mfd->use_ov1_blt &= ~(1 << (pipe->pipe_ndx-1));
- }
}
mdp4_stat.overlay_unset[pipe->mixer_num]++;
@@ -3002,7 +3185,6 @@
pr_debug("%s: pipe=%x ndx=%d num=%d used=%d\n", __func__,
(int) pipe, pipe->pipe_ndx, pipe->pipe_num, pipe->pipe_used);
-
mdp4_overlay_reg_flush(pipe, 1);
mdp4_mixer_stage_up(pipe);
}
@@ -3148,6 +3330,7 @@
}
}
+ mdp4_overlay_mdp_perf_req(mfd, ctrl->plist);
if (pipe->mixer_num == MDP4_MIXER2 ||
ctrl->panel_mode & MDP4_PANEL_MDDI)
@@ -3173,7 +3356,6 @@
return ret;
mddi:
-
if (pipe->pipe_type == OVERLAY_TYPE_VIDEO) {
mdp4_overlay_vg_setup(pipe); /* video/graphic pipe */
} else {
diff --git a/drivers/video/msm/mdp4_overlay_atv.c b/drivers/video/msm/mdp4_overlay_atv.c
index 753ff23..3fe00ed 100644
--- a/drivers/video/msm/mdp4_overlay_atv.c
+++ b/drivers/video/msm/mdp4_overlay_atv.c
@@ -110,7 +110,6 @@
mdp4_overlay_dmae_xy(pipe); /* dma_e */
mdp4_overlay_dmae_cfg(mfd, 1);
-
mdp4_overlay_rgb_setup(pipe);
mdp4_overlayproc_cfg(pipe);
@@ -183,6 +182,8 @@
} else {
pipe->srcp0_addr = (uint32)(buf + buf_offset);
}
+ mdp4_overlay_mdp_perf_req(pipe, mfd);
+ mdp4_overlay_mdp_perf_upd(mfd, 1);
mdp4_overlay_rgb_setup(pipe);
mdp4_overlay_reg_flush(pipe, 0);
mdp4_mixer_stage_up(pipe);
@@ -201,10 +202,7 @@
spin_unlock_irqrestore(&mdp_spin_lock, flag);
wait_for_completion_killable(&atv_pipe->comp);
mdp_disable_irq(MDP_OVERLAY1_TERM);
-
- /* change mdp clk while mdp is idle` */
- mdp4_set_perf_level();
-
+ mdp4_overlay_mdp_perf_upd(mfd, 0);
mdp4_stat.kickoff_atv++;
mutex_unlock(&mfd->dma->ov_mutex);
}
diff --git a/drivers/video/msm/mdp4_overlay_dsi_cmd.c b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
index e1fa02e..05a89b8 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_cmd.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
@@ -864,6 +864,7 @@
/* disable dsi trigger */
MDP_OUTP(MDP_BASE + 0x000a4, 0x00);
+
mdp4_overlay_setup_pipe_addr(mfd, pipe);
mdp4_overlay_rgb_setup(pipe);
@@ -1098,18 +1099,12 @@
mdp4_dsi_cmd_pipe_queue(0, pipe);
}
- if (mfd->use_ov0_blt != mfd->ov0_blt_state) {
-
- if (mfd->use_ov0_blt)
- mdp4_dsi_cmd_do_blt(mfd, 1);
- else
- mdp4_dsi_cmd_do_blt(mfd, 0);
-
- mfd->ov0_blt_state = mfd->use_ov0_blt;
- }
+ mdp4_overlay_mdp_perf_upd(mfd, 1);
mdp4_dsi_cmd_pipe_commit();
mdp4_dsi_cmd_wait4vsync(0, &xx);
vctrl->expire_tick = VSYNC_EXPIRE_TICK;
vctrl->clk_control = 1;
+
+ mdp4_overlay_mdp_perf_upd(mfd, 0);
}
diff --git a/drivers/video/msm/mdp4_overlay_dsi_video.c b/drivers/video/msm/mdp4_overlay_dsi_video.c
index 8654ba1..a8b906a 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_video.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_video.c
@@ -193,6 +193,8 @@
}
spin_unlock_irqrestore(&vctrl->spin_lock, flags);
+ mdp4_overlay_mdp_perf_upd(vctrl->mfd, 1);
+
if (vctrl->blt_change) {
pipe = vctrl->base_pipe;
spin_lock_irqsave(&vctrl->spin_lock, flags);
@@ -206,6 +208,7 @@
}
pipe = vp->plist;
+
for (i = 0; i < OVERLAY_PIPE_MAX; i++, pipe++) {
if (pipe->pipe_used) {
cnt++;
@@ -539,6 +542,8 @@
pipe->dst_h = fbi->var.yres;
pipe->dst_w = fbi->var.xres;
+ mdp4_overlay_mdp_pipe_req(pipe, mfd);
+
atomic_set(&vctrl->suspend, 0);
mdp4_overlay_dmap_xy(pipe); /* dma_p */
@@ -820,13 +825,6 @@
MDP_OUTP(MDP_BASE + 0x90008, addr);
}
-void mdp4_overlay_dsi_video_set_perf(struct msm_fb_data_type *mfd)
-{
- /* change mdp clk while mdp is idle */
- mdp4_set_perf_level();
-}
-
-
/*
* mdp4_primary_vsync_dsi_video: called from isr
*/
@@ -928,8 +926,6 @@
vctrl = &vsync_ctrl_db[cndx];
pipe = vctrl->base_pipe;
- mdp4_allocate_writeback_buf(mfd, MDP4_MIXER0);
-
if (mfd->ov0_wb_buf->write_addr == 0) {
pr_info("%s: no blt_base assigned\n", __func__);
return;
@@ -1011,15 +1007,7 @@
mdp4_dsi_video_pipe_queue(0, pipe);
}
- if (mfd->use_ov0_blt != mfd->ov0_blt_state) {
-
- if (mfd->use_ov0_blt)
- mdp4_dsi_video_do_blt(mfd, 1);
- else
- mdp4_dsi_video_do_blt(mfd, 0);
-
- mfd->ov0_blt_state = mfd->use_ov0_blt;
- }
+ mdp4_overlay_mdp_perf_upd(mfd, 1);
mdp4_dsi_video_pipe_commit();
@@ -1027,5 +1015,7 @@
mdp4_dsi_video_wait4ov(0);
else
mdp4_dsi_video_wait4dmap(0);
+
+ mdp4_overlay_mdp_perf_upd(mfd, 0);
}
diff --git a/drivers/video/msm/mdp4_overlay_dtv.c b/drivers/video/msm/mdp4_overlay_dtv.c
index a03e344..d22de54 100644
--- a/drivers/video/msm/mdp4_overlay_dtv.c
+++ b/drivers/video/msm/mdp4_overlay_dtv.c
@@ -647,8 +647,7 @@
void mdp4_overlay_dtv_set_perf(struct msm_fb_data_type *mfd)
{
- /* change mdp clk while mdp is idle` */
- mdp4_set_perf_level();
+
}
static void mdp4_overlay_dtv_alloc_pipe(struct msm_fb_data_type *mfd,
@@ -701,12 +700,16 @@
pipe->src_width = fbi->var.xres;
pipe->src_h = fbi->var.yres;
pipe->src_w = fbi->var.xres;
+ pipe->dst_h = fbi->var.yres;
+ pipe->dst_w = fbi->var.xres;
pipe->src_y = 0;
pipe->src_x = 0;
pipe->dst_h = fbi->var.yres;
pipe->dst_w = fbi->var.xres;
pipe->srcp0_ystride = fbi->fix.line_length;
+ mdp4_overlay_mdp_pipe_req(pipe, mfd);
+
ret = mdp4_overlay_format2pipe(pipe);
if (ret < 0)
pr_warn("%s: format2type failed\n", __func__);
@@ -838,6 +841,7 @@
} else {
mdp4_overlay_dma_commit(MDP4_MIXER1);
}
+
vsync_irq_disable(INTR_DMA_E_DONE, MDP_DMA_E_TERM);
spin_unlock(&vctrl->spin_lock);
}
diff --git a/drivers/video/msm/mdp4_overlay_lcdc.c b/drivers/video/msm/mdp4_overlay_lcdc.c
index f6ba22c..4a478cd 100644
--- a/drivers/video/msm/mdp4_overlay_lcdc.c
+++ b/drivers/video/msm/mdp4_overlay_lcdc.c
@@ -198,6 +198,8 @@
}
spin_unlock_irqrestore(&vctrl->spin_lock, flags);
+ mdp4_overlay_mdp_perf_upd(vctrl->mfd, 1);
+
if (vctrl->blt_change) {
pipe = vctrl->base_pipe;
spin_lock_irqsave(&vctrl->spin_lock, flags);
@@ -513,6 +515,8 @@
pipe->srcp0_ystride = fbi->fix.line_length;
pipe->bpp = bpp;
+ mdp4_overlay_mdp_pipe_req(pipe, mfd);
+
atomic_set(&vctrl->suspend, 0);
mdp4_overlay_dmap_xy(pipe);
@@ -714,12 +718,6 @@
MDP_OUTP(MDP_BASE + 0x90008, addr);
}
-void mdp4_overlay_lcdc_set_perf(struct msm_fb_data_type *mfd)
-{
- /* change mdp clk while mdp is idle */
- mdp4_set_perf_level();
-}
-
/*
* mdp4_primary_vsync_lcdc: called from isr
*/
@@ -900,15 +898,7 @@
mdp4_lcdc_pipe_queue(0, pipe);
}
- if (mfd->use_ov0_blt != mfd->ov0_blt_state) {
-
- if (mfd->use_ov0_blt)
- mdp4_lcdc_do_blt(mfd, 1);
- else
- mdp4_lcdc_do_blt(mfd, 0);
-
- mfd->ov0_blt_state = mfd->use_ov0_blt;
- }
+ mdp4_overlay_mdp_perf_upd(mfd, 1);
mdp4_lcdc_pipe_commit();
@@ -916,4 +906,6 @@
mdp4_lcdc_wait4ov(0);
else
mdp4_lcdc_wait4dmap(0);
+
+ mdp4_overlay_mdp_perf_upd(mfd, 0);
}
diff --git a/drivers/video/msm/mdp4_overlay_mddi.c b/drivers/video/msm/mdp4_overlay_mddi.c
index 103419e..d10e669 100644
--- a/drivers/video/msm/mdp4_overlay_mddi.c
+++ b/drivers/video/msm/mdp4_overlay_mddi.c
@@ -574,8 +574,6 @@
struct mdp4_overlay_pipe *pipe)
{
unsigned long flag;
- /* change mdp clk while mdp is idle` */
- mdp4_set_perf_level();
mdp_enable_irq(MDP_OVERLAY0_TERM);
spin_lock_irqsave(&mdp_spin_lock, flag);
@@ -660,9 +658,6 @@
void mdp4_mddi_dma_s_kickoff(struct msm_fb_data_type *mfd,
struct mdp4_overlay_pipe *pipe)
{
- /* change mdp clk while mdp is idle` */
- mdp4_set_perf_level();
-
mdp_enable_irq(MDP_DMA_S_TERM);
if (mddi_pipe->ov_blt_addr == 0)
@@ -698,9 +693,10 @@
if (mddi_pipe && mddi_pipe->ov_blt_addr)
mdp4_mddi_blt_dmap_busy_wait(mfd);
-
+ mdp4_overlay_mdp_perf_upd(mfd, 0);
mdp4_overlay_update_lcd(mfd);
+ mdp4_overlay_mdp_perf_upd(mfd, 1);
if (mdp_hw_revision < MDP4_REVISION_V2_1) {
/* dmas dmap switch */
if (mdp4_overlay_mixer_play(mddi_pipe->mixer_num)
diff --git a/drivers/video/msm/mdp4_overlay_writeback.c b/drivers/video/msm/mdp4_overlay_writeback.c
index 9c06992..d8e4be4 100644
--- a/drivers/video/msm/mdp4_overlay_writeback.c
+++ b/drivers/video/msm/mdp4_overlay_writeback.c
@@ -174,6 +174,8 @@
pipe->dst_y = 0;
pipe->dst_x = 0;
+ mdp4_overlay_mdp_pipe_req(pipe, mfd);
+
if (mfd->display_iova)
pipe->srcp0_addr = mfd->display_iova + buf_offset;
else
diff --git a/drivers/video/msm/mdp4_util.c b/drivers/video/msm/mdp4_util.c
index e76b8ba..ca73a70 100644
--- a/drivers/video/msm/mdp4_util.c
+++ b/drivers/video/msm/mdp4_util.c
@@ -249,7 +249,7 @@
/* MDP cmd block enable */
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
- mdp4_update_perf_level(OVERLAY_PERF_LEVEL4);
+ mdp_bus_scale_update_request(5);
#ifdef MDP4_ERROR
/*
diff --git a/drivers/video/msm/msm_fb.h b/drivers/video/msm/msm_fb.h
index efe6160..ae5acf4 100644
--- a/drivers/video/msm/msm_fb.h
+++ b/drivers/video/msm/msm_fb.h
@@ -184,8 +184,6 @@
u32 ov_start;
u32 mem_hid;
u32 mdp_rev;
- u32 use_ov0_blt, ov0_blt_state;
- u32 use_ov1_blt, ov1_blt_state;
u32 writeback_state;
bool writeback_active_cnt;
int cont_splash_done;