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

Commit 5a9f5463 authored by Raghavendra Kakarla's avatar Raghavendra Kakarla Committed by Tushar Nimkar
Browse files

drivers: scm: Add SCM call support to set warmboot addr



Add the SCM call support for core hotplug and set warmboot address
for multi core.

Change-Id: I747858d1ffc1008b6d9033526110c98a3bb2401b
Signed-off-by: default avatarRaghavendra Kakarla <rkakarla@codeaurora.org>
Signed-off-by: default avatarTushar Nimkar <tnimkar@codeaurora.org>
parent 2c8ec678
Loading
Loading
Loading
Loading
+47 −0
Original line number Diff line number Diff line
@@ -876,6 +876,38 @@ int __qcom_scm_set_cold_boot_addr(struct device *dev, void *entry,
	return qcom_scm_call_atomic(dev, &desc);
}

/**
 * scm_set_boot_addr_mc - Set entry physical address for cpus
 * @addr: 32bit physical address
 * @aff0: Collective bitmask of the affinity-level-0 of the mpidr
 *	  1<<aff0_CPU0| 1<<aff0_CPU1....... | 1<<aff0_CPU32
 *	  Supports maximum 32 cpus under any affinity level.
 * @aff1:  Collective bitmask of the affinity-level-1 of the mpidr
 * @aff2:  Collective bitmask of the affinity-level-2 of the mpidr
 * @flags: Flag to differentiate between coldboot vs warmboot
 */
int __qcom_scm_set_warm_boot_addr_mc(struct device *dev, void *entry, u32 aff0,
				     u32 aff1, u32 aff2, u32 flags)
{
	int ret;
	struct qcom_scm_desc desc = {
		.svc = QCOM_SCM_SVC_BOOT,
		.cmd = QCOM_SCM_BOOT_SET_ADDR_MC,
		.owner = ARM_SMCCC_OWNER_SIP,
	};

	desc.args[0] = virt_to_phys(entry);
	desc.args[1] = aff0;
	desc.args[2] = aff1;
	desc.args[3] = aff2;
	desc.args[4] = ~0ULL;
	desc.args[5] = flags;
	desc.arginfo = QCOM_SCM_ARGS(6);
	ret = qcom_scm_call(dev, &desc);

	return ret;
}

/**
 * qcom_scm_set_warm_boot_addr() - Set the warm boot address for cpus
 * @dev: Device pointer
@@ -894,6 +926,7 @@ int __qcom_scm_set_warm_boot_addr(struct device *dev, void *entry,
	struct qcom_scm_desc desc = {
		.svc = QCOM_SCM_SVC_BOOT,
		.cmd = QCOM_SCM_BOOT_SET_ADDR,
		.owner = ARM_SMCCC_OWNER_SIP,
	};

	/*
@@ -912,6 +945,7 @@ int __qcom_scm_set_warm_boot_addr(struct device *dev, void *entry,

	desc.args[0] = virt_to_phys(entry);
	desc.args[1] = flags;
	desc.arginfo = QCOM_SCM_ARGS(2);
	ret = qcom_scm_call(dev, &desc);
	if (!ret) {
		for_each_cpu(cpu, cpus)
@@ -921,6 +955,19 @@ int __qcom_scm_set_warm_boot_addr(struct device *dev, void *entry,
	return ret;
}

void __qcom_scm_cpu_hp(struct device *dev, u32 flags)
{
	struct qcom_scm_desc desc = {
		.svc = QCOM_SCM_SVC_BOOT,
		.cmd = QCOM_SCM_BOOT_TERMINATE_PC,
		.args[0] = flags,
		.arginfo = QCOM_SCM_ARGS(1),
		.owner = ARM_SMCCC_OWNER_SIP,
	};

	qcom_scm_call_atomic(dev, &desc);
}

/**
 * qcom_scm_cpu_power_down() - Power down the cpu
 * @flags - Flags to flush cache
+31 −0
Original line number Diff line number Diff line
@@ -86,6 +86,23 @@ int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus)
}
EXPORT_SYMBOL(qcom_scm_set_cold_boot_addr);

/**
 * scm_set_boot_addr_mc - Set entry physical address for cpus
 * @dev: Device pointer
 * @addr: 32bit physical address
 * @aff0: Collective bitmask of the affinity-level-0 of the mpidr
 *	  1<<aff0_CPU0| 1<<aff0_CPU1....... | 1<<aff0_CPU32
 *	  Supports maximum 32 cpus under any affinity level.
 * @aff1:  Collective bitmask of the affinity-level-1 of the mpidr
 * @aff2:  Collective bitmask of the affinity-level-2 of the mpidr
 * @flags: Flag to differentiate between coldboot vs warmboot
 */
int qcom_scm_set_warm_boot_addr_mc(void *entry, u32 aff0, u32 aff1, u32 aff2, u32 flags)
{
	return __qcom_scm_set_warm_boot_addr_mc(__scm->dev, entry, aff0, aff1, aff2, flags);
}
EXPORT_SYMBOL(qcom_scm_set_warm_boot_addr_mc);

/**
 * qcom_scm_set_warm_boot_addr() - Set the warm boot address for cpus
 * @entry: Entry point function for the cpus
@@ -100,6 +117,20 @@ int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus)
}
EXPORT_SYMBOL(qcom_scm_set_warm_boot_addr);

/**
 * qcom_scm_cpu_hp() - Power down the cpu
 * @flags - Flags to flush cache
 *
 * This is an end point to power down cpu. If there was a pending interrupt,
 * the control would return from this function, otherwise, the cpu jumps to the
 * warm boot entry point set for this cpu upon reset.
 */
void qcom_scm_cpu_hp(u32 flags)
{
	__qcom_scm_cpu_hp(__scm ? __scm->dev : NULL, flags);
}
EXPORT_SYMBOL(qcom_scm_cpu_hp);

/**
 * qcom_scm_cpu_power_down() - Power down the cpu
 * @flags - Flags to flush cache
+4 −0
Original line number Diff line number Diff line
@@ -15,13 +15,17 @@
#define QCOM_SCM_BOOT_SPIN_CPU			0x0d
#define QCOM_SCM_BOOT_SWITCH_MODE		0x0f
#define QCOM_SCM_BOOT_SET_DLOAD_MODE		0x10
#define QCOM_SCM_BOOT_SET_ADDR_MC		0x11
#define QCOM_SCM_BOOT_CONFIG_CPU_ERRATA		0x12
#define QCOM_SCM_QUSB2PHY_LVL_SHIFTER_CMD_ID	0x1B
extern int __qcom_scm_set_cold_boot_addr(struct device *dev, void *entry,
		const cpumask_t *cpus);
extern int __qcom_scm_set_warm_boot_addr(struct device *dev, void *entry,
		const cpumask_t *cpus);
extern int __qcom_scm_set_warm_boot_addr_mc(struct device *dev, void *entry,
		u32 aff0, u32 aff1, u32 aff2, u32 flags);
extern void __qcom_scm_cpu_power_down(struct device *dev, u32 flags);
extern void __qcom_scm_cpu_hp(struct device *dev, u32 flags);
extern int __qcom_scm_sec_wdog_deactivate(struct device *dev);
extern int __qcom_scm_sec_wdog_trigger(struct device *dev);
extern void __qcom_scm_disable_sdi(struct device *dev);
+9 −0
Original line number Diff line number Diff line
@@ -81,7 +81,9 @@ static inline void qcom_scm_populate_mem_map_info(
#if IS_ENABLED(CONFIG_QCOM_SCM)
extern int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus);
extern int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus);
extern int qcom_scm_set_warm_boot_addr_mc(void *entry, u32 aff0, u32 aff1, u32 aff2, u32 flags);
extern void qcom_scm_cpu_power_down(u32 flags);
extern void qcom_scm_cpu_hp(u32 flags);
extern int qcom_scm_sec_wdog_deactivate(void);
extern int qcom_scm_sec_wdog_trigger(void);
extern void qcom_scm_disable_sdi(void);
@@ -213,7 +215,14 @@ int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus)
static inline
int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus)
		{ return -ENODEV; }
static inline
int qcom_scm_set_warm_boot_addr_mc(void *entry, u32 aff0, u32 aff1, u32 aff2,
				   u32 flags)
{
	return -ENODEV;
}
static inline void qcom_scm_cpu_power_down(u32 flags) {}
static inline void qcom_scm_cpu_hp(u32 flags) {}
static inline int qcom_scm_sec_wdog_deactivate(void) { return -ENODEV; }
static inline int qcom_scm_sec_wdog_trigger(void) { return -ENODEV; }
static inline void qcom_scm_disable_sdi(void) {}