xref: /netbsd-src/sys/external/bsd/drm2/dist/drm/amd/display/dmub/inc/dmub_rb.h (revision e4a580baf2598beeaae98d953ac7635b8700b80c)
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