Merge "ARM: dts: msm: enable dynamic bit clock for SDM660 MTP panel"
This commit is contained in:
commit
00e3bb0693
16 changed files with 450 additions and 152 deletions
|
@ -165,6 +165,9 @@ Optional properties:
|
|||
- qcom,mdss-dsi-border-color: Defines the border color value if border is present.
|
||||
0 = default value.
|
||||
- qcom,mdss-dsi-pan-enable-dynamic-fps: Boolean used to enable change in frame rate dynamically.
|
||||
- qcom,mdss-dsi-pan-enable-dynamic-bitclk: Boolean used to enable change in DSI clock dynamically.
|
||||
- qcom,mdss-dsi-dynamic-bitclk_freq: An array of integers that specifies the DSI bit clock
|
||||
frequencies supported as part of dynamic bit clock feature.
|
||||
- qcom,mdss-dsi-pan-fps-update: A string that specifies when to change the frame rate.
|
||||
"dfps_suspend_resume_mode"= FPS change request is
|
||||
implemented during suspend/resume.
|
||||
|
@ -696,6 +699,9 @@ Example:
|
|||
qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
|
||||
qcom,mdss-dsi-pan-enable-dynamic-fps;
|
||||
qcom,mdss-dsi-pan-fps-update = "dfps_suspend_resume_mode";
|
||||
qcom,mdss-dsi-pan-enable-dynamic-bitclk;
|
||||
qcom,mdss-dsi-dynamic-bitclk_freq = <711037824 724453632 737869440
|
||||
751285248 764701056 778116864 791532672 804948480>;
|
||||
qcom,min-refresh-rate = <30>;
|
||||
qcom,max-refresh-rate = <60>;
|
||||
qcom,mdss-dsi-bl-pmic-bank-select = <0>;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -19,8 +19,9 @@
|
|||
#clock-cells = <1>;
|
||||
|
||||
reg = <0xc994400 0x588>,
|
||||
<0xc8c2300 0x8>;
|
||||
reg-names = "pll_base", "gdsc_base";
|
||||
<0xc8c2300 0x8>,
|
||||
<0xc994200 0x98>;
|
||||
reg-names = "pll_base", "gdsc_base", "dynamic_pll_base";
|
||||
|
||||
gdsc-supply = <&gdsc_mdss>;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -359,10 +359,19 @@
|
|||
<&clock_mmss MMSS_MDSS_ESC0_CLK>,
|
||||
<&clock_mmss BYTE0_CLK_SRC>,
|
||||
<&clock_mmss PCLK0_CLK_SRC>,
|
||||
<&clock_mmss MMSS_MDSS_BYTE0_INTF_CLK>;
|
||||
<&clock_mmss MMSS_MDSS_BYTE0_INTF_CLK>,
|
||||
<&mdss_dsi0_pll BYTE0_MUX_CLK>,
|
||||
<&mdss_dsi0_pll PIX0_MUX_CLK>,
|
||||
<&mdss_dsi0_pll BYTE0_SRC_CLK>,
|
||||
<&mdss_dsi0_pll PIX0_SRC_CLK>,
|
||||
<&mdss_dsi0_pll SHADOW_BYTE0_SRC_CLK>,
|
||||
<&mdss_dsi0_pll SHADOW_PIX0_SRC_CLK>;
|
||||
clock-names = "byte_clk", "pixel_clk", "core_clk",
|
||||
"byte_clk_rcg", "pixel_clk_rcg",
|
||||
"byte_intf_clk";
|
||||
"byte_intf_clk", "pll_byte_clk_mux",
|
||||
"pll_pixel_clk_mux", "pll_byte_clk_src",
|
||||
"pll_pixel_clk_src", "pll_shadow_byte_clk_src",
|
||||
"pll_shadow_pixel_clk_src";
|
||||
|
||||
qcom,platform-strength-ctrl = [ff 06
|
||||
ff 06
|
||||
|
|
|
@ -406,9 +406,14 @@
|
|||
};
|
||||
|
||||
cont_splash_mem: splash_region@9d400000 {
|
||||
reg = <0x0 0x9d400000 0x0 0x02400000>;
|
||||
reg = <0x0 0x9d400000 0x0 0x23ff000>;
|
||||
label = "cont_splash_mem";
|
||||
};
|
||||
|
||||
dfps_data_mem: dfps_data_mem@0x9f7ff000 {
|
||||
reg = <0 0x9f7ff000 0 0x00001000>;
|
||||
label = "dfps_data_mem";
|
||||
};
|
||||
};
|
||||
|
||||
bluetooth: bt_wcn3990 {
|
||||
|
|
|
@ -144,6 +144,9 @@
|
|||
qcom,mdss-dsi-panel-max-error-count = <3>;
|
||||
qcom,mdss-dsi-min-refresh-rate = <53>;
|
||||
qcom,mdss-dsi-max-refresh-rate = <60>;
|
||||
qcom,mdss-dsi-pan-enable-dynamic-bitclk;
|
||||
qcom,mdss-dsi-dynamic-bitclk_freq = <711037824 724453632 737869440
|
||||
751285248 764701056 778116864 791532672 804948480>;
|
||||
qcom,mdss-dsi-pan-enable-dynamic-fps;
|
||||
qcom,mdss-dsi-pan-fps-update = "dfps_immediate_porch_mode_vfp";
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -19,8 +19,9 @@
|
|||
#clock-cells = <1>;
|
||||
|
||||
reg = <0xc994400 0x588>,
|
||||
<0xc8c2300 0x8>;
|
||||
reg-names = "pll_base", "gdsc_base";
|
||||
<0xc8c2300 0x8>,
|
||||
<0xc994200 0x98>;
|
||||
reg-names = "pll_base", "gdsc_base", "dynamic_pll_base";
|
||||
|
||||
gdsc-supply = <&gdsc_mdss>;
|
||||
|
||||
|
@ -29,6 +30,7 @@
|
|||
clock-rate = <0>;
|
||||
qcom,dsi-pll-ssc-en;
|
||||
qcom,dsi-pll-ssc-mode = "down-spread";
|
||||
memory-region = <&dfps_data_mem>;
|
||||
|
||||
qcom,platform-supply-entries {
|
||||
#address-cells = <1>;
|
||||
|
@ -54,8 +56,9 @@
|
|||
#clock-cells = <1>;
|
||||
|
||||
reg = <0xc996400 0x588>,
|
||||
<0xc8c2300 0x8>;
|
||||
reg-names = "pll_base", "gdsc_base";
|
||||
<0xc8c2300 0x8>,
|
||||
<0xc996200 0x98>;
|
||||
reg-names = "pll_base", "gdsc_base", "dynamic_pll_base";
|
||||
|
||||
gdsc-supply = <&gdsc_mdss>;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -382,10 +382,19 @@
|
|||
<&clock_mmss MMSS_MDSS_ESC0_CLK>,
|
||||
<&clock_mmss BYTE0_CLK_SRC>,
|
||||
<&clock_mmss PCLK0_CLK_SRC>,
|
||||
<&clock_mmss MMSS_MDSS_BYTE0_INTF_CLK>;
|
||||
<&clock_mmss MMSS_MDSS_BYTE0_INTF_CLK>,
|
||||
<&mdss_dsi0_pll BYTE0_MUX_CLK>,
|
||||
<&mdss_dsi0_pll PIX0_MUX_CLK>,
|
||||
<&mdss_dsi0_pll BYTE0_SRC_CLK>,
|
||||
<&mdss_dsi0_pll PIX0_SRC_CLK>,
|
||||
<&mdss_dsi0_pll SHADOW_BYTE0_SRC_CLK>,
|
||||
<&mdss_dsi0_pll SHADOW_PIX0_SRC_CLK>;
|
||||
clock-names = "byte_clk", "pixel_clk", "core_clk",
|
||||
"byte_clk_rcg", "pixel_clk_rcg",
|
||||
"byte_intf_clk";
|
||||
"byte_intf_clk", "pll_byte_clk_mux",
|
||||
"pll_pixel_clk_mux", "pll_byte_clk_src",
|
||||
"pll_pixel_clk_src", "pll_shadow_byte_clk_src",
|
||||
"pll_shadow_pixel_clk_src";
|
||||
|
||||
qcom,null-insertion-enabled;
|
||||
qcom,platform-strength-ctrl = [ff 06
|
||||
|
@ -423,10 +432,19 @@
|
|||
<&clock_mmss MMSS_MDSS_ESC1_CLK>,
|
||||
<&clock_mmss BYTE1_CLK_SRC>,
|
||||
<&clock_mmss PCLK1_CLK_SRC>,
|
||||
<&clock_mmss MMSS_MDSS_BYTE1_INTF_CLK>;
|
||||
<&clock_mmss MMSS_MDSS_BYTE1_INTF_CLK>,
|
||||
<&mdss_dsi1_pll BYTE1_MUX_CLK>,
|
||||
<&mdss_dsi1_pll PIX1_MUX_CLK>,
|
||||
<&mdss_dsi1_pll BYTE1_SRC_CLK>,
|
||||
<&mdss_dsi1_pll PIX1_SRC_CLK>,
|
||||
<&mdss_dsi1_pll SHADOW_BYTE1_SRC_CLK>,
|
||||
<&mdss_dsi1_pll SHADOW_PIX1_SRC_CLK>;
|
||||
clock-names = "byte_clk", "pixel_clk", "core_clk",
|
||||
"byte_clk_rcg", "pixel_clk_rcg",
|
||||
"byte_intf_clk";
|
||||
"byte_intf_clk", "pll_byte_clk_mux",
|
||||
"pll_pixel_clk_mux", "pll_byte_clk_src",
|
||||
"pll_pixel_clk_src", "pll_shadow_byte_clk_src",
|
||||
"pll_shadow_pixel_clk_src";
|
||||
|
||||
qcom,null-insertion-enabled;
|
||||
qcom,platform-strength-ctrl = [ff 06
|
||||
|
|
|
@ -404,9 +404,14 @@
|
|||
};
|
||||
|
||||
cont_splash_mem: splash_region@9d400000 {
|
||||
reg = <0x0 0x9d400000 0x0 0x02400000>;
|
||||
reg = <0x0 0x9d400000 0x0 0x23ff000>;
|
||||
label = "cont_splash_mem";
|
||||
};
|
||||
|
||||
dfps_data_mem: dfps_data_mem@0x9f7ff000 {
|
||||
reg = <0 0x9f7ff000 0 0x00001000>;
|
||||
label = "dfps_data_mem";
|
||||
};
|
||||
};
|
||||
|
||||
bluetooth: bt_wcn3990 {
|
||||
|
|
|
@ -2043,10 +2043,9 @@ static void __mdss_dsi_calc_dfps_delay(struct mdss_panel_data *pdata)
|
|||
}
|
||||
|
||||
static int __mdss_dsi_dfps_calc_clks(struct mdss_panel_data *pdata,
|
||||
int new_fps)
|
||||
u64 new_clk_rate)
|
||||
{
|
||||
int rc = 0;
|
||||
u64 clk_rate;
|
||||
struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
|
||||
struct mdss_panel_info *pinfo;
|
||||
u32 phy_rev;
|
||||
|
@ -2066,14 +2065,9 @@ static int __mdss_dsi_dfps_calc_clks(struct mdss_panel_data *pdata,
|
|||
pinfo = &pdata->panel_info;
|
||||
phy_rev = ctrl_pdata->shared_data->phy_rev;
|
||||
|
||||
rc = mdss_dsi_clk_div_config
|
||||
(&ctrl_pdata->panel_data.panel_info, new_fps);
|
||||
if (rc) {
|
||||
pr_err("%s: unable to initialize the clk dividers\n",
|
||||
__func__);
|
||||
return rc;
|
||||
}
|
||||
|
||||
pinfo->clk_rate = new_clk_rate;
|
||||
pinfo->mipi.dsi_pclk_rate = mdss_dsi_get_pclk_rate(pinfo,
|
||||
new_clk_rate);
|
||||
__mdss_dsi_dyn_refresh_config(ctrl_pdata);
|
||||
|
||||
if (phy_rev == DSI_PHY_REV_20)
|
||||
|
@ -2086,9 +2080,8 @@ static int __mdss_dsi_dfps_calc_clks(struct mdss_panel_data *pdata,
|
|||
ctrl_pdata->byte_clk_rate_bkp = ctrl_pdata->byte_clk_rate;
|
||||
|
||||
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;
|
||||
do_div(new_clk_rate, 8U);
|
||||
ctrl_pdata->byte_clk_rate = (u32) new_clk_rate;
|
||||
|
||||
pr_debug("byte_rate=%i\n", ctrl_pdata->byte_clk_rate);
|
||||
pr_debug("pclk_rate=%i\n", ctrl_pdata->pclk_rate);
|
||||
|
@ -2096,8 +2089,7 @@ static int __mdss_dsi_dfps_calc_clks(struct mdss_panel_data *pdata,
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int __mdss_dsi_dfps_update_clks(struct mdss_panel_data *pdata,
|
||||
int new_fps)
|
||||
static int __mdss_dsi_dfps_update_clks(struct mdss_panel_data *pdata)
|
||||
{
|
||||
struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
|
||||
struct mdss_dsi_ctrl_pdata *sctrl_pdata = NULL;
|
||||
|
@ -2248,12 +2240,6 @@ static int __mdss_dsi_dfps_update_clks(struct mdss_panel_data *pdata,
|
|||
clk_disable_unprepare(ctrl_pdata->pll_byte_clk);
|
||||
clk_disable_unprepare(ctrl_pdata->pll_pixel_clk);
|
||||
|
||||
/* update new fps that at this point is already updated in hw */
|
||||
pinfo->current_fps = new_fps;
|
||||
if (sctrl_pdata) {
|
||||
spinfo->current_fps = new_fps;
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
||||
dfps_timeout:
|
||||
|
@ -2330,13 +2316,65 @@ static void mdss_dsi_avr_config(struct mdss_dsi_ctrl_pdata *ctrl_pdata,
|
|||
MDSS_XLOG(ctrl_pdata->ndx, enabled, data);
|
||||
}
|
||||
|
||||
static int mdss_dsi_dfps_config(struct mdss_panel_data *pdata, int new_fps)
|
||||
static int __mdss_dsi_dynamic_clock_switch(struct mdss_panel_data *pdata,
|
||||
u64 new_clk_rate)
|
||||
{
|
||||
int rc = 0;
|
||||
struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
|
||||
struct mdss_panel_info *pinfo;
|
||||
u32 phy_rev;
|
||||
u32 frame_rate_bkp;
|
||||
u64 clk_rate_bkp;
|
||||
|
||||
pr_debug("%s+:\n", __func__);
|
||||
|
||||
ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
|
||||
panel_data);
|
||||
|
||||
phy_rev = ctrl_pdata->shared_data->phy_rev;
|
||||
pinfo = &pdata->panel_info;
|
||||
|
||||
/* get the fps configured in HW */
|
||||
clk_rate_bkp = pinfo->clk_rate;
|
||||
|
||||
__mdss_dsi_mask_dfps_errors(ctrl_pdata, true);
|
||||
|
||||
if (phy_rev == DSI_PHY_REV_20) {
|
||||
rc = mdss_dsi_phy_calc_timing_param(pinfo, phy_rev,
|
||||
new_clk_rate);
|
||||
if (rc) {
|
||||
pr_err("PHY calculations failed-%lld\n", new_clk_rate);
|
||||
goto end_update;
|
||||
}
|
||||
}
|
||||
|
||||
rc = __mdss_dsi_dfps_calc_clks(pdata, new_clk_rate);
|
||||
if (rc) {
|
||||
pr_err("error calculating clocks for %lld\n", new_clk_rate);
|
||||
goto error_clks;
|
||||
}
|
||||
|
||||
rc = __mdss_dsi_dfps_update_clks(pdata);
|
||||
if (rc) {
|
||||
pr_err("Dynamic refresh failed-%lld\n", new_clk_rate);
|
||||
goto error_dfps;
|
||||
}
|
||||
return rc;
|
||||
error_dfps:
|
||||
if (__mdss_dsi_dfps_calc_clks(pdata, clk_rate_bkp))
|
||||
pr_err("error reverting clock calculations for %lld\n",
|
||||
clk_rate_bkp);
|
||||
error_clks:
|
||||
if (mdss_dsi_phy_calc_timing_param(pinfo, phy_rev, clk_rate_bkp))
|
||||
pr_err("Unable to revert phy timing-%lld\n", clk_rate_bkp);
|
||||
end_update:
|
||||
return rc;
|
||||
}
|
||||
|
||||
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_panel_info *pinfo;
|
||||
|
||||
pr_debug("%s+:\n", __func__);
|
||||
|
||||
|
@ -2353,12 +2391,8 @@ static int mdss_dsi_dfps_config(struct mdss_panel_data *pdata, int new_fps)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
phy_rev = ctrl_pdata->shared_data->phy_rev;
|
||||
pinfo = &pdata->panel_info;
|
||||
|
||||
/* get the fps configured in HW */
|
||||
frame_rate_bkp = pinfo->current_fps;
|
||||
|
||||
if (new_fps == pinfo->current_fps) {
|
||||
/*
|
||||
* This is unlikely as mdss driver checks for previously
|
||||
|
@ -2374,39 +2408,45 @@ static int mdss_dsi_dfps_config(struct mdss_panel_data *pdata, int new_fps)
|
|||
__mdss_dsi_update_video_mode_total(pdata, new_fps);
|
||||
} else if (pinfo->dfps_update == DFPS_IMMEDIATE_CLK_UPDATE_MODE) {
|
||||
/* Clock update method */
|
||||
u64 new_clk_rate = mdss_dsi_calc_bitclk
|
||||
(&ctrl_pdata->panel_data.panel_info, new_fps);
|
||||
if (!new_clk_rate) {
|
||||
pr_err("%s: unable to get the new bit clock rate\n",
|
||||
__func__);
|
||||
rc = -EINVAL;
|
||||
goto end_update;
|
||||
}
|
||||
|
||||
__mdss_dsi_mask_dfps_errors(ctrl_pdata, true);
|
||||
rc = __mdss_dsi_dynamic_clock_switch(pdata, new_clk_rate);
|
||||
if (!rc) {
|
||||
struct mdss_dsi_ctrl_pdata *mctrl_pdata = NULL;
|
||||
struct mdss_panel_info *mpinfo = NULL;
|
||||
|
||||
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);
|
||||
if (mdss_dsi_is_hw_config_split
|
||||
(ctrl_pdata->shared_data) &&
|
||||
mdss_dsi_is_ctrl_clk_master(ctrl_pdata))
|
||||
goto end_update;
|
||||
|
||||
if (mdss_dsi_is_hw_config_split
|
||||
(ctrl_pdata->shared_data) &&
|
||||
mdss_dsi_is_ctrl_clk_slave(ctrl_pdata)) {
|
||||
mctrl_pdata = mdss_dsi_get_ctrl_clk_master();
|
||||
if (IS_ERR_OR_NULL(mctrl_pdata)) {
|
||||
pr_err("Invalid mctrl_pdata\n");
|
||||
goto end_update;
|
||||
}
|
||||
|
||||
mpinfo = &mctrl_pdata->panel_data.panel_info;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
/*
|
||||
* update new fps that at this point is already
|
||||
* updated in hw
|
||||
*/
|
||||
pinfo->current_fps = new_fps;
|
||||
if (mctrl_pdata && mpinfo)
|
||||
mpinfo->current_fps = new_fps;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -2678,6 +2718,163 @@ static void mdss_dsi_timing_db_ctrl(struct mdss_dsi_ctrl_pdata *ctrl,
|
|||
MDSS_DSI_CORE_CLK, MDSS_DSI_CLK_OFF);
|
||||
}
|
||||
|
||||
static struct mdss_dsi_ctrl_pdata *mdss_dsi_get_drvdata(struct device *dev)
|
||||
{
|
||||
struct msm_fb_data_type *mfd;
|
||||
struct mdss_panel_data *pdata;
|
||||
struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
|
||||
struct fb_info *fbi = dev_get_drvdata(dev);
|
||||
|
||||
if (fbi) {
|
||||
mfd = (struct msm_fb_data_type *)fbi->par;
|
||||
pdata = dev_get_platdata(&mfd->pdev->dev);
|
||||
|
||||
ctrl_pdata = container_of(pdata,
|
||||
struct mdss_dsi_ctrl_pdata, panel_data);
|
||||
}
|
||||
|
||||
return ctrl_pdata;
|
||||
}
|
||||
|
||||
static ssize_t supp_bitclk_list_sysfs_rda(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
ssize_t ret = 0;
|
||||
int i = 0;
|
||||
struct mdss_dsi_ctrl_pdata *ctrl_pdata = mdss_dsi_get_drvdata(dev);
|
||||
struct mdss_panel_info *pinfo = NULL;
|
||||
|
||||
if (!ctrl_pdata) {
|
||||
pr_err("%s: invalid input\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pinfo = &ctrl_pdata->panel_data.panel_info;
|
||||
if (!pinfo) {
|
||||
pr_err("no panel connected\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!pinfo->dynamic_bitclk) {
|
||||
pr_err_once("%s: Dynamic bitclk not enabled for this panel\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
buf[0] = 0;
|
||||
for (i = 0; i < pinfo->supp_bitclk_len; i++) {
|
||||
if (ret > 0)
|
||||
ret += scnprintf(buf + ret, PAGE_SIZE - ret,
|
||||
",%d", pinfo->supp_bitclks[i]);
|
||||
else
|
||||
ret += scnprintf(buf + ret, PAGE_SIZE - ret,
|
||||
"%d", pinfo->supp_bitclks[i]);
|
||||
}
|
||||
|
||||
ret += scnprintf(buf + ret, PAGE_SIZE - ret, "\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t dynamic_bitclk_sysfs_wta(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
int rc = 0, i = 0;
|
||||
struct mdss_dsi_ctrl_pdata *ctrl_pdata = mdss_dsi_get_drvdata(dev);
|
||||
struct mdss_panel_info *pinfo = NULL;
|
||||
int clk_rate = 0;
|
||||
|
||||
if (!ctrl_pdata) {
|
||||
pr_err("%s: invalid input\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pinfo = &ctrl_pdata->panel_data.panel_info;
|
||||
if (!pinfo) {
|
||||
pr_err("no panel connected\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!pinfo->dynamic_bitclk) {
|
||||
pr_err_once("%s: Dynamic bitclk not enabled for this panel\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (mdss_panel_is_power_off(pinfo->panel_power_state)) {
|
||||
pr_err_once("%s: Panel powered off!\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = kstrtoint(buf, 10, &clk_rate);
|
||||
if (rc) {
|
||||
pr_err("%s: kstrtoint failed. rc=%d\n", __func__, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
for (i = 0; i < pinfo->supp_bitclk_len; i++) {
|
||||
if (pinfo->supp_bitclks[i] == clk_rate)
|
||||
break;
|
||||
}
|
||||
if (i == pinfo->supp_bitclk_len) {
|
||||
pr_err("Requested bitclk: %d not supported\n", clk_rate);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = __mdss_dsi_dynamic_clock_switch(&ctrl_pdata->panel_data,
|
||||
clk_rate);
|
||||
if (!rc && mdss_dsi_is_hw_config_split(ctrl_pdata->shared_data)) {
|
||||
struct mdss_dsi_ctrl_pdata *octrl =
|
||||
mdss_dsi_get_other_ctrl(ctrl_pdata);
|
||||
rc = __mdss_dsi_dynamic_clock_switch(&octrl->panel_data,
|
||||
clk_rate);
|
||||
if (rc)
|
||||
pr_err("failed to switch DSI bitclk for sctrl\n");
|
||||
} else if (rc) {
|
||||
pr_err("failed to switch DSI bitclk\n");
|
||||
}
|
||||
|
||||
return count;
|
||||
} /* dynamic_bitclk_sysfs_wta */
|
||||
|
||||
static ssize_t dynamic_bitclk_sysfs_rda(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
ssize_t ret;
|
||||
struct mdss_dsi_ctrl_pdata *ctrl_pdata = mdss_dsi_get_drvdata(dev);
|
||||
struct mdss_panel_info *pinfo = NULL;
|
||||
|
||||
if (!ctrl_pdata) {
|
||||
pr_err("%s: invalid input\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pinfo = &ctrl_pdata->panel_data.panel_info;
|
||||
if (!pinfo) {
|
||||
pr_err("no panel connected\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = snprintf(buf, PAGE_SIZE, "%llu\n", pinfo->clk_rate);
|
||||
pr_debug("%s: '%llu'\n", __func__, pinfo->clk_rate);
|
||||
|
||||
return ret;
|
||||
} /* dynamic_bitclk_sysfs_rda */
|
||||
|
||||
static DEVICE_ATTR(dynamic_bitclk, S_IRUGO | S_IWUSR | S_IWGRP,
|
||||
dynamic_bitclk_sysfs_rda, dynamic_bitclk_sysfs_wta);
|
||||
static DEVICE_ATTR(supported_bitclk, S_IRUGO, supp_bitclk_list_sysfs_rda, NULL);
|
||||
|
||||
static struct attribute *dynamic_bitclk_fs_attrs[] = {
|
||||
&dev_attr_dynamic_bitclk.attr,
|
||||
&dev_attr_supported_bitclk.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute_group mdss_dsi_fs_attrs_group = {
|
||||
.attrs = dynamic_bitclk_fs_attrs,
|
||||
};
|
||||
|
||||
static int mdss_dsi_event_handler(struct mdss_panel_data *pdata,
|
||||
int event, void *arg)
|
||||
{
|
||||
|
@ -2844,6 +3041,14 @@ static int mdss_dsi_event_handler(struct mdss_panel_data *pdata,
|
|||
ctrl_pdata->kobj = &fbi->dev->kobj;
|
||||
ctrl_pdata->fb_node = fbi->node;
|
||||
|
||||
if (!mdss_dsi_is_hw_config_split(ctrl_pdata->shared_data) ||
|
||||
(mdss_dsi_is_hw_config_split(ctrl_pdata->shared_data) &&
|
||||
mdss_dsi_is_ctrl_clk_master(ctrl_pdata))) {
|
||||
if (sysfs_create_group(&fbi->dev->kobj,
|
||||
&mdss_dsi_fs_attrs_group))
|
||||
pr_err("failed to create DSI sysfs group\n");
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_MSM_DBA) &&
|
||||
pdata->panel_info.is_dba_panel) {
|
||||
queue_delayed_work(ctrl_pdata->workq,
|
||||
|
@ -3392,7 +3597,7 @@ static int mdss_dsi_ctrl_probe(struct platform_device *pdev)
|
|||
pinfo = &(ctrl_pdata->panel_data.panel_info);
|
||||
if (!(mdss_dsi_is_hw_config_split(ctrl_pdata->shared_data) &&
|
||||
mdss_dsi_is_ctrl_clk_slave(ctrl_pdata)) &&
|
||||
pinfo->dynamic_fps) {
|
||||
(pinfo->dynamic_fps || pinfo->dynamic_bitclk)) {
|
||||
rc = mdss_dsi_shadow_clk_init(pdev, ctrl_pdata);
|
||||
|
||||
if (rc) {
|
||||
|
@ -4359,11 +4564,19 @@ int dsi_panel_device_register(struct platform_device *ctrl_pdev,
|
|||
((mipi->mode == DSI_VIDEO_MODE)
|
||||
? MIPI_VIDEO_PANEL : MIPI_CMD_PANEL);
|
||||
|
||||
rc = mdss_dsi_clk_div_config(pinfo, mipi->frame_rate);
|
||||
if (rc) {
|
||||
pr_err("%s: unable to initialize the clk dividers\n", __func__);
|
||||
return rc;
|
||||
pinfo->clk_rate = mdss_dsi_calc_bitclk(pinfo, mipi->frame_rate);
|
||||
if (!pinfo->clk_rate) {
|
||||
pr_err("%s: unable to calculate the DSI bit clock\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pinfo->mipi.dsi_pclk_rate = mdss_dsi_get_pclk_rate(pinfo,
|
||||
pinfo->clk_rate);
|
||||
if (!pinfo->mipi.dsi_pclk_rate) {
|
||||
pr_err("%s: unable to calculate the DSI pclk\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ctrl_pdata->pclk_rate = mipi->dsi_pclk_rate;
|
||||
clk_rate = pinfo->clk_rate;
|
||||
do_div(clk_rate, 8U);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -633,8 +633,8 @@ void disable_esd_thread(void);
|
|||
void mdss_dsi_irq_handler_config(struct mdss_dsi_ctrl_pdata *ctrl_pdata);
|
||||
|
||||
void mdss_dsi_set_tx_power_mode(int mode, struct mdss_panel_data *pdata);
|
||||
int mdss_dsi_clk_div_config(struct mdss_panel_info *panel_info,
|
||||
int frame_rate);
|
||||
u64 mdss_dsi_calc_bitclk(struct mdss_panel_info *panel_info, int frame_rate);
|
||||
u32 mdss_dsi_get_pclk_rate(struct mdss_panel_info *panel_info, u64 clk_rate);
|
||||
int mdss_dsi_clk_refresh(struct mdss_panel_data *pdata, bool update_phy);
|
||||
int mdss_dsi_link_clk_init(struct platform_device *pdev,
|
||||
struct mdss_dsi_ctrl_pdata *ctrl_pdata);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -2324,14 +2324,15 @@ static void mdss_dsi_parse_dfps_config(struct device_node *pan_node,
|
|||
struct mdss_dsi_ctrl_pdata *ctrl_pdata)
|
||||
{
|
||||
const char *data;
|
||||
bool dynamic_fps;
|
||||
bool dynamic_fps, dynamic_bitclk;
|
||||
struct mdss_panel_info *pinfo = &(ctrl_pdata->panel_data.panel_info);
|
||||
int rc = 0;
|
||||
|
||||
dynamic_fps = of_property_read_bool(pan_node,
|
||||
"qcom,mdss-dsi-pan-enable-dynamic-fps");
|
||||
|
||||
if (!dynamic_fps)
|
||||
return;
|
||||
goto dynamic_bitclk;
|
||||
|
||||
pinfo->dynamic_fps = true;
|
||||
data = of_get_property(pan_node, "qcom,mdss-dsi-pan-fps-update", NULL);
|
||||
|
@ -2361,6 +2362,31 @@ static void mdss_dsi_parse_dfps_config(struct device_node *pan_node,
|
|||
pinfo->new_fps = pinfo->mipi.frame_rate;
|
||||
pinfo->current_fps = pinfo->mipi.frame_rate;
|
||||
|
||||
dynamic_bitclk:
|
||||
dynamic_bitclk = of_property_read_bool(pan_node,
|
||||
"qcom,mdss-dsi-pan-enable-dynamic-bitclk");
|
||||
if (!dynamic_bitclk)
|
||||
return;
|
||||
|
||||
of_find_property(pan_node, "qcom,mdss-dsi-dynamic-bitclk_freq",
|
||||
&pinfo->supp_bitclk_len);
|
||||
pinfo->supp_bitclk_len = pinfo->supp_bitclk_len/sizeof(u32);
|
||||
if (pinfo->supp_bitclk_len < 1)
|
||||
return;
|
||||
|
||||
pinfo->supp_bitclks = kzalloc((sizeof(u32) * pinfo->supp_bitclk_len),
|
||||
GFP_KERNEL);
|
||||
if (!pinfo->supp_bitclks)
|
||||
return;
|
||||
|
||||
rc = of_property_read_u32_array(pan_node,
|
||||
"qcom,mdss-dsi-dynamic-bitclk_freq", pinfo->supp_bitclks,
|
||||
pinfo->supp_bitclk_len);
|
||||
if (rc) {
|
||||
pr_err("Error from dynamic bitclk freq u64 array read\n");
|
||||
return;
|
||||
}
|
||||
pinfo->dynamic_bitclk = true;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2015-2016, 2018 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -1034,15 +1034,10 @@ static void mdss_dsi_phy_update_timing_param_v3(struct mdss_panel_info *pinfo,
|
|||
}
|
||||
|
||||
int mdss_dsi_phy_calc_timing_param(struct mdss_panel_info *pinfo, u32 phy_rev,
|
||||
u32 frate_hz)
|
||||
u64 clk_rate)
|
||||
{
|
||||
struct dsi_phy_t_clk_param t_clk;
|
||||
struct dsi_phy_timing t_param;
|
||||
int hsync_period;
|
||||
int vsync_period;
|
||||
unsigned long inter_num;
|
||||
uint32_t lane_config = 0;
|
||||
unsigned long x, y;
|
||||
int rc = 0;
|
||||
|
||||
if (!pinfo) {
|
||||
|
@ -1050,30 +1045,12 @@ int mdss_dsi_phy_calc_timing_param(struct mdss_panel_info *pinfo, u32 phy_rev,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
hsync_period = mdss_panel_get_htotal(pinfo, true);
|
||||
vsync_period = mdss_panel_get_vtotal(pinfo);
|
||||
|
||||
inter_num = pinfo->bpp * frate_hz;
|
||||
|
||||
if (pinfo->mipi.data_lane0)
|
||||
lane_config++;
|
||||
if (pinfo->mipi.data_lane1)
|
||||
lane_config++;
|
||||
if (pinfo->mipi.data_lane2)
|
||||
lane_config++;
|
||||
if (pinfo->mipi.data_lane3)
|
||||
lane_config++;
|
||||
|
||||
x = mult_frac(vsync_period * hsync_period, inter_num, lane_config);
|
||||
y = rounddown(x, 1);
|
||||
t_clk.bitclk_mbps = rounddown(mult_frac(y, 1, 1000000), 1);
|
||||
t_clk.bitclk_mbps = rounddown((uint32_t) div_u64(clk_rate, 1000000), 1);
|
||||
t_clk.escclk_numer = ESC_CLK_MHZ;
|
||||
t_clk.escclk_denom = ESCCLK_MMSS_CC_PREDIV;
|
||||
t_clk.tlpx_numer_ns = TLPX_NUMER;
|
||||
t_clk.treot_ns = TR_EOT;
|
||||
pr_debug("hperiod=%d, vperiod=%d, inter_num=%lu, lane_cfg=%d\n",
|
||||
hsync_period, vsync_period, inter_num, lane_config);
|
||||
pr_debug("x=%lu, y=%lu, bitrate=%d\n", x, y, t_clk.bitclk_mbps);
|
||||
pr_debug("bitrate=%d\n", t_clk.bitclk_mbps);
|
||||
|
||||
rc = mdss_dsi_phy_initialize_defaults(&t_clk, &t_param, phy_rev);
|
||||
if (rc) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -42,7 +42,7 @@ enum phy_mode {
|
|||
* @frate_hz - Frame rate for which phy timing parameters are to be calculated.
|
||||
*/
|
||||
int mdss_dsi_phy_calc_timing_param(struct mdss_panel_info *pinfo, u32 phy_rev,
|
||||
u32 frate_hz);
|
||||
u64 clk_rate);
|
||||
|
||||
/*
|
||||
* mdss_dsi_phy_v3_init() - initialization sequence for DSI PHY rev v3
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Core MDSS framebuffer driver.
|
||||
*
|
||||
* Copyright (c) 2008-2017, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2008-2018, The Linux Foundation. All rights reserved.
|
||||
* Copyright (C) 2007 Google Incorporated
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
|
@ -610,7 +610,7 @@ static ssize_t mdss_fb_get_panel_info(struct device *dev,
|
|||
"red_chromaticity_x=%d\nred_chromaticity_y=%d\n"
|
||||
"green_chromaticity_x=%d\ngreen_chromaticity_y=%d\n"
|
||||
"blue_chromaticity_x=%d\nblue_chromaticity_y=%d\n"
|
||||
"panel_orientation=%d\n",
|
||||
"panel_orientation=%d\ndyn_bitclk_en=%d\n",
|
||||
pinfo->partial_update_enabled,
|
||||
pinfo->roi_alignment.xstart_pix_align,
|
||||
pinfo->roi_alignment.width_pix_align,
|
||||
|
@ -636,7 +636,7 @@ static ssize_t mdss_fb_get_panel_info(struct device *dev,
|
|||
pinfo->hdr_properties.display_primaries[5],
|
||||
pinfo->hdr_properties.display_primaries[6],
|
||||
pinfo->hdr_properties.display_primaries[7],
|
||||
pinfo->panel_orientation);
|
||||
pinfo->panel_orientation, pinfo->dynamic_bitclk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -805,6 +805,9 @@ struct mdss_panel_info {
|
|||
int pwm_lpg_chan;
|
||||
int pwm_period;
|
||||
bool dynamic_fps;
|
||||
bool dynamic_bitclk;
|
||||
u32 *supp_bitclks;
|
||||
u32 supp_bitclk_len;
|
||||
bool ulps_feature_enabled;
|
||||
bool ulps_suspend_enabled;
|
||||
bool panel_ack_disabled;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -1489,13 +1489,19 @@ int mdss_dsi_clk_refresh(struct mdss_panel_data *pdata, bool update_phy)
|
|||
__func__, pinfo->mipi.frame_rate);
|
||||
}
|
||||
|
||||
rc = mdss_dsi_clk_div_config(&pdata->panel_info,
|
||||
pdata->panel_info.mipi.frame_rate);
|
||||
if (rc) {
|
||||
pr_err("%s: unable to initialize the clk dividers\n",
|
||||
__func__);
|
||||
return rc;
|
||||
pinfo->clk_rate = mdss_dsi_calc_bitclk(pinfo, pinfo->mipi.frame_rate);
|
||||
if (!pinfo->clk_rate) {
|
||||
pr_err("%s: unable to calculate the DSI bit clock\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pinfo->mipi.dsi_pclk_rate = mdss_dsi_get_pclk_rate(pinfo,
|
||||
pinfo->clk_rate);
|
||||
if (!pinfo->mipi.dsi_pclk_rate) {
|
||||
pr_err("%s: unable to calculate the DSI pclk\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ctrl_pdata->refresh_clk_rate = false;
|
||||
ctrl_pdata->pclk_rate = pdata->panel_info.mipi.dsi_pclk_rate;
|
||||
ctrl_pdata->byte_clk_rate = pdata->panel_info.clk_rate / 8;
|
||||
|
@ -1524,7 +1530,7 @@ int mdss_dsi_clk_refresh(struct mdss_panel_data *pdata, bool update_phy)
|
|||
/* phy panel timing calaculation */
|
||||
rc = mdss_dsi_phy_calc_timing_param(pinfo,
|
||||
ctrl_pdata->shared_data->phy_rev,
|
||||
pinfo->mipi.frame_rate);
|
||||
pdata->panel_info.clk_rate);
|
||||
if (rc) {
|
||||
pr_err("Error in calculating phy timings\n");
|
||||
return rc;
|
||||
|
@ -1811,16 +1817,9 @@ bool is_diff_frame_rate(struct mdss_panel_info *panel_info,
|
|||
return (frame_rate != panel_info->mipi.frame_rate);
|
||||
}
|
||||
|
||||
int mdss_dsi_clk_div_config(struct mdss_panel_info *panel_info,
|
||||
int frame_rate)
|
||||
static u8 mdss_dsi_get_lane_cnt(struct mdss_panel_info *panel_info)
|
||||
{
|
||||
struct mdss_panel_data *pdata = container_of(panel_info,
|
||||
struct mdss_panel_data, panel_info);
|
||||
struct mdss_dsi_ctrl_pdata *ctrl_pdata = container_of(pdata,
|
||||
struct mdss_dsi_ctrl_pdata, panel_data);
|
||||
u64 h_period, v_period, clk_rate;
|
||||
u32 dsi_pclk_rate;
|
||||
u8 lanes = 0, bpp;
|
||||
u8 lanes = 0;
|
||||
|
||||
if (!panel_info)
|
||||
return -EINVAL;
|
||||
|
@ -1834,7 +1833,17 @@ int mdss_dsi_clk_div_config(struct mdss_panel_info *panel_info,
|
|||
if (panel_info->mipi.data_lane0)
|
||||
lanes += 1;
|
||||
|
||||
switch (panel_info->mipi.dst_format) {
|
||||
if (!lanes)
|
||||
lanes = 1;
|
||||
|
||||
return lanes;
|
||||
}
|
||||
|
||||
static u8 mdss_dsi_get_bpp(char dst_format)
|
||||
{
|
||||
u8 bpp = 0;
|
||||
|
||||
switch (dst_format) {
|
||||
case DSI_CMD_DST_FORMAT_RGB888:
|
||||
case DSI_VIDEO_DST_FORMAT_RGB888:
|
||||
case DSI_VIDEO_DST_FORMAT_RGB666_LOOSE:
|
||||
|
@ -1848,6 +1857,21 @@ int mdss_dsi_clk_div_config(struct mdss_panel_info *panel_info,
|
|||
bpp = 3; /* Default format set to RGB888 */
|
||||
break;
|
||||
}
|
||||
return bpp;
|
||||
}
|
||||
|
||||
u64 mdss_dsi_calc_bitclk(struct mdss_panel_info *panel_info, int frame_rate)
|
||||
{
|
||||
struct mdss_panel_data *pdata = container_of(panel_info,
|
||||
struct mdss_panel_data, panel_info);
|
||||
struct mdss_dsi_ctrl_pdata *ctrl_pdata = container_of(pdata,
|
||||
struct mdss_dsi_ctrl_pdata, panel_data);
|
||||
u64 h_period, v_period, clk_rate = 0;
|
||||
u8 lanes = 0, bpp;
|
||||
|
||||
lanes = mdss_dsi_get_lane_cnt(panel_info);
|
||||
|
||||
bpp = mdss_dsi_get_bpp(panel_info->mipi.dst_format);
|
||||
|
||||
h_period = mdss_panel_get_htotal(panel_info, true);
|
||||
if (panel_info->split_link_enabled)
|
||||
|
@ -1855,35 +1879,40 @@ int mdss_dsi_clk_div_config(struct mdss_panel_info *panel_info,
|
|||
v_period = mdss_panel_get_vtotal(panel_info);
|
||||
|
||||
if (ctrl_pdata->refresh_clk_rate || is_diff_frame_rate(panel_info,
|
||||
frame_rate) || (!panel_info->clk_rate)) {
|
||||
if (lanes > 0) {
|
||||
panel_info->clk_rate = h_period * v_period * frame_rate
|
||||
* bpp * 8;
|
||||
do_div(panel_info->clk_rate, lanes);
|
||||
} else {
|
||||
pr_err("%s: forcing mdss_dsi lanes to 1\n", __func__);
|
||||
panel_info->clk_rate =
|
||||
h_period * v_period * frame_rate * bpp * 8;
|
||||
}
|
||||
frame_rate) || (!panel_info->clk_rate)) {
|
||||
clk_rate = h_period * v_period * frame_rate * bpp * 8;
|
||||
do_div(clk_rate, lanes);
|
||||
} else if (panel_info->clk_rate) {
|
||||
clk_rate = panel_info->clk_rate;
|
||||
}
|
||||
|
||||
if (panel_info->clk_rate == 0)
|
||||
panel_info->clk_rate = 454000000;
|
||||
if (clk_rate == 0)
|
||||
clk_rate = 454000000;
|
||||
|
||||
return clk_rate;
|
||||
}
|
||||
|
||||
u32 mdss_dsi_get_pclk_rate(struct mdss_panel_info *panel_info, u64 clk_rate)
|
||||
{
|
||||
u8 lanes = 0, bpp;
|
||||
u32 pclk_rate = 0;
|
||||
|
||||
lanes = mdss_dsi_get_lane_cnt(panel_info);
|
||||
|
||||
bpp = mdss_dsi_get_bpp(panel_info->mipi.dst_format);
|
||||
|
||||
clk_rate = panel_info->clk_rate;
|
||||
do_div(clk_rate, 8 * bpp);
|
||||
|
||||
if (panel_info->split_link_enabled)
|
||||
dsi_pclk_rate = (u32) clk_rate *
|
||||
pclk_rate = (u32) clk_rate *
|
||||
panel_info->mipi.lanes_per_sublink;
|
||||
else
|
||||
dsi_pclk_rate = (u32) clk_rate * lanes;
|
||||
pclk_rate = (u32) clk_rate * lanes;
|
||||
|
||||
if ((dsi_pclk_rate < 3300000) || (dsi_pclk_rate > 250000000))
|
||||
dsi_pclk_rate = 35000000;
|
||||
panel_info->mipi.dsi_pclk_rate = dsi_pclk_rate;
|
||||
if ((pclk_rate < 3300000) || (pclk_rate > 250000000))
|
||||
pclk_rate = 35000000;
|
||||
|
||||
return 0;
|
||||
return pclk_rate;
|
||||
}
|
||||
|
||||
static bool mdss_dsi_is_ulps_req_valid(struct mdss_dsi_ctrl_pdata *ctrl,
|
||||
|
|
Loading…
Add table
Reference in a new issue