xref: /linux/drivers/staging/media/ipu7/ipu7-syscom.c (revision 8d2b0853add1d7534dc0794e3c8e0b9e8c4ec640)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2013 - 2025 Intel Corporation
4  */
5 
6 #include <linux/export.h>
7 #include <linux/io.h>
8 
9 #include "abi/ipu7_fw_syscom_abi.h"
10 
11 #include "ipu7.h"
12 #include "ipu7-syscom.h"
13 
14 static void __iomem *ipu7_syscom_get_indices(struct ipu7_syscom_context *ctx,
15 					     u32 q)
16 {
17 	return ctx->queue_indices + (q * sizeof(struct syscom_queue_indices_s));
18 }
19 
20 void *ipu7_syscom_get_token(struct ipu7_syscom_context *ctx, int q)
21 {
22 	struct syscom_queue_config *queue_params = &ctx->queue_configs[q];
23 	void __iomem *queue_indices = ipu7_syscom_get_indices(ctx, q);
24 	u32 write_index = readl(queue_indices +
25 				offsetof(struct syscom_queue_indices_s,
26 					 write_index));
27 	u32 read_index = readl(queue_indices +
28 			       offsetof(struct syscom_queue_indices_s,
29 					read_index));
30 	void *token = NULL;
31 
32 	if (q < ctx->num_output_queues) {
33 		/* Output queue */
34 		bool empty = (write_index == read_index);
35 
36 		if (!empty)
37 			token = queue_params->token_array_mem +
38 				read_index *
39 				queue_params->token_size_in_bytes;
40 	} else {
41 		/* Input queue */
42 		bool full = (read_index == ((write_index + 1U) %
43 					    (u32)queue_params->max_capacity));
44 
45 		if (!full)
46 			token = queue_params->token_array_mem +
47 				write_index * queue_params->token_size_in_bytes;
48 	}
49 	return token;
50 }
51 EXPORT_SYMBOL_NS_GPL(ipu7_syscom_get_token, "INTEL_IPU7");
52 
53 void ipu7_syscom_put_token(struct ipu7_syscom_context *ctx, int q)
54 {
55 	struct syscom_queue_config *queue_params = &ctx->queue_configs[q];
56 	void __iomem *queue_indices = ipu7_syscom_get_indices(ctx, q);
57 	u32 offset, index;
58 
59 	if (q < ctx->num_output_queues)
60 		/* Output queue */
61 		offset = offsetof(struct syscom_queue_indices_s, read_index);
62 
63 	else
64 		/* Input queue */
65 		offset = offsetof(struct syscom_queue_indices_s, write_index);
66 
67 	index = readl(queue_indices + offset);
68 	writel((index + 1U) % queue_params->max_capacity,
69 	       queue_indices + offset);
70 }
71 EXPORT_SYMBOL_NS_GPL(ipu7_syscom_put_token, "INTEL_IPU7");
72 
73 struct syscom_queue_params_config *
74 ipu7_syscom_get_queue_config(struct syscom_config_s *config)
75 {
76 	return (struct syscom_queue_params_config *)(&config[1]);
77 }
78 EXPORT_SYMBOL_NS_GPL(ipu7_syscom_get_queue_config, "INTEL_IPU7");
79