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

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

Merge "power: qcom: apm: support switching APC clock sources via the secure world"

parents 41126adf 86dbe451
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -16,6 +16,12 @@ Required properties
		"apc0-cpu0-spm", "apc0-cpu1-spm", "apc1-cpu0-spm", "apc1-cpu1-spm",
		"apc0-l2-spm", and "apc1-l2-spm".

Optional properties
- qcom,clock-source-override:	Specify this property to request a switch of the APC0 and APC1
				clock sources to GPLL0 before the APM switch begins and to
				switch back to the original clock source after the APM switch
				completes.

MSM APM Users

Required properties:
+48 −0
Original line number Diff line number Diff line
@@ -78,6 +78,14 @@

#define MSM_APM_DRIVER_NAME        "qcom,msm-apm"

asmlinkage int __invoke_psci_fn_smc(u64, u64, u64, u64);

enum {
	CLOCK_ASSERT_ENABLE,
	CLOCK_ASSERT_DISABLE,
	CLOCK_ASSERT_TOGGLE,
};

struct msm_apm_ctrl_dev {
	struct list_head	list;
	struct device		*dev;
@@ -88,6 +96,7 @@ struct msm_apm_ctrl_dev {
	void __iomem		**apcs_spm_events_addr;
	void __iomem		*apc0_pll_ctl_addr;
	void __iomem		*apc1_pll_ctl_addr;
	bool			clk_src_override;
	u32			version;
	struct dentry		*debugfs;
};
@@ -140,6 +149,12 @@ static int msm_apm_ctrl_devm_ioremap(struct platform_device *pdev,
		return -ENOMEM;
	}

	ctrl->clk_src_override = of_property_read_bool(dev->of_node,
					       "qcom,clock-source-override");

	if (ctrl->clk_src_override)
		dev_info(dev, "overriding clock sources across APM switch\n");

	ctrl->version = readl_relaxed(ctrl->apcs_csr_base + APCS_VERSION);

	if (ctrl->version >= HMSS_VERSION_1P2)
@@ -216,6 +231,23 @@ free_events:
	return ret;
}

static int msm_apm_secure_clock_source_override(
			struct msm_apm_ctrl_dev *ctrl_dev, bool enable)
{
	int ret;

	if (ctrl_dev->clk_src_override) {
		ret = __invoke_psci_fn_smc(0xC4000020, 3, enable ?
					   CLOCK_ASSERT_ENABLE :
					   CLOCK_ASSERT_DISABLE, 0);
		if (ret)
			dev_err(ctrl_dev->dev, "PSCI request to switch to %s clock source failed\n",
				enable ? "GPLL0" : "original");
	}

	return 0;
}

static int msm_apm_switch_to_mx(struct msm_apm_ctrl_dev *ctrl_dev)
{
	int i, timeout = MSM_APM_SWITCH_TIMEOUT_US;
@@ -226,6 +258,10 @@ static int msm_apm_switch_to_mx(struct msm_apm_ctrl_dev *ctrl_dev)
	mutex_lock(&scm_lmh_lock);
	spin_lock_irqsave(&ctrl_dev->lock, flags);

	ret = msm_apm_secure_clock_source_override(ctrl_dev, true);
	if (ret)
		return ret;

	/* Perform revision-specific programming steps */
	if (ctrl_dev->version < HMSS_VERSION_1P2) {
		/* Clear SPM events */
@@ -293,6 +329,10 @@ static int msm_apm_switch_to_mx(struct msm_apm_ctrl_dev *ctrl_dev)
				       ctrl_dev->apcs_spm_events_addr[i]);
	}

	ret = msm_apm_secure_clock_source_override(ctrl_dev, false);
	if (ret)
		return ret;

	if (!ret) {
		ctrl_dev->supply = MSM_APM_SUPPLY_MX;
		dev_dbg(ctrl_dev->dev, "APM supply switched to MX\n");
@@ -314,6 +354,10 @@ static int msm_apm_switch_to_apcc(struct msm_apm_ctrl_dev *ctrl_dev)
	mutex_lock(&scm_lmh_lock);
	spin_lock_irqsave(&ctrl_dev->lock, flags);

	ret = msm_apm_secure_clock_source_override(ctrl_dev, true);
	if (ret)
		return ret;

	/* Perform revision-specific programming steps */
	if (ctrl_dev->version < HMSS_VERSION_1P2) {
		/* Clear SPM events */
@@ -381,6 +425,10 @@ static int msm_apm_switch_to_apcc(struct msm_apm_ctrl_dev *ctrl_dev)
			       ctrl_dev->apc1_pll_ctl_addr);
	}

	ret = msm_apm_secure_clock_source_override(ctrl_dev, false);
	if (ret)
		return ret;

	if (!ret) {
		ctrl_dev->supply = MSM_APM_SUPPLY_APCC;
		dev_dbg(ctrl_dev->dev, "APM supply switched to APCC\n");