From 3364df41fa5eb086b8219755409ef1f3fc2e002f Mon Sep 17 00:00:00 2001 From: Siddharth Gupta Date: Mon, 4 Nov 2019 17:58:35 -0800 Subject: [PATCH] firmware: qcom_scm: Add calls for csptest Add SCM calls to check for whether mode switch and secure watchdog trigger calls are available. Add SCM call for cpu errata. Change-Id: Ibe2ccf4d44ce89c342ed3c65bbe6f075f9be8c40 Signed-off-by: Siddharth Gupta Signed-off-by: Elliot Berman --- drivers/firmware/qcom_scm-smc.c | 13 +++++++++++++ drivers/firmware/qcom_scm.c | 19 +++++++++++++++++++ drivers/firmware/qcom_scm.h | 4 ++++ include/linux/qcom_scm.h | 9 +++++++++ 4 files changed, 45 insertions(+) diff --git a/drivers/firmware/qcom_scm-smc.c b/drivers/firmware/qcom_scm-smc.c index 01e12e7bdbe1..6064dbed3357 100644 --- a/drivers/firmware/qcom_scm-smc.c +++ b/drivers/firmware/qcom_scm-smc.c @@ -729,6 +729,19 @@ int __qcom_scm_set_dload_mode(struct device *dev, bool enable) return qcom_scm_call_atomic(dev, &desc); } +int __qcom_scm_config_cpu_errata(struct device *dev) +{ + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_BOOT, + .cmd = QCOM_SCM_BOOT_CONFIG_CPU_ERRATA, + .owner = ARM_SMCCC_OWNER_SIP, + }; + + desc.arginfo = 0xffffffff; + + return qcom_scm_call(dev, &desc); +} + bool __qcom_scm_pas_supported(struct device *dev, u32 peripheral) { int ret; diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index 4fce62a76d0f..38e26c37d915 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -153,6 +153,12 @@ static void qcom_scm_set_download_mode(bool enable) dev_err(__scm->dev, "failed to set download mode: %d\n", ret); } +int qcom_scm_config_cpu_errata(void) +{ + return __qcom_scm_config_cpu_errata(__scm->dev); +} +EXPORT_SYMBOL(qcom_scm_config_cpu_errata); + /** * qcom_scm_pas_supported() - Check if the peripheral authentication service is * available for the given peripherial @@ -344,6 +350,19 @@ int qcom_scm_io_reset(void) } EXPORT_SYMBOL(qcom_scm_io_reset); +bool qcom_scm_is_secure_wdog_trigger_available(void) +{ + return __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_BOOT, + QCOM_SCM_BOOT_SEC_WDOG_TRIGGER); +} + +bool qcom_scm_is_mode_switch_available(void) +{ + return __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_BOOT, + QCOM_SCM_BOOT_SWITCH_MODE); +} +EXPORT_SYMBOL(qcom_scm_is_mode_switch_available); + int qcom_scm_get_jtag_etm_feat_id(u64 *version) { return __qcom_scm_get_feat_version(__scm ? __scm->dev : NULL, diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h index ddf022702836..6096d5a70176 100644 --- a/drivers/firmware/qcom_scm.h +++ b/drivers/firmware/qcom_scm.h @@ -9,8 +9,11 @@ #define QCOM_SCM_BOOT_SET_ADDR 0x01 #define QCOM_SCM_BOOT_TERMINATE_PC 0x02 #define QCOM_SCM_BOOT_SEC_WDOG_DIS 0x07 +#define QCOM_SCM_BOOT_SEC_WDOG_TRIGGER 0x08 #define QCOM_SCM_BOOT_SET_REMOTE_STATE 0x0a +#define QCOM_SCM_BOOT_SWITCH_MODE 0x0f #define QCOM_SCM_BOOT_SET_DLOAD_MODE 0x10 +#define QCOM_SCM_BOOT_CONFIG_CPU_ERRATA 0x12 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, @@ -19,6 +22,7 @@ extern void __qcom_scm_cpu_power_down(struct device *dev, u32 flags); extern int __qcom_scm_sec_wdog_deactivate(struct device *dev); extern int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id); extern int __qcom_scm_set_dload_mode(struct device *dev, bool enable); +extern int __qcom_scm_config_cpu_errata(struct device *dev); #define QCOM_SCM_FLUSH_FLAG_MASK 0x3 #define QCOM_SCM_SVC_PIL 0x02 diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h index 5be160ea3a8e..889a7a15826e 100644 --- a/include/linux/qcom_scm.h +++ b/include/linux/qcom_scm.h @@ -77,6 +77,7 @@ extern int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus); extern void qcom_scm_cpu_power_down(u32 flags); extern int qcom_scm_sec_wdog_deactivate(void); extern int qcom_scm_set_remote_state(u32 state, u32 id); +extern int qcom_scm_config_cpu_errata(void); extern bool qcom_scm_pas_supported(u32 peripheral); extern int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size); @@ -89,6 +90,8 @@ extern int qcom_scm_tz_blsp_modify_owner(int food, u64 subsystem, int *out); extern int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val); extern int qcom_scm_io_writel(phys_addr_t addr, unsigned int val); extern int qcom_scm_io_reset(void); +extern bool qcom_scm_is_secure_wdog_trigger_available(void); +extern bool qcom_scm_is_mode_switch_available(void); extern int qcom_scm_get_jtag_etm_feat_id(u64 *version); extern void qcom_scm_mmu_sync(bool sync); extern int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare); @@ -186,6 +189,8 @@ static inline void qcom_scm_cpu_power_down(u32 flags) {} static inline int qcom_scm_sec_wdog_deactivate(void) { return -ENODEV; } static inline u32 qcom_scm_set_remote_state(u32 state, u32 id) { return -ENODEV; } +static inline int qcom_scm_config_cpu_errata(void) + { return -ENODEV; } static inline bool qcom_scm_pas_supported(u32 peripheral) { return false; } static inline int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size) { return -ENODEV; } @@ -204,6 +209,10 @@ static inline int qcom_scm_io_writel(phys_addr_t addr, unsigned int val) { return -ENODEV; } static inline int qcom_scm_io_reset(void) { return -ENODEV; } +static inline bool qcom_scm_is_secure_wdog_trigger_available(void) + { return -ENODEV; } +static inline bool qcom_scm_is_mode_switch_available(void) + { return -ENODEV; } static inline int qcom_scm_get_jtag_etm_feat_id(u64 *version) { return -ENODEV; } static inline void qcom_scm_mmu_sync(bool sync) {}