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

Commit d7d0dbf9 authored by Archana Sathyakumar's avatar Archana Sathyakumar
Browse files

lpm-levels: Support cluster pm notifications in PSCI mode



Number of devices for each cluster is not available in PSCI mode.
Add this information in the DT and have this information available
in order to support cluster pm notification in PSCI mode as well.

Change-Id: I3328a9fa68df07b6b605bec7a13810007cb3a525
Signed-off-by: default avatarArchana Sathyakumar <asathyak@codeaurora.org>
parent 9fd50032
Loading
Loading
Loading
Loading
+12 −2
Original line number Diff line number Diff line
@@ -363,10 +363,16 @@ static int parse_cluster_params(struct device_node *node,
		key = "qcom,psci-mode-mask";
		ret = of_property_read_u32(node, key,
				&c->psci_mode_mask);
		if (ret)
		if (ret) {
			pr_err("%s(): Failed to read param: %s\n",
							__func__, key);
			return ret;
		}

		/* Set ndevice to 1 as default */
		c->ndevices = 1;

		return 0;
	} else
		return parse_legacy_cluster_params(node, c);
}
@@ -459,8 +465,12 @@ static int parse_cluster_level(struct device_node *node,
				goto failed;

			level->mode[i] = parse_lpm_mode(spm_mode);

			if (level->mode[i] < 0)
				goto failed;

			if (level->mode[i] == MSM_SPM_MODE_POWER_COLLAPSE)
				level->is_reset |= true;
		}
	}

+28 −26
Original line number Diff line number Diff line
@@ -275,12 +275,18 @@ int set_system_mode(struct low_power_ops *ops, int mode, bool notify_rpm)
	return msm_spm_config_low_power_mode(ops->spm, mode, notify_rpm);
}

static int set_device_mode(struct low_power_ops *ops, int mode, bool notify_rpm)
static int set_device_mode(struct lpm_cluster *cluster, int ndevice,
		struct lpm_cluster_level *level)
{
	struct low_power_ops *ops;

	if (use_psci)
		return 0;
	else if (ops && ops->set_mode)
		return ops->set_mode(ops, mode, notify_rpm);

	ops = &cluster->lpm_dev[ndevice];
	if (ops && ops->set_mode)
		return ops->set_mode(ops, level->mode[ndevice],
				level->notify_rpm);
	else
		return -EINVAL;
}
@@ -500,6 +506,15 @@ static int cluster_select(struct lpm_cluster *cluster, bool from_idle)
	return best_level;
}

static void cluster_notify(struct lpm_cluster *cluster,
		struct lpm_cluster_level *level, bool enter)
{
	if (level->is_reset && enter)
		cpu_cluster_pm_enter(cluster->aff_level);
	else if (level->is_reset && !enter)
		cpu_cluster_pm_exit(cluster->aff_level);
}

static int cluster_configure(struct lpm_cluster *cluster, int idx,
		bool from_idle)
{
@@ -525,21 +540,11 @@ static int cluster_configure(struct lpm_cluster *cluster, int idx,
	}

	for (i = 0; i < cluster->ndevices; i++) {
		ret = set_device_mode(&cluster->lpm_dev[i],
				level->mode[i],
				level->notify_rpm);

		ret = set_device_mode(cluster, i, level);
		if (ret)
			goto failed_set_mode;

		/*
		 * Notify that the cluster is entering a low power mode
		 */
		if ((level->mode[i] == MSM_SPM_MODE_POWER_COLLAPSE) ||
				level->is_reset) {
			cpu_cluster_pm_enter(cluster->aff_level);
		}
	}

	if (level->notify_rpm) {
		struct cpumask nextcpu, *cpumask;
		uint32_t us;
@@ -556,17 +561,20 @@ static int cluster_configure(struct lpm_cluster *cluster, int idx,
		do_div(us, USEC_PER_SEC/SCLK_HZ);
		msm_mpm_enter_sleep((uint32_t)us, from_idle, cpumask);
	}

	/* Notify cluster enter event after successfully config completion */
	cluster_notify(cluster, level, true);

	cluster->last_level = idx;
	spin_unlock(&cluster->sync_lock);
	return 0;

failed_set_mode:

	for (i = 0; i < cluster->ndevices; i++) {
		int rc = 0;
		level = &cluster->levels[cluster->default_level];
		rc = set_device_mode(&cluster->lpm_dev[i],
				level->mode[i],
				level->notify_rpm);
		rc = set_device_mode(cluster, i, level);
		BUG_ON(rc);
	}
	spin_unlock(&cluster->sync_lock);
@@ -680,18 +688,12 @@ static void cluster_unprepare(struct lpm_cluster *cluster,

	for (i = 0; i < cluster->ndevices; i++) {
		level = &cluster->levels[cluster->default_level];
		ret = set_device_mode(&cluster->lpm_dev[i],
				level->mode[i],
				level->notify_rpm);
		ret = set_device_mode(cluster, i, level);

		BUG_ON(ret);

		if ((cluster->levels[last_level].mode[i] ==
				MSM_SPM_MODE_POWER_COLLAPSE) ||
				cluster->levels[last_level].is_reset) {
			cpu_cluster_pm_exit(cluster->aff_level);
		}
	}
	cluster_notify(cluster, &cluster->levels[last_level], false);
unlock_return:
	spin_unlock(&cluster->sync_lock);
	cluster_unprepare(cluster->parent, &cluster->child_cpus,