Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f8c42113 authored by Padmanabhan Komanduru's avatar Padmanabhan Komanduru
Browse files

msm: mdss: add support to switch the DSI clock dynamically



Add change to support changing the DSI bit clock dynamically
for video mode panels. This helps to avoid interference of
DSI clock with other subsystems runtime.

Change-Id: I05790a6dd9d8a2fc3cf31727d032e5220d6164e5
Signed-off-by: default avatarPadmanabhan Komanduru <pkomandu@codeaurora.org>
parent 0f0f8c61
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -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>;
+271 −58
Original line number Diff line number Diff line
@@ -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;
			}
		}

		rc = __mdss_dsi_dfps_calc_clks(pdata, new_fps);
		if (rc) {
			pr_err("error calculating clocks for %d\n", new_fps);
			goto error_clks;
			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;
				}

		rc = __mdss_dsi_dfps_update_clks(pdata,	new_fps);
		if (rc) {
			pr_err("Dynamic refresh failed-%d\n", new_fps);
			goto error_dfps;
				mpinfo = &mctrl_pdata->panel_data.panel_info;
			}
			/*
			 * 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);
+3 −3
Original line number Diff line number Diff line
/* 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);
+29 −3
Original line number Diff line number Diff line
/* 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;
}

+4 −27
Original line number Diff line number Diff line
/* 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) {
Loading