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

Commit d7eb67f7 authored by Tony Lindgren's avatar Tony Lindgren
Browse files

Merge branch 'pull/v3.18/powerdomain-fixes' of...

Merge branch 'pull/v3.18/powerdomain-fixes' of https://github.com/nmenon/linux-2.6-playground into omap-for-v3.18/fixes-not-urgent
parents 9a15fff0 3e6a1c94
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -298,6 +298,10 @@ int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
	if (omap_rev() == OMAP4430_REV_ES1_0)
		return -ENXIO;

	/* Use the achievable power state for the domain */
	power_state = pwrdm_get_valid_lp_state(pm_info->pwrdm,
					       false, power_state);

	if (power_state == PWRDM_POWER_OFF)
		cpu_state = 1;

+7 −2
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ u16 pm44xx_errata;
struct power_state {
	struct powerdomain *pwrdm;
	u32 next_state;
	u32 next_logic_state;
#ifdef CONFIG_SUSPEND
	u32 saved_state;
	u32 saved_logic_state;
@@ -54,7 +55,7 @@ static int omap4_pm_suspend(void)
	/* Set targeted power domain states by suspend */
	list_for_each_entry(pwrst, &pwrst_list, node) {
		omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
		pwrdm_set_logic_retst(pwrst->pwrdm, PWRDM_POWER_OFF);
		pwrdm_set_logic_retst(pwrst->pwrdm, pwrst->next_logic_state);
	}

	/*
@@ -120,7 +121,11 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
		return -ENOMEM;

	pwrst->pwrdm = pwrdm;
	pwrst->next_state = PWRDM_POWER_RET;
	pwrst->next_state = pwrdm_get_valid_lp_state(pwrdm, false,
						     PWRDM_POWER_RET);
	pwrst->next_logic_state = pwrdm_get_valid_lp_state(pwrdm, true,
							   PWRDM_POWER_OFF);

	list_add(&pwrst->node, &pwrst_list);

	return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
+78 −1
Original line number Diff line number Diff line
@@ -546,6 +546,7 @@ int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
		return -EINVAL;

	for (i = 0; i < PWRDM_MAX_CLKDMS && !ret; i++)
		if (pwrdm->pwrdm_clkdms[i])
			ret = (*fn)(pwrdm, pwrdm->pwrdm_clkdms[i]);

	return ret;
@@ -1079,6 +1080,82 @@ int pwrdm_post_transition(struct powerdomain *pwrdm)
	return 0;
}

/**
 * pwrdm_get_valid_lp_state() - Find best match deep power state
 * @pwrdm:	power domain for which we want to find best match
 * @is_logic_state: Are we looking for logic state match here? Should
 *		    be one of PWRDM_xxx macro values
 * @req_state:	requested power state
 *
 * Returns: closest match for requested power state. default fallback
 * is RET for logic state and ON for power state.
 *
 * This does a search from the power domain data looking for the
 * closest valid power domain state that the hardware can achieve.
 * PRCM definitions for PWRSTCTRL allows us to program whatever
 * configuration we'd like, and PRCM will actually attempt such
 * a transition, however if the powerdomain does not actually support it,
 * we endup with a hung system. The valid power domain states are already
 * available in our powerdomain data files. So this function tries to do
 * the following:
 * a) find if we have an exact match to the request - no issues.
 * b) else find if a deeper power state is possible.
 * c) failing which, it tries to find closest higher power state for the
 * request.
 */
u8 pwrdm_get_valid_lp_state(struct powerdomain *pwrdm,
			    bool is_logic_state, u8 req_state)
{
	u8 pwrdm_states = is_logic_state ? pwrdm->pwrsts_logic_ret :
			pwrdm->pwrsts;
	/* For logic, ret is highest and others, ON is highest */
	u8 default_pwrst = is_logic_state ? PWRDM_POWER_RET : PWRDM_POWER_ON;
	u8 new_pwrst;
	bool found;

	/* If it is already supported, nothing to search */
	if (pwrdm_states & BIT(req_state))
		return req_state;

	if (!req_state)
		goto up_search;

	/*
	 * So, we dont have a exact match
	 * Can we get a deeper power state match?
	 */
	new_pwrst = req_state - 1;
	found = true;
	while (!(pwrdm_states & BIT(new_pwrst))) {
		/* No match even at OFF? Not available */
		if (new_pwrst == PWRDM_POWER_OFF) {
			found = false;
			break;
		}
		new_pwrst--;
	}

	if (found)
		goto done;

up_search:
	/* OK, no deeper ones, can we get a higher match? */
	new_pwrst = req_state + 1;
	while (!(pwrdm_states & BIT(new_pwrst))) {
		if (new_pwrst > PWRDM_POWER_ON) {
			WARN(1, "powerdomain: %s: Fix max powerstate to ON\n",
			     pwrdm->name);
			return PWRDM_POWER_ON;
		}

		if (new_pwrst == default_pwrst)
			break;
		new_pwrst++;
	}
done:
	return new_pwrst;
}

/**
 * omap_set_pwrdm_state - change a powerdomain's current power state
 * @pwrdm: struct powerdomain * to change the power state of
+4 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@
#define PWRSTS_OFF_RET		(PWRSTS_OFF | PWRSTS_RET)
#define PWRSTS_RET_ON		(PWRSTS_RET | PWRSTS_ON)
#define PWRSTS_OFF_RET_ON	(PWRSTS_OFF_RET | PWRSTS_ON)
#define PWRSTS_INA_ON		(PWRSTS_INACTIVE | PWRSTS_ON)


/*
@@ -219,6 +220,9 @@ struct voltagedomain *pwrdm_get_voltdm(struct powerdomain *pwrdm);

int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm);

u8 pwrdm_get_valid_lp_state(struct powerdomain *pwrdm,
			    bool is_logic_state, u8 req_state);

int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst);
int pwrdm_read_next_pwrst(struct powerdomain *pwrdm);
int pwrdm_read_pwrst(struct powerdomain *pwrdm);
+6 −6
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@ static struct powerdomain core_54xx_pwrdm = {
	.prcm_offs	  = OMAP54XX_PRM_CORE_INST,
	.prcm_partition	  = OMAP54XX_PRM_PARTITION,
	.pwrsts		  = PWRSTS_RET_ON,
	.pwrsts_logic_ret = PWRSTS_OFF_RET,
	.pwrsts_logic_ret = PWRSTS_RET,
	.banks		  = 5,
	.pwrsts_mem_ret	= {
		[0] = PWRSTS_OFF_RET,	/* core_nret_bank */
@@ -107,8 +107,8 @@ static struct powerdomain cpu0_54xx_pwrdm = {
	.voltdm		  = { .name = "mpu" },
	.prcm_offs	  = OMAP54XX_PRCM_MPU_PRM_C0_INST,
	.prcm_partition	  = OMAP54XX_PRCM_MPU_PARTITION,
	.pwrsts		  = PWRSTS_OFF_RET_ON,
	.pwrsts_logic_ret = PWRSTS_OFF_RET,
	.pwrsts		  = PWRSTS_RET_ON,
	.pwrsts_logic_ret = PWRSTS_RET,
	.banks		  = 1,
	.pwrsts_mem_ret	= {
		[0] = PWRSTS_OFF_RET,	/* cpu0_l1 */
@@ -124,8 +124,8 @@ static struct powerdomain cpu1_54xx_pwrdm = {
	.voltdm		  = { .name = "mpu" },
	.prcm_offs	  = OMAP54XX_PRCM_MPU_PRM_C1_INST,
	.prcm_partition	  = OMAP54XX_PRCM_MPU_PARTITION,
	.pwrsts		  = PWRSTS_OFF_RET_ON,
	.pwrsts_logic_ret = PWRSTS_OFF_RET,
	.pwrsts		  = PWRSTS_RET_ON,
	.pwrsts_logic_ret = PWRSTS_RET,
	.banks		  = 1,
	.pwrsts_mem_ret	= {
		[0] = PWRSTS_OFF_RET,	/* cpu1_l1 */
@@ -158,7 +158,7 @@ static struct powerdomain mpu_54xx_pwrdm = {
	.prcm_offs	  = OMAP54XX_PRM_MPU_INST,
	.prcm_partition	  = OMAP54XX_PRM_PARTITION,
	.pwrsts		  = PWRSTS_RET_ON,
	.pwrsts_logic_ret = PWRSTS_OFF_RET,
	.pwrsts_logic_ret = PWRSTS_RET,
	.banks		  = 2,
	.pwrsts_mem_ret	= {
		[0] = PWRSTS_OFF_RET,	/* mpu_l2 */
Loading