Lines Matching +full:tcsr +full:- +full:mutex
1 // SPDX-License-Identifier: GPL-2.0-only
6 #include <linux/arm-smccc.h>
10 #include <linux/dma-mapping.h>
22 #include <linux/reset-controller.h>
40 struct mutex scm_bw_lock;
60 * struct qcom_scm_qseecom_resp - QSEECOM SCM call response.
130 ret = clk_prepare_enable(__scm->core_clk); in qcom_scm_clk_enable()
134 ret = clk_prepare_enable(__scm->iface_clk); in qcom_scm_clk_enable()
138 ret = clk_prepare_enable(__scm->bus_clk); in qcom_scm_clk_enable()
145 clk_disable_unprepare(__scm->iface_clk); in qcom_scm_clk_enable()
147 clk_disable_unprepare(__scm->core_clk); in qcom_scm_clk_enable()
154 clk_disable_unprepare(__scm->core_clk); in qcom_scm_clk_disable()
155 clk_disable_unprepare(__scm->iface_clk); in qcom_scm_clk_disable()
156 clk_disable_unprepare(__scm->bus_clk); in qcom_scm_clk_disable()
163 if (!__scm->path) in qcom_scm_bw_enable()
166 if (IS_ERR(__scm->path)) in qcom_scm_bw_enable()
167 return -EINVAL; in qcom_scm_bw_enable()
169 mutex_lock(&__scm->scm_bw_lock); in qcom_scm_bw_enable()
170 if (!__scm->scm_vote_count) { in qcom_scm_bw_enable()
171 ret = icc_set_bw(__scm->path, 0, UINT_MAX); in qcom_scm_bw_enable()
173 dev_err(__scm->dev, "failed to set bandwidth request\n"); in qcom_scm_bw_enable()
177 __scm->scm_vote_count++; in qcom_scm_bw_enable()
179 mutex_unlock(&__scm->scm_bw_lock); in qcom_scm_bw_enable()
186 if (IS_ERR_OR_NULL(__scm->path)) in qcom_scm_bw_disable()
189 mutex_lock(&__scm->scm_bw_lock); in qcom_scm_bw_disable()
190 if (__scm->scm_vote_count-- == 1) in qcom_scm_bw_disable()
191 icc_set_bw(__scm->path, 0, 0); in qcom_scm_bw_disable()
192 mutex_unlock(&__scm->scm_bw_lock); in qcom_scm_bw_disable()
219 * Per the "SMC calling convention specification", the 64-bit calling in __get_convention()
220 * convention can only be used when the client is 64-bit, otherwise in __get_convention()
225 * Device isn't required as there is only one argument - no device in __get_convention()
240 if (of_device_is_compatible(__scm ? __scm->dev->of_node : NULL, "qcom,scm-sc7180")) { in __get_convention()
266 * qcom_scm_call() - Invoke a syscall in the secure world
272 * This should *only* be called in pre-emptible context.
286 return -EINVAL; in qcom_scm_call()
291 * qcom_scm_call_atomic() - atomic variation of qcom_scm_call()
311 return -EINVAL; in qcom_scm_call_atomic()
359 return -EINVAL; in qcom_scm_set_boot_addr()
366 return qcom_scm_call_atomic(__scm ? __scm->dev : NULL, &desc, NULL); in qcom_scm_set_boot_addr()
386 return -EOPNOTSUPP; in qcom_scm_set_boot_addr_mc()
388 return qcom_scm_call(__scm->dev, &desc, NULL); in qcom_scm_set_boot_addr_mc()
392 * qcom_scm_set_warm_boot_addr() - Set the warm boot address for all cpus
408 * qcom_scm_set_cold_boot_addr() - Set the cold boot address for all cpus
421 * qcom_scm_cpu_power_down() - Power down the cpu
438 qcom_scm_call_atomic(__scm ? __scm->dev : NULL, &desc, NULL); in qcom_scm_cpu_power_down()
455 ret = qcom_scm_call(__scm->dev, &desc, &res); in qcom_scm_set_remote_state()
477 ret = qcom_scm_call(__scm->dev, &desc, &res); in qcom_scm_disable_sdi()
496 return qcom_scm_call_atomic(__scm->dev, &desc, NULL); in __qcom_scm_set_dload_mode()
504 avail = __qcom_scm_is_call_available(__scm->dev, in qcom_scm_set_download_mode()
508 ret = __qcom_scm_set_dload_mode(__scm->dev, enable); in qcom_scm_set_download_mode()
509 } else if (__scm->dload_mode_addr) { in qcom_scm_set_download_mode()
510 ret = qcom_scm_io_writel(__scm->dload_mode_addr, in qcom_scm_set_download_mode()
513 dev_err(__scm->dev, in qcom_scm_set_download_mode()
518 dev_err(__scm->dev, "failed to set download mode: %d\n", ret); in qcom_scm_set_download_mode()
522 * qcom_scm_pas_init_image() - Initialize peripheral authentication service
556 * non-cachable to avoid XPU violations. in qcom_scm_pas_init_image()
558 mdata_buf = dma_alloc_coherent(__scm->dev, size, &mdata_phys, in qcom_scm_pas_init_image()
561 dev_err(__scm->dev, "Allocation of metadata buffer failed.\n"); in qcom_scm_pas_init_image()
562 return -ENOMEM; in qcom_scm_pas_init_image()
576 ret = qcom_scm_call(__scm->dev, &desc, &res); in qcom_scm_pas_init_image()
583 dma_free_coherent(__scm->dev, size, mdata_buf, mdata_phys); in qcom_scm_pas_init_image()
585 ctx->ptr = mdata_buf; in qcom_scm_pas_init_image()
586 ctx->phys = mdata_phys; in qcom_scm_pas_init_image()
587 ctx->size = size; in qcom_scm_pas_init_image()
595 * qcom_scm_pas_metadata_release() - release metadata context
600 if (!ctx->ptr) in qcom_scm_pas_metadata_release()
603 dma_free_coherent(__scm->dev, ctx->size, ctx->ptr, ctx->phys); in qcom_scm_pas_metadata_release()
605 ctx->ptr = NULL; in qcom_scm_pas_metadata_release()
606 ctx->phys = 0; in qcom_scm_pas_metadata_release()
607 ctx->size = 0; in qcom_scm_pas_metadata_release()
612 * qcom_scm_pas_mem_setup() - Prepare the memory related to a given peripheral
642 ret = qcom_scm_call(__scm->dev, &desc, &res); in qcom_scm_pas_mem_setup()
651 * qcom_scm_pas_auth_and_reset() - Authenticate the given peripheral firmware
677 ret = qcom_scm_call(__scm->dev, &desc, &res); in qcom_scm_pas_auth_and_reset()
686 * qcom_scm_pas_shutdown() - Shut down the remote processor
711 ret = qcom_scm_call(__scm->dev, &desc, &res); in qcom_scm_pas_shutdown()
721 * qcom_scm_pas_supported() - Check if the peripheral authentication service is
739 if (!__qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_PIL, in qcom_scm_pas_supported()
743 ret = qcom_scm_call(__scm->dev, &desc, &res); in qcom_scm_pas_supported()
762 ret = qcom_scm_call(__scm->dev, &desc, &res); in __qcom_scm_pas_mss_reset()
771 return -EINVAL; in qcom_scm_pas_reset_assert()
773 return __qcom_scm_pas_mss_reset(__scm->dev, 1); in qcom_scm_pas_reset_assert()
780 return -EINVAL; in qcom_scm_pas_reset_deassert()
782 return __qcom_scm_pas_mss_reset(__scm->dev, 0); in qcom_scm_pas_reset_deassert()
803 ret = qcom_scm_call_atomic(__scm->dev, &desc, &res); in qcom_scm_io_readl()
822 return qcom_scm_call_atomic(__scm->dev, &desc, NULL); in qcom_scm_io_writel()
827 * qcom_scm_restore_sec_cfg_available() - Check if secure environment
830 * Return true if restore-cfg interface is supported, false if not.
834 return __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_MP, in qcom_scm_restore_sec_cfg_available()
852 ret = qcom_scm_call(__scm->dev, &desc, &res); in qcom_scm_restore_sec_cfg()
870 ret = qcom_scm_call(__scm->dev, &desc, &res); in qcom_scm_iommu_secure_ptbl_size()
893 ret = qcom_scm_call(__scm->dev, &desc, NULL); in qcom_scm_iommu_secure_ptbl_init()
896 if (ret == -EPERM) in qcom_scm_iommu_secure_ptbl_init()
914 return qcom_scm_call(__scm->dev, &desc, NULL); in qcom_scm_iommu_set_cp_pool_size()
936 ret = qcom_scm_call(__scm->dev, &desc, &res); in qcom_scm_mem_protect_video_var()
970 * qcom_scm_assign_mem() - Make a secure call to reassign memory ownership
1007 ptr = dma_alloc_coherent(__scm->dev, ptr_sz, &ptr_phys, GFP_KERNEL); in qcom_scm_assign_mem()
1009 return -ENOMEM; in qcom_scm_assign_mem()
1022 mem_to_map->mem_addr = cpu_to_le64(mem_addr); in qcom_scm_assign_mem()
1023 mem_to_map->mem_size = cpu_to_le64(mem_sz); in qcom_scm_assign_mem()
1030 destvm->vmid = cpu_to_le32(newvm->vmid); in qcom_scm_assign_mem()
1031 destvm->perm = cpu_to_le32(newvm->perm); in qcom_scm_assign_mem()
1032 destvm->ctx = 0; in qcom_scm_assign_mem()
1033 destvm->ctx_size = 0; in qcom_scm_assign_mem()
1034 next_vm |= BIT(newvm->vmid); in qcom_scm_assign_mem()
1037 ret = __qcom_scm_assign_mem(__scm->dev, mem_to_map_phys, mem_to_map_sz, in qcom_scm_assign_mem()
1039 dma_free_coherent(__scm->dev, ptr_sz, ptr, ptr_phys); in qcom_scm_assign_mem()
1041 dev_err(__scm->dev, in qcom_scm_assign_mem()
1043 return -EINVAL; in qcom_scm_assign_mem()
1052 * qcom_scm_ocmem_lock_available() - is OCMEM lock/unlock interface available
1056 return __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_OCMEM, in qcom_scm_ocmem_lock_available()
1062 * qcom_scm_ocmem_lock() - call OCMEM lock interface to assign an OCMEM
1083 return qcom_scm_call(__scm->dev, &desc, NULL); in qcom_scm_ocmem_lock()
1088 * qcom_scm_ocmem_unlock() - call OCMEM unlock interface to release an OCMEM
1106 return qcom_scm_call(__scm->dev, &desc, NULL); in qcom_scm_ocmem_unlock()
1111 * qcom_scm_ice_available() - Is the ICE key programming interface available?
1118 return __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_ES, in qcom_scm_ice_available()
1120 __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_ES, in qcom_scm_ice_available()
1126 * qcom_scm_ice_invalidate_key() - Invalidate an inline encryption key
1135 * Return: 0 on success; -errno on failure.
1147 return qcom_scm_call(__scm->dev, &desc, NULL); in qcom_scm_ice_invalidate_key()
1152 * qcom_scm_ice_set_key() - Set an inline encryption key
1158 * individual plaintext and ciphertext. Given in 512-byte
1170 * Return: 0 on success; -errno on failure.
1198 * keys is normally rare and thus not performance-critical. in qcom_scm_ice_set_key()
1201 keybuf = dma_alloc_coherent(__scm->dev, key_size, &key_phys, in qcom_scm_ice_set_key()
1204 return -ENOMEM; in qcom_scm_ice_set_key()
1208 ret = qcom_scm_call(__scm->dev, &desc, NULL); in qcom_scm_ice_set_key()
1212 dma_free_coherent(__scm->dev, key_size, keybuf, key_phys); in qcom_scm_ice_set_key()
1218 * qcom_scm_hdcp_available() - Check if secure environment supports HDCP.
1230 avail = __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_HDCP, in qcom_scm_hdcp_available()
1240 * qcom_scm_hdcp_req() - Send HDCP request.
1271 return -ERANGE; in qcom_scm_hdcp_req()
1277 ret = qcom_scm_call(__scm->dev, &desc, &res); in qcom_scm_hdcp_req()
1294 .args[2] = pt_fmt, /* 0: LPAE AArch32 - 1: AArch64 */ in qcom_scm_iommu_set_pt_format()
1298 return qcom_scm_call(__scm->dev, &desc, NULL); in qcom_scm_iommu_set_pt_format()
1314 return qcom_scm_call_atomic(__scm->dev, &desc, NULL); in qcom_scm_qsmmu500_wait_safe_toggle()
1320 return __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_LMH, QCOM_SCM_LMH_LIMIT_DCVSH); in qcom_scm_lmh_dcvsh_available()
1334 return qcom_scm_call(__scm->dev, &desc, NULL); in qcom_scm_lmh_profile_change()
1357 payload_buf = dma_alloc_coherent(__scm->dev, payload_size, &payload_phys, GFP_KERNEL); in qcom_scm_lmh_dcvsh()
1359 return -ENOMEM; in qcom_scm_lmh_dcvsh()
1369 ret = qcom_scm_call(__scm->dev, &desc, NULL); in qcom_scm_lmh_dcvsh()
1371 dma_free_coherent(__scm->dev, payload_size, payload_buf, payload_phys); in qcom_scm_lmh_dcvsh()
1378 struct device_node *tcsr; in qcom_scm_find_dload_address() local
1379 struct device_node *np = dev->of_node; in qcom_scm_find_dload_address()
1384 tcsr = of_parse_phandle(np, "qcom,dload-mode", 0); in qcom_scm_find_dload_address()
1385 if (!tcsr) in qcom_scm_find_dload_address()
1388 ret = of_address_to_resource(tcsr, 0, &res); in qcom_scm_find_dload_address()
1389 of_node_put(tcsr); in qcom_scm_find_dload_address()
1393 ret = of_property_read_u32_index(np, "qcom,dload-mode", 1, &offset); in qcom_scm_find_dload_address()
1419 status = qcom_scm_call(__scm->dev, desc, &scm_res); in __qcom_scm_qseecom_call()
1421 res->result = scm_res.result[0]; in __qcom_scm_qseecom_call()
1422 res->resp_type = scm_res.result[1]; in __qcom_scm_qseecom_call()
1423 res->data = scm_res.result[2]; in __qcom_scm_qseecom_call()
1432 * qcom_scm_qseecom_call() - Perform a QSEECOM SCM call.
1456 dev_dbg(__scm->dev, "%s: owner=%x, svc=%x, cmd=%x, result=%lld, type=%llx, data=%llx\n", in qcom_scm_qseecom_call()
1457 __func__, desc->owner, desc->svc, desc->cmd, res->result, in qcom_scm_qseecom_call()
1458 res->resp_type, res->data); in qcom_scm_qseecom_call()
1461 dev_err(__scm->dev, "qseecom: scm call failed with error %d\n", status); in qcom_scm_qseecom_call()
1473 WARN_ON(res->result == QSEECOM_RESULT_INCOMPLETE); in qcom_scm_qseecom_call()
1474 WARN_ON(res->result == QSEECOM_RESULT_BLOCKED_ON_LISTENER); in qcom_scm_qseecom_call()
1480 * qcom_scm_qseecom_get_version() - Query the QSEECOM version.
1510 * qcom_scm_qseecom_app_get_id() - Query the app ID for a given QSEE app name.
1518 * Return: Zero on success, nonzero on failure, -ENOENT if the app has not been
1532 return -EINVAL; in qcom_scm_qseecom_app_get_id()
1536 return -ENOMEM; in qcom_scm_qseecom_app_get_id()
1540 name_buf_phys = dma_map_single(__scm->dev, name_buf, name_buf_size, DMA_TO_DEVICE); in qcom_scm_qseecom_app_get_id()
1541 status = dma_mapping_error(__scm->dev, name_buf_phys); in qcom_scm_qseecom_app_get_id()
1544 dev_err(__scm->dev, "qseecom: failed to map dma address\n"); in qcom_scm_qseecom_app_get_id()
1556 dma_unmap_single(__scm->dev, name_buf_phys, name_buf_size, DMA_TO_DEVICE); in qcom_scm_qseecom_app_get_id()
1563 return -ENOENT; in qcom_scm_qseecom_app_get_id()
1566 return -EINVAL; in qcom_scm_qseecom_app_get_id()
1569 return -EINVAL; in qcom_scm_qseecom_app_get_id()
1577 * qcom_scm_qseecom_app_send() - Send to and receive data from a given QSEE app.
1579 * @req: Request buffer sent to the app (must be DMA-mappable).
1581 * @rsp: Response buffer, written to by the app (must be DMA-mappable).
1587 * respective (app-specific) request data. The QSEE app reads this and returns
1602 req_phys = dma_map_single(__scm->dev, req, req_size, DMA_TO_DEVICE); in qcom_scm_qseecom_app_send()
1603 status = dma_mapping_error(__scm->dev, req_phys); in qcom_scm_qseecom_app_send()
1605 dev_err(__scm->dev, "qseecom: failed to map request buffer\n"); in qcom_scm_qseecom_app_send()
1610 rsp_phys = dma_map_single(__scm->dev, rsp, rsp_size, DMA_FROM_DEVICE); in qcom_scm_qseecom_app_send()
1611 status = dma_mapping_error(__scm->dev, rsp_phys); in qcom_scm_qseecom_app_send()
1613 dma_unmap_single(__scm->dev, req_phys, req_size, DMA_TO_DEVICE); in qcom_scm_qseecom_app_send()
1614 dev_err(__scm->dev, "qseecom: failed to map response buffer\n"); in qcom_scm_qseecom_app_send()
1635 dma_unmap_single(__scm->dev, rsp_phys, rsp_size, DMA_FROM_DEVICE); in qcom_scm_qseecom_app_send()
1636 dma_unmap_single(__scm->dev, req_phys, req_size, DMA_TO_DEVICE); in qcom_scm_qseecom_app_send()
1642 return -EIO; in qcom_scm_qseecom_app_send()
1649 * We do not yet support re-entrant calls via the qseecom interface. To prevent
1653 { .compatible = "lenovo,thinkpad-x13s", },
1701 dev_info(scm->dev, "qseecom: found qseecom with version 0x%x\n", version); in qcom_scm_qseecom_init()
1704 dev_info(scm->dev, "qseecom: untested machine, skipping\n"); in qcom_scm_qseecom_init()
1712 qseecom_dev = platform_device_alloc("qcom_qseecom", -1); in qcom_scm_qseecom_init()
1714 return -ENOMEM; in qcom_scm_qseecom_init()
1716 qseecom_dev->dev.parent = scm->dev; in qcom_scm_qseecom_init()
1724 return devm_add_action_or_reset(scm->dev, qcom_scm_qseecom_free, qseecom_dev); in qcom_scm_qseecom_init()
1737 * qcom_scm_is_available() - Checks if SCM is available
1752 dev_err(__scm->dev, "Firmware unexpectedly passed non-zero wq_ctx\n"); in qcom_scm_assert_valid_wq_ctx()
1753 return -EINVAL; in qcom_scm_assert_valid_wq_ctx()
1767 wait_for_completion(&__scm->waitq_comp); in qcom_scm_wait_for_wq_completion()
1780 complete(&__scm->waitq_comp); in qcom_scm_waitq_wakeup()
1794 dev_err(scm->dev, "GET_WQ_CTX SMC call failed: %d\n", ret); in qcom_scm_irq_handler()
1800 dev_err(scm->dev, "Invalid flags found for wq_ctx: %u\n", flags); in qcom_scm_irq_handler()
1818 scm = devm_kzalloc(&pdev->dev, sizeof(*scm), GFP_KERNEL); in qcom_scm_probe()
1820 return -ENOMEM; in qcom_scm_probe()
1822 ret = qcom_scm_find_dload_address(&pdev->dev, &scm->dload_mode_addr); in qcom_scm_probe()
1826 mutex_init(&scm->scm_bw_lock); in qcom_scm_probe()
1828 scm->path = devm_of_icc_get(&pdev->dev, NULL); in qcom_scm_probe()
1829 if (IS_ERR(scm->path)) in qcom_scm_probe()
1830 return dev_err_probe(&pdev->dev, PTR_ERR(scm->path), in qcom_scm_probe()
1833 scm->core_clk = devm_clk_get_optional(&pdev->dev, "core"); in qcom_scm_probe()
1834 if (IS_ERR(scm->core_clk)) in qcom_scm_probe()
1835 return PTR_ERR(scm->core_clk); in qcom_scm_probe()
1837 scm->iface_clk = devm_clk_get_optional(&pdev->dev, "iface"); in qcom_scm_probe()
1838 if (IS_ERR(scm->iface_clk)) in qcom_scm_probe()
1839 return PTR_ERR(scm->iface_clk); in qcom_scm_probe()
1841 scm->bus_clk = devm_clk_get_optional(&pdev->dev, "bus"); in qcom_scm_probe()
1842 if (IS_ERR(scm->bus_clk)) in qcom_scm_probe()
1843 return PTR_ERR(scm->bus_clk); in qcom_scm_probe()
1845 scm->reset.ops = &qcom_scm_pas_reset_ops; in qcom_scm_probe()
1846 scm->reset.nr_resets = 1; in qcom_scm_probe()
1847 scm->reset.of_node = pdev->dev.of_node; in qcom_scm_probe()
1848 ret = devm_reset_controller_register(&pdev->dev, &scm->reset); in qcom_scm_probe()
1853 ret = clk_set_rate(scm->core_clk, INT_MAX); in qcom_scm_probe()
1858 __scm->dev = &pdev->dev; in qcom_scm_probe()
1860 init_completion(&__scm->waitq_comp); in qcom_scm_probe()
1864 if (irq != -ENXIO) in qcom_scm_probe()
1867 ret = devm_request_threaded_irq(__scm->dev, irq, NULL, qcom_scm_irq_handler, in qcom_scm_probe()
1868 IRQF_ONESHOT, "qcom-scm", __scm); in qcom_scm_probe()
1870 return dev_err_probe(scm->dev, ret, "Failed to request qcom-scm irq\n"); in qcom_scm_probe()
1887 if (of_property_read_bool(pdev->dev.of_node, "qcom,sdi-enabled")) in qcom_scm_probe()
1893 * Note: QSEECOM is fairly self-contained and this only adds the in qcom_scm_probe()
1895 * lifting). So any errors returned here should be either -ENOMEM or in qcom_scm_probe()
1896 * -EINVAL (with the latter only in case there's a bug in our code). in qcom_scm_probe()
1916 { .compatible = "qcom,scm-apq8064" },
1917 { .compatible = "qcom,scm-apq8084" },
1918 { .compatible = "qcom,scm-ipq4019" },
1919 { .compatible = "qcom,scm-msm8953" },
1920 { .compatible = "qcom,scm-msm8974" },
1921 { .compatible = "qcom,scm-msm8996" },