xref: /linux-6.15/include/linux/soc/apple/rtkit.h (revision bf8b4e49)
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