diff options
| author | Jeevan Shriram <jshriram@codeaurora.org> | 2015-09-11 14:58:49 -0700 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 21:11:54 -0700 |
| commit | f04b3e457d883b8b83c528016fb3af180d9a1950 (patch) | |
| tree | b2bd4599dc619a1eb075927cdac6567fe76f38ed /drivers/video/fbdev | |
| parent | f72230df470dbc1069d263b4c818f707fe759b9c (diff) | |
msm: mdss: add support for dynamic refresh in clock update method
It is possible to change the refresh rate of the panel by
changing the byte clock and pixel clock to the required panel supported
frequency. This change adds support to program dynamic refresh
registers and trigger the dynamic refresh interrupt. Once the current
frame is done, hardware ensures that the change in clock frequency is
taken effect within the vertical blanking period.
Change-Id: I3a1e0eb478c34111e94f977088c20e9a50c4ef25
Signed-off-by: Jeevan Shriram <jshriram@codeaurora.org>
Signed-off-by: Ingrid Gallardo <ingridg@codeaurora.org>
Diffstat (limited to 'drivers/video/fbdev')
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dsi.c | 418 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dsi.h | 10 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dsi_host.c | 41 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/msm_mdss_io_8974.c | 360 |
4 files changed, 701 insertions, 128 deletions
diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c index 1904bf395ed5..a171fa5bb084 100644 --- a/drivers/video/fbdev/msm/mdss_dsi.c +++ b/drivers/video/fbdev/msm/mdss_dsi.c @@ -31,6 +31,7 @@ #include "mdss_panel.h" #include "mdss_dsi.h" #include "mdss_debug.h" +#include "mdss_dsi_phy.h" #define XO_CLK_RATE 19200000 #define CMDLINE_DSI_CTL_NUM_STRING_LEN 2 @@ -1272,6 +1273,7 @@ int mdss_dsi_on(struct mdss_panel_data *pdata) * sent to panel */ mdss_dsi_read_hw_revision(ctrl_pdata); + mdss_dsi_read_phy_revision(ctrl_pdata); mdss_dsi_restore_intr_mask(ctrl_pdata); pr_debug("%s: panel already on\n", __func__); goto end; @@ -1320,6 +1322,7 @@ int mdss_dsi_on(struct mdss_panel_data *pdata) MDSS_DSI_LINK_CLK, MDSS_DSI_CLK_ON); mdss_dsi_sw_reset(ctrl_pdata, true); mdss_dsi_read_hw_revision(ctrl_pdata); + mdss_dsi_read_phy_revision(ctrl_pdata); /* * Issue hardware reset line after enabling the DSI clocks and data @@ -1672,13 +1675,33 @@ static void __mdss_dsi_update_video_mode_total(struct mdss_panel_data *pdata, static void __mdss_dsi_dyn_refresh_config( struct mdss_dsi_ctrl_pdata *ctrl_pdata) { - int reg_data; + int reg_data = 0; + u32 phy_rev = mdss_dsi_get_phy_revision(ctrl_pdata); - reg_data = MIPI_INP((ctrl_pdata->ctrl_base) + DSI_DYNAMIC_REFRESH_CTRL); - reg_data &= ~BIT(12); + /* configure only for master control in split display */ + if (mdss_dsi_is_hw_config_split(ctrl_pdata->shared_data) && + mdss_dsi_is_ctrl_clk_slave(ctrl_pdata)) + return; + + switch (phy_rev) { + case DSI_PHY_REV_10: + reg_data = MIPI_INP((ctrl_pdata->ctrl_base) + + DSI_DYNAMIC_REFRESH_CTRL); + reg_data &= ~BIT(12); + MIPI_OUTP((ctrl_pdata->ctrl_base) + + DSI_DYNAMIC_REFRESH_CTRL, reg_data); + break; + case DSI_PHY_REV_20: + reg_data = BIT(13); + MIPI_OUTP((ctrl_pdata->ctrl_base) + + DSI_DYNAMIC_REFRESH_CTRL, reg_data); + break; + default: + pr_err("Phy rev %d unsupported\n", phy_rev); + break; + } pr_debug("Dynamic fps ctrl = 0x%x\n", reg_data); - MIPI_OUTP((ctrl_pdata->ctrl_base) + DSI_DYNAMIC_REFRESH_CTRL, reg_data); } static void __mdss_dsi_calc_dfps_delay(struct mdss_panel_data *pdata) @@ -1698,6 +1721,14 @@ static void __mdss_dsi_calc_dfps_delay(struct mdss_panel_data *pdata) ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); + if (ctrl_pdata == NULL) { + pr_err("%s Invalid ctrl_pdata\n", __func__); + return; + } + + if (mdss_dsi_is_hw_config_split(ctrl_pdata->shared_data) && + mdss_dsi_is_ctrl_clk_slave(ctrl_pdata)) + return; pinfo = &pdata->panel_info; pd = &(pinfo->mipi.dsi_phy_db); @@ -1736,13 +1767,14 @@ static void __mdss_dsi_calc_dfps_delay(struct mdss_panel_data *pdata) pll_delay); } -static int __mdss_dsi_dfps_update_clks(struct mdss_panel_data *pdata, +static int __mdss_dsi_dfps_calc_clks(struct mdss_panel_data *pdata, int new_fps) { int rc = 0; - u32 data; u64 clk_rate; struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; + struct mdss_panel_info *pinfo; + u32 phy_rev; if (pdata == NULL) { pr_err("%s Invalid pdata\n", __func__); @@ -1756,6 +1788,9 @@ static int __mdss_dsi_dfps_update_clks(struct mdss_panel_data *pdata, return -EINVAL; } + pinfo = &pdata->panel_info; + phy_rev = mdss_dsi_get_phy_revision(ctrl_pdata); + rc = mdss_dsi_clk_div_config (&ctrl_pdata->panel_data.panel_info, new_fps); if (rc) { @@ -1764,98 +1799,211 @@ static int __mdss_dsi_dfps_update_clks(struct mdss_panel_data *pdata, return rc; } - if (pdata->panel_info.dfps_update - == DFPS_IMMEDIATE_CLK_UPDATE_MODE) { - __mdss_dsi_dyn_refresh_config(ctrl_pdata); - __mdss_dsi_calc_dfps_delay(pdata); - ctrl_pdata->pclk_rate = - pdata->panel_info.mipi.dsi_pclk_rate; - clk_rate = pdata->panel_info.clk_rate; - do_div(clk_rate, 8U); - ctrl_pdata->byte_clk_rate = (u32) clk_rate; + __mdss_dsi_dyn_refresh_config(ctrl_pdata); - pr_debug("byte_rate=%i\n", ctrl_pdata->byte_clk_rate); - pr_debug("pclk_rate=%i\n", ctrl_pdata->pclk_rate); + if (phy_rev == DSI_PHY_REV_20) + mdss_dsi_dfps_config_8996(ctrl_pdata); - if (mdss_dsi_is_ctrl_clk_slave(ctrl_pdata)) { - pr_debug("%s DFPS already updated.\n", __func__); - ctrl_pdata->panel_data.panel_info.mipi.frame_rate = - new_fps; - return rc; - } + __mdss_dsi_calc_dfps_delay(pdata); - /* add an extra reference to main clks */ - clk_prepare_enable(ctrl_pdata->pll_byte_clk); - clk_prepare_enable(ctrl_pdata->pll_pixel_clk); + /* take a backup of current clk rates */ + ctrl_pdata->pclk_rate_bkp = ctrl_pdata->pclk_rate; + ctrl_pdata->byte_clk_rate_bkp = ctrl_pdata->byte_clk_rate; - /* change the parent to shadow clocks*/ - clk_set_parent(ctrl_pdata->mux_byte_clk, - ctrl_pdata->shadow_byte_clk); - clk_set_parent(ctrl_pdata->mux_pixel_clk, - ctrl_pdata->shadow_pixel_clk); + ctrl_pdata->pclk_rate = pinfo->mipi.dsi_pclk_rate; + clk_rate = pinfo->clk_rate; + do_div(clk_rate, 8U); + ctrl_pdata->byte_clk_rate = (u32) clk_rate; - rc = mdss_dsi_clk_set_link_rate(ctrl_pdata->dsi_clk_handle, - MDSS_DSI_LINK_BYTE_CLK, ctrl_pdata->byte_clk_rate, 0); - if (rc) { - pr_err("%s: dsi_byte_clk - clk_set_rate failed\n", - __func__); - return rc; + pr_debug("byte_rate=%i\n", ctrl_pdata->byte_clk_rate); + pr_debug("pclk_rate=%i\n", ctrl_pdata->pclk_rate); + + return rc; +} + +static int __mdss_dsi_dfps_update_clks(struct mdss_panel_data *pdata, + int new_fps) +{ + struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; + struct mdss_dsi_ctrl_pdata *sctrl_pdata = NULL; + struct mdss_panel_info *pinfo, *spinfo; + int rc = 0; + u32 data; + + if (pdata == NULL) { + pr_err("%s Invalid pdata\n", __func__); + return -EINVAL; + } + + ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, + panel_data); + if (IS_ERR_OR_NULL(ctrl_pdata)) { + pr_err("Invalid sctrl_pdata = %lu\n", PTR_ERR(ctrl_pdata)); + return PTR_ERR(ctrl_pdata); + } + + pinfo = &ctrl_pdata->panel_data.panel_info; + + /* + * In split display case, configure and enable dynamic refresh + * register only after both the ctrl data is programmed. So, + * ignore enabling dynamic refresh for the master control and + * configure only when it is slave control. + */ + if (mdss_dsi_is_hw_config_split(ctrl_pdata->shared_data) && + mdss_dsi_is_ctrl_clk_master(ctrl_pdata)) + return 0; + + if (mdss_dsi_is_hw_config_split(ctrl_pdata->shared_data) && + mdss_dsi_is_ctrl_clk_slave(ctrl_pdata)) { + sctrl_pdata = ctrl_pdata; + spinfo = pinfo; + ctrl_pdata = mdss_dsi_get_ctrl_clk_master(); + if (IS_ERR_OR_NULL(ctrl_pdata)) { + pr_err("Invalid ctrl_pdata = %lu\n", + PTR_ERR(ctrl_pdata)); + return PTR_ERR(ctrl_pdata); } - rc = mdss_dsi_clk_set_link_rate(ctrl_pdata->dsi_clk_handle, - MDSS_DSI_LINK_PIX_CLK, ctrl_pdata->pclk_rate, 0); - if (rc) { - pr_err("%s: dsi_pixel_clk - clk_set_rate failed\n", + pinfo = &ctrl_pdata->panel_data.panel_info; + } + + /* + * For programming dynamic refresh registers, we need to change + * the parent to shadow clocks for the software byte and pixel mux. + * After switching to shadow clocks, if there is no ref count on + * main byte and pixel clocks, clock driver may shutdown those + * unreferenced byte and pixel clocks. Hence add an extra reference + * count to avoid shutting down the main byte and pixel clocks. + */ + rc = clk_prepare_enable(ctrl_pdata->pll_byte_clk); + if (rc) { + pr_err("Unable to add extra refcnt for byte clock\n"); + goto error_byte; + } + + rc = clk_prepare_enable(ctrl_pdata->pll_pixel_clk); + if (rc) { + pr_err("Unable to add extra refcnt for pixel clock\n"); + goto error_pixel; + } + + /* change the parent to shadow clocks*/ + rc = clk_set_parent(ctrl_pdata->mux_byte_clk, + ctrl_pdata->shadow_byte_clk); + if (rc) { + pr_err("Unable to set parent to shadow byte clock\n"); + goto error_shadow_byte; + } + + rc = clk_set_parent(ctrl_pdata->mux_pixel_clk, + ctrl_pdata->shadow_pixel_clk); + if (rc) { + pr_err("Unable to set parent to shadow pixel clock\n"); + goto error_shadow_pixel; + } + + rc = mdss_dsi_clk_set_link_rate(ctrl_pdata->dsi_clk_handle, + MDSS_DSI_LINK_BYTE_CLK, ctrl_pdata->byte_clk_rate, 0); + if (rc) { + pr_err("%s: dsi_byte_clk - clk_set_rate failed\n", __func__); - return rc; - } + goto error_byte_link; + } - rc = mdss_dsi_en_wait4dynamic_done(ctrl_pdata); - MIPI_OUTP((ctrl_pdata->ctrl_base) + DSI_DYNAMIC_REFRESH_CTRL, - 0x00); - - data = MIPI_INP((ctrl_pdata->ctrl_base) + 0x0120); - MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x120, data); - pr_debug("pll unlock: 0x%x\n", data); - clk_set_parent(ctrl_pdata->mux_byte_clk, - ctrl_pdata->pll_byte_clk); - clk_set_parent(ctrl_pdata->mux_pixel_clk, - ctrl_pdata->pll_pixel_clk); - clk_disable_unprepare(ctrl_pdata->pll_byte_clk); - clk_disable_unprepare(ctrl_pdata->pll_pixel_clk); - - if (!rc) { - ctrl_pdata->panel_data.panel_info.mipi.frame_rate = - new_fps; - /* we are using current_fps to compare if dfps needed */ - ctrl_pdata->panel_data.panel_info.current_fps = - new_fps; - } - } else { - ctrl_pdata->pclk_rate = - pdata->panel_info.mipi.dsi_pclk_rate; - clk_rate = pdata->panel_info.clk_rate; - do_div(clk_rate, 8U); - ctrl_pdata->byte_clk_rate = (u32) clk_rate; - rc = mdss_dsi_clk_set_link_rate(ctrl_pdata->dsi_clk_handle, - MDSS_DSI_LINK_BYTE_CLK, ctrl_pdata->byte_clk_rate, - MDSS_DSI_CLK_UPDATE_CLK_RATE_AT_ON); + rc = mdss_dsi_clk_set_link_rate(ctrl_pdata->dsi_clk_handle, + MDSS_DSI_LINK_PIX_CLK, ctrl_pdata->pclk_rate, 0); + if (rc) { + pr_err("%s: dsi_pixel_clk - clk_set_rate failed\n", + __func__); + goto error_pixel_link; + } + + if (sctrl_pdata) { + rc = mdss_dsi_clk_set_link_rate(sctrl_pdata->dsi_clk_handle, + MDSS_DSI_LINK_BYTE_CLK, sctrl_pdata->byte_clk_rate, 0); if (rc) { - pr_err("%s: dsi_byte_clk - clk_set_rate failed\n", + pr_err("%s: slv dsi_byte_clk - clk_set_rate failed\n", __func__); - return rc; + goto error_sbyte_link; } - rc = mdss_dsi_clk_set_link_rate(ctrl_pdata->dsi_clk_handle, - MDSS_DSI_LINK_PIX_CLK, ctrl_pdata->pclk_rate, - MDSS_DSI_CLK_UPDATE_CLK_RATE_AT_ON); + rc = mdss_dsi_clk_set_link_rate(sctrl_pdata->dsi_clk_handle, + MDSS_DSI_LINK_PIX_CLK, sctrl_pdata->pclk_rate, 0); if (rc) { - pr_err("%s: dsi_pixel_clk - clk_set_rate failed\n", - __func__); - return rc; + pr_err("%s: slv dsi_pixel_clk - clk_set_rate failed\n", + __func__); + goto error_spixel_link; } } + rc = mdss_dsi_en_wait4dynamic_done(ctrl_pdata); + if (rc) { + pr_err("Unsuccessful dynamic fps change"); + goto dfps_timeout; + } + + MIPI_OUTP((ctrl_pdata->ctrl_base) + DSI_DYNAMIC_REFRESH_CTRL, 0x00); + if (sctrl_pdata) + MIPI_OUTP((sctrl_pdata->ctrl_base) + DSI_DYNAMIC_REFRESH_CTRL, + 0x00); + + data = MIPI_INP((ctrl_pdata->ctrl_base) + 0x0120); + if (data & BIT(16)) { + pr_debug("pll unlocked: 0x%x\n", data); + /* clear PLL unlock bit */ + MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x120, BIT(16)); + } + + /* Move the mux clocks to main byte and pixel clocks */ + rc = clk_set_parent(ctrl_pdata->mux_byte_clk, + ctrl_pdata->pll_byte_clk); + if (rc) + pr_err("Unable to set parent back to main byte clock\n"); + + rc = clk_set_parent(ctrl_pdata->mux_pixel_clk, + ctrl_pdata->pll_pixel_clk); + if (rc) + pr_err("Unable to set parent back to main pixel clock\n"); + + /* Remove extra ref count on parent clocks */ + clk_disable_unprepare(ctrl_pdata->pll_byte_clk); + clk_disable_unprepare(ctrl_pdata->pll_pixel_clk); + + pinfo->mipi.frame_rate = new_fps; + pinfo->current_fps = new_fps; + if (sctrl_pdata) { + spinfo->mipi.frame_rate = new_fps; + spinfo->current_fps = new_fps; + } + + return rc; + +dfps_timeout: + if (sctrl_pdata) + mdss_dsi_clk_set_link_rate(sctrl_pdata->dsi_clk_handle, + MDSS_DSI_LINK_PIX_CLK, + sctrl_pdata->pclk_rate_bkp, 0); +error_spixel_link: + if (sctrl_pdata) + mdss_dsi_clk_set_link_rate(sctrl_pdata->dsi_clk_handle, + MDSS_DSI_LINK_BYTE_CLK, + sctrl_pdata->byte_clk_rate_bkp, 0); +error_sbyte_link: + mdss_dsi_clk_set_link_rate(ctrl_pdata->dsi_clk_handle, + MDSS_DSI_LINK_PIX_CLK, ctrl_pdata->pclk_rate_bkp, 0); +error_pixel_link: + mdss_dsi_clk_set_link_rate(ctrl_pdata->dsi_clk_handle, + MDSS_DSI_LINK_BYTE_CLK, ctrl_pdata->byte_clk_rate_bkp, 0); +error_byte_link: + clk_set_parent(ctrl_pdata->mux_pixel_clk, ctrl_pdata->pll_pixel_clk); +error_shadow_pixel: + clk_set_parent(ctrl_pdata->mux_byte_clk, ctrl_pdata->pll_byte_clk); +error_shadow_byte: + clk_disable_unprepare(ctrl_pdata->pll_pixel_clk); +error_pixel: + clk_disable_unprepare(ctrl_pdata->pll_byte_clk); +error_byte: return rc; } @@ -1863,8 +2011,9 @@ static int mdss_dsi_dfps_config(struct mdss_panel_data *pdata, int new_fps) { int rc = 0; struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; - struct mdss_dsi_ctrl_pdata *sctrl_pdata = NULL; struct mdss_panel_info *pinfo; + u32 phy_rev; + u32 frame_rate_bkp; pr_debug("%s+:\n", __func__); @@ -1877,57 +2026,61 @@ static int mdss_dsi_dfps_config(struct mdss_panel_data *pdata, int new_fps) panel_data); if (!ctrl_pdata->panel_data.panel_info.dynamic_fps) { - pr_err("%s: Dynamic fps not enabled for this panel\n", - __func__); + pr_err("Dynamic fps not enabled for this panel\n"); return -EINVAL; } - /* - * at split display case, DFPS registers were already programmed - * while programming the left ctrl(DSI0). Ignore right ctrl (DSI1) - * reguest. - */ + phy_rev = mdss_dsi_get_phy_revision(ctrl_pdata); pinfo = &pdata->panel_info; - if (mdss_dsi_is_hw_config_split(ctrl_pdata->shared_data)) { - if (mdss_dsi_is_right_ctrl(ctrl_pdata)) { - pr_debug("%s DFPS already updated.\n", __func__); - return rc; - } - /* left ctrl to get right ctrl */ - sctrl_pdata = mdss_dsi_get_other_ctrl(ctrl_pdata); - } - - if (new_fps != - ctrl_pdata->panel_data.panel_info.current_fps) { - if (pdata->panel_info.dfps_update - == DFPS_IMMEDIATE_PORCH_UPDATE_MODE_HFP || - pdata->panel_info.dfps_update - == DFPS_IMMEDIATE_PORCH_UPDATE_MODE_VFP) { - - __mdss_dsi_update_video_mode_total(pdata, new_fps); - if (sctrl_pdata) { - pr_debug("%s Updating slave ctrl DFPS\n", - __func__); - __mdss_dsi_update_video_mode_total( - &sctrl_pdata->panel_data, - new_fps); - } - } else { - rc = __mdss_dsi_dfps_update_clks(pdata, new_fps); - if (!rc && sctrl_pdata) { - pr_debug("%s Updating slave ctrl DFPS\n", - __func__); - rc = __mdss_dsi_dfps_update_clks( - &sctrl_pdata->panel_data, - new_fps); + frame_rate_bkp = mdss_panel_get_framerate(pinfo); + if (new_fps == pinfo->mipi.frame_rate) { + /* + * This is unlikely as mdss driver checks for previously + * configured frame rate. + */ + pr_debug("Panel is already at this FPS\n"); + goto end_update; + } + + if (pinfo->dfps_update == DFPS_IMMEDIATE_PORCH_UPDATE_MODE_HFP || + pinfo->dfps_update == DFPS_IMMEDIATE_PORCH_UPDATE_MODE_VFP) { + /* Porch method */ + __mdss_dsi_update_video_mode_total(pdata, new_fps); + } else if (pinfo->dfps_update == DFPS_IMMEDIATE_CLK_UPDATE_MODE) { + /* Clock update method */ + if (phy_rev == DSI_PHY_REV_20) { + rc = mdss_dsi_phy_calc_timing_param(pinfo, phy_rev, + new_fps); + if (rc) { + pr_err("PHY calculations failed-%d\n", new_fps); + goto end_update; } } - } else { - pr_debug("%s: Panel is already at this FPS\n", __func__); + + rc = __mdss_dsi_dfps_calc_clks(pdata, new_fps); + if (rc) { + pr_err("error calculating clocks for %d\n", new_fps); + goto error_clks; + } + + rc = __mdss_dsi_dfps_update_clks(pdata, new_fps); + if (rc) { + pr_err("Dynamic refresh failed-%d\n", new_fps); + goto error_dfps; + } } return rc; +error_dfps: + if (__mdss_dsi_dfps_calc_clks(pdata, frame_rate_bkp)) + pr_err("error reverting clock calculations for %d\n", + frame_rate_bkp); +error_clks: + if (mdss_dsi_phy_calc_timing_param(pinfo, phy_rev, frame_rate_bkp)) + pr_err("Unable to revert phy timing-%d\n", frame_rate_bkp); +end_update: + return rc; } static int mdss_dsi_ctl_partial_roi(struct mdss_panel_data *pdata) @@ -2165,8 +2318,12 @@ static int mdss_dsi_event_handler(struct mdss_panel_data *pdata, if (arg != NULL) { rc = mdss_dsi_dfps_config(pdata, (int) (unsigned long) arg); - pr_debug("%s:update fps to = %d\n", - __func__, (int) (unsigned long) arg); + if (rc) + pr_err("unable to change fps-%d, error-%d\n", + (int) (unsigned long) arg, rc); + else + pr_debug("panel frame rate changed to %d\n", + (int) (unsigned long) arg); } break; case MDSS_EVENT_CONT_SPLASH_BEGIN: @@ -2681,10 +2838,17 @@ static int mdss_dsi_ctrl_probe(struct platform_device *pdev) } pinfo = &(ctrl_pdata->panel_data.panel_info); - if (pinfo->dynamic_fps) - if (mdss_dsi_shadow_clk_init(pdev, ctrl_pdata)) + if (!(mdss_dsi_is_hw_config_split(ctrl_pdata->shared_data) && + mdss_dsi_is_ctrl_clk_slave(ctrl_pdata)) && + pinfo->dynamic_fps) { + rc = mdss_dsi_shadow_clk_init(pdev, ctrl_pdata); + + if (rc) { pr_err("%s: unable to initialize shadow ctrl clks\n", __func__); + rc = -EPERM; + } + } rc = mdss_dsi_set_clk_rates(ctrl_pdata); if (rc) { diff --git a/drivers/video/fbdev/msm/mdss_dsi.h b/drivers/video/fbdev/msm/mdss_dsi.h index 7922bba30d52..16f0c675d287 100644 --- a/drivers/video/fbdev/msm/mdss_dsi.h +++ b/drivers/video/fbdev/msm/mdss_dsi.h @@ -234,6 +234,7 @@ struct dsi_shared_data { u32 hw_config; /* DSI setup configuration i.e. single/dual/split */ u32 pll_src_config; /* PLL source selection for DSI link clocks */ u32 hw_rev; /* DSI h/w revision */ + u32 phy_rev; /* DSI PHY revision*/ /* DSI ULPS clamp register offsets */ u32 ulps_clamp_ctrl_off; @@ -440,6 +441,8 @@ struct mdss_dsi_ctrl_pdata { struct pwm_device *pwm_bl; u32 pclk_rate; u32 byte_clk_rate; + u32 pclk_rate_bkp; + u32 byte_clk_rate_bkp; bool refresh_clk_rate; /* flag to recalculate clk_rate */ struct dss_module_power panel_power_data; struct dss_module_power power_data[DSI_MAX_PM]; /* for 8x10 */ @@ -620,6 +623,7 @@ void mdss_dsi_ctrl_setup(struct mdss_dsi_ctrl_pdata *ctrl); void mdss_dsi_dln0_phy_err(struct mdss_dsi_ctrl_pdata *ctrl, bool print_en); void mdss_dsi_lp_cd_rx(struct mdss_dsi_ctrl_pdata *ctrl); void mdss_dsi_get_hw_revision(struct mdss_dsi_ctrl_pdata *ctrl); +void mdss_dsi_read_phy_revision(struct mdss_dsi_ctrl_pdata *ctrl); u32 mdss_dsi_panel_cmd_read(struct mdss_dsi_ctrl_pdata *ctrl, char cmd0, char cmd1, void (*fxn)(int), char *rbuf, int len); int mdss_dsi_panel_init(struct device_node *node, @@ -640,6 +644,7 @@ void mdss_dsi_panel_dsc_pps_send(struct mdss_dsi_ctrl_pdata *ctrl, struct mdss_panel_info *pinfo); void mdss_dsi_dsc_config(struct mdss_dsi_ctrl_pdata *ctrl, struct dsc_desc *dsc); +void mdss_dsi_dfps_config_8996(struct mdss_dsi_ctrl_pdata *ctrl); static inline const char *__mdss_dsi_pm_name(enum dsi_pm_type module) { @@ -736,6 +741,11 @@ static inline bool mdss_dsi_is_dsi1_active(struct dsi_shared_data *sdata) return sdata->dsi1_active; } +static inline u32 mdss_dsi_get_phy_revision(struct mdss_dsi_ctrl_pdata *ctrl) +{ + return ctrl->shared_data->phy_rev; +} + static inline bool mdss_dsi_sync_wait_enable(struct mdss_dsi_ctrl_pdata *ctrl) { return ctrl->cmd_sync_wait_broadcast; diff --git a/drivers/video/fbdev/msm/mdss_dsi_host.c b/drivers/video/fbdev/msm/mdss_dsi_host.c index ed5256e2f7cf..7c4b698d4ef6 100644 --- a/drivers/video/fbdev/msm/mdss_dsi_host.c +++ b/drivers/video/fbdev/msm/mdss_dsi_host.c @@ -28,6 +28,7 @@ #include "mdss_panel.h" #include "mdss_debug.h" #include "mdss_smmu.h" +#include "mdss_dsi_phy.h" #define VSYNC_PERIOD 17 #define DMA_TX_TIMEOUT 200 @@ -290,6 +291,23 @@ void mdss_dsi_get_hw_revision(struct mdss_dsi_ctrl_pdata *ctrl) ctrl->ndx, ctrl->shared_data->hw_rev); } +void mdss_dsi_read_phy_revision(struct mdss_dsi_ctrl_pdata *ctrl) +{ + u32 reg_val; + + if (ctrl->shared_data->phy_rev > DSI_PHY_REV_UNKNOWN) + return; + + reg_val = MIPI_INP(ctrl->phy_io.base); + + if (reg_val == DSI_PHY_REV_20) + ctrl->shared_data->phy_rev = DSI_PHY_REV_20; + else if (reg_val == DSI_PHY_REV_10) + ctrl->shared_data->phy_rev = DSI_PHY_REV_10; + else + ctrl->shared_data->phy_rev = DSI_PHY_REV_UNKNOWN; +} + void mdss_dsi_host_init(struct mdss_panel_data *pdata) { u32 dsi_ctrl, intr_ctrl; @@ -2119,6 +2137,7 @@ int mdss_dsi_en_wait4dynamic_done(struct mdss_dsi_ctrl_pdata *ctrl) unsigned long flag; u32 data; int rc = 0; + struct mdss_dsi_ctrl_pdata *sctrl_pdata; /* DSI_INTL_CTRL */ data = MIPI_INP((ctrl->ctrl_base) + 0x0110); @@ -2130,8 +2149,21 @@ int mdss_dsi_en_wait4dynamic_done(struct mdss_dsi_ctrl_pdata *ctrl) reinit_completion(&ctrl->dynamic_comp); mdss_dsi_enable_irq(ctrl, DSI_DYNAMIC_TERM); spin_unlock_irqrestore(&ctrl->mdp_lock, flag); + + /* + * Ensure that registers are updated before triggering + * dynamic refresh + */ + wmb(); + MIPI_OUTP((ctrl->ctrl_base) + DSI_DYNAMIC_REFRESH_CTRL, - (BIT(8) | BIT(0))); + (BIT(13) | BIT(8) | BIT(0))); + + sctrl_pdata = mdss_dsi_get_ctrl_clk_slave(); + + if (sctrl_pdata) + MIPI_OUTP((sctrl_pdata->ctrl_base) + DSI_DYNAMIC_REFRESH_CTRL, + (BIT(13) | BIT(8) | BIT(0))); if (!wait_for_completion_timeout(&ctrl->dynamic_comp, msecs_to_jiffies(VSYNC_PERIOD * 4))) { @@ -2814,6 +2846,7 @@ void mdss_dsi_error(struct mdss_dsi_ctrl_pdata *ctrl) irqreturn_t mdss_dsi_isr(int irq, void *ptr) { u32 isr; + u32 intr; struct mdss_dsi_ctrl_pdata *ctrl = (struct mdss_dsi_ctrl_pdata *)ptr; @@ -2890,6 +2923,12 @@ irqreturn_t mdss_dsi_isr(int irq, void *ptr) if (isr & DSI_INTR_DYNAMIC_REFRESH_DONE) { spin_lock(&ctrl->mdp_lock); mdss_dsi_disable_irq_nosync(ctrl, DSI_DYNAMIC_TERM); + + /* clear dfps interrupt */ + intr = MIPI_INP(ctrl->ctrl_base + 0x0110); + intr |= DSI_INTR_DYNAMIC_REFRESH_DONE; + MIPI_OUTP(ctrl->ctrl_base + 0x0110, intr); + complete(&ctrl->dynamic_comp); spin_unlock(&ctrl->mdp_lock); } diff --git a/drivers/video/fbdev/msm/msm_mdss_io_8974.c b/drivers/video/fbdev/msm/msm_mdss_io_8974.c index b01bc180809c..a03120b8fe18 100644 --- a/drivers/video/fbdev/msm/msm_mdss_io_8974.c +++ b/drivers/video/fbdev/msm/msm_mdss_io_8974.c @@ -42,6 +42,7 @@ /* 8996 */ #define DATALANE_OFFSET_FROM_BASE_8996 0x100 +#define DSIPHY_CMN_PLL_CNTRL 0x0048 #define DATALANE_SIZE_8996 0x80 #define DSIPHY_CMN_GLBL_TEST_CTRL 0x0018 @@ -51,6 +52,365 @@ #define DSIPHY_PLL_CLKBUFLR_EN 0x041c #define DSIPHY_PLL_PLL_BANDGAP 0x0508 +#define DSI_DYNAMIC_REFRESH_PLL_CTRL0 0x214 +#define DSI_DYNAMIC_REFRESH_PLL_CTRL1 0x218 +#define DSI_DYNAMIC_REFRESH_PLL_CTRL2 0x21C +#define DSI_DYNAMIC_REFRESH_PLL_CTRL3 0x220 +#define DSI_DYNAMIC_REFRESH_PLL_CTRL4 0x224 +#define DSI_DYNAMIC_REFRESH_PLL_CTRL5 0x228 +#define DSI_DYNAMIC_REFRESH_PLL_CTRL6 0x22C +#define DSI_DYNAMIC_REFRESH_PLL_CTRL7 0x230 +#define DSI_DYNAMIC_REFRESH_PLL_CTRL8 0x234 +#define DSI_DYNAMIC_REFRESH_PLL_CTRL9 0x238 +#define DSI_DYNAMIC_REFRESH_PLL_CTRL10 0x23C +#define DSI_DYNAMIC_REFRESH_PLL_CTRL11 0x240 +#define DSI_DYNAMIC_REFRESH_PLL_CTRL12 0x244 +#define DSI_DYNAMIC_REFRESH_PLL_CTRL13 0x248 +#define DSI_DYNAMIC_REFRESH_PLL_CTRL14 0x24C +#define DSI_DYNAMIC_REFRESH_PLL_CTRL15 0x250 +#define DSI_DYNAMIC_REFRESH_PLL_CTRL16 0x254 +#define DSI_DYNAMIC_REFRESH_PLL_CTRL17 0x258 +#define DSI_DYNAMIC_REFRESH_PLL_CTRL18 0x25C +#define DSI_DYNAMIC_REFRESH_PLL_CTRL19 0x260 +#define DSI_DYNAMIC_REFRESH_PLL_CTRL19 0x260 +#define DSI_DYNAMIC_REFRESH_PLL_CTRL20 0x264 +#define DSI_DYNAMIC_REFRESH_PLL_CTRL21 0x268 +#define DSI_DYNAMIC_REFRESH_PLL_CTRL22 0x26C +#define DSI_DYNAMIC_REFRESH_PLL_CTRL23 0x270 +#define DSI_DYNAMIC_REFRESH_PLL_CTRL24 0x274 +#define DSI_DYNAMIC_REFRESH_PLL_CTRL25 0x278 +#define DSI_DYNAMIC_REFRESH_PLL_CTRL26 0x27C +#define DSI_DYNAMIC_REFRESH_PLL_CTRL27 0x280 +#define DSI_DYNAMIC_REFRESH_PLL_CTRL28 0x284 +#define DSI_DYNAMIC_REFRESH_PLL_CTRL29 0x288 +#define DSI_DYNAMIC_REFRESH_PLL_CTRL30 0x28C +#define DSI_DYNAMIC_REFRESH_PLL_CTRL31 0x290 +#define DSI_DYNAMIC_REFRESH_PLL_UPPER_ADDR 0x294 +#define DSI_DYNAMIC_REFRESH_PLL_UPPER_ADDR2 0x298 + +#define DSIPHY_DLN0_CFG1 0x0104 +#define DSIPHY_DLN0_TIMING_CTRL_4 0x0118 +#define DSIPHY_DLN0_TIMING_CTRL_5 0x011C +#define DSIPHY_DLN0_TIMING_CTRL_6 0x0120 +#define DSIPHY_DLN0_TIMING_CTRL_7 0x0124 +#define DSIPHY_DLN0_TIMING_CTRL_8 0x0128 + +#define DSIPHY_DLN1_CFG1 0x0184 +#define DSIPHY_DLN1_TIMING_CTRL_4 0x0198 +#define DSIPHY_DLN1_TIMING_CTRL_5 0x019C +#define DSIPHY_DLN1_TIMING_CTRL_6 0x01A0 +#define DSIPHY_DLN1_TIMING_CTRL_7 0x01A4 +#define DSIPHY_DLN1_TIMING_CTRL_8 0x01A8 + +#define DSIPHY_DLN2_CFG1 0x0204 +#define DSIPHY_DLN2_TIMING_CTRL_4 0x0218 +#define DSIPHY_DLN2_TIMING_CTRL_5 0x021C +#define DSIPHY_DLN2_TIMING_CTRL_6 0x0220 +#define DSIPHY_DLN2_TIMING_CTRL_7 0x0224 +#define DSIPHY_DLN2_TIMING_CTRL_8 0x0228 + +#define DSIPHY_DLN3_CFG1 0x0284 +#define DSIPHY_DLN3_TIMING_CTRL_4 0x0298 +#define DSIPHY_DLN3_TIMING_CTRL_5 0x029C +#define DSIPHY_DLN3_TIMING_CTRL_6 0x02A0 +#define DSIPHY_DLN3_TIMING_CTRL_7 0x02A4 +#define DSIPHY_DLN3_TIMING_CTRL_8 0x02A8 + +#define DSIPHY_CKLN_CFG1 0x0304 +#define DSIPHY_CKLN_TIMING_CTRL_4 0x0318 +#define DSIPHY_CKLN_TIMING_CTRL_5 0x031C +#define DSIPHY_CKLN_TIMING_CTRL_6 0x0320 +#define DSIPHY_CKLN_TIMING_CTRL_7 0x0324 +#define DSIPHY_CKLN_TIMING_CTRL_8 0x0328 + +#define DSIPHY_PLL_RESETSM_CNTRL5 0x043c + +#define PLL_CALC_DATA(addr0, addr1, data0, data1) \ + (((data1) << 24) | ((((addr1)/4) & 0xFF) << 16) | \ + ((data0) << 8) | (((addr0)/4) & 0xFF)) + +#define MDSS_DYN_REF_REG_W(base, offset, addr0, addr1, data0, data1) \ + writel_relaxed(PLL_CALC_DATA(addr0, addr1, data0, data1), \ + (base) + (offset)) + +void mdss_dsi_dfps_config_8996(struct mdss_dsi_ctrl_pdata *ctrl) +{ + struct mdss_panel_data *pdata; + struct mdss_panel_info *pinfo; + struct mdss_dsi_phy_ctrl *pd; + int glbl_tst_cntrl = + MIPI_INP(ctrl->phy_io.base + DSIPHY_CMN_GLBL_TEST_CTRL); + + pdata = &ctrl->panel_data; + if (!pdata) { + pr_err("%s: Invalid panel data\n", __func__); + return; + } + pinfo = &pdata->panel_info; + pd = &(((ctrl->panel_data).panel_info.mipi).dsi_phy_db); + + if (mdss_dsi_is_ctrl_clk_slave(ctrl)) { + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL0, + DSIPHY_DLN0_CFG1, DSIPHY_DLN1_CFG1, + 0, 0); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL1, + DSIPHY_DLN2_CFG1, DSIPHY_DLN3_CFG1, + 0x0, 0x0); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL2, + DSIPHY_CKLN_CFG1, DSIPHY_DLN0_TIMING_CTRL_4, + 0x0, pd->timing_8996[0]); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL3, + DSIPHY_DLN1_TIMING_CTRL_4, + DSIPHY_DLN2_TIMING_CTRL_4, + pd->timing_8996[8], + pd->timing_8996[16]); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL4, + DSIPHY_DLN3_TIMING_CTRL_4, + DSIPHY_CKLN_TIMING_CTRL_4, + pd->timing_8996[24], + pd->timing_8996[32]); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL5, + DSIPHY_DLN0_TIMING_CTRL_5, + DSIPHY_DLN1_TIMING_CTRL_5, + pd->timing_8996[1], + pd->timing_8996[9]); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL6, + DSIPHY_DLN2_TIMING_CTRL_5, + DSIPHY_DLN3_TIMING_CTRL_5, + pd->timing_8996[17], + pd->timing_8996[25]); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL7, + DSIPHY_CKLN_TIMING_CTRL_5, + DSIPHY_DLN0_TIMING_CTRL_6, + pd->timing_8996[33], + pd->timing_8996[2]); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL8, + DSIPHY_DLN1_TIMING_CTRL_6, + DSIPHY_DLN2_TIMING_CTRL_6, + pd->timing_8996[10], + pd->timing_8996[18]); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL9, + DSIPHY_DLN3_TIMING_CTRL_6, + DSIPHY_CKLN_TIMING_CTRL_6, + pd->timing_8996[26], + pd->timing_8996[34]); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL10, + DSIPHY_DLN0_TIMING_CTRL_7, + DSIPHY_DLN1_TIMING_CTRL_7, + pd->timing_8996[3], + pd->timing_8996[11]); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL11, + DSIPHY_DLN2_TIMING_CTRL_7, + DSIPHY_DLN3_TIMING_CTRL_7, + pd->timing_8996[19], + pd->timing_8996[27]); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL12, + DSIPHY_CKLN_TIMING_CTRL_7, + DSIPHY_DLN0_TIMING_CTRL_8, + pd->timing_8996[35], + pd->timing_8996[4]); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL13, + DSIPHY_DLN1_TIMING_CTRL_8, + DSIPHY_DLN2_TIMING_CTRL_8, + pd->timing_8996[12], + pd->timing_8996[20]); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL14, + DSIPHY_DLN3_TIMING_CTRL_8, + DSIPHY_CKLN_TIMING_CTRL_8, + pd->timing_8996[28], + pd->timing_8996[36]); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL15, + 0x0110, 0x0110, 0, 0); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL16, + 0x0110, 0x0110, 0, 0); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL17, + 0x0110, 0x0110, 0, 0); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL18, + 0x0110, 0x0110, 0, 0); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL19, + 0x0110, 0x0110, 0, 0); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL20, + 0x110, 0x110, 0, 0); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL21, + 0x110, 0x110, 0, 0); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL22, + 0x110, 0x110, 0, 0); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL23, + 0x110, 0x110, 0, 0); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL24, + 0x110, 0x110, 0, 0); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL25, + 0x110, 0x110, 0, 0); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL26, + 0x110, 0x110, 0, 0); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL27, + 0x110, 0x110, 0, 0); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL28, + 0x110, 0x110, 0, 0); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL29, + 0x110, 0x110, 0, 0); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL30, + 0x110, 0x110, 0, 0); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL31, + 0x110, 0x110, 0, 0); + MIPI_OUTP(ctrl->ctrl_base + + DSI_DYNAMIC_REFRESH_PLL_UPPER_ADDR, 0x0); + MIPI_OUTP(ctrl->ctrl_base + + DSI_DYNAMIC_REFRESH_PLL_UPPER_ADDR2, 0x0); + } else { + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL0, + DSIPHY_CMN_GLBL_TEST_CTRL, + DSIPHY_PLL_PLL_BANDGAP, + glbl_tst_cntrl | BIT(1), 0x1); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL1, + DSIPHY_PLL_RESETSM_CNTRL5, + DSIPHY_PLL_PLL_BANDGAP, + 0x0D, 0x03); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL2, + DSIPHY_PLL_RESETSM_CNTRL5, + DSIPHY_CMN_PLL_CNTRL, + 0x1D, 0x00); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL3, + DSIPHY_CMN_CTRL_1, DSIPHY_DLN0_CFG1, + 0x20, 0); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL4, + DSIPHY_DLN1_CFG1, DSIPHY_DLN2_CFG1, + 0, 0); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL5, + DSIPHY_DLN3_CFG1, DSIPHY_CKLN_CFG1, + 0, 0); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL6, + DSIPHY_DLN0_TIMING_CTRL_4, + DSIPHY_DLN1_TIMING_CTRL_4, + pd->timing_8996[0], + pd->timing_8996[8]); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL7, + DSIPHY_DLN2_TIMING_CTRL_4, + DSIPHY_DLN3_TIMING_CTRL_4, + pd->timing_8996[16], + pd->timing_8996[24]); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL8, + DSIPHY_CKLN_TIMING_CTRL_4, + DSIPHY_DLN0_TIMING_CTRL_5, + pd->timing_8996[32], + pd->timing_8996[1]); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL9, + DSIPHY_DLN1_TIMING_CTRL_5, + DSIPHY_DLN2_TIMING_CTRL_5, + pd->timing_8996[9], + pd->timing_8996[17]); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL10, + DSIPHY_DLN3_TIMING_CTRL_5, + DSIPHY_CKLN_TIMING_CTRL_5, + pd->timing_8996[25], + pd->timing_8996[33]); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL11, + DSIPHY_DLN0_TIMING_CTRL_6, + DSIPHY_DLN1_TIMING_CTRL_6, + pd->timing_8996[2], + pd->timing_8996[10]); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL12, + DSIPHY_DLN2_TIMING_CTRL_6, + DSIPHY_DLN3_TIMING_CTRL_6, + pd->timing_8996[18], + pd->timing_8996[26]); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL13, + DSIPHY_CKLN_TIMING_CTRL_6, + DSIPHY_DLN0_TIMING_CTRL_7, + pd->timing_8996[34], + pd->timing_8996[3]); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL14, + DSIPHY_DLN1_TIMING_CTRL_7, + DSIPHY_DLN2_TIMING_CTRL_7, + pd->timing_8996[11], + pd->timing_8996[19]); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL15, + DSIPHY_DLN3_TIMING_CTRL_7, + DSIPHY_CKLN_TIMING_CTRL_7, + pd->timing_8996[27], + pd->timing_8996[35]); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL16, + DSIPHY_DLN0_TIMING_CTRL_8, + DSIPHY_DLN1_TIMING_CTRL_8, + pd->timing_8996[4], + pd->timing_8996[12]); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL17, + DSIPHY_DLN2_TIMING_CTRL_8, + DSIPHY_DLN3_TIMING_CTRL_8, + pd->timing_8996[20], + pd->timing_8996[28]); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL18, + DSIPHY_CKLN_TIMING_CTRL_8, + DSIPHY_CMN_CTRL_1, + pd->timing_8996[36], 0); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL30, + DSIPHY_CMN_GLBL_TEST_CTRL, + DSIPHY_CMN_GLBL_TEST_CTRL, + ((glbl_tst_cntrl) & (~BIT(2))), + ((glbl_tst_cntrl) & (~BIT(2)))); + MDSS_DYN_REF_REG_W(ctrl->ctrl_base, + DSI_DYNAMIC_REFRESH_PLL_CTRL31, + DSIPHY_CMN_GLBL_TEST_CTRL, + DSIPHY_CMN_GLBL_TEST_CTRL, + ((glbl_tst_cntrl) & (~BIT(2))), + ((glbl_tst_cntrl) & (~BIT(2)))); + } + + wmb(); /* make sure phy timings are updated*/ +} + static void mdss_dsi_ctrl_phy_reset(struct mdss_dsi_ctrl_pdata *ctrl) { /* start phy sw reset */ |
