1 | /* |
2 | * Copyright 2020 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 | |
27 | #include "dc_bios_types.h" |
28 | #include "dcn30_vpg.h" |
29 | #include "reg_helper.h" |
30 | |
31 | #define DC_LOGGER \ |
32 | vpg3->base.ctx->logger |
33 | |
34 | #define REG(reg)\ |
35 | (vpg3->regs->reg) |
36 | |
37 | #undef FN |
38 | #define FN(reg_name, field_name) \ |
39 | vpg3->vpg_shift->field_name, vpg3->vpg_mask->field_name |
40 | |
41 | |
42 | #define CTX \ |
43 | vpg3->base.ctx |
44 | |
45 | |
46 | void vpg3_update_generic_info_packet( |
47 | struct vpg *vpg, |
48 | uint32_t packet_index, |
49 | const struct dc_info_packet *info_packet, |
50 | bool immediate_update) |
51 | { |
52 | struct dcn30_vpg *vpg3 = DCN30_VPG_FROM_VPG(vpg); |
53 | uint32_t i; |
54 | |
55 | /* TODOFPGA Figure out a proper number for max_retries polling for lock |
56 | * use 50 for now. |
57 | */ |
58 | uint32_t max_retries = 50; |
59 | |
60 | if (packet_index > 14) |
61 | ASSERT(0); |
62 | |
63 | /* poll dig_update_lock is not locked -> asic internal signal |
64 | * assume otg master lock will unlock it |
65 | */ |
66 | /* REG_WAIT(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_LOCK_STATUS, |
67 | * 0, 10, max_retries); |
68 | */ |
69 | |
70 | /* TODO: Check if this is required */ |
71 | /* check if HW reading GSP memory */ |
72 | REG_WAIT(VPG_GENERIC_STATUS, VPG_GENERIC_CONFLICT_OCCURED, |
73 | 0, 10, max_retries); |
74 | |
75 | /* HW does is not reading GSP memory not reading too long -> |
76 | * something wrong. clear GPS memory access and notify? |
77 | * hw SW is writing to GSP memory |
78 | */ |
79 | REG_UPDATE(VPG_GENERIC_STATUS, VPG_GENERIC_CONFLICT_CLR, 1); |
80 | |
81 | /* choose which generic packet to use */ |
82 | REG_UPDATE(VPG_GENERIC_PACKET_ACCESS_CTRL, |
83 | VPG_GENERIC_DATA_INDEX, packet_index*9); |
84 | |
85 | /* write generic packet header |
86 | * (4th byte is for GENERIC0 only) |
87 | */ |
88 | REG_SET_4(VPG_GENERIC_PACKET_DATA, 0, |
89 | VPG_GENERIC_DATA_BYTE0, info_packet->hb0, |
90 | VPG_GENERIC_DATA_BYTE1, info_packet->hb1, |
91 | VPG_GENERIC_DATA_BYTE2, info_packet->hb2, |
92 | VPG_GENERIC_DATA_BYTE3, info_packet->hb3); |
93 | |
94 | /* write generic packet contents |
95 | * (we never use last 4 bytes) |
96 | * there are 8 (0-7) mmDIG0_AFMT_GENERIC0_x registers |
97 | */ |
98 | { |
99 | const uint32_t *content = |
100 | (const uint32_t *) &info_packet->sb[0]; |
101 | |
102 | for (i = 0; i < 8; i++) { |
103 | REG_WRITE(VPG_GENERIC_PACKET_DATA, *content++); |
104 | } |
105 | } |
106 | |
107 | /* atomically update double-buffered GENERIC0 registers in immediate mode |
108 | * (update at next block_update when block_update_lock == 0). |
109 | */ |
110 | if (immediate_update) { |
111 | switch (packet_index) { |
112 | case 0: |
113 | REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, |
114 | VPG_GENERIC0_IMMEDIATE_UPDATE, 1); |
115 | break; |
116 | case 1: |
117 | REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, |
118 | VPG_GENERIC1_IMMEDIATE_UPDATE, 1); |
119 | break; |
120 | case 2: |
121 | REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, |
122 | VPG_GENERIC2_IMMEDIATE_UPDATE, 1); |
123 | break; |
124 | case 3: |
125 | REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, |
126 | VPG_GENERIC3_IMMEDIATE_UPDATE, 1); |
127 | break; |
128 | case 4: |
129 | REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, |
130 | VPG_GENERIC4_IMMEDIATE_UPDATE, 1); |
131 | break; |
132 | case 5: |
133 | REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, |
134 | VPG_GENERIC5_IMMEDIATE_UPDATE, 1); |
135 | break; |
136 | case 6: |
137 | REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, |
138 | VPG_GENERIC6_IMMEDIATE_UPDATE, 1); |
139 | break; |
140 | case 7: |
141 | REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, |
142 | VPG_GENERIC7_IMMEDIATE_UPDATE, 1); |
143 | break; |
144 | case 8: |
145 | REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, |
146 | VPG_GENERIC8_IMMEDIATE_UPDATE, 1); |
147 | break; |
148 | case 9: |
149 | REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, |
150 | VPG_GENERIC9_IMMEDIATE_UPDATE, 1); |
151 | break; |
152 | case 10: |
153 | REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, |
154 | VPG_GENERIC10_IMMEDIATE_UPDATE, 1); |
155 | break; |
156 | case 11: |
157 | REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, |
158 | VPG_GENERIC11_IMMEDIATE_UPDATE, 1); |
159 | break; |
160 | case 12: |
161 | REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, |
162 | VPG_GENERIC12_IMMEDIATE_UPDATE, 1); |
163 | break; |
164 | case 13: |
165 | REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, |
166 | VPG_GENERIC13_IMMEDIATE_UPDATE, 1); |
167 | break; |
168 | case 14: |
169 | REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, |
170 | VPG_GENERIC14_IMMEDIATE_UPDATE, 1); |
171 | break; |
172 | default: |
173 | break; |
174 | } |
175 | } else { |
176 | switch (packet_index) { |
177 | case 0: |
178 | REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, |
179 | VPG_GENERIC0_FRAME_UPDATE, 1); |
180 | break; |
181 | case 1: |
182 | REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, |
183 | VPG_GENERIC1_FRAME_UPDATE, 1); |
184 | break; |
185 | case 2: |
186 | REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, |
187 | VPG_GENERIC2_FRAME_UPDATE, 1); |
188 | break; |
189 | case 3: |
190 | REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, |
191 | VPG_GENERIC3_FRAME_UPDATE, 1); |
192 | break; |
193 | case 4: |
194 | REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, |
195 | VPG_GENERIC4_FRAME_UPDATE, 1); |
196 | break; |
197 | case 5: |
198 | REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, |
199 | VPG_GENERIC5_FRAME_UPDATE, 1); |
200 | break; |
201 | case 6: |
202 | REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, |
203 | VPG_GENERIC6_FRAME_UPDATE, 1); |
204 | break; |
205 | case 7: |
206 | REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, |
207 | VPG_GENERIC7_FRAME_UPDATE, 1); |
208 | break; |
209 | case 8: |
210 | REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, |
211 | VPG_GENERIC8_FRAME_UPDATE, 1); |
212 | break; |
213 | case 9: |
214 | REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, |
215 | VPG_GENERIC9_FRAME_UPDATE, 1); |
216 | break; |
217 | case 10: |
218 | REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, |
219 | VPG_GENERIC10_FRAME_UPDATE, 1); |
220 | break; |
221 | case 11: |
222 | REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, |
223 | VPG_GENERIC11_FRAME_UPDATE, 1); |
224 | break; |
225 | case 12: |
226 | REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, |
227 | VPG_GENERIC12_FRAME_UPDATE, 1); |
228 | break; |
229 | case 13: |
230 | REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, |
231 | VPG_GENERIC13_FRAME_UPDATE, 1); |
232 | break; |
233 | case 14: |
234 | REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, |
235 | VPG_GENERIC14_FRAME_UPDATE, 1); |
236 | break; |
237 | |
238 | default: |
239 | break; |
240 | } |
241 | |
242 | } |
243 | } |
244 | |
245 | static struct vpg_funcs dcn30_vpg_funcs = { |
246 | .update_generic_info_packet = vpg3_update_generic_info_packet, |
247 | }; |
248 | |
249 | void vpg3_construct(struct dcn30_vpg *vpg3, |
250 | struct dc_context *ctx, |
251 | uint32_t inst, |
252 | const struct dcn30_vpg_registers *vpg_regs, |
253 | const struct dcn30_vpg_shift *vpg_shift, |
254 | const struct dcn30_vpg_mask *vpg_mask) |
255 | { |
256 | vpg3->base.ctx = ctx; |
257 | |
258 | vpg3->base.inst = inst; |
259 | vpg3->base.funcs = &dcn30_vpg_funcs; |
260 | |
261 | vpg3->regs = vpg_regs; |
262 | vpg3->vpg_shift = vpg_shift; |
263 | vpg3->vpg_mask = vpg_mask; |
264 | } |
265 | |