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

Commit 86dbe451 authored by Osvaldo Banuelos's avatar Osvaldo Banuelos
Browse files

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



Add support to switch the APC0 and APC1 clock sources to GPLL0 via
the secure world before VDD_APCC to VDD_MX or VDD_MX to VDD_APCC APM
transitions begin and to switch back to the original clock source
after the APM sequence completes. This is necessary to guarantee
stable operation of certain CPUSS blocks.

Change-Id: I348a9dec7e35cfbc217e19f864794af999167108
Signed-off-by: default avatarOsvaldo Banuelos <osvaldob@codeaurora.org>
parent 50e0173f
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
@@ -77,6 +77,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;
@@ -87,6 +95,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;
};
@@ -139,6 +148,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)
@@ -215,6 +230,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;
@@ -224,6 +256,10 @@ static int msm_apm_switch_to_mx(struct msm_apm_ctrl_dev *ctrl_dev)

	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 */
@@ -291,6 +327,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");
@@ -310,6 +350,10 @@ static int msm_apm_switch_to_apcc(struct msm_apm_ctrl_dev *ctrl_dev)

	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 */
@@ -377,6 +421,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");