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