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

Commit 5dd0040b authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "drm/msm: fix sde rsc solver and amc mode sequence" into msm-4.9

parents 9e3c3a30 d2dd1adf
Loading
Loading
Loading
Loading
+70 −42
Original line number Diff line number Diff line
@@ -388,7 +388,7 @@ static int sde_rsc_switch_to_idle(struct sde_rsc_priv *rsc)

static int sde_rsc_switch_to_cmd(struct sde_rsc_priv *rsc,
	struct sde_rsc_cmd_config *config,
	struct sde_rsc_client *caller_client, bool wait_req)
	struct sde_rsc_client *caller_client)
{
	struct sde_rsc_client *client;
	int rc = STATE_UPDATE_NOT_ALLOWED;
@@ -416,8 +416,8 @@ static int sde_rsc_switch_to_cmd(struct sde_rsc_priv *rsc,
	if (rsc->hw_ops.state_update)
		rc = rsc->hw_ops.state_update(rsc, SDE_RSC_CMD_STATE);

	/* wait for vsync */
	if (!rc && wait_req)
	/* wait for vsync for vid to cmd state switch */
	if (!rc && (rsc->current_state == SDE_RSC_VID_STATE))
		drm_wait_one_vblank(rsc->master_drm,
						rsc->primary_client->crtc_id);
end:
@@ -436,13 +436,19 @@ static bool sde_rsc_switch_to_clk(struct sde_rsc_priv *rsc)

	if (rsc->hw_ops.state_update)
		rc = rsc->hw_ops.state_update(rsc, SDE_RSC_CLK_STATE);

	/* wait for vsync for cmd to clk state switch */
	if (!rc && rsc->primary_client &&
				(rsc->current_state == SDE_RSC_CMD_STATE))
		drm_wait_one_vblank(rsc->master_drm,
						rsc->primary_client->crtc_id);
end:
	return rc;
}

static bool sde_rsc_switch_to_vid(struct sde_rsc_priv *rsc,
	struct sde_rsc_cmd_config *config,
	struct sde_rsc_client *caller_client, bool wait_req)
	struct sde_rsc_client *caller_client)
{
	int rc = 0;

@@ -454,8 +460,9 @@ static bool sde_rsc_switch_to_vid(struct sde_rsc_priv *rsc,
	if (rsc->hw_ops.state_update)
		rc = rsc->hw_ops.state_update(rsc, SDE_RSC_VID_STATE);

	/* wait for vsync */
	if (!rc && rsc->primary_client && wait_req)
	/* wait for vsync for cmd to vid state switch */
	if (!rc && rsc->primary_client &&
			(rsc->current_state == SDE_RSC_CMD_STATE))
		drm_wait_one_vblank(rsc->master_drm,
						rsc->primary_client->crtc_id);
	return rc;
@@ -481,7 +488,6 @@ int sde_rsc_client_state_update(struct sde_rsc_client *caller_client,
{
	int rc = 0;
	struct sde_rsc_priv *rsc;
	bool wait_requested = false;

	if (!caller_client) {
		pr_err("invalid client for rsc state update\n");
@@ -512,11 +518,7 @@ int sde_rsc_client_state_update(struct sde_rsc_client *caller_client,
		__builtin_return_address(0), rsc->current_state,
		caller_client->name, state);

	/* only switch state needs vsync wait */
	wait_requested = (rsc->current_state == SDE_RSC_VID_STATE) ||
			(rsc->current_state == SDE_RSC_CMD_STATE);

	if (rsc->power_collapse)
	if (rsc->current_state == SDE_RSC_IDLE_STATE)
		sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true);

	switch (state) {
@@ -526,7 +528,7 @@ int sde_rsc_client_state_update(struct sde_rsc_client *caller_client,
		/* video state client might be exiting; try cmd state switch */
		if (rc == TRY_CMD_MODE_SWITCH) {
			rc = sde_rsc_switch_to_cmd(rsc, NULL,
					rsc->primary_client, wait_requested);
							rsc->primary_client);
			if (!rc)
				state = SDE_RSC_CMD_STATE;

@@ -539,13 +541,11 @@ int sde_rsc_client_state_update(struct sde_rsc_client *caller_client,
		break;

	case SDE_RSC_CMD_STATE:
		rc = sde_rsc_switch_to_cmd(rsc, config, caller_client,
								wait_requested);
		rc = sde_rsc_switch_to_cmd(rsc, config, caller_client);
		break;

	case SDE_RSC_VID_STATE:
		rc = sde_rsc_switch_to_vid(rsc, config, caller_client,
								wait_requested);
		rc = sde_rsc_switch_to_vid(rsc, config, caller_client);
		break;

	case SDE_RSC_CLK_STATE:
@@ -561,7 +561,7 @@ int sde_rsc_client_state_update(struct sde_rsc_client *caller_client,
		rc = 0;
		goto clk_disable;
	} else if (rc) {
		pr_err("state update failed rc:%d\n", rc);
		pr_debug("state:%d update failed rc:%d\n", state, rc);
		goto clk_disable;
	}

@@ -569,7 +569,7 @@ int sde_rsc_client_state_update(struct sde_rsc_client *caller_client,
	rsc->current_state = state;

clk_disable:
	if (rsc->power_collapse)
	if (rsc->current_state == SDE_RSC_IDLE_STATE)
		sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, false);
end:
	mutex_unlock(&rsc->client_lock);
@@ -615,14 +615,9 @@ int sde_rsc_client_vote(struct sde_rsc_client *caller_client,
			caller_client->name, ab_vote, ib_vote);

	mutex_lock(&rsc->client_lock);
	if ((caller_client->current_state == SDE_RSC_IDLE_STATE) ||
		(rsc->current_state == SDE_RSC_IDLE_STATE)) {

		pr_err("invalid state: client state:%d rsc state:%d\n",
			caller_client->current_state, rsc->current_state);
		rc = -EINVAL;
		goto end;
	}
	rc = sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true);
	if (rc)
		goto clk_enable_fail;

	if (rsc->hw_ops.is_amc_mode)
		amc_mode = rsc->hw_ops.is_amc_mode(rsc);
@@ -644,14 +639,19 @@ int sde_rsc_client_vote(struct sde_rsc_client *caller_client,
		}
	}

	rpmh_invalidate(rsc->disp_rsc);
	sde_power_data_bus_set_quota(&rsc->phandle, rsc->pclient,
		SDE_POWER_HANDLE_DATA_BUS_CLIENT_RT, ab_vote, ib_vote);
	rpmh_flush(rsc->disp_rsc);

	if (rsc->hw_ops.tcs_use_ok)
		rsc->hw_ops.tcs_use_ok(rsc);

end:
	sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, false);
clk_enable_fail:
	mutex_unlock(&rsc->client_lock);

	return rc;
}
EXPORT_SYMBOL(sde_rsc_client_vote);
@@ -668,6 +668,10 @@ static int _sde_debugfs_status_show(struct seq_file *s, void *data)
	rsc = s->private;

	mutex_lock(&rsc->client_lock);
	ret = sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true);
	if (ret)
		goto end;

	seq_printf(s, "rsc current state:%d\n", rsc->current_state);
	seq_printf(s, "wraper backoff time(ns):%d\n",
				rsc->timer_config.static_wakeup_time_ns);
@@ -691,17 +695,15 @@ static int _sde_debugfs_status_show(struct seq_file *s, void *data)
		seq_printf(s, "\t client:%s state:%d\n",
				client->name, client->current_state);

	sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true);

	if (rsc->hw_ops.debug_show) {
		ret = rsc->hw_ops.debug_show(s, rsc);
		if (ret)
			pr_err("sde rsc: hw debug failed ret:%d\n", ret);
	}

	sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, false);
	mutex_unlock(&rsc->client_lock);

end:
	mutex_unlock(&rsc->client_lock);
	return 0;
}

@@ -722,20 +724,23 @@ static ssize_t _sde_debugfs_mode_ctrl_read(struct file *file, char __user *buf,
{
	struct sde_rsc_priv *rsc = file->private_data;
	char buffer[MAX_BUFFER_SIZE];
	int blen = 0;
	int blen = 0, rc;

	if (*ppos || !rsc || !rsc->hw_ops.mode_ctrl)
		return 0;

	mutex_lock(&rsc->client_lock);
	sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true);
	rc = sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true);
	if (rc)
		goto end;

	blen = rsc->hw_ops.mode_ctrl(rsc, MODE_READ, buffer,
							MAX_BUFFER_SIZE, 0);

	sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, false);
	mutex_unlock(&rsc->client_lock);

end:
	mutex_unlock(&rsc->client_lock);
	if (blen < 0)
		return 0;

@@ -752,6 +757,7 @@ static ssize_t _sde_debugfs_mode_ctrl_write(struct file *file,
	struct sde_rsc_priv *rsc = file->private_data;
	char *input, *mode;
	u32 mode0_state = 0, mode1_state = 0, mode2_state = 0;
	int rc;

	if (!rsc || !rsc->hw_ops.mode_ctrl)
		return 0;
@@ -767,7 +773,9 @@ static ssize_t _sde_debugfs_mode_ctrl_write(struct file *file,
	input[count - 1] = '\0';

	mutex_lock(&rsc->client_lock);
	sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true);
	rc = sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true);
	if (rc)
		goto clk_enable_fail;

	mode = strnstr(input, "mode0=", strlen("mode0="));
	if (mode) {
@@ -794,9 +802,10 @@ static ssize_t _sde_debugfs_mode_ctrl_write(struct file *file,

end:
	sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, false);
clk_enable_fail:
	mutex_unlock(&rsc->client_lock);

	pr_err("req: mode0:%d mode1:%d mode2:%d\n", mode0_state, mode1_state,
	pr_info("req: mode0:%d mode1:%d mode2:%d\n", mode0_state, mode1_state,
								mode2_state);
	kfree(input);
	return count;
@@ -814,20 +823,23 @@ static ssize_t _sde_debugfs_vsync_mode_read(struct file *file, char __user *buf,
{
	struct sde_rsc_priv *rsc = file->private_data;
	char buffer[MAX_BUFFER_SIZE];
	int blen = 0;
	int blen = 0, rc;

	if (*ppos || !rsc || !rsc->hw_ops.hw_vsync)
		return 0;

	mutex_lock(&rsc->client_lock);
	sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true);
	rc = sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true);
	if (rc)
		goto end;

	blen = rsc->hw_ops.hw_vsync(rsc, VSYNC_READ, buffer,
						MAX_BUFFER_SIZE, 0);

	sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, false);
	mutex_unlock(&rsc->client_lock);

end:
	mutex_unlock(&rsc->client_lock);
	if (blen < 0)
		return 0;

@@ -844,6 +856,7 @@ static ssize_t _sde_debugfs_vsync_mode_write(struct file *file,
	struct sde_rsc_priv *rsc = file->private_data;
	char *input, *vsync_mode;
	u32 vsync_state = 0;
	int rc;

	if (!rsc || !rsc->hw_ops.hw_vsync)
		return 0;
@@ -865,7 +878,9 @@ static ssize_t _sde_debugfs_vsync_mode_write(struct file *file,
	}

	mutex_lock(&rsc->client_lock);
	sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true);
	rc = sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true);
	if (rc)
		goto end;

	if (vsync_state)
		rsc->hw_ops.hw_vsync(rsc, VSYNC_ENABLE, NULL,
@@ -874,8 +889,9 @@ static ssize_t _sde_debugfs_vsync_mode_write(struct file *file,
		rsc->hw_ops.hw_vsync(rsc, VSYNC_DISABLE, NULL, 0, 0);

	sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, false);
	mutex_unlock(&rsc->client_lock);

end:
	mutex_unlock(&rsc->client_lock);
	kfree(input);
	return count;
}
@@ -930,6 +946,8 @@ static void sde_rsc_deinit(struct platform_device *pdev,
		msm_dss_iounmap(&rsc->wrapper_io);
	if (rsc->drv_io.base)
		msm_dss_iounmap(&rsc->drv_io);
	if (rsc->disp_rsc)
		rpmh_release(rsc->disp_rsc);
	if (rsc->pclient)
		sde_power_client_destroy(&rsc->phandle, rsc->pclient);

@@ -1038,6 +1056,17 @@ static int sde_rsc_probe(struct platform_device *pdev)
		goto sde_rsc_fail;
	}

	rsc->disp_rsc = rpmh_get_byname(pdev, "disp_rsc");
	if (IS_ERR_OR_NULL(rsc->disp_rsc)) {
		ret = PTR_ERR(rsc->disp_rsc);
		rsc->disp_rsc = NULL;
		pr_err("sde rsc:get display rsc failed ret:%d\n", ret);
		goto sde_rsc_fail;
	}
	rpmh_invalidate(rsc->disp_rsc);
	/* call flush to disable the disp rsc interrupt */
	rpmh_flush(rsc->disp_rsc);

	ret = msm_dss_ioremap_byname(pdev, &rsc->wrapper_io, "wrapper");
	if (ret) {
		pr_err("sde rsc: wrapper io data mapping failed ret=%d\n", ret);
@@ -1084,7 +1113,6 @@ static int sde_rsc_probe(struct platform_device *pdev)
	snprintf(name, MAX_RSC_CLIENT_NAME_LEN, "%s%d", "sde_rsc", counter);
	_sde_rsc_init_debugfs(rsc, name);
	counter++;
	rsc->power_collapse = true;

	ret = component_add(&pdev->dev, &sde_rsc_comp_ops);
	if (ret)
+32 −13
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@
#define SDE_RSCC_AMC_TCS_MODE_IRQ_STATUS_DRV0		0x1c00

#define SDE_RSCC_SOFT_WAKEUP_TIME_LO_DRV0		0xc04
#define SDE_RSCC_SOFT_WAKEUP_TIME_HI_DRV0		0xc08
#define SDE_RSCC_MAX_IDLE_DURATION_DRV0			0xc0c
#define SDE_RSC_SOLVER_TIME_SLOT_TABLE_0_DRV0		0x1000
#define SDE_RSC_SOLVER_TIME_SLOT_TABLE_1_DRV0		0x1004
@@ -224,7 +225,9 @@ static int rsc_hw_solver_init(struct sde_rsc_priv *rsc)
	pr_debug("rsc solver init\n");

	dss_reg_w(&rsc->drv_io, SDE_RSCC_SOFT_WAKEUP_TIME_LO_DRV0,
					0x7FFFFFFF, rsc->debug_mode);
					0xFFFFFFFF, rsc->debug_mode);
	dss_reg_w(&rsc->drv_io, SDE_RSCC_SOFT_WAKEUP_TIME_HI_DRV0,
					0xFFFFFFFF, rsc->debug_mode);
	dss_reg_w(&rsc->drv_io, SDE_RSCC_MAX_IDLE_DURATION_DRV0,
					0xEFFFFFFF, rsc->debug_mode);

@@ -308,6 +311,15 @@ int sde_rsc_mode2_entry(struct sde_rsc_priv *rsc)

	rsc_event_trigger(rsc, SDE_RSC_EVENT_PRE_CORE_PC);

	/* update qtimers to high during clk & video mode state */
	if ((rsc->current_state == SDE_RSC_VID_STATE) ||
			(rsc->current_state == SDE_RSC_CLK_STATE)) {
		dss_reg_w(&rsc->wrapper_io, SDE_RSCC_F0_QTMR_V1_CNTP_CVAL_HI,
						0xffffffff, rsc->debug_mode);
		dss_reg_w(&rsc->wrapper_io, SDE_RSCC_F0_QTMR_V1_CNTP_CVAL_LO,
						0xffffffff, rsc->debug_mode);
	}

	wrapper_status = dss_reg_r(&rsc->wrapper_io, SDE_RSCC_WRAPPER_CTRL,
				rsc->debug_mode);
	wrapper_status |= BIT(3);
@@ -357,8 +369,6 @@ int sde_rsc_mode2_entry(struct sde_rsc_priv *rsc)
	return 0;

end:
	regulator_set_mode(rsc->fs, REGULATOR_MODE_NORMAL);

	rsc_event_trigger(rsc, SDE_RSC_EVENT_POST_CORE_RESTORE);

	return rc;
@@ -378,8 +388,7 @@ int sde_rsc_mode2_exit(struct sde_rsc_priv *rsc, enum sde_rsc_state state)
	if ((state == SDE_RSC_VID_STATE) || (state == SDE_RSC_CLK_STATE)) {
		reg = dss_reg_r(&rsc->wrapper_io,
			SDE_RSCC_WRAPPER_OVERRIDE_CTRL, rsc->debug_mode);
		reg |= BIT(8);
		reg &= ~(BIT(1) | BIT(0));
		reg &= ~(BIT(8) | BIT(0));
		dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_OVERRIDE_CTRL,
							reg, rsc->debug_mode);
	}
@@ -411,7 +420,7 @@ int sde_rsc_mode2_exit(struct sde_rsc_priv *rsc, enum sde_rsc_state state)
			rc = 0;
			break;
		}
		usleep_range(1, 2);
		usleep_range(10, 100);
	}

	reg = dss_reg_r(&rsc->wrapper_io, SDE_RSCC_SPARE_PWR_EVENT,
@@ -419,14 +428,9 @@ int sde_rsc_mode2_exit(struct sde_rsc_priv *rsc, enum sde_rsc_state state)
	reg &= ~BIT(13);
	dss_reg_w(&rsc->wrapper_io, SDE_RSCC_SPARE_PWR_EVENT,
							reg, rsc->debug_mode);

	if (rc)
		pr_err("vdd reg is not enabled yet\n");

	rc = regulator_set_mode(rsc->fs, REGULATOR_MODE_NORMAL);
	if (rc)
		pr_err("vdd reg normal mode set failed rc:%d\n", rc);

	rsc_event_trigger(rsc, SDE_RSC_EVENT_POST_CORE_RESTORE);

	return rc;
@@ -454,6 +458,9 @@ static int sde_rsc_state_update(struct sde_rsc_priv *rsc,
						0x1, rsc->debug_mode);
		dss_reg_w(&rsc->drv_io, SDE_RSCC_SOLVER_OVERRIDE_CTRL_DRV0,
							0x0, rsc->debug_mode);
		dss_reg_w(&rsc->drv_io,
			SDE_RSC_SOLVER_SOLVER_MODES_ENABLED_DRV0, 0x7,
			rsc->debug_mode);
		reg = dss_reg_r(&rsc->wrapper_io,
			SDE_RSCC_WRAPPER_OVERRIDE_CTRL, rsc->debug_mode);
		reg |= (BIT(0) | BIT(8));
@@ -477,8 +484,9 @@ static int sde_rsc_state_update(struct sde_rsc_priv *rsc,
		reg &= ~(BIT(1) | BIT(0));
		dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_OVERRIDE_CTRL,
							reg, rsc->debug_mode);
		dss_reg_w(&rsc->drv_io, SDE_RSCC_SOLVER_OVERRIDE_CTRL_DRV0,
							0x1, rsc->debug_mode);
		dss_reg_w(&rsc->drv_io,
			SDE_RSC_SOLVER_SOLVER_MODES_ENABLED_DRV0, 0x5,
			rsc->debug_mode);
		/* make sure that solver mode is override */
		wmb();

@@ -487,6 +495,17 @@ static int sde_rsc_state_update(struct sde_rsc_priv *rsc,

	case SDE_RSC_CLK_STATE:
		pr_debug("clk state handling\n");

		reg = dss_reg_r(&rsc->wrapper_io,
			SDE_RSCC_WRAPPER_OVERRIDE_CTRL, rsc->debug_mode);
		reg &= ~(BIT(8) | BIT(0));
		dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_OVERRIDE_CTRL,
							reg, rsc->debug_mode);
		dss_reg_w(&rsc->drv_io,
			SDE_RSC_SOLVER_SOLVER_MODES_ENABLED_DRV0, 0x5,
			rsc->debug_mode);
		/* make sure that solver mode is disabled */
		wmb();
		break;

	case SDE_RSC_IDLE_STATE:
+2 −0
Original line number Diff line number Diff line
@@ -111,6 +111,7 @@ struct sde_rsc_timer_config {
 * @pclient:		module power client of phandle
 * @fs:			"MDSS GDSC" handle
 *
 * @disp_rsc:		display rsc handle
 * @drv_io:		sde drv io data mapping
 * @wrapper_io:		wrapper io data mapping
 *
@@ -141,6 +142,7 @@ struct sde_rsc_priv {
	struct sde_power_client *pclient;
	struct regulator *fs;

	struct rpmh_client *disp_rsc;
	struct dss_io_data drv_io;
	struct dss_io_data wrapper_io;