From 6553d598cdb507f7ede020f25da646ba084a23c6 Mon Sep 17 00:00:00 2001 From: Ziyang Huang Date: Sun, 8 Sep 2024 16:40:12 +0800 Subject: [PATCH] firmware: qcom_scm: support MPD Add SCM calls to power up / down the SoC's internal WiFi radio and to load PIL segments to support the MPD architecture. Signed-off-by: Ziyang Huang Signed-off-by: George Moussalem --- drivers/firmware/qcom_scm.c | 79 ++++++++++++++++++++++++++ drivers/firmware/qcom_scm.h | 3 + include/linux/firmware/qcom/qcom_scm.h | 3 + 3 files changed, 85 insertions(+) --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -713,6 +713,85 @@ bool qcom_scm_pas_supported(u32 peripher EXPORT_SYMBOL_GPL(qcom_scm_pas_supported); /** + * qcom_scm_internal_wifi_powerup() - Bring up internal wifi + * @peripheral: peripheral id + * + * Return 0 on success. + */ +int qcom_scm_internal_wifi_powerup(u32 peripheral) +{ + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_PIL, + .cmd = QCOM_SCM_INTERNAL_WIFI_POWERUP, + .arginfo = QCOM_SCM_ARGS(1), + .args[0] = peripheral, + .owner = ARM_SMCCC_OWNER_SIP, + }; + struct qcom_scm_res res; + int ret; + + ret = qcom_scm_call(__scm->dev, &desc, &res); + + return ret ? : res.result[0]; +} +EXPORT_SYMBOL(qcom_scm_internal_wifi_powerup); + +/** + * qcom_scm_internal_wifi_shutdown() - Shut down internal wifi + * @peripheral: peripheral id + * + * Returns 0 on success. + */ +int qcom_scm_internal_wifi_shutdown(u32 peripheral) +{ + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_PIL, + .cmd = QCOM_SCM_INTERNAL_WIFI_SHUTDOWN, + .arginfo = QCOM_SCM_ARGS(1), + .args[0] = peripheral, + .owner = ARM_SMCCC_OWNER_SIP, + }; + struct qcom_scm_res res; + int ret; + + ret = qcom_scm_call(__scm->dev, &desc, &res); + + return ret ? : res.result[0]; +} +EXPORT_SYMBOL(qcom_scm_internal_wifi_shutdown); + +/** + * qcom_scm_pas_load_segment() - copy userpd PIL segments data to dma blocks + * @peripheral: peripheral id + * @segment: segment id + * @dma: handle of dma region + * @seg_cnt: no of dma blocks + * + * Returns 0 if trustzone successfully loads userpd PIL segments from dma + * blocks to DDR + */ +int qcom_scm_pas_load_segment(u32 peripheral, int segment, dma_addr_t dma, int seg_cnt) +{ + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_PIL, + .cmd = QCOM_SCM_PIL_PAS_LOAD_SEG, + .arginfo = QCOM_SCM_ARGS(4, QCOM_SCM_VAL, QCOM_SCM_VAL, QCOM_SCM_RW, QCOM_SCM_VAL), + .args[0] = peripheral, + .args[1] = segment, + .args[2] = dma, + .args[3] = seg_cnt, + .owner = ARM_SMCCC_OWNER_SIP, + }; + struct qcom_scm_res res; + int ret; + + ret = qcom_scm_call(__scm->dev, &desc, &res); + + return ret ? : res.result[0]; +} +EXPORT_SYMBOL(qcom_scm_pas_load_segment); + +/** * qcom_scm_msa_lock() - Lock given peripheral firmware region as MSA * * @peripheral: peripheral id --- a/drivers/firmware/qcom_scm.h +++ b/drivers/firmware/qcom_scm.h @@ -98,6 +98,9 @@ extern int scm_legacy_call(struct device #define QCOM_SCM_PIL_PAS_SHUTDOWN 0x06 #define QCOM_SCM_PIL_PAS_IS_SUPPORTED 0x07 #define QCOM_SCM_PIL_PAS_MSS_RESET 0x0a +#define QCOM_SCM_INTERNAL_WIFI_POWERUP 0x17 +#define QCOM_SCM_INTERNAL_WIFI_SHUTDOWN 0x18 +#define QCOM_SCM_PIL_PAS_LOAD_SEG 0x19 #define QCOM_SCM_MSA_LOCK 0x24 #define QCOM_SCM_MSA_UNLOCK 0x25 --- a/include/linux/firmware/qcom/qcom_scm.h +++ b/include/linux/firmware/qcom/qcom_scm.h @@ -81,6 +81,9 @@ extern int qcom_scm_pas_mem_setup(u32 pe extern int qcom_scm_pas_auth_and_reset(u32 peripheral); extern int qcom_scm_pas_shutdown(u32 peripheral); extern bool qcom_scm_pas_supported(u32 peripheral); +extern int qcom_scm_internal_wifi_powerup(u32 peripheral); +extern int qcom_scm_internal_wifi_shutdown(u32 peripheral); +extern int qcom_scm_pas_load_segment(u32 peripheral, int segment, dma_addr_t dma, int seg_cnt); extern int qcom_scm_msa_lock(u32 peripheral); extern int qcom_scm_msa_unlock(u32 peripheral);