Lines Matching +full:scmi +full:- +full:shmem
1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2019-2021 Linaro Ltd.
23 * PTA_SCMI_CMD_CAPABILITIES - Get channel capabilities
31 * PTA_SCMI_CMD_PROCESS_SMT_CHANNEL - Process SCMI message in SMT buffer
35 * Shared memory used for SCMI message/response exhange is expected
36 * already identified and bound to channel handle in both SCMI agent
37 * and SCMI server (OP-TEE) parts.
38 * The memory uses SMT header to carry SCMI meta-data (protocol ID and
44 * PTA_SCMI_CMD_PROCESS_SMT_CHANNEL_MESSAGE - Process SMT/SCMI message
47 * [in/out] memref[1]: Message/response buffer (SMT and SCMI payload)
49 * Shared memory used for SCMI message/response is a SMT buffer
52 * The memory uses SMT header to carry SCMI meta-data (protocol ID and
58 * PTA_SCMI_CMD_GET_CHANNEL - Get channel handle
60 * SCMI shm information are 0 if agent expects to use OP-TEE regular SHM
69 * PTA_SCMI_CMD_PROCESS_MSG_CHANNEL - Process SCMI message in a MSG
73 * [in] memref[1]: Message buffer (MSG and SCMI payload)
74 * [out] memref[2]: Response buffer (MSG and SCMI payload)
76 * Shared memories used for SCMI message/response are MSG buffers
78 * uses a 32bit header to carry SCMI meta-data (protocol ID and
79 * protocol message ID) followed by the effective SCMI message
86 * OP-TEE SCMI service capabilities bit flags (32bit)
89 * When set, OP-TEE supports command using SMT header protocol (SCMI shmem) in
90 * shared memory buffers to carry SCMI protocol synchronisation information.
93 * When set, OP-TEE supports command using MSG header protocol in an OP-TEE
94 * shared memory to carry SCMI protocol synchronisation information and SCMI
104 * struct scmi_optee_channel - Description of an OP-TEE SCMI channel
106 * @channel_id: OP-TEE channel ID used for this transport
108 * @caps: OP-TEE SCMI channel capabilities
111 * @cinfo: SCMI channel information
112 * @shmem: Virtual base address of the shared memory
113 * @req: Shared memory protocol handle for SCMI request and synchronous response
114 * @tee_shm: TEE shared memory handle @req or NULL if using IOMEM shmem
125 struct scmi_shared_mem __iomem *shmem; member
133 * struct scmi_optee_agent - OP-TEE transport private data
149 /* There can be only 1 SCMI service in OP-TEE we connect to */
155 /* Open a session toward SCMI OP-TEE service with REE_KERNEL identity */
158 struct device *dev = agent->dev; in open_session()
163 memcpy(arg.uuid, scmi_pta->id.uuid.b, TEE_IOCTL_UUID_LEN); in open_session()
166 ret = tee_client_open_session(agent->tee_ctx, &arg, NULL); in open_session()
169 return -EOPNOTSUPP; in open_session()
179 tee_client_close_session(agent->tee_ctx, tee_session); in close_session()
200 ret = tee_client_invoke_func(agent->tee_ctx, &arg, param); in get_capabilities()
205 dev_err(agent->dev, "Can't get capabilities: %d / %#x\n", ret, arg.ret); in get_capabilities()
206 return -EOPNOTSUPP; in get_capabilities()
212 dev_err(agent->dev, "OP-TEE SCMI PTA doesn't support SMT and MSG\n"); in get_capabilities()
213 return -EOPNOTSUPP; in get_capabilities()
216 agent->caps = caps; in get_capabilities()
223 struct device *dev = scmi_optee_private->dev; in get_channel()
229 if (channel->tee_shm) in get_channel()
235 arg.session = channel->tee_session; in get_channel()
239 param[0].u.value.a = channel->channel_id; in get_channel()
242 ret = tee_client_invoke_func(scmi_optee_private->tee_ctx, &arg, param); in get_channel()
246 return -EOPNOTSUPP; in get_channel()
249 /* From now on use channel identifer provided by OP-TEE SCMI service */ in get_channel()
250 channel->channel_id = param[0].u.value.a; in get_channel()
251 channel->caps = caps; in get_channel()
260 .session = channel->tee_session, in invoke_process_smt_channel()
267 param[0].u.value.a = channel->channel_id; in invoke_process_smt_channel()
269 ret = tee_client_invoke_func(scmi_optee_private->tee_ctx, &arg, param); in invoke_process_smt_channel()
271 dev_err(scmi_optee_private->dev, "Can't invoke channel %u: %d / %#x\n", in invoke_process_smt_channel()
272 channel->channel_id, ret, arg.ret); in invoke_process_smt_channel()
273 return -EIO; in invoke_process_smt_channel()
283 .session = channel->tee_session, in invoke_process_msg_channel()
290 param[0].u.value.a = channel->channel_id; in invoke_process_msg_channel()
293 param[1].u.memref.shm = channel->tee_shm; in invoke_process_msg_channel()
297 param[2].u.memref.shm = channel->tee_shm; in invoke_process_msg_channel()
300 ret = tee_client_invoke_func(scmi_optee_private->tee_ctx, &arg, param); in invoke_process_msg_channel()
302 dev_err(scmi_optee_private->dev, "Can't invoke channel %u: %d / %#x\n", in invoke_process_msg_channel()
303 channel->channel_id, ret, arg.ret); in invoke_process_msg_channel()
304 return -EIO; in invoke_process_msg_channel()
308 channel->rx_len = param[2].u.memref.size; in invoke_process_msg_channel()
320 return -EPROBE_DEFER; in scmi_optee_link_supplier()
323 if (!device_link_add(dev, scmi_optee_private->dev, DL_FLAG_AUTOREMOVE_CONSUMER)) { in scmi_optee_link_supplier()
325 return -ECANCELED; in scmi_optee_link_supplier()
335 return !of_property_read_u32_index(dev->of_node, "linaro,optee-channel-id", in scmi_optee_chan_available()
341 struct scmi_optee_channel *channel = cinfo->transport_info; in scmi_optee_clear_channel()
343 if (!channel->tee_shm) in scmi_optee_clear_channel()
344 shmem_clear_channel(channel->req.shmem); in scmi_optee_clear_channel()
352 channel->tee_shm = tee_shm_alloc_kernel_buf(scmi_optee_private->tee_ctx, msg_size); in setup_dynamic_shmem()
353 if (IS_ERR(channel->tee_shm)) { in setup_dynamic_shmem()
354 dev_err(channel->cinfo->dev, "shmem allocation failed\n"); in setup_dynamic_shmem()
355 return -ENOMEM; in setup_dynamic_shmem()
358 shbuf = tee_shm_get_va(channel->tee_shm, 0); in setup_dynamic_shmem()
360 channel->req.msg = shbuf; in setup_dynamic_shmem()
361 channel->rx_len = msg_size; in setup_dynamic_shmem()
374 np = of_parse_phandle(cinfo->dev->of_node, "shmem", 0); in setup_static_shmem()
375 if (!of_device_is_compatible(np, "arm,scmi-shmem")) { in setup_static_shmem()
376 ret = -ENXIO; in setup_static_shmem()
382 dev_err(dev, "Failed to get SCMI Tx shared memory\n"); in setup_static_shmem()
388 channel->req.shmem = devm_ioremap(dev, res.start, size); in setup_static_shmem()
389 if (!channel->req.shmem) { in setup_static_shmem()
390 dev_err(dev, "Failed to ioremap SCMI Tx shared memory\n"); in setup_static_shmem()
391 ret = -EADDRNOTAVAIL; in setup_static_shmem()
406 if (of_find_property(cinfo->dev->of_node, "shmem", NULL)) in setup_shmem()
419 return -ENODEV; in scmi_optee_chan_setup()
423 return -ENOMEM; in scmi_optee_chan_setup()
425 ret = of_property_read_u32_index(cinfo->dev->of_node, "linaro,optee-channel-id", in scmi_optee_chan_setup()
430 cinfo->transport_info = channel; in scmi_optee_chan_setup()
431 channel->cinfo = cinfo; in scmi_optee_chan_setup()
432 channel->channel_id = channel_id; in scmi_optee_chan_setup()
433 mutex_init(&channel->mu); in scmi_optee_chan_setup()
439 ret = open_session(scmi_optee_private, &channel->tee_session); in scmi_optee_chan_setup()
448 cinfo->no_completion_irq = true; in scmi_optee_chan_setup()
450 mutex_lock(&scmi_optee_private->mu); in scmi_optee_chan_setup()
451 list_add(&channel->link, &scmi_optee_private->channel_list); in scmi_optee_chan_setup()
452 mutex_unlock(&scmi_optee_private->mu); in scmi_optee_chan_setup()
457 close_session(scmi_optee_private, channel->tee_session); in scmi_optee_chan_setup()
459 if (channel->tee_shm) in scmi_optee_chan_setup()
460 tee_shm_free(channel->tee_shm); in scmi_optee_chan_setup()
468 struct scmi_optee_channel *channel = cinfo->transport_info; in scmi_optee_chan_free()
470 mutex_lock(&scmi_optee_private->mu); in scmi_optee_chan_free()
471 list_del(&channel->link); in scmi_optee_chan_free()
472 mutex_unlock(&scmi_optee_private->mu); in scmi_optee_chan_free()
474 close_session(scmi_optee_private, channel->tee_session); in scmi_optee_chan_free()
476 if (channel->tee_shm) { in scmi_optee_chan_free()
477 tee_shm_free(channel->tee_shm); in scmi_optee_chan_free()
478 channel->tee_shm = NULL; in scmi_optee_chan_free()
481 cinfo->transport_info = NULL; in scmi_optee_chan_free()
482 channel->cinfo = NULL; in scmi_optee_chan_free()
492 struct scmi_optee_channel *channel = cinfo->transport_info; in scmi_optee_send_message()
495 mutex_lock(&channel->mu); in scmi_optee_send_message()
497 if (channel->tee_shm) { in scmi_optee_send_message()
498 msg_tx_prepare(channel->req.msg, xfer); in scmi_optee_send_message()
501 shmem_tx_prepare(channel->req.shmem, xfer, cinfo); in scmi_optee_send_message()
506 mutex_unlock(&channel->mu); in scmi_optee_send_message()
514 struct scmi_optee_channel *channel = cinfo->transport_info; in scmi_optee_fetch_response()
516 if (channel->tee_shm) in scmi_optee_fetch_response()
517 msg_fetch_response(channel->req.msg, channel->rx_len, xfer); in scmi_optee_fetch_response()
519 shmem_fetch_response(channel->req.shmem, xfer); in scmi_optee_fetch_response()
525 struct scmi_optee_channel *channel = cinfo->transport_info; in scmi_optee_mark_txdone()
527 mutex_unlock(&channel->mu); in scmi_optee_mark_txdone()
543 return ver->impl_id == TEE_IMPL_ID_OPTEE; in scmi_optee_ctx_match()
552 /* Only one SCMI OP-TEE device allowed */ in scmi_optee_service_probe()
554 dev_err(dev, "An SCMI OP-TEE device was already initialized: only one allowed\n"); in scmi_optee_service_probe()
555 return -EBUSY; in scmi_optee_service_probe()
560 return -ENODEV; in scmi_optee_service_probe()
564 ret = -ENOMEM; in scmi_optee_service_probe()
568 agent->dev = dev; in scmi_optee_service_probe()
569 agent->tee_ctx = tee_ctx; in scmi_optee_service_probe()
570 INIT_LIST_HEAD(&agent->channel_list); in scmi_optee_service_probe()
571 mutex_init(&agent->mu); in scmi_optee_service_probe()
594 return -EINVAL; in scmi_optee_service_remove()
596 if (!list_empty(&scmi_optee_private->channel_list)) in scmi_optee_service_remove()
597 return -EBUSY; in scmi_optee_service_remove()
602 tee_client_close_context(agent->tee_ctx); in scmi_optee_service_remove()
620 .name = "scmi-optee",