Loading drivers/firmware/qcom_scm-smc.c +47 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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, }; /* Loading @@ -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) Loading @@ -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 Loading drivers/firmware/qcom_scm.c +31 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading drivers/firmware/qcom_scm.h +4 −0 Original line number Diff line number Diff line Loading @@ -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); Loading include/linux/qcom_scm.h +9 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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) {} Loading Loading
drivers/firmware/qcom_scm-smc.c +47 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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, }; /* Loading @@ -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) Loading @@ -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 Loading
drivers/firmware/qcom_scm.c +31 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading
drivers/firmware/qcom_scm.h +4 −0 Original line number Diff line number Diff line Loading @@ -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); Loading
include/linux/qcom_scm.h +9 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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) {} Loading