From 5317ce310c18ebee8889ed61adc90e6b5bee3ec1 Mon Sep 17 00:00:00 2001 From: Elliot Berman Date: Tue, 24 Sep 2019 17:58:00 -0700 Subject: [PATCH] msm: kgsl: Migrate SCM calls in GPU bus governor Migrate MSM Adreno Governor TZ interface to upstream SCM driver. Change-Id: I1c4347d33b6be835f04422918c29e9c627e02874 Signed-off-by: Elliot Berman Signed-off-by: Siddharth Gupta --- drivers/firmware/qcom_scm-smc.c | 138 ++++++++++++++++++++++++++++++++ drivers/firmware/qcom_scm.c | 70 ++++++++++++++++ drivers/firmware/qcom_scm.h | 27 +++++++ include/linux/qcom_scm.h | 24 ++++++ 4 files changed, 259 insertions(+) diff --git a/drivers/firmware/qcom_scm-smc.c b/drivers/firmware/qcom_scm-smc.c index a149857b5a5f..a3eece5c663e 100644 --- a/drivers/firmware/qcom_scm-smc.c +++ b/drivers/firmware/qcom_scm-smc.c @@ -858,6 +858,19 @@ int __qcom_scm_io_writel(struct device *dev, phys_addr_t addr, unsigned int val) return qcom_scm_call_atomic(dev, &desc); } +int __qcom_scm_io_reset(struct device *dev) +{ + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_IO, + .cmd = QCOM_SCM_IO_RESET, + .owner = ARM_SMCCC_OWNER_SIP + }; + + desc.arginfo = QCOM_SCM_ARGS(2); + + return qcom_scm_call_atomic(dev, &desc); +} + int __qcom_scm_is_call_available(struct device *dev, u32 svc_id, u32 cmd_id) { int ret; @@ -1222,6 +1235,131 @@ int __qcom_scm_smmu_prepare_atos_id(struct device *dev, u64 dev_id, int cb_num, return ret; } +bool __qcom_scm_dcvs_core_available(struct device *dev) +{ + return __qcom_scm_is_call_available(dev, QCOM_SCM_SVC_DCVS, + QCOM_SCM_DCVS_INIT) && + __qcom_scm_is_call_available(dev, QCOM_SCM_SVC_DCVS, + QCOM_SCM_DCVS_UPDATE) && + __qcom_scm_is_call_available(dev, QCOM_SCM_SVC_DCVS, + QCOM_SCM_DCVS_RESET); +} + +bool __qcom_scm_dcvs_ca_available(struct device *dev) +{ + return __qcom_scm_is_call_available(dev, QCOM_SCM_SVC_DCVS, + QCOM_SCM_DCVS_INIT_CA_V2) && + __qcom_scm_is_call_available(dev, QCOM_SCM_SVC_DCVS, + QCOM_SCM_DCVS_UPDATE_CA_V2); +} + +int __qcom_scm_dcvs_reset(struct device *dev) +{ + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_DCVS, + .cmd = QCOM_SCM_DCVS_RESET, + .owner = ARM_SMCCC_OWNER_SIP + }; + + return qcom_scm_call(dev, &desc); +} + +int __qcom_scm_dcvs_init_v2(struct device *dev, phys_addr_t addr, size_t size, + int *version) +{ + int ret; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_DCVS, + .cmd = QCOM_SCM_DCVS_INIT_V2, + .owner = ARM_SMCCC_OWNER_SIP + }; + + desc.args[0] = addr; + desc.args[1] = size; + desc.arginfo = QCOM_SCM_ARGS(2, QCOM_SCM_RW, QCOM_SCM_VAL); + + ret = qcom_scm_call(dev, &desc); + + if (ret >= 0) + *version = desc.res[0]; + return ret; +} + +int __qcom_scm_dcvs_init_ca_v2(struct device *dev, phys_addr_t addr, + size_t size) +{ + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_DCVS, + .cmd = QCOM_SCM_DCVS_INIT_CA_V2, + .owner = ARM_SMCCC_OWNER_SIP + }; + + desc.args[0] = addr; + desc.args[1] = size; + desc.arginfo = QCOM_SCM_ARGS(2, QCOM_SCM_RW, QCOM_SCM_VAL); + + return qcom_scm_call(dev, &desc); +} + +int __qcom_scm_dcvs_update(struct device *dev, int level, s64 total_time, + s64 busy_time) +{ + int ret; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_DCVS, + .cmd = QCOM_SCM_DCVS_UPDATE, + .owner = ARM_SMCCC_OWNER_SIP + }; + + desc.args[0] = level; + desc.args[1] = total_time; + desc.args[2] = busy_time; + desc.arginfo = QCOM_SCM_ARGS(3); + + ret = qcom_scm_call_atomic(dev, &desc); + + return ret ? : desc.res[0]; +} + +int __qcom_scm_dcvs_update_v2(struct device *dev, int level, s64 total_time, + s64 busy_time) +{ + int ret; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_DCVS, + .cmd = QCOM_SCM_DCVS_UPDATE_V2, + .owner = ARM_SMCCC_OWNER_SIP + }; + + desc.args[0] = level; + desc.args[1] = total_time; + desc.args[2] = busy_time; + desc.arginfo = QCOM_SCM_ARGS(3); + + ret = qcom_scm_call(dev, &desc); + return ret ? : desc.res[0]; +} + +int __qcom_scm_dcvs_update_ca_v2(struct device *dev, int level, s64 total_time, + s64 busy_time, int context_count) +{ + int ret; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_DCVS, + .cmd = QCOM_SCM_DCVS_UPDATE_CA_V2, + .owner = ARM_SMCCC_OWNER_SIP + }; + + desc.args[0] = level; + desc.args[1] = total_time; + desc.args[2] = busy_time; + desc.args[3] = context_count; + desc.arginfo = QCOM_SCM_ARGS(4); + + ret = qcom_scm_call(dev, &desc); + return ret ? : desc.res[0]; +} + int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp) { diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index 63268266b1a5..fb7add7aff2a 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -341,6 +341,15 @@ int qcom_scm_io_writel(phys_addr_t addr, unsigned int val) } EXPORT_SYMBOL(qcom_scm_io_writel); +/** + * qcom_scm_io_reset() + */ +int qcom_scm_io_reset(void) +{ + return __qcom_scm_io_reset(__scm ? __scm->dev : NULL); +} +EXPORT_SYMBOL(qcom_scm_io_reset); + int qcom_scm_get_jtag_etm_feat_id(u64 *version) { return __qcom_scm_get_feat_version(__scm ? __scm->dev : NULL, @@ -533,6 +542,67 @@ int qcom_scm_smmu_prepare_atos_id(u64 dev_id, int cb_num, int operation) } EXPORT_SYMBOL(qcom_scm_smmu_prepare_atos_id); +/** + * qcom_scm_dcvs_core_available() - check if core DCVS operations are available + */ +bool qcom_scm_dcvs_core_available(void) +{ + return __qcom_scm_dcvs_core_available(__scm ? __scm->dev : NULL); +} +EXPORT_SYMBOL(qcom_scm_dcvs_core_available); + +/** + * qcom_scm_dcvs_ca_available() - check if context aware DCVS operations are + * available + */ +bool qcom_scm_dcvs_ca_available(void) +{ + return __qcom_scm_dcvs_ca_available(__scm ? __scm->dev : NULL); +} +EXPORT_SYMBOL(qcom_scm_dcvs_ca_available); + +/** + * qcom_scm_dcvs_reset() + */ +int qcom_scm_dcvs_reset(void) +{ + return __qcom_scm_dcvs_reset(__scm ? __scm->dev : NULL); +} +EXPORT_SYMBOL(qcom_scm_dcvs_reset); + +int qcom_scm_dcvs_init_v2(phys_addr_t addr, size_t size, int *version) +{ + return __qcom_scm_dcvs_init_v2(__scm->dev, addr, size, version); +} +EXPORT_SYMBOL(qcom_scm_dcvs_init_v2); + +int qcom_scm_dcvs_init_ca_v2(phys_addr_t addr, size_t size) +{ + return __qcom_scm_dcvs_init_ca_v2(__scm->dev, addr, size); +} +EXPORT_SYMBOL(qcom_scm_dcvs_init_ca_v2); + +int qcom_scm_dcvs_update(int level, s64 total_time, s64 busy_time) +{ + return __qcom_scm_dcvs_update(__scm->dev, level, total_time, busy_time); +} +EXPORT_SYMBOL(qcom_scm_dcvs_update); + +int qcom_scm_dcvs_update_v2(int level, s64 total_time, s64 busy_time) +{ + return __qcom_scm_dcvs_update_v2(__scm->dev, level, total_time, + busy_time); +} +EXPORT_SYMBOL(qcom_scm_dcvs_update_v2); + +int qcom_scm_dcvs_update_ca_v2(int level, s64 total_time, s64 busy_time, + int context_count) +{ + return __qcom_scm_dcvs_update_ca_v2(__scm->dev, level, total_time, + busy_time, context_count); +} +EXPORT_SYMBOL(qcom_scm_dcvs_update_ca_v2); + /** * qcom_scm_hdcp_available() - Check if secure environment supports HDCP. * diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h index 537e8c7d997b..6686d489a72e 100644 --- a/drivers/firmware/qcom_scm.h +++ b/drivers/firmware/qcom_scm.h @@ -44,8 +44,10 @@ extern int __qcom_scm_get_sec_dump_state(struct device *dev, u32 *dump_state); #define QCOM_SCM_SVC_IO 0x05 #define QCOM_SCM_IO_READ 0x01 #define QCOM_SCM_IO_WRITE 0x02 +#define QCOM_SCM_IO_RESET 0x03 extern int __qcom_scm_io_readl(struct device *dev, phys_addr_t addr, unsigned int *val); extern int __qcom_scm_io_writel(struct device *dev, phys_addr_t addr, unsigned int val); +extern int __qcom_scm_io_reset(struct device *dev); #define QCOM_SCM_SVC_INFO 0x06 #define QCOM_SCM_INFO_IS_CALL_AVAIL 0x01 @@ -109,6 +111,31 @@ extern int __qcom_scm_smmu_prepare_atos_id(struct device *dev, u64 dev_id, #define QCOM_SCM_IOMMU_TLBINVAL_FLAG 0x00000001 #define QCOM_SCM_CP_APERTURE_REG 0x0 +#define QCOM_SCM_SVC_DCVS 0x0D +#define QCOM_SCM_DCVS_RESET 0x07 +#define QCOM_SCM_DCVS_UPDATE 0x08 +#define QCOM_SCM_DCVS_INIT 0x09 +#define QCOM_SCM_DCVS_UPDATE_V2 0x0a +#define QCOM_SCM_DCVS_INIT_V2 0x0b +#define QCOM_SCM_DCVS_INIT_CA_V2 0x0c +#define QCOM_SCM_DCVS_UPDATE_CA_V2 0x0d +extern bool __qcom_scm_dcvs_core_available(struct device *dev); +extern bool __qcom_scm_dcvs_ca_available(struct device *dev); +extern int __qcom_scm_dcvs_reset(struct device *dev); +extern int __qcom_scm_dcvs_init_v2(struct device *dev, phys_addr_t addr, + size_t size, int *version); +extern int __qcom_scm_dcvs_init_ca_v2(struct device *dev, phys_addr_t addr, + size_t size); +extern int __qcom_scm_dcvs_update(struct device *dev, int level, + s64 total_time, s64 busy_time); + +extern int __qcom_scm_dcvs_update_v2(struct device *dev, int level, + s64 total_time, s64 busy_time); + +extern int __qcom_scm_dcvs_update_ca_v2(struct device *dev, int level, + s64 total_time, s64 busy_time, + int context_count); + #define QCOM_SCM_SVC_HDCP 0x11 #define QCOM_SCM_HDCP_INVOKE 0x01 extern int __qcom_scm_hdcp_req(struct device *dev, diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h index 5f9763e84090..7fc1df0b320a 100644 --- a/include/linux/qcom_scm.h +++ b/include/linux/qcom_scm.h @@ -50,6 +50,7 @@ extern int qcom_scm_pas_shutdown(u32 peripheral); extern int qcom_scm_get_sec_dump_state(u32 *dump_state); 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 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); @@ -72,6 +73,15 @@ extern bool qcom_scm_kgsl_set_smmu_aperture_available(void); extern int qcom_scm_kgsl_set_smmu_aperture( unsigned int num_context_bank); extern int qcom_scm_smmu_prepare_atos_id(u64 dev_id, int cb_num, int operation); +extern bool qcom_scm_dcvs_core_available(void); +extern bool qcom_scm_dcvs_ca_available(void); +extern int qcom_scm_dcvs_reset(void); +extern int qcom_scm_dcvs_init_v2(phys_addr_t addr, size_t size, int *version); +extern int qcom_scm_dcvs_init_ca_v2(phys_addr_t addr, size_t size); +extern int qcom_scm_dcvs_update(int level, s64 total_time, s64 busy_time); +extern int qcom_scm_dcvs_update_v2(int level, s64 total_time, s64 busy_time); +extern int qcom_scm_dcvs_update_ca_v2(int level, s64 total_time, s64 busy_time, + int context_count); extern bool qcom_scm_hdcp_available(void); extern int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp); @@ -112,6 +122,8 @@ static inline int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val) { return -ENODEV; } 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 int qcom_scm_get_jtag_etm_feat_id(u64 *version) { return -ENODEV; } static inline void qcom_scm_mmu_sync(bool sync) {} @@ -141,6 +153,18 @@ static inline int qcom_scm_kgsl_set_smmu_aperture( unsigned int num_context_bank) { return -ENODEV; } static inline int qcom_scm_smmu_prepare_atos_id(u64 dev_id, int cb_num, int operation) { return -ENODEV; } +static inline bool qcom_scm_dcvs_core_available(void) { return false; } +static inline bool qcom_scm_dcvs_ca_available(void) { return false; } +static inline int qcom_scm_dcvs_init_v2(phys_addr_t addr, size_t size, + int *version) { return -ENODEV; } +static inline int qcom_scm_dcvs_init_ca_v2(phys_addr_t addr, size_t size) + { return -ENODEV; } +static inline int qcom_scm_dcvs_update(int level, s64 total_time, s64 busy_time) + { return -ENODEV; } +static inline int qcom_scm_dcvs_update_v2(int level, s64 total_time, + s64 busy_time) { return -ENODEV; } +static inline int qcom_scm_dcvs_update_ca_v2(int level, s64 total_time, + s64 busy_time, int context_count) { return -ENODEV; } static inline bool qcom_scm_hdcp_available(void) { return false; } static inline int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp) { return -ENODEV; }