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

Commit 7981047e authored by Namratha Siddappa's avatar Namratha Siddappa
Browse files

Merge remote-tracking branch 'quic/dev/msm-4.14-display' into msm-4.14



* quic/dev/msm-4.14-display:
  drm/msm: disp rsc sequence update
  drm/msm/sde: fix restore handling for encoders
  drm/msm: allow ab/ib vote update without rsc client

Change-Id: Ib44d47dcf5829a61e6850cd820e89f7ba64e38e7
Signed-off-by: default avatarNamratha Siddappa <namratha@codeaurora.org>
parents 3ee4b6f5 a48ade34
Loading
Loading
Loading
Loading
+18 −2
Original line number Original line Diff line number Diff line
@@ -205,6 +205,7 @@ enum sde_enc_rc_states {
 * @input_handler:			handler for input device events
 * @input_handler:			handler for input device events
 * @topology:                   topology of the display
 * @topology:                   topology of the display
 * @vblank_enabled:		boolean to track userspace vblank vote
 * @vblank_enabled:		boolean to track userspace vblank vote
 * @idle_pc_restore:		flag to indicate idle_pc_restore happened
 * @rsc_config:			rsc configuration for display vtotal, fps, etc.
 * @rsc_config:			rsc configuration for display vtotal, fps, etc.
 * @cur_conn_roi:		current connector roi
 * @cur_conn_roi:		current connector roi
 * @prv_conn_roi:		previous connector roi to optimize if unchanged
 * @prv_conn_roi:		previous connector roi to optimize if unchanged
@@ -251,6 +252,7 @@ struct sde_encoder_virt {
	struct input_handler *input_handler;
	struct input_handler *input_handler;
	struct msm_display_topology topology;
	struct msm_display_topology topology;
	bool vblank_enabled;
	bool vblank_enabled;
	bool idle_pc_restore;


	struct sde_rsc_cmd_config rsc_config;
	struct sde_rsc_cmd_config rsc_config;
	struct sde_rect cur_conn_roi;
	struct sde_rect cur_conn_roi;
@@ -2713,11 +2715,18 @@ void sde_encoder_virt_restore(struct drm_encoder *drm_enc)
	sde_enc = to_sde_encoder_virt(drm_enc);
	sde_enc = to_sde_encoder_virt(drm_enc);
	memset(&sde_enc->cur_master->intf_cfg_v1, 0,
	memset(&sde_enc->cur_master->intf_cfg_v1, 0,
			sizeof(sde_enc->cur_master->intf_cfg_v1));
			sizeof(sde_enc->cur_master->intf_cfg_v1));
	sde_enc->idle_pc_restore = true;


	for (i = 0; i < sde_enc->num_phys_encs; i++) {
	for (i = 0; i < sde_enc->num_phys_encs; i++) {
		struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
		struct sde_encoder_phys *phys = sde_enc->phys_encs[i];


		if (phys && (phys != sde_enc->cur_master) && phys->ops.restore)
		if (!phys)
			continue;

		if (phys->hw_ctl && phys->hw_ctl->ops.clear_pending_flush)
			phys->hw_ctl->ops.clear_pending_flush(phys->hw_ctl);

		if ((phys != sde_enc->cur_master) && phys->ops.restore)
			phys->ops.restore(phys);
			phys->ops.restore(phys);
	}
	}


@@ -3584,7 +3593,13 @@ void sde_encoder_trigger_kickoff_pending(struct drm_encoder *drm_enc)


		if (phys && phys->hw_ctl) {
		if (phys && phys->hw_ctl) {
			ctl = phys->hw_ctl;
			ctl = phys->hw_ctl;
			if (ctl->ops.clear_pending_flush)
			/*
			 * avoid clearing the pending flush during the first
			 * frame update after idle power collpase as the
			 * restore path would have updated the pending flush
			 */
			if (!sde_enc->idle_pc_restore &&
					ctl->ops.clear_pending_flush)
				ctl->ops.clear_pending_flush(ctl);
				ctl->ops.clear_pending_flush(ctl);


			/* update only for command mode primary ctl */
			/* update only for command mode primary ctl */
@@ -3594,6 +3609,7 @@ void sde_encoder_trigger_kickoff_pending(struct drm_encoder *drm_enc)
				ctl->ops.trigger_pending(ctl);
				ctl->ops.trigger_pending(ctl);
		}
		}
	}
	}
	sde_enc->idle_pc_restore = false;
}
}


static void _sde_encoder_setup_dither(struct sde_encoder_phys *phys)
static void _sde_encoder_setup_dither(struct sde_encoder_phys *phys)
+23 −29
Original line number Original line Diff line number Diff line
/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * 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
 * it under the terms of the GNU General Public License version 2 and
@@ -56,12 +56,9 @@ static void sde_power_event_trigger_locked(struct sde_power_handle *phandle,
	}
	}
}
}


static int sde_power_rsc_update(struct sde_power_handle *phandle, bool enable)
static inline void sde_power_rsc_client_init(struct sde_power_handle *phandle)
{
{
	u32 rsc_state;
	/* creates the rsc client */
	int ret = 0;

	/* creates the rsc client on the first enable */
	if (!phandle->rsc_client_init) {
	if (!phandle->rsc_client_init) {
		phandle->rsc_client = sde_rsc_client_create(SDE_RSC_INDEX,
		phandle->rsc_client = sde_rsc_client_create(SDE_RSC_INDEX,
				"sde_power_handle", false);
				"sde_power_handle", false);
@@ -72,6 +69,12 @@ static int sde_power_rsc_update(struct sde_power_handle *phandle, bool enable)
		}
		}
		phandle->rsc_client_init = true;
		phandle->rsc_client_init = true;
	}
	}
}

static int sde_power_rsc_update(struct sde_power_handle *phandle, bool enable)
{
	u32 rsc_state;
	int ret = 0;


	rsc_state = enable ? SDE_RSC_CLK_STATE : SDE_RSC_IDLE_STATE;
	rsc_state = enable ? SDE_RSC_CLK_STATE : SDE_RSC_IDLE_STATE;


@@ -890,6 +893,9 @@ int sde_power_resource_enable(struct sde_power_handle *phandle,
	if (!changed)
	if (!changed)
		goto end;
		goto end;


	/* RSC client init */
	sde_power_rsc_client_init(phandle);

	if (enable) {
	if (enable) {
		sde_power_event_trigger_locked(phandle,
		sde_power_event_trigger_locked(phandle,
				SDE_POWER_EVENT_PRE_ENABLE);
				SDE_POWER_EVENT_PRE_ENABLE);
@@ -903,22 +909,12 @@ int sde_power_resource_enable(struct sde_power_handle *phandle,
				goto data_bus_hdl_err;
				goto data_bus_hdl_err;
			}
			}
		}
		}
		/*
		 * - When the target is RSCC enabled, regulator should
		 *   be enabled by the s/w only for the first time during
		 *   bootup. After that, RSCC hardware takes care of enabling/
		 *   disabling it.
		 * - When the target is not RSCC enabled, regulator should
		 *   be totally handled by the software.
		 */
		if (!phandle->rsc_client) {
		rc = msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg,
		rc = msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg,
				enable);
				enable);
		if (rc) {
		if (rc) {
			pr_err("failed to enable vregs rc=%d\n", rc);
			pr_err("failed to enable vregs rc=%d\n", rc);
			goto vreg_err;
			goto vreg_err;
		}
		}
		}


		rc = sde_power_reg_bus_update(phandle->reg_bus_hdl,
		rc = sde_power_reg_bus_update(phandle->reg_bus_hdl,
							max_usecase_ndx);
							max_usecase_ndx);
@@ -927,13 +923,13 @@ int sde_power_resource_enable(struct sde_power_handle *phandle,
			goto reg_bus_hdl_err;
			goto reg_bus_hdl_err;
		}
		}


		SDE_EVT32_VERBOSE(enable, SDE_EVTLOG_FUNC_CASE1);
		rc = sde_power_rsc_update(phandle, true);
		rc = sde_power_rsc_update(phandle, true);
		if (rc) {
		if (rc) {
			pr_err("failed to update rsc\n");
			pr_err("failed to update rsc\n");
			goto rsc_err;
			goto rsc_err;
		}
		}


		SDE_EVT32_VERBOSE(enable, SDE_EVTLOG_FUNC_CASE1);
		rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, enable);
		rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, enable);
		if (rc) {
		if (rc) {
			pr_err("clock enable failed rc:%d\n", rc);
			pr_err("clock enable failed rc:%d\n", rc);
@@ -948,16 +944,15 @@ int sde_power_resource_enable(struct sde_power_handle *phandle,
				SDE_POWER_EVENT_PRE_DISABLE);
				SDE_POWER_EVENT_PRE_DISABLE);


		SDE_EVT32_VERBOSE(enable, SDE_EVTLOG_FUNC_CASE2);
		SDE_EVT32_VERBOSE(enable, SDE_EVTLOG_FUNC_CASE2);
		msm_dss_enable_clk(mp->clk_config, mp->num_clk, enable);

		sde_power_rsc_update(phandle, false);
		sde_power_rsc_update(phandle, false);


		msm_dss_enable_clk(mp->clk_config, mp->num_clk, enable);

		sde_power_reg_bus_update(phandle->reg_bus_hdl,
		sde_power_reg_bus_update(phandle->reg_bus_hdl,
							max_usecase_ndx);
							max_usecase_ndx);


		if (!phandle->rsc_client)
		msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg, enable);
			msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg,

									enable);
		for (i = 0 ; i < SDE_POWER_HANDLE_DBUS_ID_MAX; i++)
		for (i = 0 ; i < SDE_POWER_HANDLE_DBUS_ID_MAX; i++)
			sde_power_data_bus_update(&phandle->data_bus_handle[i],
			sde_power_data_bus_update(&phandle->data_bus_handle[i],
					enable);
					enable);
@@ -977,7 +972,6 @@ int sde_power_resource_enable(struct sde_power_handle *phandle,
rsc_err:
rsc_err:
	sde_power_reg_bus_update(phandle->reg_bus_hdl, prev_usecase_ndx);
	sde_power_reg_bus_update(phandle->reg_bus_hdl, prev_usecase_ndx);
reg_bus_hdl_err:
reg_bus_hdl_err:
	if (!phandle->rsc_client)
	msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg, 0);
	msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg, 0);
vreg_err:
vreg_err:
	for (i = 0 ; i < SDE_POWER_HANDLE_DBUS_ID_MAX; i++)
	for (i = 0 ; i < SDE_POWER_HANDLE_DBUS_ID_MAX; i++)
+6 −7
Original line number Original line Diff line number Diff line
@@ -898,23 +898,22 @@ EXPORT_SYMBOL(sde_rsc_client_state_update);
int sde_rsc_client_vote(struct sde_rsc_client *caller_client,
int sde_rsc_client_vote(struct sde_rsc_client *caller_client,
		u32 bus_id, u64 ab_vote, u64 ib_vote)
		u32 bus_id, u64 ab_vote, u64 ib_vote)
{
{
	int rc = 0;
	int rc = 0, rsc_index;
	struct sde_rsc_priv *rsc;
	struct sde_rsc_priv *rsc;


	if (!caller_client) {
	if (caller_client && caller_client->rsc_index >= MAX_RSC_COUNT) {
		pr_err("invalid client for ab/ib vote\n");
		return -EINVAL;
	} else if (caller_client->rsc_index >= MAX_RSC_COUNT) {
		pr_err("invalid rsc index\n");
		pr_err("invalid rsc index\n");
		return -EINVAL;
		return -EINVAL;
	}
	}


	rsc = rsc_prv_list[caller_client->rsc_index];
	rsc_index = caller_client ? caller_client->rsc_index : SDE_RSC_INDEX;
	rsc = rsc_prv_list[rsc_index];
	if (!rsc)
	if (!rsc)
		return -EINVAL;
		return -EINVAL;


	pr_debug("client:%s ab:%llu ib:%llu\n",
	pr_debug("client:%s ab:%llu ib:%llu\n",
			caller_client->name, ab_vote, ib_vote);
			caller_client ? caller_client->name : "unknown",
			ab_vote, ib_vote);


	mutex_lock(&rsc->client_lock);
	mutex_lock(&rsc->client_lock);
	rc = sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true);
	rc = sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true);
+23 −19
Original line number Original line Diff line number Diff line
@@ -191,39 +191,40 @@ static int rsc_hw_seq_memory_init_v2(struct sde_rsc_priv *rsc)
						0x38bb9ebe, rsc->debug_mode);
						0x38bb9ebe, rsc->debug_mode);
	dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x10,
	dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x10,
						0xbeff39e0, rsc->debug_mode);
						0xbeff39e0, rsc->debug_mode);

	/* Mode - 2 sequence */
	dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x14,
	dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x14,
						0x20209b9e, rsc->debug_mode);
						0x20209b9e, rsc->debug_mode);

	/* Mode - 2 sequence */
	dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x18,
	dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x18,
						0xfab9baa0, rsc->debug_mode);
						0xb9bae5a0, rsc->debug_mode);
	dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x1c,
	dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x1c,
						0xfebdbbf9, rsc->debug_mode);
						0xbdbbf9fa, rsc->debug_mode);
	dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x20,
	dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x20,
						0xa138999a, rsc->debug_mode);
						0x38999afe, rsc->debug_mode);
	dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x24,
	dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x24,
						0xa2e081e1, rsc->debug_mode);
						0xac81e1a1, rsc->debug_mode);
	dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x28,
	dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x28,
						0x9d3982e2, rsc->debug_mode);
						0x82e2a2e0, rsc->debug_mode);

	/* tcs sleep & wake sequence */
	dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x2c,
	dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x2c,
						0x20209bfd, rsc->debug_mode);
						0x8cfd9d39, rsc->debug_mode);
	dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x30,
	dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x30,
						0x01a6fcbc, rsc->debug_mode);
						0xbc20209b, rsc->debug_mode);

	/* tcs sleep & wake sequence */
	dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x34,
	dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x34,
						0x20209ce6, rsc->debug_mode);
						0xe601a6fc, rsc->debug_mode);
	dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x38,
	dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x38,
						0x01a7fcbc, rsc->debug_mode);
						0xbc20209c, rsc->debug_mode);
	dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x3c,
	dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x3c,
						0x00209ce7, rsc->debug_mode);
						0xe701a7fc, rsc->debug_mode);

	dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_MEM_0_DRV0 + 0x40,
						0x0000209c, rsc->debug_mode);


	/* branch address */
	/* branch address */
	dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_CFG_BR_ADDR_0_DRV0,
	dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_CFG_BR_ADDR_0_DRV0,
						0x30, rsc->debug_mode);
						0x33, rsc->debug_mode);
	dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_CFG_BR_ADDR_1_DRV0,
	dss_reg_w(&rsc->drv_io, SDE_RSCC_SEQ_CFG_BR_ADDR_1_DRV0,
						0x38, rsc->debug_mode);
						0x3b, rsc->debug_mode);


	/* start address */
	/* start address */
	dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_OVERRIDE_CTRL_DRV0,
	dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_OVERRIDE_CTRL_DRV0,
@@ -550,8 +551,11 @@ static int sde_rsc_mode2_entry(struct sde_rsc_priv *rsc)
	}
	}


	if (rc) {
	if (rc) {
		pr_err("mdss gdsc power down failed rc:%d\n", rc);
		reg = dss_reg_r(&rsc->drv_io,
		SDE_EVT32(rc, SDE_EVTLOG_ERROR);
				SDE_RSCC_SEQ_PROGRAM_COUNTER, rsc->debug_mode);
		pr_err("mdss gdsc power down failed, instruction:0x%x, rc:%d\n",
				reg, rc);
		SDE_EVT32(rc, reg, SDE_EVTLOG_ERROR);
		goto end;
		goto end;
	}
	}