diff options
| author | Siddhartha Agrawal <agrawals@codeaurora.org> | 2013-01-31 19:36:15 -0800 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 20:15:00 -0700 |
| commit | a83bd56c966bf6d036ecf767e81fb02c8a043d5e (patch) | |
| tree | 0c884f527785d69e724efc9e40ba745eefdf38b5 /drivers/video/fbdev/msm | |
| parent | 4c991bc6620ca1d99a5e6f48fd2382bac42a3866 (diff) | |
mdss: display: Enable continuous splash for Toshiba 720p
Enabling for MTP, CDP and FLUID devices. The continuous splash
flag is set in the platform dtsi which will keep the MDSS and
DSI settings intact till the first frame update.
Since the MDSS related clocks are enabled in the lk,
we still vote for the clocks in our probe to carry them
forward. The bandwidth request is made for the same
reason as well.
Change-Id: Iffb2d1b63b85d63db5db234b546805962bd9b913
Signed-off-by: Siddhartha Agrawal <agrawals@codeaurora.org>
Diffstat (limited to 'drivers/video/fbdev/msm')
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dsi.c | 91 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_fb.c | 9 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp.c | 43 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp.h | 6 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_ctl.c | 17 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_overlay.c | 102 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_panel.h | 4 |
7 files changed, 224 insertions, 48 deletions
diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c index 5bd70947fa97..83a5f5bc64a6 100644 --- a/drivers/video/fbdev/msm/mdss_dsi.c +++ b/drivers/video/fbdev/msm/mdss_dsi.c @@ -135,8 +135,8 @@ static int mdss_dsi_panel_power_on(struct mdss_panel_data *pdata, int enable) pr_err("%s: Failed to enable regulator.\n", __func__); return ret; } - - mdss_dsi_panel_reset(pdata, 1); + if (pdata->panel_info.panel_power_on == 0) + mdss_dsi_panel_reset(pdata, 1); } else { @@ -222,6 +222,13 @@ static int mdss_dsi_off(struct mdss_panel_data *pdata) return -EINVAL; } + if (!pdata->panel_info.panel_power_on) { + pr_warn("%s:%d Panel already off.\n", __func__, __LINE__); + return -EPERM; + } + + pdata->panel_info.panel_power_on = 0; + ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); mdss_dsi_clk_disable(pdata); @@ -241,7 +248,38 @@ static int mdss_dsi_off(struct mdss_panel_data *pdata) return ret; } -static int mdss_dsi_on(struct mdss_panel_data *pdata) +int mdss_dsi_cont_splash_on(struct mdss_panel_data *pdata) +{ + int ret = 0; + struct mipi_panel_info *mipi; + + pr_info("%s:%d DSI on for continuous splash.\n", __func__, __LINE__); + + if (pdata == NULL) { + pr_err("%s: Invalid input data\n", __func__); + return -EINVAL; + } + + mipi = &pdata->panel_info.mipi; + + ret = mdss_dsi_panel_power_on(pdata, 1); + if (ret) { + pr_err("%s: Panel power on failed\n", __func__); + return ret; + } + mdss_dsi_sw_reset(pdata); + mdss_dsi_host_init(mipi, pdata); + + pdata->panel_info.panel_power_on = 1; + + mdss_dsi_op_mode_config(mipi->mode, pdata); + + pr_debug("%s-:End\n", __func__); + return ret; +} + + +int mdss_dsi_on(struct mdss_panel_data *pdata) { int ret = 0; u32 clk_rate; @@ -257,6 +295,11 @@ static int mdss_dsi_on(struct mdss_panel_data *pdata) return -EINVAL; } + if (pdata->panel_info.panel_power_on) { + pr_warn("%s:%d Panel already on.\n", __func__, __LINE__); + return 0; + } + ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); pinfo = &pdata->panel_info; @@ -267,6 +310,8 @@ static int mdss_dsi_on(struct mdss_panel_data *pdata) return ret; } + pdata->panel_info.panel_power_on = 1; + mdss_dsi_phy_sw_reset((ctrl_pdata->ctrl_base)); mdss_dsi_phy_init(pdata); @@ -394,6 +439,16 @@ static int mdss_dsi_event_handler(struct mdss_panel_data *pdata, } rc = mdss_dsi_off(pdata); break; + case MDSS_EVENT_CONT_SPLASH_FINISH: + if (ctrl_pdata->on_cmds->ctrl_state == DSI_LP_MODE) { + rc = mdss_dsi_cont_splash_on(pdata); + } else { + pr_debug("%s:event=%d, Dsi On not called: ctrl_state: %d\n", + __func__, event, + ctrl_pdata->on_cmds->ctrl_state); + rc = -EINVAL; + } + break; default: pr_debug("%s: unhandled event=%d\n", __func__, event); break; @@ -542,6 +597,7 @@ int dsi_panel_device_register(struct platform_device *pdev, struct platform_device *ctrl_pdev = NULL; unsigned char *ctrl_addr; bool broadcast; + bool cont_splash_enabled = false; h_period = ((panel_data->panel_info.lcdc.h_pulse_width) + (panel_data->panel_info.lcdc.h_back_porch) @@ -649,13 +705,6 @@ int dsi_panel_device_register(struct platform_device *pdev, gpio_free(ctrl_pdata->disp_en_gpio); return -ENODEV; } - rc = gpio_direction_output(ctrl_pdata->disp_en_gpio, 1); - if (rc) { - pr_err("set_direction for disp_en gpio failed, rc=%d\n", - rc); - gpio_free(ctrl_pdata->disp_en_gpio); - return -ENODEV; - } } ctrl_pdata->rst_gpio = of_get_named_gpio(pdev->dev.of_node, @@ -705,6 +754,28 @@ int dsi_panel_device_register(struct platform_device *pdev, /* * register in mdp driver */ + + cont_splash_enabled = of_property_read_bool(pdev->dev.of_node, + "qcom,cont-splash-enabled"); + if (!cont_splash_enabled) { + pr_info("%s:%d Continous splash flag not found.\n", + __func__, __LINE__); + ctrl_pdata->panel_data.panel_info.cont_splash_enabled = 0; + ctrl_pdata->panel_data.panel_info.panel_power_on = 0; + } else { + pr_info("%s:%d Continous splash flag enabled.\n", + __func__, __LINE__); + + ctrl_pdata->panel_data.panel_info.cont_splash_enabled = 1; + ctrl_pdata->panel_data.panel_info.panel_power_on = 1; + } + + + if (ctrl_pdata->panel_data.panel_info.cont_splash_enabled) { + mdss_dsi_prepare_clocks(ctrl_pdata); + mdss_dsi_clk_enable(&(ctrl_pdata->panel_data)); + } + rc = mdss_register_panel(ctrl_pdev, &(ctrl_pdata->panel_data)); if (rc) { dev_err(&pdev->dev, "unable to register MIPI DSI panel\n"); diff --git a/drivers/video/fbdev/msm/mdss_fb.c b/drivers/video/fbdev/msm/mdss_fb.c index fa5d4c1ebc6b..36f70dab2e4f 100644 --- a/drivers/video/fbdev/msm/mdss_fb.c +++ b/drivers/video/fbdev/msm/mdss_fb.c @@ -1844,6 +1844,15 @@ int mdss_register_panel(struct platform_device *pdev, fb_pdev->dev.platform_data = pdata; } + /* + * Clocks are already on if continuous splash is enabled, + * increasing ref_cnt to help balance clocks once done. + */ + if (pdata->panel_info.cont_splash_enabled) { + mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false); + mdss_mdp_footswitch_ctrl_splash(1); + } + mdss_notfound: of_node_put(node); diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c index de88c546a7c0..77762d773313 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.c +++ b/drivers/video/fbdev/msm/mdss_mdp.c @@ -54,6 +54,9 @@ struct mdss_data_type *mdss_res; +#define IB_QUOTA 800000000 +#define AB_QUOTA 800000000 + static DEFINE_SPINLOCK(mdp_lock); static DEFINE_MUTEX(mdp_clk_lock); @@ -644,7 +647,7 @@ int mdss_iommu_attach(struct mdss_data_type *mdata) int i; if (mdata->iommu_attached) { - pr_warn("mdp iommu already attached\n"); + pr_debug("mdp iommu already attached\n"); return 0; } @@ -751,7 +754,7 @@ static int mdss_mdp_debug_init(struct mdss_data_type *mdata) return 0; } -static int mdss_hw_init(struct mdss_data_type *mdata) +int mdss_hw_init(struct mdss_data_type *mdata) { int i, j; char *offset; @@ -823,6 +826,24 @@ static u32 mdss_mdp_res_init(struct mdss_data_type *mdata) return rc; } +void mdss_mdp_footswitch_ctrl_splash(int on) +{ + int ret; + if (mdss_res != NULL) { + if (on) { + pr_debug("Enable MDP FS for splash.\n"); + ret = regulator_enable(mdss_res->fs); + if (ret) + pr_err("Footswitch failed to enable\n"); + } else { + pr_debug("Disable MDP FS for splash.\n"); + regulator_disable(mdss_res->fs); + } + } else { + pr_warn("mdss mdata not initialized\n"); + } +} + static int mdss_mdp_probe(struct platform_device *pdev) { struct resource *res; @@ -915,6 +936,7 @@ static int mdss_mdp_probe(struct platform_device *pdev) pr_err("unable to register bus scaling\n"); goto probe_done; } + mdss_mdp_bus_scale_set_quota(AB_QUOTA, IB_QUOTA); rc = mdss_mdp_debug_init(mdata); if (rc) { @@ -1332,18 +1354,19 @@ static void mdss_mdp_footswitch_ctrl(struct mdss_data_type *mdata, int on) if (!mdata->fs) return; - if (on && !mdata->fs_ena) { + if (on) { pr_debug("Enable MDP FS\n"); - ret = regulator_enable(mdata->fs); - if (ret) - pr_err("Footswitch failed to enable\n"); - mdss_iommu_attach(mdata); - mdss_hw_init(mdata); + if (!mdata->fs_ena) { + ret = regulator_enable(mdata->fs); + if (ret) + pr_err("Footswitch failed to enable\n"); + } mdata->fs_ena = true; - } else if (!on && mdata->fs_ena) { + } else { pr_debug("Disable MDP FS\n"); mdss_iommu_dettach(mdata); - regulator_disable(mdata->fs); + if (mdata->fs_ena) + regulator_disable(mdata->fs); mdata->fs_ena = false; } } diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h index 29bc79ac7dff..eadf87708d98 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.h +++ b/drivers/video/fbdev/msm/mdss_mdp.h @@ -27,7 +27,7 @@ #define MDSS_MDP_CURSOR_HEIGHT 64 #define MDSS_MDP_CURSOR_SIZE (MDSS_MDP_CURSOR_WIDTH*MDSS_MDP_CURSOR_WIDTH*4) -#define MDP_CLK_DEFAULT_RATE 37500000 +#define MDP_CLK_DEFAULT_RATE 200000000 #define PHASE_STEP_SHIFT 21 #define MAX_MIXER_WIDTH 2048 #define MAX_MIXER_HEIGHT 2400 @@ -295,6 +295,7 @@ static inline u32 mdss_mdp_ctl_read(struct mdss_mdp_ctl *ctl, u32 reg) } irqreturn_t mdss_mdp_isr(int irq, void *ptr); +int mdss_iommu_attach(struct mdss_data_type *mdata); int mdss_mdp_irq_enable(u32 intr_type, u32 intf_num); void mdss_mdp_irq_disable(u32 intr_type, u32 intf_num); int mdss_mdp_hist_irq_enable(u32 irq); @@ -303,6 +304,7 @@ void mdss_mdp_irq_disable_nosync(u32 intr_type, u32 intf_num); int mdss_mdp_set_intr_callback(u32 intr_type, u32 intf_num, void (*fnc_ptr)(void *), void *arg); +void mdss_mdp_footswitch_ctrl_splash(int on); int mdss_mdp_bus_scale_set_quota(u64 ab_quota, u64 ib_quota); void mdss_mdp_set_clk_rate(unsigned long min_clk_rate); unsigned long mdss_mdp_get_clk_rate(u32 clk_idx); @@ -352,6 +354,8 @@ int mdss_mdp_pipe_pp_setup(struct mdss_mdp_pipe *pipe, u32 *op); int mdss_mdp_pipe_sspp_setup(struct mdss_mdp_pipe *pipe, u32 *op); void mdss_mdp_pipe_sspp_term(struct mdss_mdp_pipe *pipe); +int mdss_hw_init(struct mdss_data_type *mdata); + int mdss_mdp_pa_config(struct mdss_mdp_ctl *ctl, struct mdp_pa_cfg_data *config, u32 *copyback); diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c index 4b7263d206dc..4d6298db9f0b 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c +++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c @@ -566,6 +566,12 @@ struct mdss_mdp_ctl *mdss_mdp_ctl_init(struct mdss_panel_data *pdata, ctl->opmode |= (ctl->intf_num << 4); + ret = mdss_mdp_ctl_setup(ctl); + if (ret) { + pr_err("unable to setup control path %d\n", ctl->num); + goto ctl_init_fail; + } + if (ctl->intf_num == MDSS_MDP_NO_INTF) { ctl->dst_format = pdata->panel_info.out_format; } else { @@ -766,14 +772,15 @@ int mdss_mdp_ctl_start(struct mdss_mdp_ctl *ctl) struct mdss_mdp_ctl *sctl; int ret = 0; + if (ctl->power_on) { + pr_debug("%s:%d already on!\n", __func__, __LINE__); + return 0; + } + ret = mdss_mdp_ctl_setup(ctl); if (ret) return ret; - if (ctl->power_on) { - WARN(1, "already on!\n"); - return 0; - } sctl = mdss_mdp_get_split_ctl(ctl); @@ -823,7 +830,7 @@ int mdss_mdp_ctl_stop(struct mdss_mdp_ctl *ctl) int ret = 0; if (!ctl->power_on) { - WARN(1, "already off!\n"); + pr_debug("%s %d already off!\n", __func__, __LINE__); return 0; } diff --git a/drivers/video/fbdev/msm/mdss_mdp_overlay.c b/drivers/video/fbdev/msm/mdss_mdp_overlay.c index 63ad005214ed..4f7176de8202 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_overlay.c +++ b/drivers/video/fbdev/msm/mdss_mdp_overlay.c @@ -20,9 +20,11 @@ #include <linux/module.h> #include <linux/pm_runtime.h> #include <linux/uaccess.h> +#include <linux/delay.h> #include <mach/iommu_domains.h> +#include "mdss.h" #include "mdss_fb.h" #include "mdss_mdp.h" #include "mdss_mdp_rotator.h" @@ -498,6 +500,74 @@ static int mdss_mdp_overlay_cleanup(struct msm_fb_data_type *mfd) return 0; } +static int mdss_mdp_reconfigure_splash_done(struct mdss_mdp_ctl *ctl) +{ + + struct msm_fb_data_type *mfd = ctl->mfd; + int ret = 0, off; + + if (!mfd) { + pr_debug("Invalid handle for reconfigure splash\n"); + return ret; + } + off = 0; + ctl->panel_data->panel_info.cont_splash_enabled = 0; + + mdss_mdp_ctl_write(ctl, 0, MDSS_MDP_LM_BORDER_COLOR); + off = MDSS_MDP_REG_INTF_OFFSET(ctl->intf_num); + + /* wait for 1 VSYNC for the pipe to be unstaged */ + msleep(20); + MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_TIMING_ENGINE_EN, 0); + ret = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_CONT_SPLASH_FINISH, + NULL); + mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false); + mdss_mdp_footswitch_ctrl_splash(0); + return ret; +} + +static int mdss_mdp_overlay_start(struct msm_fb_data_type *mfd) +{ + int rc; + + if (mfd->ctl->power_on) + return 0; + + pr_debug("starting overlay\n"); + + rc = pm_runtime_get_sync(&mfd->pdev->dev); + if (rc) { + pr_err("unable to resume with pm_runtime_get_sync (%d)\n", rc); + return rc; + } + + if (mfd->panel_info->cont_splash_enabled) + mdss_mdp_reconfigure_splash_done(mfd->ctl); + + if (!is_mdss_iommu_attached()) { + mdss_iommu_attach(mdss_res); + mdss_hw_init(mdss_res); + } + + rc = mdss_mdp_ctl_start(mfd->ctl); + if (rc == 0) { + atomic_inc(&ov_active_panels); + + if (mfd->vsync_pending) { + mfd->vsync_pending = 0; + mdss_mdp_overlay_vsync_ctrl(mfd, mfd->vsync_pending); + } + } else { + pr_err("overlay start failed.\n"); + mdss_mdp_ctl_destroy(mfd->ctl); + mfd->ctl = NULL; + + pm_runtime_put(&mfd->pdev->dev); + } + + return rc; +} + int mdss_mdp_overlay_kickoff(struct mdss_mdp_ctl *ctl) { struct msm_fb_data_type *mfd = ctl->mfd; @@ -743,6 +813,12 @@ static int mdss_mdp_overlay_play(struct msm_fb_data_type *mfd, return -EPERM; } + ret = mdss_mdp_overlay_start(mfd); + if (ret) { + pr_err("unable to start overlay %d (%d)\n", mfd->index, ret); + return ret; + } + if (req->id & MDSS_MDP_ROT_SESSION_MASK) { ret = mdss_mdp_overlay_rotate(mfd, req); } else if (req->id == BORDERFILL_NDX) { @@ -1286,7 +1362,7 @@ static int mdss_mdp_overlay_ioctl_handler(struct msm_fb_data_type *mfd, static int mdss_mdp_overlay_on(struct msm_fb_data_type *mfd) { - int rc; + int rc = 0; if (!mfd) return -ENODEV; @@ -1322,27 +1398,6 @@ static int mdss_mdp_overlay_on(struct msm_fb_data_type *mfd) mfd->ctl = ctl; } - rc = pm_runtime_get_sync(&mfd->pdev->dev); - if (rc) { - pr_err("unable to resume with pm_runtime_get_sync (%d)\n", rc); - return rc; - } - - rc = mdss_mdp_ctl_start(mfd->ctl); - if (rc == 0) { - atomic_inc(&ov_active_panels); - - if (mfd->vsync_pending) { - mfd->vsync_pending = 0; - mdss_mdp_overlay_vsync_ctrl(mfd, mfd->vsync_pending); - } - } else { - mdss_mdp_ctl_destroy(mfd->ctl); - mfd->ctl = NULL; - - pm_runtime_put(&mfd->pdev->dev); - } - return rc; } @@ -1361,6 +1416,9 @@ static int mdss_mdp_overlay_off(struct msm_fb_data_type *mfd) return -ENODEV; } + if (!mfd->ctl->power_on) + return 0; + mdss_mdp_overlay_release_all(mfd); rc = mdss_mdp_ctl_stop(mfd->ctl); diff --git a/drivers/video/fbdev/msm/mdss_panel.h b/drivers/video/fbdev/msm/mdss_panel.h index 40131eb79780..2b66181a9cdf 100644 --- a/drivers/video/fbdev/msm/mdss_panel.h +++ b/drivers/video/fbdev/msm/mdss_panel.h @@ -65,6 +65,7 @@ enum mdss_intf_events { MDSS_EVENT_SUSPEND, MDSS_EVENT_RESUME, MDSS_EVENT_CHECK_PARAMS, + MDSS_EVENT_CONT_SPLASH_FINISH, MDSS_EVENT_FB_REGISTERED, }; @@ -183,6 +184,9 @@ struct mdss_panel_info { u32 out_format; u32 vic; /* video identification code */ + u32 cont_splash_enabled; + u32 panel_power_on; + struct lcd_panel_info lcd; struct lcdc_panel_info lcdc; struct mipi_panel_info mipi; |
