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
ipu7_syscom_get_indices(struct ipu7_syscom_context * ctx,u32 q)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
ipu7_syscom_get_token(struct ipu7_syscom_context * ctx,int q)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
ipu7_syscom_put_token(struct ipu7_syscom_context * ctx,int q)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 *
ipu7_syscom_get_queue_config(struct syscom_config_s * 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