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

Commit e9961ae3 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/sde: add support to scale data bus" into dev/msm-4.14-display

parents 3c033e77 5b9b4846
Loading
Loading
Loading
Loading
+76 −6
Original line number Original line Diff line number Diff line
@@ -847,6 +847,68 @@ void sde_power_resource_deinit(struct platform_device *pdev,
		sde_rsc_client_destroy(phandle->rsc_client);
		sde_rsc_client_destroy(phandle->rsc_client);
}
}



int sde_power_scale_reg_bus(struct sde_power_handle *phandle,
	struct sde_power_client *pclient, u32 usecase_ndx, bool skip_lock)
{
	struct sde_power_client *client;
	int rc = 0;
	u32 max_usecase_ndx = VOTE_INDEX_DISABLE;

	if (!skip_lock) {
		mutex_lock(&phandle->phandle_lock);

		if (WARN_ON(pclient->refcount == 0)) {
			/*
			 * This is not expected, clients calling without skip
			 * lock are outside the power resource enable, which
			 * means that they should have enabled the power
			 * resource before trying to scale.
			 */
			rc = -EINVAL;
			goto exit;
		}
	}

	pr_debug("%pS: current idx:%d requested:%d client:%d\n",
		__builtin_return_address(0), pclient->usecase_ndx,
		usecase_ndx, pclient->id);

	pclient->usecase_ndx = usecase_ndx;

	list_for_each_entry(client, &phandle->power_client_clist, list) {
		if (client->usecase_ndx < VOTE_INDEX_MAX &&
		    client->usecase_ndx > max_usecase_ndx)
			max_usecase_ndx = client->usecase_ndx;
	}

	rc = sde_power_reg_bus_update(phandle->reg_bus_hdl,
						max_usecase_ndx);
	if (rc)
		pr_err("failed to set reg bus vote rc=%d\n", rc);

exit:
	if (!skip_lock)
		mutex_unlock(&phandle->phandle_lock);

	return rc;
}

static inline bool _resource_changed(u32 current_usecase_ndx,
		u32 max_usecase_ndx)
{
	WARN_ON((current_usecase_ndx >= VOTE_INDEX_MAX)
		|| (max_usecase_ndx >= VOTE_INDEX_MAX));

	if (((current_usecase_ndx >= VOTE_INDEX_LOW) && /* enabled */
		(max_usecase_ndx == VOTE_INDEX_DISABLE)) || /* max disabled */
		((current_usecase_ndx == VOTE_INDEX_DISABLE) && /* disabled */
		(max_usecase_ndx >= VOTE_INDEX_LOW))) /* max enabled */
		return true;

	return false;
}

int sde_power_resource_enable(struct sde_power_handle *phandle,
int sde_power_resource_enable(struct sde_power_handle *phandle,
	struct sde_power_client *pclient, bool enable)
	struct sde_power_client *pclient, bool enable)
{
{
@@ -880,7 +942,15 @@ int sde_power_resource_enable(struct sde_power_handle *phandle,
			max_usecase_ndx = client->usecase_ndx;
			max_usecase_ndx = client->usecase_ndx;
	}
	}


	if (phandle->current_usecase_ndx != max_usecase_ndx) {
	/*
	 * Check if we need to enable/disable the power resource, we won't
	 * only-scale up/down the AHB vote in this API; if a client wants to
	 * bump up the AHB clock above the LOW (default) level, it needs to
	 * call 'sde_power_scale_reg_bus' with the desired vote after the power
	 * resource was enabled.
	 */
	if (_resource_changed(phandle->current_usecase_ndx,
			max_usecase_ndx)) {
		changed = true;
		changed = true;
		prev_usecase_ndx = phandle->current_usecase_ndx;
		prev_usecase_ndx = phandle->current_usecase_ndx;
		phandle->current_usecase_ndx = max_usecase_ndx;
		phandle->current_usecase_ndx = max_usecase_ndx;
@@ -916,8 +986,8 @@ int sde_power_resource_enable(struct sde_power_handle *phandle,
			goto vreg_err;
			goto vreg_err;
		}
		}


		rc = sde_power_reg_bus_update(phandle->reg_bus_hdl,
		rc = sde_power_scale_reg_bus(phandle, pclient,
							max_usecase_ndx);
				max_usecase_ndx, true);
		if (rc) {
		if (rc) {
			pr_err("failed to set reg bus vote rc=%d\n", rc);
			pr_err("failed to set reg bus vote rc=%d\n", rc);
			goto reg_bus_hdl_err;
			goto reg_bus_hdl_err;
@@ -948,8 +1018,8 @@ int sde_power_resource_enable(struct sde_power_handle *phandle,


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


		sde_power_reg_bus_update(phandle->reg_bus_hdl,
		sde_power_scale_reg_bus(phandle, pclient,
							max_usecase_ndx);
				max_usecase_ndx, true);


		msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg, enable);
		msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg, enable);


@@ -970,7 +1040,7 @@ int sde_power_resource_enable(struct sde_power_handle *phandle,
clk_err:
clk_err:
	sde_power_rsc_update(phandle, false);
	sde_power_rsc_update(phandle, false);
rsc_err:
rsc_err:
	sde_power_reg_bus_update(phandle->reg_bus_hdl, prev_usecase_ndx);
	sde_power_scale_reg_bus(phandle, pclient, max_usecase_ndx, true);
reg_bus_hdl_err:
reg_bus_hdl_err:
	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:
+17 −0
Original line number Original line Diff line number Diff line
@@ -43,11 +43,15 @@
 * mdss_bus_vote_type: register bus vote type
 * mdss_bus_vote_type: register bus vote type
 * VOTE_INDEX_DISABLE: removes the client vote
 * VOTE_INDEX_DISABLE: removes the client vote
 * VOTE_INDEX_LOW: keeps the lowest vote for register bus
 * VOTE_INDEX_LOW: keeps the lowest vote for register bus
 * VOTE_INDEX_MEDIUM: keeps medium vote for register bus
 * VOTE_INDEX_HIGH: keeps the highest vote for register bus
 * VOTE_INDEX_MAX: invalid
 * VOTE_INDEX_MAX: invalid
 */
 */
enum mdss_bus_vote_type {
enum mdss_bus_vote_type {
	VOTE_INDEX_DISABLE,
	VOTE_INDEX_DISABLE,
	VOTE_INDEX_LOW,
	VOTE_INDEX_LOW,
	VOTE_INDEX_MEDIUM,
	VOTE_INDEX_HIGH,
	VOTE_INDEX_MAX,
	VOTE_INDEX_MAX,
};
};


@@ -227,6 +231,19 @@ void sde_power_client_destroy(struct sde_power_handle *phandle,
int sde_power_resource_enable(struct sde_power_handle *pdata,
int sde_power_resource_enable(struct sde_power_handle *pdata,
	struct sde_power_client *pclient, bool enable);
	struct sde_power_client *pclient, bool enable);


/**
 * sde_power_scale_reg_bus() - Scale the registers bus for the specified client
 * @phandle:  power handle containing the resources
 * @pclient: client information to scale its vote
 * @usecase_ndx: new use case to scale the reg bus
 * @skip_lock: will skip holding the power rsrc mutex during the call, this is
 *		for internal callers that already hold this required lock.
 *
 * Return: error code.
 */
int sde_power_scale_reg_bus(struct sde_power_handle *phandle,
	struct sde_power_client *pclient, u32 usecase_ndx, bool skip_lock);

/**
/**
 * sde_power_resource_is_enabled() - return true if power resource is enabled
 * sde_power_resource_is_enabled() - return true if power resource is enabled
 * @pdata:  power handle containing the resources
 * @pdata:  power handle containing the resources