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

Commit 9a6ed862 authored by Venkata Prahlad Valluru's avatar Venkata Prahlad Valluru
Browse files

disp: msm: sde: unset and set clk parents during pm_suspend



Currently link clk parent set/unset are done as part of dsi_prepare
and dsi_unprepare, but in case of deepsleep with display ON, these
will not be called. Due to mismatch in parent between clk
framework and actual parent, subsequent clk_set_parent will
early return without setting the parent.

To avoid this condition, do set parent to xo, as part of
pm_suspend and restore to link clk source in pm_resume.

Change-Id: I626899304580f9d9fbcc92cd8b139cd89cd48999
Signed-off-by: default avatarVenkata Prahlad Valluru <quic_vvalluru@quicinc.com>
parent 14385872
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -2659,7 +2659,7 @@ static int dsi_display_phy_power_off(struct dsi_display *display)
}

#ifdef CONFIG_DEEPSLEEP
static int dsi_display_unset_clk_src(struct dsi_display *display)
int dsi_display_unset_clk_src(struct dsi_display *display)
{
	int rc = 0;
	int i;
@@ -2684,13 +2684,13 @@ static int dsi_display_unset_clk_src(struct dsi_display *display)
	return 0;
}
#else
static inline int dsi_display_unset_clk_src(struct dsi_display *display)
inline int dsi_display_unset_clk_src(struct dsi_display *display)
{
	return 0;
}
#endif

static int dsi_display_set_clk_src(struct dsi_display *display)
int dsi_display_set_clk_src(struct dsi_display *display)
{
	int rc = 0;
	int i;
@@ -4200,6 +4200,9 @@ static int dsi_display_parse_dt(struct dsi_display *display)
	/* Parse TE data */
	dsi_display_parse_te_data(display);

	display->needs_clk_src_reset = of_property_read_bool(of_node,
				"qcom,needs-clk-src-reset");

	/* Parse all external bridges from port 0 */
	display_for_each_ctrl(i, display) {
		display->ext_bridge[i].node_of =
+16 −0
Original line number Diff line number Diff line
@@ -214,6 +214,7 @@ struct dsi_display {
	int disp_te_gpio;
	bool is_te_irq_enabled;
	struct completion esd_te_gate;
	bool needs_clk_src_reset;

	u32 ctrl_count;
	struct dsi_display_ctrl ctrl[MAX_DSI_CTRLS_PER_DISPLAY];
@@ -801,4 +802,19 @@ int dsi_display_dump_clks_state(struct dsi_display *display);
 */
void dsi_display_dfps_update_parent(struct dsi_display *display);

/**
 * dsi_display_unset_clk_src() - reset the clocks source to default
 * @display:         Handle to display
 *
 * Return: Zero on Success
 */
int dsi_display_unset_clk_src(struct dsi_display *display);

/**
 * dsi_display_set_clk_src() - set the clocks source
 * @display:         Handle to display
 *
 * Return: Zero on Success
 */
int dsi_display_set_clk_src(struct dsi_display *display);
#endif /* _DSI_DISPLAY_H_ */
+45 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include <linux/of_irq.h>
#include <linux/dma-buf.h>
#include <linux/memblock.h>
#include <linux/suspend.h>
#include <drm/drm_atomic_uapi.h>
#include <drm/drm_probe_helper.h>

@@ -3713,6 +3714,44 @@ void sde_kms_display_early_wakeup(struct drm_device *dev,
	drm_connector_list_iter_end(&conn_iter);
}

#ifdef CONFIG_DEEPSLEEP
static int _sde_kms_pm_set_clk_src(struct sde_kms *sde_kms, bool enable)
{
	int i, rc = 0;
	void *display;
	struct dsi_display *dsi_display;

	if (mem_sleep_current == PM_SUSPEND_MEM) {
		SDE_INFO("Deepsleep\n");

		for (i = 0; i < sde_kms->dsi_display_count; i++) {
			display = sde_kms->dsi_displays[i];
			dsi_display = (struct dsi_display *)display;

			if (!dsi_display->needs_clk_src_reset)
				continue;

			if (enable)
				rc = dsi_display_set_clk_src(dsi_display);
			else
				rc = dsi_display_unset_clk_src(dsi_display);

			if (rc) {
				SDE_ERROR("failed to set clks rc:%d\n", rc);
				return rc;
			}
		}
	}

	return rc;
}
#else
static inline int _sde_kms_pm_set_clk_src(struct sde_kms *sde_kms, bool enable)
{
	return 0;
}
#endif

static void _sde_kms_pm_suspend_idle_helper(struct sde_kms *sde_kms,
	struct device *dev)
{
@@ -3904,6 +3943,9 @@ static int sde_kms_pm_suspend(struct device *dev)
	pm_runtime_put_sync(dev);
	pm_runtime_get_noresume(dev);

	/* reset clock source based on PM suspend state */
	_sde_kms_pm_set_clk_src(sde_kms, false);

	/* dump clock state before entering suspend */
	if (sde_kms->pm_suspend_clk_dump)
		_sde_kms_dump_clks_state(sde_kms);
@@ -3941,6 +3983,9 @@ static int sde_kms_pm_resume(struct device *dev)
		goto end;
	}

	/* reset clock source based on PM suspend state */
	_sde_kms_pm_set_clk_src(sde_kms, true);

	sde_kms->suspend_block = false;

	if (sde_kms->suspend_state) {