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

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

Merge "msm: spm: Support RPM handshake control bit in SPM"

parents 913a8f3f fe6c032d
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -57,6 +57,9 @@ Optional properties
- qcom,use-qchannel-for-pc: Boolean property to specify if qchannel should be
	ignored when entering power collapse. If this property is set qchannel
	will not be ignored in power collapse.
- qcom,supports-rpm-hs: Indicates that this SPM instance allow handshake with
RPM processor when executing the sleep command in the SPM sequence. Supported
only on SAW2 v3.0 and above.

Example 1:
	qcom,spm@f9089000 {
+1 −1
Original line number Diff line number Diff line
@@ -213,7 +213,7 @@ int set_l2_mode(struct low_power_ops *ops, int mode, bool notify_rpm)
		lpm = MSM_SPM_MODE_DISABLED;
		break;
	}
	rc = msm_spm_config_low_power_mode(ops->spm, lpm, true);
	rc = msm_spm_config_low_power_mode(ops->spm, lpm, notify_rpm);

	if (rc)
		pr_err("%s: Failed to set L2 low power mode %d, ERR %d",
+27 −7
Original line number Diff line number Diff line
@@ -134,22 +134,41 @@ static inline uint32_t msm_spm_drv_get_num_spm_entry(
	return (dev->reg_shadow[MSM_SPM_REG_SAW2_ID] >> 24) & 0xFF;
}

static inline void msm_spm_drv_set_start_addr(
static inline void msm_spm_drv_set_notify_rpm(
		struct msm_spm_driver_data *dev, bool notify_rpm)
{
	if (dev->major != 0x3)
		return;

	dev->reg_shadow[MSM_SPM_REG_SAW2_SPM_CTL] &= ~BIT(17);
	dev->reg_shadow[MSM_SPM_REG_SAW2_SPM_CTL] |= notify_rpm << 17;
}

static inline void msm_spm_drv_set_start_addr2(
		struct msm_spm_driver_data *dev, uint32_t addr, bool pc_mode)
{
	addr &= 0x7F;
	addr &= 0x1FF;
	addr <<= 4;
	dev->reg_shadow[MSM_SPM_REG_SAW2_SPM_CTL] &= 0xFFFFF80F;
	dev->reg_shadow[MSM_SPM_REG_SAW2_SPM_CTL] &= ~0x1FF0;
	dev->reg_shadow[MSM_SPM_REG_SAW2_SPM_CTL] |= addr;

	if (dev->major != 0x3)
		return;

	dev->reg_shadow[MSM_SPM_REG_SAW2_SPM_CTL] &= 0xFFFEFFFF;
	if (pc_mode)
		dev->reg_shadow[MSM_SPM_REG_SAW2_SPM_CTL] |= 0x00010000;
}

static inline void msm_spm_drv_set_start_addr(
		struct msm_spm_driver_data *dev, uint32_t addr, bool pc_mode)
{
	if (dev->major == 0x3)
		return msm_spm_drv_set_start_addr2(dev, addr, pc_mode);

	addr &= 0x7F;
	addr <<= 4;
	dev->reg_shadow[MSM_SPM_REG_SAW2_SPM_CTL] &= 0xFFFFF80F;
	dev->reg_shadow[MSM_SPM_REG_SAW2_SPM_CTL] |= addr;
}

static inline bool msm_spm_pmic_arb_present(struct msm_spm_driver_data *dev)
{
	msm_spm_drv_load_shadow(dev, MSM_SPM_REG_SAW2_ID);
@@ -299,7 +318,7 @@ int msm_spm_drv_write_seq_data(struct msm_spm_driver_data *dev,
}

int msm_spm_drv_set_low_power_mode(struct msm_spm_driver_data *dev,
		uint32_t addr, bool pc_mode)
		uint32_t addr, bool pc_mode, bool notify_rpm)
{

	/* SPM is configured to reset start address to zero after end of Program
@@ -308,6 +327,7 @@ int msm_spm_drv_set_low_power_mode(struct msm_spm_driver_data *dev,
		return -EINVAL;

	msm_spm_drv_set_start_addr(dev, addr, pc_mode);
	msm_spm_drv_set_notify_rpm(dev, notify_rpm);

	msm_spm_drv_flush_shadow(dev, MSM_SPM_REG_SAW2_SPM_CTL);
	wmb();
+21 −18
Original line number Diff line number Diff line
@@ -29,7 +29,6 @@

struct msm_spm_power_modes {
	uint32_t mode;
	bool notify_rpm;
	uint32_t start_addr;
};

@@ -44,6 +43,7 @@ struct msm_spm_device {
	struct cpumask mask;
	void __iomem *q2s_reg;
	bool qchannel_ignore;
	bool allow_rpm_hs;
};

struct msm_spm_vdd_info {
@@ -201,14 +201,17 @@ static int msm_spm_dev_set_low_power_mode(struct msm_spm_device *dev,
		ret = msm_spm_drv_set_spm_enable(&dev->reg_data, false);
	} else if (!msm_spm_drv_set_spm_enable(&dev->reg_data, true)) {
		for (i = 0; i < dev->num_modes; i++) {
			if ((dev->modes[i].mode == mode) &&
				(dev->modes[i].notify_rpm == notify_rpm)) {
			if (dev->modes[i].mode != mode)
				continue;

			if (!dev->allow_rpm_hs && notify_rpm)
				notify_rpm = false;

			start_addr = dev->modes[i].start_addr;
			break;
		}
		}
		ret = msm_spm_drv_set_low_power_mode(&dev->reg_data,
					start_addr, pc_mode);
					start_addr, pc_mode, notify_rpm);
	}

	msm_spm_config_q2s(dev, mode);
@@ -249,10 +252,10 @@ static int msm_spm_dev_init(struct msm_spm_device *dev,
			goto spm_failed_init;

		dev->modes[i].mode = data->modes[i].mode;
		dev->modes[i].notify_rpm = data->modes[i].notify_rpm;
	}
	msm_spm_drv_flush_seq_entry(&dev->reg_data);
	dev->initialized = true;

	return 0;

spm_failed_init:
@@ -552,15 +555,14 @@ static int msm_spm_dev_probe(struct platform_device *pdev)
	struct mode_of {
		char *key;
		uint32_t id;
		uint32_t notify_rpm;
	};

	struct mode_of mode_of_data[] = {
		{"qcom,saw2-spm-cmd-wfi", MSM_SPM_MODE_CLOCK_GATING, 0},
		{"qcom,saw2-spm-cmd-ret", MSM_SPM_MODE_RETENTION, 0},
		{"qcom,saw2-spm-cmd-gdhs", MSM_SPM_MODE_GDHS, 1},
		{"qcom,saw2-spm-cmd-spc", MSM_SPM_MODE_POWER_COLLAPSE, 0},
		{"qcom,saw2-spm-cmd-pc", MSM_SPM_MODE_POWER_COLLAPSE, 1},
		{"qcom,saw2-spm-cmd-wfi", MSM_SPM_MODE_CLOCK_GATING},
		{"qcom,saw2-spm-cmd-ret", MSM_SPM_MODE_RETENTION},
		{"qcom,saw2-spm-cmd-gdhs", MSM_SPM_MODE_GDHS},
		{"qcom,saw2-spm-cmd-spc", MSM_SPM_MODE_POWER_COLLAPSE},
		{"qcom,saw2-spm-cmd-pc", MSM_SPM_MODE_POWER_COLLAPSE},
	};

	dev = msm_spm_get_device(pdev);
@@ -650,16 +652,17 @@ static int msm_spm_dev_probe(struct platform_device *pdev)
		if (!modes[mode_count].cmd)
			continue;
		modes[mode_count].mode = mode_of_data[i].id;
		modes[mode_count].notify_rpm = mode_of_data[i].notify_rpm;
		pr_debug("%s(): dev: %s cmd:%s, mode:%d rpm:%d\n", __func__,
				dev->name, key, modes[mode_count].mode,
				modes[mode_count].notify_rpm);
		pr_debug("%s(): dev: %s cmd:%s, mode:%d\n", __func__,
				dev->name, key, modes[mode_count].mode);
		mode_count++;
	}

	spm_data.modes = modes;
	spm_data.num_modes = mode_count;

	key = "qcom,supports-rpm-hs";
	dev->allow_rpm_hs = of_property_read_bool(pdev->dev.of_node, key);

	ret = msm_spm_dev_init(dev, &spm_data);
	if (ret)
		goto fail;
+1 −1
Original line number Diff line number Diff line
@@ -98,7 +98,7 @@ int msm_spm_drv_init(struct msm_spm_driver_data *dev,
		struct msm_spm_platform_data *data);
void msm_spm_drv_reinit(struct msm_spm_driver_data *dev);
int msm_spm_drv_set_low_power_mode(struct msm_spm_driver_data *dev,
		uint32_t addr, bool pc_mode);
		uint32_t addr, bool pc_mode, bool notify_rpm);
int msm_spm_drv_set_vdd(struct msm_spm_driver_data *dev,
		unsigned int vlevel);
void dump_regs(struct msm_spm_driver_data *dev, int cpu);