1 /* $NetBSD: dmub_rb.h,v 1.3 2021/12/19 10:59:02 riastradh Exp $ */
2
3 /*
4 * Copyright 2019 Advanced Micro Devices, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: AMD
25 *
26 */
27
28 #ifndef _DMUB_RB_H_
29 #define _DMUB_RB_H_
30
31 #include "dmub_types.h"
32 #include "dmub_cmd.h"
33
34 #if defined(__cplusplus)
35 extern "C" {
36 #endif
37
38 struct dmub_cmd_header;
39
40 struct dmub_rb_init_params {
41 void *ctx;
42 void *base_address;
43 uint32_t capacity;
44 };
45
46 struct dmub_rb {
47 void *base_address;
48 uint32_t data_count;
49 uint32_t rptr;
50 uint32_t wrpt;
51 uint32_t capacity;
52
53 void *ctx;
54 void *dmub;
55 };
56
57
dmub_rb_empty(struct dmub_rb * rb)58 static inline bool dmub_rb_empty(struct dmub_rb *rb)
59 {
60 return (rb->wrpt == rb->rptr);
61 }
62
dmub_rb_full(struct dmub_rb * rb)63 static inline bool dmub_rb_full(struct dmub_rb *rb)
64 {
65 uint32_t data_count;
66
67 if (rb->wrpt >= rb->rptr)
68 data_count = rb->wrpt - rb->rptr;
69 else
70 data_count = rb->capacity - (rb->rptr - rb->wrpt);
71
72 return (data_count == (rb->capacity - DMUB_RB_CMD_SIZE));
73 }
74
dmub_rb_push_front(struct dmub_rb * rb,const struct dmub_cmd_header * cmd)75 static inline bool dmub_rb_push_front(struct dmub_rb *rb,
76 const struct dmub_cmd_header *cmd)
77 {
78 uint64_t volatile *dst = (uint64_t volatile *)(rb->base_address) + rb->wrpt / sizeof(uint64_t);
79 const uint64_t *src = (const uint64_t *)cmd;
80 int i;
81
82 if (dmub_rb_full(rb))
83 return false;
84
85 // copying data
86 for (i = 0; i < DMUB_RB_CMD_SIZE / sizeof(uint64_t); i++)
87 *dst++ = *src++;
88
89 rb->wrpt += DMUB_RB_CMD_SIZE;
90
91 if (rb->wrpt >= rb->capacity)
92 rb->wrpt %= rb->capacity;
93
94 return true;
95 }
96
dmub_rb_front(struct dmub_rb * rb,struct dmub_cmd_header * cmd)97 static inline bool dmub_rb_front(struct dmub_rb *rb,
98 struct dmub_cmd_header *cmd)
99 {
100 uint8_t *rd_ptr = (uint8_t *)rb->base_address + rb->rptr;
101
102 if (dmub_rb_empty(rb))
103 return false;
104
105 dmub_memcpy(cmd, rd_ptr, DMUB_RB_CMD_SIZE);
106
107 return true;
108 }
109
dmub_rb_pop_front(struct dmub_rb * rb)110 static inline bool dmub_rb_pop_front(struct dmub_rb *rb)
111 {
112 if (dmub_rb_empty(rb))
113 return false;
114
115 rb->rptr += DMUB_RB_CMD_SIZE;
116
117 if (rb->rptr >= rb->capacity)
118 rb->rptr %= rb->capacity;
119
120 return true;
121 }
122
dmub_rb_flush_pending(const struct dmub_rb * rb)123 static inline void dmub_rb_flush_pending(const struct dmub_rb *rb)
124 {
125 uint32_t rptr = rb->rptr;
126 uint32_t wptr = rb->wrpt;
127
128 while (rptr != wptr) {
129 uint64_t volatile *data = (uint64_t volatile *)rb->base_address + rptr / sizeof(uint64_t);
130 //uint64_t volatile *p = (uint64_t volatile *)data;
131 uint64_t temp __unused;
132 int i;
133
134 for (i = 0; i < DMUB_RB_CMD_SIZE / sizeof(uint64_t); i++)
135 temp = *data++;
136
137 rptr += DMUB_RB_CMD_SIZE;
138 if (rptr >= rb->capacity)
139 rptr %= rb->capacity;
140 }
141 }
142
dmub_rb_init(struct dmub_rb * rb,struct dmub_rb_init_params * init_params)143 static inline void dmub_rb_init(struct dmub_rb *rb,
144 struct dmub_rb_init_params *init_params)
145 {
146 rb->base_address = init_params->base_address;
147 rb->capacity = init_params->capacity;
148 rb->rptr = 0;
149 rb->wrpt = 0;
150 }
151
152 #if defined(__cplusplus)
153 }
154 #endif
155
156 #endif /* _DMUB_RB_H_ */
157