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

Commit 60cc3554 authored by Alan Kwong's avatar Alan Kwong
Browse files

drm/msm/dsi-staging: add min data rate to use phy regulator



Add minimum per lane data rate to control if regulator is required
to turn on. Below the minimum rate, phy regulator is not required
and can be turned off. With regulator off, phy power is sourced
from mx domain.

Change-Id: I1d717a848825c74f3b3f8a352bcba1e2b0ba88e6
Signed-off-by: default avatarAlan Kwong <akwong@codeaurora.org>
parent 797e0894
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -126,6 +126,7 @@ Optional properties:
					in floating state(not LP00 or LP11) to turn on this property. Software
					turns off PHY pmic power supply, phy ldo and DSI Lane ldo during
					idle screen (footswitch control off) when this property is enabled.
- qcom,dsi-phy-regulator-min-datarate-bps:  Minimum per lane data rate (bps) to turn on PHY regulator.

[1] Documentation/devicetree/bindings/clocks/clock-bindings.txt
[2] Documentation/devicetree/bindings/graph.txt
@@ -235,4 +236,5 @@ Example:

		qcom,dsi-phy-regulator-ldo-mode;
		qcom,panel-allow-phy-poweroff;
		qcom,dsi-phy-regulator-min-datarate-bps = <1200000000>;
	};
+25 −0
Original line number Diff line number Diff line
@@ -740,6 +740,17 @@ static int dsi_display_debugfs_init(struct dsi_display *display)
			       display->name, name, rc);
			goto error_remove_dir;
		}

		snprintf(name, ARRAY_SIZE(name),
				"%s_regulator_min_datarate_bps", phy->name);
		dump_file = debugfs_create_u32(name, 0600, dir,
				&phy->regulator_min_datarate_bps);
		if (IS_ERR_OR_NULL(dump_file)) {
			rc = PTR_ERR(dump_file);
			pr_err("[%s] debugfs create %s failed, rc=%d\n",
			       display->name, name, rc);
			goto error_remove_dir;
		}
	}

	display->root = dir;
@@ -3006,6 +3017,20 @@ static int dsi_display_set_mode_sub(struct dsi_display *display,
		}
	}

	for (i = 0; i < display->ctrl_count; i++) {
		ctrl = &display->ctrl[i];

		if (!ctrl->phy || !ctrl->ctrl)
			continue;

		rc = dsi_phy_set_clk_freq(ctrl->phy, &ctrl->ctrl->clk_freq);
		if (rc) {
			pr_err("[%s] failed to set phy clk freq, rc=%d\n",
			       display->name, rc);
			goto error;
		}
	}

	if (priv_info->phy_timing_len) {
		for (i = 0; i < display->ctrl_count; i++) {
			ctrl = &display->ctrl[i];
+37 −2
Original line number Diff line number Diff line
@@ -33,6 +33,8 @@

#define DSI_PHY_DEFAULT_LABEL "MDSS PHY CTRL"

#define BITS_PER_BYTE	8

struct dsi_phy_list_item {
	struct msm_dsi_phy *phy;
	struct list_head list;
@@ -294,6 +296,10 @@ static int dsi_phy_settings_init(struct platform_device *pdev,
	phy->allow_phy_power_off = of_property_read_bool(pdev->dev.of_node,
			"qcom,panel-allow-phy-poweroff");

	of_property_read_u32(pdev->dev.of_node,
			"qcom,dsi-phy-regulator-min-datarate-bps",
			&phy->regulator_min_datarate_bps);

	return 0;
err:
	lane->count_per_lane = 0;
@@ -645,7 +651,8 @@ int dsi_phy_set_power_state(struct msm_dsi_phy *dsi_phy, bool enable)
			goto error;
		}

		if (dsi_phy->dsi_phy_state == DSI_PHY_ENGINE_OFF) {
		if (dsi_phy->dsi_phy_state == DSI_PHY_ENGINE_OFF &&
				dsi_phy->regulator_required) {
			rc = dsi_pwr_enable_regulator(
				&dsi_phy->pwr_info.phy_pwr, true);
			if (rc) {
@@ -656,7 +663,8 @@ int dsi_phy_set_power_state(struct msm_dsi_phy *dsi_phy, bool enable)
			}
		}
	} else {
		if (dsi_phy->dsi_phy_state == DSI_PHY_ENGINE_OFF) {
		if (dsi_phy->dsi_phy_state == DSI_PHY_ENGINE_OFF &&
				dsi_phy->regulator_required) {
			rc = dsi_pwr_enable_regulator(
				&dsi_phy->pwr_info.phy_pwr, false);
			if (rc) {
@@ -909,6 +917,33 @@ int dsi_phy_idle_ctrl(struct msm_dsi_phy *phy, bool enable)
	return 0;
}

/**
 * dsi_phy_set_clk_freq() - set DSI PHY clock frequency setting
 * @phy:          DSI PHY handle
 * @clk_freq:     link clock frequency
 *
 * Return: error code.
 */
int dsi_phy_set_clk_freq(struct msm_dsi_phy *phy,
		struct link_clk_freq *clk_freq)
{
	if (!phy || !clk_freq) {
		pr_err("Invalid params\n");
		return -EINVAL;
	}

	phy->regulator_required = clk_freq->byte_clk_rate >
		(phy->regulator_min_datarate_bps / BITS_PER_BYTE);

	pr_debug("[%s] lane_datarate=%u min_datarate=%u required=%d\n",
			phy->name,
			clk_freq->byte_clk_rate * BITS_PER_BYTE,
			phy->regulator_min_datarate_bps,
			phy->regulator_required);

	return 0;
}

/**
 * dsi_phy_set_timing_params() - timing parameters for the panel
 * @phy:          DSI PHY handle
+14 −0
Original line number Diff line number Diff line
@@ -68,6 +68,8 @@ enum phy_engine_state {
 * @data_lanes:        Number of data lanes used.
 * @dst_format:        Destination format.
 * @allow_phy_power_off: True if PHY is allowed to power off when idle
 * @regulator_min_datarate_bps: Minimum per lane data rate to turn on regulator
 * @regulator_required: True if phy regulator is required
 */
struct msm_dsi_phy {
	struct platform_device *pdev;
@@ -91,6 +93,8 @@ struct msm_dsi_phy {
	enum dsi_pixel_format dst_format;

	bool allow_phy_power_off;
	u32 regulator_min_datarate_bps;
	bool regulator_required;
};

/**
@@ -211,6 +215,16 @@ int dsi_phy_clk_cb_register(struct msm_dsi_phy *phy,
 */
int dsi_phy_idle_ctrl(struct msm_dsi_phy *phy, bool enable);

/**
 * dsi_phy_set_clk_freq() - set DSI PHY clock frequency setting
 * @phy:          DSI PHY handle
 * @clk_freq:     link clock frequency
 *
 * Return: error code.
 */
int dsi_phy_set_clk_freq(struct msm_dsi_phy *phy,
		struct link_clk_freq *clk_freq);

/**
 * dsi_phy_set_timing_params() - timing parameters for the panel
 * @phy:          DSI PHY handle