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

Commit 5599d64b authored by osaisruj's avatar osaisruj
Browse files

disp: msm: dsi: add support for ultra low power state



During lp2 state the load on the panel and
controller regulators can be reduced. Configure ldos
in optimum mode during this state.

Change-Id: I75c180f28f636ebb23ecbe9679ba89c00977fe0f
Signed-off-by: default avatarosaisruj <osaisruj@codeaurora.org>
parent 5d29dc42
Loading
Loading
Loading
Loading
+39 −0
Original line number Diff line number Diff line
@@ -1247,12 +1247,22 @@ int dsi_display_set_power(struct drm_connector *connector,

	switch (power_mode) {
	case SDE_MODE_DPMS_LP1:
		if (display->panel->power_mode == SDE_MODE_DPMS_LP2) {
			if (dsi_display_set_ulp_load(display, false) < 0)
				DSI_WARN("failed to set load for lp1 state\n");
		}
		rc = dsi_panel_set_lp1(display->panel);
		break;
	case SDE_MODE_DPMS_LP2:
		rc = dsi_panel_set_lp2(display->panel);
		if (dsi_display_set_ulp_load(display, true) < 0)
			DSI_WARN("failed to set load for lp2 state\n");
		break;
	case SDE_MODE_DPMS_ON:
		if (display->panel->power_mode == SDE_MODE_DPMS_LP2) {
			if (dsi_display_set_ulp_load(display, false) < 0)
				DSI_WARN("failed to set load for on state\n");
		}
		if ((display->panel->power_mode == SDE_MODE_DPMS_LP1) ||
			(display->panel->power_mode == SDE_MODE_DPMS_LP2))
			rc = dsi_panel_set_nolp(display->panel);
@@ -3904,6 +3914,35 @@ int dsi_pre_clkon_cb(void *priv,
	return rc;
}

int dsi_display_set_ulp_load(struct dsi_display *display, bool enable)
{
	int i, rc = 0;
	struct dsi_display_ctrl *display_ctrl;
	struct dsi_ctrl *ctrl;
	struct dsi_panel *panel;

	display_for_each_ctrl(i, display) {
		display_ctrl = &display->ctrl[i];
		if (!display_ctrl->ctrl)
			continue;
		ctrl = display_ctrl->ctrl;

		rc = dsi_pwr_config_vreg_opt_mode(&ctrl->pwr_info.host_pwr, enable);
		if (rc) {
			DSI_ERR("failed to set ctrl load\n");
			return rc;
		}
	}

	panel = display->panel;
	rc = dsi_pwr_config_vreg_opt_mode(&panel->power_info, enable);
	if (rc) {
		DSI_ERR("failed to set panel load\n");
		return rc;
	}
	return rc;
}

static void __set_lane_map_v2(u8 *lane_map_v2,
	enum dsi_phy_data_lanes lane0,
	enum dsi_phy_data_lanes lane1,
+1 −1
Original line number Diff line number Diff line
@@ -628,7 +628,7 @@ int dsi_pre_clkon_cb(void *priv, enum dsi_clk_type clk_type,
 * Return: error code.
 */
int dsi_display_unprepare(struct dsi_display *display);

int dsi_display_set_ulp_load(struct dsi_display *display, bool enable);
int dsi_display_set_tpg_state(struct dsi_display *display, bool enable);

int dsi_display_clock_gate(struct dsi_display *display, bool enable);
+33 −1
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2016-2020,2021 The Linux Foundation. All rights reserved.
 */

#include <linux/of.h>
@@ -65,6 +65,14 @@ static int dsi_pwr_parse_supply_node(struct dsi_parser_utils *utils,
		regs->vregs[i].disable_load = tmp;

		/* Optional values */
		rc = utils->read_u32(node, "qcom,supply-ulp-load", &tmp);
		if (rc) {
			DSI_DEBUG("ulp-load not specified\n");
			rc = 0;
		}
		regs->vregs[i].ulp_load = (!rc ? tmp :
			regs->vregs[i].enable_load);

		rc = utils->read_u32(node, "qcom,supply-off-min-voltage", &tmp);
		if (rc) {
			DSI_DEBUG("off-min-voltage not specified\n");
@@ -118,6 +126,30 @@ static int dsi_pwr_parse_supply_node(struct dsi_parser_utils *utils,
	return rc;
}

int dsi_pwr_config_vreg_opt_mode(struct dsi_regulator_info *regs,
				bool enable)
{
	int i = 0, rc = 0;
	struct dsi_vreg *vreg;
	u32 mode;

	for (i = 0; i < regs->count; i++) {
		vreg = &regs->vregs[i];
		mode = enable ? vreg->ulp_load : vreg->enable_load;

		DSI_DEBUG(" Setting optimum mode for %s load = %d\n",
				vreg->vreg_name, mode);

		rc = regulator_set_load(vreg->vreg, mode);
		if (rc < 0) {
			DSI_ERR("Set opt mode failed for %s",
				vreg->vreg_name);
			return rc;
		}
	}
	return rc;
}

/**
 * dsi_pwr_enable_vregs() - enable/disable regulators
 */
+12 −1
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2016-2019,2021 The Linux Foundation. All rights reserved.
 */

#ifndef _DSI_PWR_H_
@@ -21,6 +21,7 @@ struct dsi_parser_utils;
 * @max_voltage:     Maximum voltage in uV.
 * @enable_load:     Load, in uA, when enabled.
 * @disable_load:    Load, in uA, when disabled.
 * @ulp_load:        Load, in uA, when ulp is enabled.
 * @off_min_voltage: Minimum voltage in uV when regulator is disabled.
 * @pre_on_sleep:    Sleep, in ms, before enabling the regulator.
 * @post_on_sleep:   Sleep, in ms, after enabling the regulator.
@@ -34,6 +35,7 @@ struct dsi_vreg {
	u32 max_voltage;
	u32 enable_load;
	u32 disable_load;
	u32 ulp_load;
	u32 off_min_voltage;
	u32 pre_on_sleep;
	u32 post_on_sleep;
@@ -103,4 +105,13 @@ int dsi_pwr_enable_regulator(struct dsi_regulator_info *regs, bool enable);
int dsi_pwr_panel_regulator_mode_set(struct dsi_regulator_info *regs,
						const char *reg_name,
						int regulator_mode);

/**
 * dsi_pwr_config_vreg_opt_mode()
 * set regulator load
 * @regs:       Pointer to set of regulators to enable or disable.
 * @enable:     enable ulp_load or disable
 * return: error code in case of failure or 0 for success.
 */
int dsi_pwr_config_vreg_opt_mode(struct dsi_regulator_info *regs, bool enable);
#endif /* _DSI_PWR_H_ */