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 * @private: Private data pointer for the parent driver. 26 */ 27 28struct apple_rtkit_shmem { 29 void *buffer; 30 void __iomem *iomem; 31 size_t size; 32 dma_addr_t iova; 33 bool is_mapped; 34 void *private; 35}; 36 37/* 38 * Struct to represent implementation-specific RTKit operations. 39 * 40 * @crashed: Called when the co-processor has crashed. Runs in process 41 * context. 42 * @recv_message: Function called when a message from RTKit is received 43 * on a non-system endpoint. Called from a worker thread. 44 * @recv_message_early: 45 * Like recv_message, but called from atomic context. It 46 * should return true if it handled the message. If it 47 * returns false, the message will be passed on to the 48 * worker thread. 49 * @shmem_setup: Setup shared memory buffer. If bfr.is_iomem is true the 50 * buffer is managed by the co-processor and needs to be mapped. 51 * Otherwise the buffer is managed by Linux and needs to be 52 * allocated. If not specified dma_alloc_coherent is used. 53 * Called in process context. 54 * @shmem_destroy: Undo the shared memory buffer setup in shmem_setup. If not 55 * specified dma_free_coherent is used. Called in process 56 * context. 57 */ 58struct apple_rtkit_ops { 59 void (*crashed)(void *cookie); 60 void (*recv_message)(void *cookie, u8 endpoint, u64 message); 61 bool (*recv_message_early)(void *cookie, u8 endpoint, u64 message); 62 int (*shmem_setup)(void *cookie, struct apple_rtkit_shmem *bfr); 63 void (*shmem_destroy)(void *cookie, struct apple_rtkit_shmem *bfr); 64}; 65 66struct apple_rtkit; 67 68/* 69 * Initializes the internal state required to handle RTKit. This 70 * should usually be called within _probe. 71 * 72 * @dev: Pointer to the device node this coprocessor is assocated with 73 * @cookie: opaque cookie passed to all functions defined in rtkit_ops 74 * @mbox_name: mailbox name used to communicate with the co-processor 75 * @mbox_idx: mailbox index to be used if mbox_name is NULL 76 * @ops: pointer to rtkit_ops to be used for this co-processor 77 */ 78struct apple_rtkit *devm_apple_rtkit_init(struct device *dev, void *cookie, 79 const char *mbox_name, int mbox_idx, 80 const struct apple_rtkit_ops *ops); 81 82/* 83 * Non-devm version of devm_apple_rtkit_init. Must be freed with 84 * apple_rtkit_free. 85 * 86 * @dev: Pointer to the device node this coprocessor is assocated with 87 * @cookie: opaque cookie passed to all functions defined in rtkit_ops 88 * @mbox_name: mailbox name used to communicate with the co-processor 89 * @mbox_idx: mailbox index to be used if mbox_name is NULL 90 * @ops: pointer to rtkit_ops to be used for this co-processor 91 */ 92struct apple_rtkit *apple_rtkit_init(struct device *dev, void *cookie, 93 const char *mbox_name, int mbox_idx, 94 const struct apple_rtkit_ops *ops); 95 96/* 97 * Free an instance of apple_rtkit. 98 */ 99void apple_rtkit_free(struct apple_rtkit *rtk); 100 101/* 102 * Reinitialize internal structures. Must only be called with the co-processor 103 * is held in reset. 104 */ 105int apple_rtkit_reinit(struct apple_rtkit *rtk); 106 107/* 108 * Handle RTKit's boot process. Should be called after the CPU of the 109 * co-processor has been started. 110 */ 111int apple_rtkit_boot(struct apple_rtkit *rtk); 112 113/* 114 * Quiesce the co-processor. 115 */ 116int apple_rtkit_quiesce(struct apple_rtkit *rtk); 117 118/* 119 * Wake the co-processor up from hibernation mode. 120 */ 121int apple_rtkit_wake(struct apple_rtkit *rtk); 122 123/* 124 * Shutdown the co-processor 125 */ 126int apple_rtkit_shutdown(struct apple_rtkit *rtk); 127 128/* 129 * Put the co-processor into idle mode 130 */ 131int apple_rtkit_idle(struct apple_rtkit *rtk); 132 133/* 134 * Checks if RTKit is running and ready to handle messages. 135 */ 136bool apple_rtkit_is_running(struct apple_rtkit *rtk); 137 138/* 139 * Checks if RTKit has crashed. 140 */ 141bool apple_rtkit_is_crashed(struct apple_rtkit *rtk); 142 143/* 144 * Starts an endpoint. Must be called after boot but before any messages can be 145 * sent or received from that endpoint. 146 */ 147int apple_rtkit_start_ep(struct apple_rtkit *rtk, u8 endpoint); 148 149/* 150 * Send a message to the given endpoint. 151 * 152 * @rtk: RTKit reference 153 * @ep: target endpoint 154 * @message: message to be sent 155 * @completeion: will be completed once the message has been submitted 156 * to the hardware FIFO. Can be NULL. 157 * @atomic: if set to true this function can be called from atomic 158 * context. 159 */ 160int apple_rtkit_send_message(struct apple_rtkit *rtk, u8 ep, u64 message, 161 struct completion *completion, bool atomic); 162 163/* 164 * Process incoming messages in atomic context. 165 * This only guarantees that messages arrive as far as the recv_message_early 166 * callback; drivers expecting to handle incoming messages synchronously 167 * by calling this function must do it that way. 168 * Will return 1 if some data was processed, 0 if none was, or a 169 * negative error code on failure. 170 * 171 * @rtk: RTKit reference 172 */ 173int apple_rtkit_poll(struct apple_rtkit *rtk); 174 175#endif /* _LINUX_APPLE_RTKIT_H_ */ 176