msm: mdss: Add support for dynamic refresh rate
Add support for dynamic refresh rate through immediate clock update and dynamic refresh pll register configuration. Change-Id: I3ea8da3db100b6e5f21697a80f7b97543d4689f1 Signed-off-by: Jeevan Shriram <jshriram@codeaurora.org> [abhimany@codeaurora.org: INIT_COMPLETION fixups] Signed-off-by: Abhimanyu Kapur <abhimany@codeaurora.org>
This commit is contained in:
parent
eb5019c32c
commit
1745ed0ed5
5 changed files with 272 additions and 38 deletions
|
@ -22,12 +22,15 @@
|
|||
#include <linux/err.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/leds-qpnp-wled.h>
|
||||
#include <linux/clk.h>
|
||||
|
||||
#include "mdss.h"
|
||||
#include "mdss_panel.h"
|
||||
#include "mdss_dsi.h"
|
||||
#include "mdss_debug.h"
|
||||
|
||||
#define XO_CLK_RATE 19200000
|
||||
|
||||
static int mdss_dsi_pinctrl_set_state(struct mdss_dsi_ctrl_pdata *ctrl_pdata,
|
||||
bool active);
|
||||
|
||||
|
@ -850,12 +853,77 @@ 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;
|
||||
|
||||
reg_data = MIPI_INP((ctrl_pdata->ctrl_base) + DSI_DYNAMIC_REFRESH_CTRL);
|
||||
reg_data &= ~BIT(12);
|
||||
|
||||
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)
|
||||
{
|
||||
u32 esc_clk_rate = XO_CLK_RATE;
|
||||
u32 pipe_delay, pipe_delay2 = 0, pll_delay;
|
||||
u32 hsync_period = 0;
|
||||
u32 pclk_to_esc_ratio, byte_to_esc_ratio, hr_bit_to_esc_ratio;
|
||||
struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
|
||||
struct mdss_panel_info *pinfo = NULL;
|
||||
struct mdss_dsi_phy_ctrl *pd = NULL;
|
||||
|
||||
if (pdata == NULL) {
|
||||
pr_err("%s Invalid pdata\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
|
||||
panel_data);
|
||||
|
||||
pinfo = &pdata->panel_info;
|
||||
pd = &(pinfo->mipi.dsi_phy_db);
|
||||
|
||||
pclk_to_esc_ratio = (ctrl_pdata->pclk_rate / esc_clk_rate);
|
||||
byte_to_esc_ratio = (ctrl_pdata->byte_clk_rate / esc_clk_rate);
|
||||
hr_bit_to_esc_ratio = ((ctrl_pdata->byte_clk_rate * 4) / esc_clk_rate);
|
||||
|
||||
hsync_period = mdss_panel_get_htotal(pinfo, true);
|
||||
pipe_delay = (hsync_period + 1) / pclk_to_esc_ratio;
|
||||
if (pinfo->mipi.eof_bllp_power_stop == 0)
|
||||
pipe_delay += (17 / pclk_to_esc_ratio) +
|
||||
((21 + pinfo->mipi.t_clk_pre +
|
||||
pinfo->mipi.t_clk_post) / byte_to_esc_ratio) +
|
||||
((((pd->timing[8] >> 1) + 1) +
|
||||
((pd->timing[6] >> 1) + 1) +
|
||||
((pd->timing[3] * 4) + (pd->timing[5] >> 1) + 1) +
|
||||
((pd->timing[7] >> 1) + 1) +
|
||||
((pd->timing[1] >> 1) + 1) +
|
||||
((pd->timing[4] >> 1) + 1)) / hr_bit_to_esc_ratio);
|
||||
|
||||
if (pinfo->mipi.force_clk_lane_hs)
|
||||
pipe_delay2 = (6 / byte_to_esc_ratio) +
|
||||
((((pd->timing[1] >> 1) + 1) +
|
||||
((pd->timing[4] >> 1) + 1)) / hr_bit_to_esc_ratio);
|
||||
|
||||
pll_delay = ((1000 * esc_clk_rate) / 1000000) * 2;
|
||||
|
||||
MIPI_OUTP((ctrl_pdata->ctrl_base) + DSI_DYNAMIC_REFRESH_PIPE_DELAY,
|
||||
pipe_delay);
|
||||
MIPI_OUTP((ctrl_pdata->ctrl_base) + DSI_DYNAMIC_REFRESH_PIPE_DELAY2,
|
||||
pipe_delay2);
|
||||
MIPI_OUTP((ctrl_pdata->ctrl_base) + DSI_DYNAMIC_REFRESH_PLL_DELAY,
|
||||
pll_delay);
|
||||
}
|
||||
|
||||
static int __mdss_dsi_dfps_update_clks(struct mdss_panel_data *pdata,
|
||||
int new_fps)
|
||||
{
|
||||
int rc = 0;
|
||||
u32 data;
|
||||
struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
|
||||
u32 dsi_ctrl;
|
||||
|
||||
if (pdata == NULL) {
|
||||
pr_err("%s Invalid pdata\n", __func__);
|
||||
|
@ -876,25 +944,63 @@ static int __mdss_dsi_dfps_update_clks(struct mdss_panel_data *pdata,
|
|||
__func__);
|
||||
return rc;
|
||||
}
|
||||
ctrl_pdata->pclk_rate =
|
||||
pdata->panel_info.mipi.dsi_pclk_rate;
|
||||
ctrl_pdata->byte_clk_rate =
|
||||
pdata->panel_info.clk_rate / 8;
|
||||
|
||||
if (pdata->panel_info.dfps_update
|
||||
== DFPS_IMMEDIATE_CLK_UPDATE_MODE) {
|
||||
dsi_ctrl = MIPI_INP((ctrl_pdata->ctrl_base) +
|
||||
0x0004);
|
||||
pdata->panel_info.mipi.frame_rate = new_fps;
|
||||
dsi_ctrl &= ~0x2;
|
||||
MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x0004,
|
||||
dsi_ctrl);
|
||||
mdss_dsi_controller_cfg(true, pdata);
|
||||
mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 0);
|
||||
mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1);
|
||||
dsi_ctrl |= 0x2;
|
||||
MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x0004,
|
||||
dsi_ctrl);
|
||||
|
||||
__mdss_dsi_dyn_refresh_config(ctrl_pdata);
|
||||
__mdss_dsi_calc_dfps_delay(pdata);
|
||||
ctrl_pdata->pclk_rate =
|
||||
pdata->panel_info.mipi.dsi_pclk_rate;
|
||||
ctrl_pdata->byte_clk_rate =
|
||||
pdata->panel_info.clk_rate / 8;
|
||||
|
||||
pr_debug("byte_rate=%i\n", ctrl_pdata->byte_clk_rate);
|
||||
pr_debug("pclk_rate=%i\n", ctrl_pdata->pclk_rate);
|
||||
|
||||
/* add an extra reference to main clks */
|
||||
clk_prepare_enable(ctrl_pdata->pll_byte_clk);
|
||||
clk_prepare_enable(ctrl_pdata->pll_pixel_clk);
|
||||
|
||||
/* 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);
|
||||
|
||||
rc = clk_set_rate(ctrl_pdata->byte_clk,
|
||||
ctrl_pdata->byte_clk_rate);
|
||||
if (rc) {
|
||||
pr_err("%s: dsi_byte_clk - clk_set_rate failed\n",
|
||||
__func__);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = clk_set_rate(ctrl_pdata->pixel_clk, ctrl_pdata->pclk_rate);
|
||||
if (rc) {
|
||||
pr_err("%s: dsi_pixel_clk - clk_set_rate failed\n",
|
||||
__func__);
|
||||
return 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);
|
||||
} else {
|
||||
ctrl_pdata->pclk_rate =
|
||||
pdata->panel_info.mipi.dsi_pclk_rate;
|
||||
ctrl_pdata->byte_clk_rate =
|
||||
pdata->panel_info.clk_rate / 8;
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
@ -1648,6 +1754,14 @@ int dsi_panel_device_register(struct device_node *pan_node,
|
|||
return -EPERM;
|
||||
}
|
||||
|
||||
if (pinfo->dynamic_fps &&
|
||||
pinfo->dfps_update == DFPS_IMMEDIATE_CLK_UPDATE_MODE) {
|
||||
if (mdss_dsi_shadow_clk_init(ctrl_pdev, ctrl_pdata)) {
|
||||
pr_err("unable to initialize shadow ctrl clks\n");
|
||||
return -EPERM;
|
||||
}
|
||||
}
|
||||
|
||||
if (mdss_dsi_retrieve_ctrl_resources(ctrl_pdev,
|
||||
pinfo->pdest,
|
||||
ctrl_pdata)) {
|
||||
|
|
|
@ -147,6 +147,8 @@ enum dsi_pm_type {
|
|||
#define DSI_CMD_DST_FORMAT_RGB666 7
|
||||
#define DSI_CMD_DST_FORMAT_RGB888 8
|
||||
|
||||
#define DSI_INTR_DYNAMIC_REFRESH_MASK BIT(29)
|
||||
#define DSI_INTR_DYNAMIC_REFRESH_DONE BIT(28)
|
||||
#define DSI_INTR_ERROR_MASK BIT(25)
|
||||
#define DSI_INTR_ERROR BIT(24)
|
||||
#define DSI_INTR_BTA_DONE_MASK BIT(21)
|
||||
|
@ -166,9 +168,16 @@ enum dsi_pm_type {
|
|||
|
||||
#define DSI_VIDEO_TERM BIT(16)
|
||||
#define DSI_MDP_TERM BIT(8)
|
||||
#define DSI_DYNAMIC_TERM BIT(4)
|
||||
#define DSI_BTA_TERM BIT(1)
|
||||
#define DSI_CMD_TERM BIT(0)
|
||||
|
||||
/* offsets for dynamic refresh */
|
||||
#define DSI_DYNAMIC_REFRESH_CTRL 0x200
|
||||
#define DSI_DYNAMIC_REFRESH_PIPE_DELAY 0x204
|
||||
#define DSI_DYNAMIC_REFRESH_PIPE_DELAY2 0x208
|
||||
#define DSI_DYNAMIC_REFRESH_PLL_DELAY 0x20C
|
||||
|
||||
extern struct device dsi_dev;
|
||||
extern u32 dsi_irq;
|
||||
extern struct mdss_dsi_ctrl_pdata *ctrl_list[];
|
||||
|
@ -293,6 +302,12 @@ struct mdss_dsi_ctrl_pdata {
|
|||
struct clk *byte_clk;
|
||||
struct clk *esc_clk;
|
||||
struct clk *pixel_clk;
|
||||
struct clk *mux_byte_clk;
|
||||
struct clk *mux_pixel_clk;
|
||||
struct clk *pll_byte_clk;
|
||||
struct clk *pll_pixel_clk;
|
||||
struct clk *shadow_byte_clk;
|
||||
struct clk *shadow_pixel_clk;
|
||||
u8 ctrl_state;
|
||||
int panel_mode;
|
||||
int irq_cnt;
|
||||
|
@ -337,6 +352,7 @@ struct mdss_dsi_ctrl_pdata {
|
|||
struct completion dma_comp;
|
||||
struct completion mdp_comp;
|
||||
struct completion video_comp;
|
||||
struct completion dynamic_comp;
|
||||
struct completion bta_comp;
|
||||
spinlock_t irq_lock;
|
||||
spinlock_t mdp_lock;
|
||||
|
@ -406,7 +422,10 @@ int mdss_dsi_clk_div_config(struct mdss_panel_info *panel_info,
|
|||
int frame_rate);
|
||||
int mdss_dsi_clk_init(struct platform_device *pdev,
|
||||
struct mdss_dsi_ctrl_pdata *ctrl_pdata);
|
||||
int mdss_dsi_shadow_clk_init(struct platform_device *pdev,
|
||||
struct mdss_dsi_ctrl_pdata *ctrl_pdata);
|
||||
void mdss_dsi_clk_deinit(struct mdss_dsi_ctrl_pdata *ctrl_pdata);
|
||||
void mdss_dsi_shadow_clk_deinit(struct mdss_dsi_ctrl_pdata *ctrl_pdata);
|
||||
int mdss_dsi_enable_bus_clocks(struct mdss_dsi_ctrl_pdata *ctrl_pdata);
|
||||
void mdss_dsi_disable_bus_clocks(struct mdss_dsi_ctrl_pdata *ctrl_pdata);
|
||||
int mdss_dsi_panel_reset(struct mdss_panel_data *pdata, int enable);
|
||||
|
@ -419,6 +438,7 @@ void mdss_dsi_ctrl_init(struct device *ctrl_dev,
|
|||
struct mdss_dsi_ctrl_pdata *ctrl);
|
||||
void mdss_dsi_cmd_mdp_busy(struct mdss_dsi_ctrl_pdata *ctrl);
|
||||
void mdss_dsi_wait4video_done(struct mdss_dsi_ctrl_pdata *ctrl);
|
||||
void mdss_dsi_en_wait4dynamic_done(struct mdss_dsi_ctrl_pdata *ctrl);
|
||||
int mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp);
|
||||
void mdss_dsi_cmdlist_kickoff(int intf);
|
||||
int mdss_dsi_bta_status_check(struct mdss_dsi_ctrl_pdata *ctrl);
|
||||
|
|
|
@ -96,6 +96,7 @@ void mdss_dsi_ctrl_init(struct device *ctrl_dev,
|
|||
init_completion(&ctrl->dma_comp);
|
||||
init_completion(&ctrl->mdp_comp);
|
||||
init_completion(&ctrl->video_comp);
|
||||
init_completion(&ctrl->dynamic_comp);
|
||||
init_completion(&ctrl->bta_comp);
|
||||
spin_lock_init(&ctrl->irq_lock);
|
||||
spin_lock_init(&ctrl->mdp_lock);
|
||||
|
@ -1272,6 +1273,30 @@ static int mdss_dsi_cmd_dma_rx(struct mdss_dsi_ctrl_pdata *ctrl,
|
|||
return rx_byte;
|
||||
}
|
||||
|
||||
void mdss_dsi_en_wait4dynamic_done(struct mdss_dsi_ctrl_pdata *ctrl)
|
||||
{
|
||||
unsigned long flag;
|
||||
u32 data;
|
||||
/* DSI_INTL_CTRL */
|
||||
data = MIPI_INP((ctrl->ctrl_base) + 0x0110);
|
||||
data |= DSI_INTR_DYNAMIC_REFRESH_MASK;
|
||||
MIPI_OUTP((ctrl->ctrl_base) + 0x0110, data);
|
||||
|
||||
spin_lock_irqsave(&ctrl->mdp_lock, flag);
|
||||
reinit_completion(&ctrl->dynamic_comp);
|
||||
mdss_dsi_enable_irq(ctrl, DSI_DYNAMIC_TERM);
|
||||
spin_unlock_irqrestore(&ctrl->mdp_lock, flag);
|
||||
MIPI_OUTP((ctrl->ctrl_base) + DSI_DYNAMIC_REFRESH_CTRL,
|
||||
(BIT(8) | BIT(0)));
|
||||
|
||||
if (!wait_for_completion_timeout(&ctrl->dynamic_comp,
|
||||
msecs_to_jiffies(VSYNC_PERIOD * 4)))
|
||||
pr_err("Dynamic interrupt timedout\n");
|
||||
|
||||
data = MIPI_INP((ctrl->ctrl_base) + 0x0110);
|
||||
data &= ~DSI_INTR_DYNAMIC_REFRESH_MASK;
|
||||
MIPI_OUTP((ctrl->ctrl_base) + 0x0110, data);
|
||||
}
|
||||
|
||||
void mdss_dsi_wait4video_done(struct mdss_dsi_ctrl_pdata *ctrl)
|
||||
{
|
||||
|
@ -1746,5 +1771,12 @@ irqreturn_t mdss_dsi_isr(int irq, void *ptr)
|
|||
spin_unlock(&ctrl->mdp_lock);
|
||||
}
|
||||
|
||||
if (isr & DSI_INTR_DYNAMIC_REFRESH_DONE) {
|
||||
spin_lock(&ctrl->mdp_lock);
|
||||
mdss_dsi_disable_irq_nosync(ctrl, DSI_DYNAMIC_TERM);
|
||||
complete(&ctrl->dynamic_comp);
|
||||
spin_unlock(&ctrl->mdp_lock);
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
|
|
@ -636,33 +636,13 @@ static int mdss_mdp_video_config_fps(struct mdss_mdp_ctl *ctl,
|
|||
pr_err("TG is OFF. DFPS mode invalid\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
ctl->force_screen_state = MDSS_SCREEN_FORCE_BLANK;
|
||||
mdss_mdp_display_commit(ctl, NULL, NULL);
|
||||
mdss_mdp_display_wait4comp(ctl);
|
||||
mdp_video_write(ctx,
|
||||
MDSS_MDP_REG_INTF_TIMING_ENGINE_EN, 0);
|
||||
/*
|
||||
* Need to wait for atleast one vsync time for proper
|
||||
* TG OFF before doing changes on interfaces
|
||||
*/
|
||||
msleep(20);
|
||||
rc = mdss_mdp_ctl_intf_event(ctl,
|
||||
MDSS_EVENT_PANEL_UPDATE_FPS,
|
||||
(void *) (unsigned long) new_fps);
|
||||
WARN(rc, "intf %d panel fps update error (%d)\n",
|
||||
ctl->intf_num, rc);
|
||||
mdp_video_write(ctx,
|
||||
MDSS_MDP_REG_INTF_TIMING_ENGINE_EN, 1);
|
||||
/*
|
||||
* Add memory barrier to make sure the MDP Video
|
||||
* mode engine is enabled before next frame is sent
|
||||
*/
|
||||
mb();
|
||||
ctl->force_screen_state = MDSS_SCREEN_DEFAULT;
|
||||
mdss_mdp_display_commit(ctl, NULL, NULL);
|
||||
mdss_mdp_display_wait4comp(ctl);
|
||||
} else if (pdata->panel_info.dfps_update
|
||||
== DFPS_IMMEDIATE_PORCH_UPDATE_MODE){
|
||||
== DFPS_IMMEDIATE_PORCH_UPDATE_MODE) {
|
||||
u32 line_cnt;
|
||||
unsigned long flags;
|
||||
if (!ctx->timegen_en) {
|
||||
|
|
|
@ -418,6 +418,78 @@ mdss_dsi_clk_err:
|
|||
return rc;
|
||||
}
|
||||
|
||||
int mdss_dsi_shadow_clk_init(struct platform_device *pdev,
|
||||
struct mdss_dsi_ctrl_pdata *ctrl)
|
||||
{
|
||||
struct device *dev = NULL;
|
||||
int rc = 0;
|
||||
|
||||
if (!pdev) {
|
||||
pr_err("%s: Invalid pdev\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dev = &pdev->dev;
|
||||
ctrl->mux_byte_clk = clk_get(dev, "mdss_byte_clk_mux");
|
||||
if (IS_ERR(ctrl->mux_byte_clk)) {
|
||||
rc = PTR_ERR(ctrl->mux_byte_clk);
|
||||
pr_err("%s: can't find mux_byte_clk. rc=%d\n",
|
||||
__func__, rc);
|
||||
ctrl->mux_byte_clk = NULL;
|
||||
goto mdss_dsi_shadow_clk_err;
|
||||
}
|
||||
|
||||
ctrl->mux_pixel_clk = clk_get(dev, "mdss_pixel_clk_mux");
|
||||
if (IS_ERR(ctrl->mux_pixel_clk)) {
|
||||
rc = PTR_ERR(ctrl->mux_pixel_clk);
|
||||
pr_err("%s: can't find mdss_mux_pixel_clk. rc=%d\n",
|
||||
__func__, rc);
|
||||
ctrl->mux_pixel_clk = NULL;
|
||||
goto mdss_dsi_shadow_clk_err;
|
||||
}
|
||||
|
||||
ctrl->pll_byte_clk = clk_get(dev, "byte_clk_src");
|
||||
if (IS_ERR(ctrl->pll_byte_clk)) {
|
||||
rc = PTR_ERR(ctrl->pll_byte_clk);
|
||||
pr_err("%s: can't find pll_byte_clk. rc=%d\n",
|
||||
__func__, rc);
|
||||
ctrl->pll_byte_clk = NULL;
|
||||
goto mdss_dsi_shadow_clk_err;
|
||||
}
|
||||
|
||||
ctrl->pll_pixel_clk = clk_get(dev, "pixel_clk_src");
|
||||
if (IS_ERR(ctrl->pll_pixel_clk)) {
|
||||
rc = PTR_ERR(ctrl->pll_pixel_clk);
|
||||
pr_err("%s: can't find pll_pixel_clk. rc=%d\n",
|
||||
__func__, rc);
|
||||
ctrl->pll_pixel_clk = NULL;
|
||||
goto mdss_dsi_shadow_clk_err;
|
||||
}
|
||||
|
||||
ctrl->shadow_byte_clk = clk_get(dev, "shadow_byte_clk_src");
|
||||
if (IS_ERR(ctrl->shadow_byte_clk)) {
|
||||
rc = PTR_ERR(ctrl->shadow_byte_clk);
|
||||
pr_err("%s: can't find shadow_byte_clk. rc=%d\n",
|
||||
__func__, rc);
|
||||
ctrl->shadow_byte_clk = NULL;
|
||||
goto mdss_dsi_shadow_clk_err;
|
||||
}
|
||||
|
||||
ctrl->shadow_pixel_clk = clk_get(dev, "shadow_pixel_clk_src");
|
||||
if (IS_ERR(ctrl->shadow_pixel_clk)) {
|
||||
rc = PTR_ERR(ctrl->shadow_pixel_clk);
|
||||
pr_err("%s: can't find shadow_pixel_clk. rc=%d\n",
|
||||
__func__, rc);
|
||||
ctrl->shadow_pixel_clk = NULL;
|
||||
goto mdss_dsi_shadow_clk_err;
|
||||
}
|
||||
|
||||
mdss_dsi_shadow_clk_err:
|
||||
if (rc)
|
||||
mdss_dsi_shadow_clk_deinit(ctrl);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void mdss_dsi_clk_deinit(struct mdss_dsi_ctrl_pdata *ctrl)
|
||||
{
|
||||
if (ctrl->byte_clk)
|
||||
|
@ -436,6 +508,22 @@ void mdss_dsi_clk_deinit(struct mdss_dsi_ctrl_pdata *ctrl)
|
|||
clk_put(ctrl->mdp_core_clk);
|
||||
}
|
||||
|
||||
void mdss_dsi_shadow_clk_deinit(struct mdss_dsi_ctrl_pdata *ctrl)
|
||||
{
|
||||
if (ctrl->mux_byte_clk)
|
||||
clk_put(ctrl->mux_byte_clk);
|
||||
if (ctrl->mux_pixel_clk)
|
||||
clk_put(ctrl->mux_pixel_clk);
|
||||
if (ctrl->pll_byte_clk)
|
||||
clk_put(ctrl->pll_byte_clk);
|
||||
if (ctrl->pll_pixel_clk)
|
||||
clk_put(ctrl->pll_pixel_clk);
|
||||
if (ctrl->shadow_byte_clk)
|
||||
clk_put(ctrl->shadow_byte_clk);
|
||||
if (ctrl->shadow_pixel_clk)
|
||||
clk_put(ctrl->shadow_pixel_clk);
|
||||
}
|
||||
|
||||
#define PREF_DIV_RATIO 27
|
||||
struct dsiphy_pll_divider_config pll_divider_config;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue