1 /* SPDX-License-Identifier: GPL-2.0-only OR MIT */ 2 /* 3 * Apple RTKit IPC Library 4 * Copyright (C) The Asahi Linux Contributors 5 * 6 * Apple's SoCs come with various co-processors running their RTKit operating 7 * system. This protocol library is used by client drivers to use the 8 * features provided by them. 9 */ 10 #ifndef _LINUX_APPLE_RTKIT_H_ 11 #define _LINUX_APPLE_RTKIT_H_ 12 13 #include <linux/device.h> 14 #include <linux/types.h> 15 #include <linux/mailbox_client.h> 16 17 /* 18 * Struct to represent implementation-specific RTKit operations. 19 * 20 * @buffer: Shared memory buffer allocated inside normal RAM. 21 * @iomem: Shared memory buffer controlled by the co-processors. 22 * @size: Size of the shared memory buffer. 23 * @iova: Device VA of shared memory buffer. 24 * @is_mapped: Shared memory buffer is managed by the co-processor. 25 */ 26 27 struct apple_rtkit_shmem { 28 void *buffer; 29 void __iomem *iomem; 30 size_t size; 31 dma_addr_t iova; 32 bool is_mapped; 33 }; 34 35 /* 36 * Struct to represent implementation-specific RTKit operations. 37 * 38 * @crashed: Called when the co-processor has crashed. Runs in process 39 * context. 40 * @recv_message: Function called when a message from RTKit is received 41 * on a non-system endpoint. Called from a worker thread. 42 * @recv_message_early: 43 * Like recv_message, but called from atomic context. It 44 * should return true if it handled the message. If it 45 * returns false, the message will be passed on to the 46 * worker thread. 47 * @shmem_setup: Setup shared memory buffer. If bfr.is_iomem is true the 48 * buffer is managed by the co-processor and needs to be mapped. 49 * Otherwise the buffer is managed by Linux and needs to be 50 * allocated. If not specified dma_alloc_coherent is used. 51 * Called in process context. 52 * @shmem_destroy: Undo the shared memory buffer setup in shmem_setup. If not 53 * specified dma_free_coherent is used. Called in process 54 * context. 55 */ 56 struct apple_rtkit_ops { 57 void (*crashed)(void *cookie); 58 void (*recv_message)(void *cookie, u8 endpoint, u64 message); 59 bool (*recv_message_early)(void *cookie, u8 endpoint, u64 message); 60 int (*shmem_setup)(void *cookie, struct apple_rtkit_shmem *bfr); 61 void (*shmem_destroy)(void *cookie, struct apple_rtkit_shmem *bfr); 62 }; 63 64 struct apple_rtkit; 65 66 /* 67 * Initializes the internal state required to handle RTKit. This 68 * should usually be called within _probe. 69 * 70 * @dev: Pointer to the device node this coprocessor is assocated with 71 * @cookie: opaque cookie passed to all functions defined in rtkit_ops 72 * @mbox_name: mailbox name used to communicate with the co-processor 73 * @mbox_idx: mailbox index to be used if mbox_name is NULL 74 * @ops: pointer to rtkit_ops to be used for this co-processor 75 */ 76 struct apple_rtkit *devm_apple_rtkit_init(struct device *dev, void *cookie, 77 const char *mbox_name, int mbox_idx, 78 const struct apple_rtkit_ops *ops); 79 80 /* 81 * Reinitialize internal structures. Must only be called with the co-processor 82 * is held in reset. 83 */ 84 int apple_rtkit_reinit(struct apple_rtkit *rtk); 85 86 /* 87 * Handle RTKit's boot process. Should be called after the CPU of the 88 * co-processor has been started. 89 */ 90 int apple_rtkit_boot(struct apple_rtkit *rtk); 91 92 /* 93 * Quiesce the co-processor. 94 */ 95 int apple_rtkit_quiesce(struct apple_rtkit *rtk); 96 97 /* 98 * Wake the co-processor up from hibernation mode. 99 */ 100 int apple_rtkit_wake(struct apple_rtkit *rtk); 101 102 /* 103 * Shutdown the co-processor 104 */ 105 int apple_rtkit_shutdown(struct apple_rtkit *rtk); 106 107 /* 108 * Checks if RTKit is running and ready to handle messages. 109 */ 110 bool apple_rtkit_is_running(struct apple_rtkit *rtk); 111 112 /* 113 * Checks if RTKit has crashed. 114 */ 115 bool apple_rtkit_is_crashed(struct apple_rtkit *rtk); 116 117 /* 118 * Starts an endpoint. Must be called after boot but before any messages can be 119 * sent or received from that endpoint. 120 */ 121 int apple_rtkit_start_ep(struct apple_rtkit *rtk, u8 endpoint); 122 123 /* 124 * Send a message to the given endpoint. 125 * 126 * @rtk: RTKit reference 127 * @ep: target endpoint 128 * @message: message to be sent 129 * @completeion: will be completed once the message has been submitted 130 * to the hardware FIFO. Can be NULL. 131 * @atomic: if set to true this function can be called from atomic 132 * context. 133 */ 134 int apple_rtkit_send_message(struct apple_rtkit *rtk, u8 ep, u64 message, 135 struct completion *completion, bool atomic); 136 137 /* 138 * Send a message to the given endpoint and wait until it has been submitted 139 * to the hardware FIFO. 140 * Will return zero on success and a negative error code on failure 141 * (e.g. -ETIME when the message couldn't be written within the given 142 * timeout) 143 * 144 * @rtk: RTKit reference 145 * @ep: target endpoint 146 * @message: message to be sent 147 * @timeout: timeout in milliseconds to allow the message transmission 148 * to be completed 149 * @atomic: if set to true this function can be called from atomic 150 * context. 151 */ 152 int apple_rtkit_send_message_wait(struct apple_rtkit *rtk, u8 ep, u64 message, 153 unsigned long timeout, bool atomic); 154 155 /* 156 * Process incoming messages in atomic context. 157 * This only guarantees that messages arrive as far as the recv_message_early 158 * callback; drivers expecting to handle incoming messages synchronously 159 * by calling this function must do it that way. 160 * Will return 1 if some data was processed, 0 if none was, or a 161 * negative error code on failure. 162 * 163 * @rtk: RTKit reference 164 */ 165 int apple_rtkit_poll(struct apple_rtkit *rtk); 166 167 #endif /* _LINUX_APPLE_RTKIT_H_ */ 168