19bd1d9a0SSven Peter /* SPDX-License-Identifier: GPL-2.0-only OR MIT */ 29bd1d9a0SSven Peter /* 39bd1d9a0SSven Peter * Apple RTKit IPC Library 49bd1d9a0SSven Peter * Copyright (C) The Asahi Linux Contributors 59bd1d9a0SSven Peter * 69bd1d9a0SSven Peter * Apple's SoCs come with various co-processors running their RTKit operating 79bd1d9a0SSven Peter * system. This protocol library is used by client drivers to use the 89bd1d9a0SSven Peter * features provided by them. 99bd1d9a0SSven Peter */ 109bd1d9a0SSven Peter #ifndef _LINUX_APPLE_RTKIT_H_ 119bd1d9a0SSven Peter #define _LINUX_APPLE_RTKIT_H_ 129bd1d9a0SSven Peter 139bd1d9a0SSven Peter #include <linux/device.h> 149bd1d9a0SSven Peter #include <linux/types.h> 159bd1d9a0SSven Peter #include <linux/mailbox_client.h> 169bd1d9a0SSven Peter 179bd1d9a0SSven Peter /* 189bd1d9a0SSven Peter * Struct to represent implementation-specific RTKit operations. 199bd1d9a0SSven Peter * 209bd1d9a0SSven Peter * @buffer: Shared memory buffer allocated inside normal RAM. 219bd1d9a0SSven Peter * @iomem: Shared memory buffer controlled by the co-processors. 229bd1d9a0SSven Peter * @size: Size of the shared memory buffer. 239bd1d9a0SSven Peter * @iova: Device VA of shared memory buffer. 249bd1d9a0SSven Peter * @is_mapped: Shared memory buffer is managed by the co-processor. 254435d63fSAsahi Lina * @private: Private data pointer for the parent driver. 269bd1d9a0SSven Peter */ 279bd1d9a0SSven Peter 289bd1d9a0SSven Peter struct apple_rtkit_shmem { 299bd1d9a0SSven Peter void *buffer; 309bd1d9a0SSven Peter void __iomem *iomem; 319bd1d9a0SSven Peter size_t size; 329bd1d9a0SSven Peter dma_addr_t iova; 339bd1d9a0SSven Peter bool is_mapped; 344435d63fSAsahi Lina void *private; 359bd1d9a0SSven Peter }; 369bd1d9a0SSven Peter 379bd1d9a0SSven Peter /* 389bd1d9a0SSven Peter * Struct to represent implementation-specific RTKit operations. 399bd1d9a0SSven Peter * 409bd1d9a0SSven Peter * @crashed: Called when the co-processor has crashed. Runs in process 419bd1d9a0SSven Peter * context. 429bd1d9a0SSven Peter * @recv_message: Function called when a message from RTKit is received 439bd1d9a0SSven Peter * on a non-system endpoint. Called from a worker thread. 449bd1d9a0SSven Peter * @recv_message_early: 459bd1d9a0SSven Peter * Like recv_message, but called from atomic context. It 469bd1d9a0SSven Peter * should return true if it handled the message. If it 479bd1d9a0SSven Peter * returns false, the message will be passed on to the 489bd1d9a0SSven Peter * worker thread. 499bd1d9a0SSven Peter * @shmem_setup: Setup shared memory buffer. If bfr.is_iomem is true the 509bd1d9a0SSven Peter * buffer is managed by the co-processor and needs to be mapped. 519bd1d9a0SSven Peter * Otherwise the buffer is managed by Linux and needs to be 529bd1d9a0SSven Peter * allocated. If not specified dma_alloc_coherent is used. 539bd1d9a0SSven Peter * Called in process context. 549bd1d9a0SSven Peter * @shmem_destroy: Undo the shared memory buffer setup in shmem_setup. If not 559bd1d9a0SSven Peter * specified dma_free_coherent is used. Called in process 569bd1d9a0SSven Peter * context. 579bd1d9a0SSven Peter */ 589bd1d9a0SSven Peter struct apple_rtkit_ops { 59*bf8b4e49SAsahi Lina void (*crashed)(void *cookie, const void *crashlog, size_t crashlog_size); 609bd1d9a0SSven Peter void (*recv_message)(void *cookie, u8 endpoint, u64 message); 619bd1d9a0SSven Peter bool (*recv_message_early)(void *cookie, u8 endpoint, u64 message); 629bd1d9a0SSven Peter int (*shmem_setup)(void *cookie, struct apple_rtkit_shmem *bfr); 639bd1d9a0SSven Peter void (*shmem_destroy)(void *cookie, struct apple_rtkit_shmem *bfr); 649bd1d9a0SSven Peter }; 659bd1d9a0SSven Peter 669bd1d9a0SSven Peter struct apple_rtkit; 679bd1d9a0SSven Peter 689bd1d9a0SSven Peter /* 699bd1d9a0SSven Peter * Initializes the internal state required to handle RTKit. This 709bd1d9a0SSven Peter * should usually be called within _probe. 719bd1d9a0SSven Peter * 72b8c7dd15SJesse Brandeburg * @dev: Pointer to the device node this coprocessor is associated with 739bd1d9a0SSven Peter * @cookie: opaque cookie passed to all functions defined in rtkit_ops 749bd1d9a0SSven Peter * @mbox_name: mailbox name used to communicate with the co-processor 759bd1d9a0SSven Peter * @mbox_idx: mailbox index to be used if mbox_name is NULL 769bd1d9a0SSven Peter * @ops: pointer to rtkit_ops to be used for this co-processor 779bd1d9a0SSven Peter */ 789bd1d9a0SSven Peter struct apple_rtkit *devm_apple_rtkit_init(struct device *dev, void *cookie, 799bd1d9a0SSven Peter const char *mbox_name, int mbox_idx, 809bd1d9a0SSven Peter const struct apple_rtkit_ops *ops); 819bd1d9a0SSven Peter 829bd1d9a0SSven Peter /* 83b3892860SAsahi Lina * Non-devm version of devm_apple_rtkit_init. Must be freed with 84b3892860SAsahi Lina * apple_rtkit_free. 85b3892860SAsahi Lina * 86b8c7dd15SJesse Brandeburg * @dev: Pointer to the device node this coprocessor is associated with 87b3892860SAsahi Lina * @cookie: opaque cookie passed to all functions defined in rtkit_ops 88b3892860SAsahi Lina * @mbox_name: mailbox name used to communicate with the co-processor 89b3892860SAsahi Lina * @mbox_idx: mailbox index to be used if mbox_name is NULL 90b3892860SAsahi Lina * @ops: pointer to rtkit_ops to be used for this co-processor 91b3892860SAsahi Lina */ 92b3892860SAsahi Lina struct apple_rtkit *apple_rtkit_init(struct device *dev, void *cookie, 93b3892860SAsahi Lina const char *mbox_name, int mbox_idx, 94b3892860SAsahi Lina const struct apple_rtkit_ops *ops); 95b3892860SAsahi Lina 96b3892860SAsahi Lina /* 97b3892860SAsahi Lina * Free an instance of apple_rtkit. 98b3892860SAsahi Lina */ 99b3892860SAsahi Lina void apple_rtkit_free(struct apple_rtkit *rtk); 100b3892860SAsahi Lina 101b3892860SAsahi Lina /* 1029bd1d9a0SSven Peter * Reinitialize internal structures. Must only be called with the co-processor 1039bd1d9a0SSven Peter * is held in reset. 1049bd1d9a0SSven Peter */ 1059bd1d9a0SSven Peter int apple_rtkit_reinit(struct apple_rtkit *rtk); 1069bd1d9a0SSven Peter 1079bd1d9a0SSven Peter /* 1089bd1d9a0SSven Peter * Handle RTKit's boot process. Should be called after the CPU of the 1099bd1d9a0SSven Peter * co-processor has been started. 1109bd1d9a0SSven Peter */ 1119bd1d9a0SSven Peter int apple_rtkit_boot(struct apple_rtkit *rtk); 1129bd1d9a0SSven Peter 1139bd1d9a0SSven Peter /* 1149bd1d9a0SSven Peter * Quiesce the co-processor. 1159bd1d9a0SSven Peter */ 1169bd1d9a0SSven Peter int apple_rtkit_quiesce(struct apple_rtkit *rtk); 1179bd1d9a0SSven Peter 1189bd1d9a0SSven Peter /* 1199bd1d9a0SSven Peter * Wake the co-processor up from hibernation mode. 1209bd1d9a0SSven Peter */ 1219bd1d9a0SSven Peter int apple_rtkit_wake(struct apple_rtkit *rtk); 1229bd1d9a0SSven Peter 1239bd1d9a0SSven Peter /* 1249bd1d9a0SSven Peter * Shutdown the co-processor 1259bd1d9a0SSven Peter */ 1269bd1d9a0SSven Peter int apple_rtkit_shutdown(struct apple_rtkit *rtk); 1279bd1d9a0SSven Peter 1289bd1d9a0SSven Peter /* 12940eaa8c0SHector Martin * Put the co-processor into idle mode 13040eaa8c0SHector Martin */ 13140eaa8c0SHector Martin int apple_rtkit_idle(struct apple_rtkit *rtk); 13240eaa8c0SHector Martin 13340eaa8c0SHector Martin /* 1349bd1d9a0SSven Peter * Checks if RTKit is running and ready to handle messages. 1359bd1d9a0SSven Peter */ 1369bd1d9a0SSven Peter bool apple_rtkit_is_running(struct apple_rtkit *rtk); 1379bd1d9a0SSven Peter 1389bd1d9a0SSven Peter /* 1399bd1d9a0SSven Peter * Checks if RTKit has crashed. 1409bd1d9a0SSven Peter */ 1419bd1d9a0SSven Peter bool apple_rtkit_is_crashed(struct apple_rtkit *rtk); 1429bd1d9a0SSven Peter 1439bd1d9a0SSven Peter /* 1449bd1d9a0SSven Peter * Starts an endpoint. Must be called after boot but before any messages can be 1459bd1d9a0SSven Peter * sent or received from that endpoint. 1469bd1d9a0SSven Peter */ 1479bd1d9a0SSven Peter int apple_rtkit_start_ep(struct apple_rtkit *rtk, u8 endpoint); 1489bd1d9a0SSven Peter 1499bd1d9a0SSven Peter /* 1509bd1d9a0SSven Peter * Send a message to the given endpoint. 1519bd1d9a0SSven Peter * 1529bd1d9a0SSven Peter * @rtk: RTKit reference 1539bd1d9a0SSven Peter * @ep: target endpoint 1549bd1d9a0SSven Peter * @message: message to be sent 1559bd1d9a0SSven Peter * @completeion: will be completed once the message has been submitted 1569bd1d9a0SSven Peter * to the hardware FIFO. Can be NULL. 1579bd1d9a0SSven Peter * @atomic: if set to true this function can be called from atomic 1589bd1d9a0SSven Peter * context. 1599bd1d9a0SSven Peter */ 1609bd1d9a0SSven Peter int apple_rtkit_send_message(struct apple_rtkit *rtk, u8 ep, u64 message, 1619bd1d9a0SSven Peter struct completion *completion, bool atomic); 1629bd1d9a0SSven Peter 1639bd1d9a0SSven Peter /* 164f5a5e833SHector Martin * Process incoming messages in atomic context. 165f5a5e833SHector Martin * This only guarantees that messages arrive as far as the recv_message_early 166f5a5e833SHector Martin * callback; drivers expecting to handle incoming messages synchronously 167f5a5e833SHector Martin * by calling this function must do it that way. 168f5a5e833SHector Martin * Will return 1 if some data was processed, 0 if none was, or a 169f5a5e833SHector Martin * negative error code on failure. 170f5a5e833SHector Martin * 171f5a5e833SHector Martin * @rtk: RTKit reference 172f5a5e833SHector Martin */ 173f5a5e833SHector Martin int apple_rtkit_poll(struct apple_rtkit *rtk); 174f5a5e833SHector Martin 1759bd1d9a0SSven Peter #endif /* _LINUX_APPLE_RTKIT_H_ */ 176