1 /* $NetBSD: amdgpu_dcn10_hw_sequencer_debug.c,v 1.3 2021/12/19 11:24:52 riastradh Exp $ */
2
3 /*
4 * Copyright 2016 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 #include <sys/cdefs.h>
29 __KERNEL_RCSID(0, "$NetBSD: amdgpu_dcn10_hw_sequencer_debug.c,v 1.3 2021/12/19 11:24:52 riastradh Exp $");
30
31 #include "dm_services.h"
32 #include "core_types.h"
33 #include "resource.h"
34 #include "custom_float.h"
35 #include "dcn10_hw_sequencer.h"
36 #include "dce110/dce110_hw_sequencer.h"
37 #include "dce/dce_hwseq.h"
38 #include "abm.h"
39 #include "dmcu.h"
40 #include "dcn10_optc.h"
41 #include "dcn10/dcn10_dpp.h"
42 #include "dcn10/dcn10_mpc.h"
43 #include "timing_generator.h"
44 #include "opp.h"
45 #include "ipp.h"
46 #include "mpc.h"
47 #include "reg_helper.h"
48 #include "dcn10_hubp.h"
49 #include "dcn10_hubbub.h"
50 #include "dcn10_cm_common.h"
51 #include "clk_mgr.h"
52
snprintf_count(char * pBuf,unsigned int bufSize,const char * fmt,...)53 unsigned int __printflike(3,4) snprintf_count(char *pBuf, unsigned int bufSize, const char *fmt, ...)
54 {
55 unsigned int ret_vsnprintf;
56 unsigned int chars_printed;
57
58 va_list args;
59 va_start(args, fmt);
60
61 ret_vsnprintf = vsnprintf(pBuf, bufSize, fmt, args);
62
63 va_end(args);
64
65 if (ret_vsnprintf > 0) {
66 if (ret_vsnprintf < bufSize)
67 chars_printed = ret_vsnprintf;
68 else
69 chars_printed = bufSize - 1;
70 } else
71 chars_printed = 0;
72
73 return chars_printed;
74 }
75
dcn10_get_hubbub_state(struct dc * dc,char * pBuf,unsigned int bufSize)76 static unsigned int dcn10_get_hubbub_state(struct dc *dc, char *pBuf, unsigned int bufSize)
77 {
78 struct dc_context *dc_ctx = dc->ctx;
79 struct dcn_hubbub_wm wm;
80 int i;
81
82 unsigned int chars_printed = 0;
83 unsigned int remaining_buffer = bufSize;
84
85 const uint32_t ref_clk_mhz = dc_ctx->dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000;
86 static const unsigned int frac = 1000;
87
88 memset(&wm, 0, sizeof(struct dcn_hubbub_wm));
89 dc->res_pool->hubbub->funcs->wm_read_state(dc->res_pool->hubbub, &wm);
90
91 chars_printed = snprintf_count(pBuf, remaining_buffer, "wm_set_index,data_urgent,pte_meta_urgent,sr_enter,sr_exit,dram_clk_chanage\n");
92 remaining_buffer -= chars_printed;
93 pBuf += chars_printed;
94
95 for (i = 0; i < 4; i++) {
96 struct dcn_hubbub_wm_set *s;
97
98 s = &wm.sets[i];
99
100 chars_printed = snprintf_count(pBuf, remaining_buffer, "%x,%d.%03d,%d.%03d,%d.%03d,%d.%03d,%d.%03d\n",
101 s->wm_set,
102 (s->data_urgent * frac) / ref_clk_mhz / frac, (s->data_urgent * frac) / ref_clk_mhz % frac,
103 (s->pte_meta_urgent * frac) / ref_clk_mhz / frac, (s->pte_meta_urgent * frac) / ref_clk_mhz % frac,
104 (s->sr_enter * frac) / ref_clk_mhz / frac, (s->sr_enter * frac) / ref_clk_mhz % frac,
105 (s->sr_exit * frac) / ref_clk_mhz / frac, (s->sr_exit * frac) / ref_clk_mhz % frac,
106 (s->dram_clk_chanage * frac) / ref_clk_mhz / frac, (s->dram_clk_chanage * frac) / ref_clk_mhz % frac);
107 remaining_buffer -= chars_printed;
108 pBuf += chars_printed;
109 }
110
111 return bufSize - remaining_buffer;
112 }
113
dcn10_get_hubp_states(struct dc * dc,char * pBuf,unsigned int bufSize,bool invarOnly)114 static unsigned int dcn10_get_hubp_states(struct dc *dc, char *pBuf, unsigned int bufSize, bool invarOnly)
115 {
116 struct dc_context *dc_ctx = dc->ctx;
117 struct resource_pool *pool = dc->res_pool;
118 int i;
119
120 unsigned int chars_printed = 0;
121 unsigned int remaining_buffer = bufSize;
122
123 const uint32_t ref_clk_mhz = dc_ctx->dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000;
124 static const unsigned int frac = 1000;
125
126 if (invarOnly)
127 chars_printed = snprintf_count(pBuf, remaining_buffer, "instance,format,addr_hi,width,height,rotation,mirror,sw_mode,dcc_en,blank_en,ttu_dis,underflow,"
128 "min_ttu_vblank,qos_low_wm,qos_high_wm"
129 "\n");
130 else
131 chars_printed = snprintf_count(pBuf, remaining_buffer, "instance,format,addr_hi,addr_lo,width,height,rotation,mirror,sw_mode,dcc_en,blank_en,ttu_dis,underflow,"
132 "min_ttu_vblank,qos_low_wm,qos_high_wm"
133 "\n");
134
135 remaining_buffer -= chars_printed;
136 pBuf += chars_printed;
137
138 for (i = 0; i < pool->pipe_count; i++) {
139 struct hubp *hubp = pool->hubps[i];
140 struct dcn_hubp_state *s = &(TO_DCN10_HUBP(hubp)->state);
141
142 hubp->funcs->hubp_read_state(hubp);
143
144 if (!s->blank_en) {
145 if (invarOnly)
146 chars_printed = snprintf_count(pBuf, remaining_buffer, "%x,%x,%x,%d,%d,%x,%x,%x,%x,%x,%x,%x,"
147 "%d.%03d,%d.%03d,%d.%03d"
148 "\n",
149 hubp->inst,
150 s->pixel_format,
151 s->inuse_addr_hi,
152 s->viewport_width,
153 s->viewport_height,
154 s->rotation_angle,
155 s->h_mirror_en,
156 s->sw_mode,
157 s->dcc_en,
158 s->blank_en,
159 s->ttu_disable,
160 s->underflow_status,
161 (s->min_ttu_vblank * frac) / ref_clk_mhz / frac, (s->min_ttu_vblank * frac) / ref_clk_mhz % frac,
162 (s->qos_level_low_wm * frac) / ref_clk_mhz / frac, (s->qos_level_low_wm * frac) / ref_clk_mhz % frac,
163 (s->qos_level_high_wm * frac) / ref_clk_mhz / frac, (s->qos_level_high_wm * frac) / ref_clk_mhz % frac);
164 else
165 chars_printed = snprintf_count(pBuf, remaining_buffer, "%x,%x,%x,%x,%d,%d,%x,%x,%x,%x,%x,%x,%x,"
166 "%d.%03d,%d.%03d,%d.%03d"
167 "\n",
168 hubp->inst,
169 s->pixel_format,
170 s->inuse_addr_hi,
171 s->inuse_addr_lo,
172 s->viewport_width,
173 s->viewport_height,
174 s->rotation_angle,
175 s->h_mirror_en,
176 s->sw_mode,
177 s->dcc_en,
178 s->blank_en,
179 s->ttu_disable,
180 s->underflow_status,
181 (s->min_ttu_vblank * frac) / ref_clk_mhz / frac, (s->min_ttu_vblank * frac) / ref_clk_mhz % frac,
182 (s->qos_level_low_wm * frac) / ref_clk_mhz / frac, (s->qos_level_low_wm * frac) / ref_clk_mhz % frac,
183 (s->qos_level_high_wm * frac) / ref_clk_mhz / frac, (s->qos_level_high_wm * frac) / ref_clk_mhz % frac);
184
185 remaining_buffer -= chars_printed;
186 pBuf += chars_printed;
187 }
188 }
189
190 return bufSize - remaining_buffer;
191 }
192
dcn10_get_rq_states(struct dc * dc,char * pBuf,unsigned int bufSize)193 static unsigned int dcn10_get_rq_states(struct dc *dc, char *pBuf, unsigned int bufSize)
194 {
195 struct resource_pool *pool = dc->res_pool;
196 int i;
197
198 unsigned int chars_printed = 0;
199 unsigned int remaining_buffer = bufSize;
200
201 chars_printed = snprintf_count(pBuf, remaining_buffer, "instance,drq_exp_m,prq_exp_m,mrq_exp_m,crq_exp_m,plane1_ba,"
202 "luma_chunk_s,luma_min_chu_s,luma_meta_ch_s,luma_min_m_c_s,luma_dpte_gr_s,luma_mpte_gr_s,luma_swath_hei,luma_pte_row_h,"
203 "chroma_chunk_s,chroma_min_chu_s,chroma_meta_ch_s,chroma_min_m_c_s,chroma_dpte_gr_s,chroma_mpte_gr_s,chroma_swath_hei,chroma_pte_row_h"
204 "\n");
205 remaining_buffer -= chars_printed;
206 pBuf += chars_printed;
207
208 for (i = 0; i < pool->pipe_count; i++) {
209 struct dcn_hubp_state *s = &(TO_DCN10_HUBP(pool->hubps[i])->state);
210 struct _vcs_dpi_display_rq_regs_st *rq_regs = &s->rq_regs;
211
212 if (!s->blank_en) {
213 chars_printed = snprintf_count(pBuf, remaining_buffer, "%x,%x,%x,%x,%x,%x,"
214 "%x,%x,%x,%x,%x,%x,%x,%x,"
215 "%x,%x,%x,%x,%x,%x,%x,%x"
216 "\n",
217 pool->hubps[i]->inst, rq_regs->drq_expansion_mode, rq_regs->prq_expansion_mode, rq_regs->mrq_expansion_mode,
218 rq_regs->crq_expansion_mode, rq_regs->plane1_base_address, rq_regs->rq_regs_l.chunk_size,
219 rq_regs->rq_regs_l.min_chunk_size, rq_regs->rq_regs_l.meta_chunk_size,
220 rq_regs->rq_regs_l.min_meta_chunk_size, rq_regs->rq_regs_l.dpte_group_size,
221 rq_regs->rq_regs_l.mpte_group_size, rq_regs->rq_regs_l.swath_height,
222 rq_regs->rq_regs_l.pte_row_height_linear, rq_regs->rq_regs_c.chunk_size, rq_regs->rq_regs_c.min_chunk_size,
223 rq_regs->rq_regs_c.meta_chunk_size, rq_regs->rq_regs_c.min_meta_chunk_size,
224 rq_regs->rq_regs_c.dpte_group_size, rq_regs->rq_regs_c.mpte_group_size,
225 rq_regs->rq_regs_c.swath_height, rq_regs->rq_regs_c.pte_row_height_linear);
226
227 remaining_buffer -= chars_printed;
228 pBuf += chars_printed;
229 }
230 }
231
232 return bufSize - remaining_buffer;
233 }
234
dcn10_get_dlg_states(struct dc * dc,char * pBuf,unsigned int bufSize)235 static unsigned int dcn10_get_dlg_states(struct dc *dc, char *pBuf, unsigned int bufSize)
236 {
237 struct resource_pool *pool = dc->res_pool;
238 int i;
239
240 unsigned int chars_printed = 0;
241 unsigned int remaining_buffer = bufSize;
242
243 chars_printed = snprintf_count(pBuf, remaining_buffer, "instance,rc_hbe,dlg_vbe,min_d_y_n,rc_per_ht,rc_x_a_s,"
244 "dst_y_a_s,dst_y_pf,dst_y_vvb,dst_y_rvb,dst_y_vfl,dst_y_rfl,rf_pix_fq,"
245 "vratio_pf,vrat_pf_c,rc_pg_vbl,rc_pg_vbc,rc_mc_vbl,rc_mc_vbc,rc_pg_fll,"
246 "rc_pg_flc,rc_mc_fll,rc_mc_flc,pr_nom_l,pr_nom_c,rc_pg_nl,rc_pg_nc,"
247 "mr_nom_l,mr_nom_c,rc_mc_nl,rc_mc_nc,rc_ld_pl,rc_ld_pc,rc_ld_l,"
248 "rc_ld_c,cha_cur0,ofst_cur1,cha_cur1,vr_af_vc0,ddrq_limt,x_rt_dlay,x_rp_dlay,x_rr_sfl"
249 "\n");
250 remaining_buffer -= chars_printed;
251 pBuf += chars_printed;
252
253 for (i = 0; i < pool->pipe_count; i++) {
254 struct dcn_hubp_state *s = &(TO_DCN10_HUBP(pool->hubps[i])->state);
255 struct _vcs_dpi_display_dlg_regs_st *dlg_regs = &s->dlg_attr;
256
257 if (!s->blank_en) {
258 chars_printed = snprintf_count(pBuf, remaining_buffer, "%x,%x,%x,%x,%x,"
259 "%x,%x,%x,%x,%x,%x,%x,"
260 "%x,%x,%x,%x,%x,%x,%x,"
261 "%x,%x,%x,%x,%x,%x,%x,"
262 "%x,%x,%x,%x,%x,%x,%x,"
263 "%x,%x,%x,%x,%x,%x,%x,%x,%x,%x"
264 "\n",
265 pool->hubps[i]->inst, dlg_regs->refcyc_h_blank_end, dlg_regs->dlg_vblank_end, dlg_regs->min_dst_y_next_start,
266 dlg_regs->refcyc_per_htotal, dlg_regs->refcyc_x_after_scaler, dlg_regs->dst_y_after_scaler,
267 dlg_regs->dst_y_prefetch, dlg_regs->dst_y_per_vm_vblank, dlg_regs->dst_y_per_row_vblank,
268 dlg_regs->dst_y_per_vm_flip, dlg_regs->dst_y_per_row_flip, dlg_regs->ref_freq_to_pix_freq,
269 dlg_regs->vratio_prefetch, dlg_regs->vratio_prefetch_c, dlg_regs->refcyc_per_pte_group_vblank_l,
270 dlg_regs->refcyc_per_pte_group_vblank_c, dlg_regs->refcyc_per_meta_chunk_vblank_l,
271 dlg_regs->refcyc_per_meta_chunk_vblank_c, dlg_regs->refcyc_per_pte_group_flip_l,
272 dlg_regs->refcyc_per_pte_group_flip_c, dlg_regs->refcyc_per_meta_chunk_flip_l,
273 dlg_regs->refcyc_per_meta_chunk_flip_c, dlg_regs->dst_y_per_pte_row_nom_l,
274 dlg_regs->dst_y_per_pte_row_nom_c, dlg_regs->refcyc_per_pte_group_nom_l,
275 dlg_regs->refcyc_per_pte_group_nom_c, dlg_regs->dst_y_per_meta_row_nom_l,
276 dlg_regs->dst_y_per_meta_row_nom_c, dlg_regs->refcyc_per_meta_chunk_nom_l,
277 dlg_regs->refcyc_per_meta_chunk_nom_c, dlg_regs->refcyc_per_line_delivery_pre_l,
278 dlg_regs->refcyc_per_line_delivery_pre_c, dlg_regs->refcyc_per_line_delivery_l,
279 dlg_regs->refcyc_per_line_delivery_c, dlg_regs->chunk_hdl_adjust_cur0, dlg_regs->dst_y_offset_cur1,
280 dlg_regs->chunk_hdl_adjust_cur1, dlg_regs->vready_after_vcount0, dlg_regs->dst_y_delta_drq_limit,
281 dlg_regs->xfc_reg_transfer_delay, dlg_regs->xfc_reg_precharge_delay,
282 dlg_regs->xfc_reg_remote_surface_flip_latency);
283
284 remaining_buffer -= chars_printed;
285 pBuf += chars_printed;
286 }
287 }
288
289 return bufSize - remaining_buffer;
290 }
291
dcn10_get_ttu_states(struct dc * dc,char * pBuf,unsigned int bufSize)292 static unsigned int dcn10_get_ttu_states(struct dc *dc, char *pBuf, unsigned int bufSize)
293 {
294 struct resource_pool *pool = dc->res_pool;
295 int i;
296
297 unsigned int chars_printed = 0;
298 unsigned int remaining_buffer = bufSize;
299
300 chars_printed = snprintf_count(pBuf, remaining_buffer, "instance,qos_ll_wm,qos_lh_wm,mn_ttu_vb,qos_l_flp,rc_rd_p_l,rc_rd_l,rc_rd_p_c,"
301 "rc_rd_c,rc_rd_c0,rc_rd_pc0,rc_rd_c1,rc_rd_pc1,qos_lf_l,qos_rds_l,"
302 "qos_lf_c,qos_rds_c,qos_lf_c0,qos_rds_c0,qos_lf_c1,qos_rds_c1"
303 "\n");
304 remaining_buffer -= chars_printed;
305 pBuf += chars_printed;
306
307 for (i = 0; i < pool->pipe_count; i++) {
308 struct dcn_hubp_state *s = &(TO_DCN10_HUBP(pool->hubps[i])->state);
309 struct _vcs_dpi_display_ttu_regs_st *ttu_regs = &s->ttu_attr;
310
311 if (!s->blank_en) {
312 chars_printed = snprintf_count(pBuf, remaining_buffer, "%x,%x,%x,%x,%x,%x,%x,%x,"
313 "%x,%x,%x,%x,%x,%x,%x,"
314 "%x,%x,%x,%x,%x,%x"
315 "\n",
316 pool->hubps[i]->inst, ttu_regs->qos_level_low_wm, ttu_regs->qos_level_high_wm, ttu_regs->min_ttu_vblank,
317 ttu_regs->qos_level_flip, ttu_regs->refcyc_per_req_delivery_pre_l, ttu_regs->refcyc_per_req_delivery_l,
318 ttu_regs->refcyc_per_req_delivery_pre_c, ttu_regs->refcyc_per_req_delivery_c, ttu_regs->refcyc_per_req_delivery_cur0,
319 ttu_regs->refcyc_per_req_delivery_pre_cur0, ttu_regs->refcyc_per_req_delivery_cur1,
320 ttu_regs->refcyc_per_req_delivery_pre_cur1, ttu_regs->qos_level_fixed_l, ttu_regs->qos_ramp_disable_l,
321 ttu_regs->qos_level_fixed_c, ttu_regs->qos_ramp_disable_c, ttu_regs->qos_level_fixed_cur0,
322 ttu_regs->qos_ramp_disable_cur0, ttu_regs->qos_level_fixed_cur1, ttu_regs->qos_ramp_disable_cur1);
323
324 remaining_buffer -= chars_printed;
325 pBuf += chars_printed;
326 }
327 }
328
329 return bufSize - remaining_buffer;
330 }
331
dcn10_get_cm_states(struct dc * dc,char * pBuf,unsigned int bufSize)332 static unsigned int dcn10_get_cm_states(struct dc *dc, char *pBuf, unsigned int bufSize)
333 {
334 struct resource_pool *pool = dc->res_pool;
335 int i;
336
337 unsigned int chars_printed = 0;
338 unsigned int remaining_buffer = bufSize;
339
340 chars_printed = snprintf_count(pBuf, remaining_buffer, "instance,igam_format,igam_mode,dgam_mode,rgam_mode,gamut_mode,"
341 "c11_c12,c13_c14,c21_c22,c23_c24,c31_c32,c33_c34"
342 "\n");
343 remaining_buffer -= chars_printed;
344 pBuf += chars_printed;
345
346 for (i = 0; i < pool->pipe_count; i++) {
347 struct dpp *dpp = pool->dpps[i];
348 struct dcn_dpp_state s = {0};
349
350 dpp->funcs->dpp_read_state(dpp, &s);
351
352 if (s.is_enabled) {
353 chars_printed = snprintf_count(pBuf, remaining_buffer, "%x,%x,"
354 "%s,%s,%s,"
355 "%x,%08x,%08x,%08x,%08x,%08x,%08x"
356 "\n",
357 dpp->inst, s.igam_input_format,
358 (s.igam_lut_mode == 0) ? "BypassFixed" :
359 ((s.igam_lut_mode == 1) ? "BypassFloat" :
360 ((s.igam_lut_mode == 2) ? "RAM" :
361 ((s.igam_lut_mode == 3) ? "RAM" :
362 "Unknown"))),
363 (s.dgam_lut_mode == 0) ? "Bypass" :
364 ((s.dgam_lut_mode == 1) ? "sRGB" :
365 ((s.dgam_lut_mode == 2) ? "Ycc" :
366 ((s.dgam_lut_mode == 3) ? "RAM" :
367 ((s.dgam_lut_mode == 4) ? "RAM" :
368 "Unknown")))),
369 (s.rgam_lut_mode == 0) ? "Bypass" :
370 ((s.rgam_lut_mode == 1) ? "sRGB" :
371 ((s.rgam_lut_mode == 2) ? "Ycc" :
372 ((s.rgam_lut_mode == 3) ? "RAM" :
373 ((s.rgam_lut_mode == 4) ? "RAM" :
374 "Unknown")))),
375 s.gamut_remap_mode, s.gamut_remap_c11_c12,
376 s.gamut_remap_c13_c14, s.gamut_remap_c21_c22, s.gamut_remap_c23_c24,
377 s.gamut_remap_c31_c32, s.gamut_remap_c33_c34);
378
379 remaining_buffer -= chars_printed;
380 pBuf += chars_printed;
381 }
382 }
383
384 return bufSize - remaining_buffer;
385 }
386
dcn10_get_mpcc_states(struct dc * dc,char * pBuf,unsigned int bufSize)387 static unsigned int dcn10_get_mpcc_states(struct dc *dc, char *pBuf, unsigned int bufSize)
388 {
389 struct resource_pool *pool = dc->res_pool;
390 int i;
391
392 unsigned int chars_printed = 0;
393 unsigned int remaining_buffer = bufSize;
394
395 chars_printed = snprintf_count(pBuf, remaining_buffer, "instance,opp,dpp,mpccbot,mode,alpha_mode,premult,overlap_only,idle\n");
396 remaining_buffer -= chars_printed;
397 pBuf += chars_printed;
398
399 for (i = 0; i < pool->pipe_count; i++) {
400 struct mpcc_state s = {0};
401
402 pool->mpc->funcs->read_mpcc_state(pool->mpc, i, &s);
403
404 if (s.opp_id != 0xf) {
405 chars_printed = snprintf_count(pBuf, remaining_buffer, "%x,%x,%x,%x,%x,%x,%x,%x,%x\n",
406 i, s.opp_id, s.dpp_id, s.bot_mpcc_id,
407 s.mode, s.alpha_mode, s.pre_multiplied_alpha, s.overlap_only,
408 s.idle);
409
410 remaining_buffer -= chars_printed;
411 pBuf += chars_printed;
412 }
413 }
414
415 return bufSize - remaining_buffer;
416 }
417
dcn10_get_otg_states(struct dc * dc,char * pBuf,unsigned int bufSize)418 static unsigned int dcn10_get_otg_states(struct dc *dc, char *pBuf, unsigned int bufSize)
419 {
420 struct resource_pool *pool = dc->res_pool;
421 int i;
422
423 unsigned int chars_printed = 0;
424 unsigned int remaining_buffer = bufSize;
425
426 chars_printed = snprintf_count(pBuf, remaining_buffer, "instance,v_bs,v_be,v_ss,v_se,vpol,vmax,vmin,vmax_sel,vmin_sel,"
427 "h_bs,h_be,h_ss,h_se,hpol,htot,vtot,underflow,pixelclk[khz]\n");
428 remaining_buffer -= chars_printed;
429 pBuf += chars_printed;
430
431 for (i = 0; i < pool->timing_generator_count; i++) {
432 struct timing_generator *tg = pool->timing_generators[i];
433 struct dcn_otg_state s = {0};
434 int pix_clk = 0;
435
436 optc1_read_otg_state(DCN10TG_FROM_TG(tg), &s);
437 pix_clk = dc->current_state->res_ctx.pipe_ctx[i].stream_res.pix_clk_params.requested_pix_clk_100hz / 10;
438
439 //only print if OTG master is enabled
440 if (s.otg_enabled & 1) {
441 chars_printed = snprintf_count(pBuf, remaining_buffer, "%x,%d,%d,%d,%d,%d,%d,%d,%d,%d,"
442 "%d,%d,%d,%d,%d,%d,%d,%d,%d"
443 "\n",
444 tg->inst,
445 s.v_blank_start,
446 s.v_blank_end,
447 s.v_sync_a_start,
448 s.v_sync_a_end,
449 s.v_sync_a_pol,
450 s.v_total_max,
451 s.v_total_min,
452 s.v_total_max_sel,
453 s.v_total_min_sel,
454 s.h_blank_start,
455 s.h_blank_end,
456 s.h_sync_a_start,
457 s.h_sync_a_end,
458 s.h_sync_a_pol,
459 s.h_total,
460 s.v_total,
461 s.underflow_occurred_status,
462 pix_clk);
463
464 remaining_buffer -= chars_printed;
465 pBuf += chars_printed;
466 }
467 }
468
469 return bufSize - remaining_buffer;
470 }
471
dcn10_get_clock_states(struct dc * dc,char * pBuf,unsigned int bufSize)472 static unsigned int dcn10_get_clock_states(struct dc *dc, char *pBuf, unsigned int bufSize)
473 {
474 unsigned int chars_printed = 0;
475 unsigned int remaining_buffer = bufSize;
476
477 chars_printed = snprintf_count(pBuf, bufSize, "dcfclk,dcfclk_deep_sleep,dispclk,"
478 "dppclk,fclk,socclk\n"
479 "%d,%d,%d,%d,%d,%d\n",
480 dc->current_state->bw_ctx.bw.dcn.clk.dcfclk_khz,
481 dc->current_state->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz,
482 dc->current_state->bw_ctx.bw.dcn.clk.dispclk_khz,
483 dc->current_state->bw_ctx.bw.dcn.clk.dppclk_khz,
484 dc->current_state->bw_ctx.bw.dcn.clk.fclk_khz,
485 dc->current_state->bw_ctx.bw.dcn.clk.socclk_khz);
486
487 remaining_buffer -= chars_printed;
488 pBuf += chars_printed;
489
490 return bufSize - remaining_buffer;
491 }
492
dcn10_clear_otpc_underflow(struct dc * dc)493 static void dcn10_clear_otpc_underflow(struct dc *dc)
494 {
495 struct resource_pool *pool = dc->res_pool;
496 int i;
497
498 for (i = 0; i < pool->timing_generator_count; i++) {
499 struct timing_generator *tg = pool->timing_generators[i];
500 struct dcn_otg_state s = {0};
501
502 optc1_read_otg_state(DCN10TG_FROM_TG(tg), &s);
503
504 if (s.otg_enabled & 1)
505 tg->funcs->clear_optc_underflow(tg);
506 }
507 }
508
dcn10_clear_hubp_underflow(struct dc * dc)509 static void dcn10_clear_hubp_underflow(struct dc *dc)
510 {
511 struct resource_pool *pool = dc->res_pool;
512 int i;
513
514 for (i = 0; i < pool->pipe_count; i++) {
515 struct hubp *hubp = pool->hubps[i];
516 struct dcn_hubp_state *s = &(TO_DCN10_HUBP(hubp)->state);
517
518 hubp->funcs->hubp_read_state(hubp);
519
520 if (!s->blank_en)
521 hubp->funcs->hubp_clear_underflow(hubp);
522 }
523 }
524
dcn10_clear_status_bits(struct dc * dc,unsigned int mask)525 void dcn10_clear_status_bits(struct dc *dc, unsigned int mask)
526 {
527 /*
528 * Mask Format
529 * Bit 0 - 31: Status bit to clear
530 *
531 * Mask = 0x0 means clear all status bits
532 */
533 const unsigned int DC_HW_STATE_MASK_HUBP_UNDERFLOW = 0x1;
534 const unsigned int DC_HW_STATE_MASK_OTPC_UNDERFLOW = 0x2;
535
536 if (mask == 0x0)
537 mask = 0xFFFFFFFF;
538
539 if (mask & DC_HW_STATE_MASK_HUBP_UNDERFLOW)
540 dcn10_clear_hubp_underflow(dc);
541
542 if (mask & DC_HW_STATE_MASK_OTPC_UNDERFLOW)
543 dcn10_clear_otpc_underflow(dc);
544 }
545
dcn10_get_hw_state(struct dc * dc,char * pBuf,unsigned int bufSize,unsigned int mask)546 void dcn10_get_hw_state(struct dc *dc, char *pBuf, unsigned int bufSize, unsigned int mask)
547 {
548 /*
549 * Mask Format
550 * Bit 0 - 15: Hardware block mask
551 * Bit 15: 1 = Invariant Only, 0 = All
552 */
553 const unsigned int DC_HW_STATE_MASK_HUBBUB = 0x1;
554 const unsigned int DC_HW_STATE_MASK_HUBP = 0x2;
555 const unsigned int DC_HW_STATE_MASK_RQ = 0x4;
556 const unsigned int DC_HW_STATE_MASK_DLG = 0x8;
557 const unsigned int DC_HW_STATE_MASK_TTU = 0x10;
558 const unsigned int DC_HW_STATE_MASK_CM = 0x20;
559 const unsigned int DC_HW_STATE_MASK_MPCC = 0x40;
560 const unsigned int DC_HW_STATE_MASK_OTG = 0x80;
561 const unsigned int DC_HW_STATE_MASK_CLOCKS = 0x100;
562 const unsigned int DC_HW_STATE_INVAR_ONLY = 0x8000;
563
564 unsigned int chars_printed = 0;
565 unsigned int remaining_buf_size = bufSize;
566
567 if (mask == 0x0)
568 mask = 0xFFFF; // Default, capture all, invariant only
569
570 if ((mask & DC_HW_STATE_MASK_HUBBUB) && remaining_buf_size > 0) {
571 chars_printed = dcn10_get_hubbub_state(dc, pBuf, remaining_buf_size);
572 pBuf += chars_printed;
573 remaining_buf_size -= chars_printed;
574 }
575
576 if ((mask & DC_HW_STATE_MASK_HUBP) && remaining_buf_size > 0) {
577 chars_printed = dcn10_get_hubp_states(dc, pBuf, remaining_buf_size, mask & DC_HW_STATE_INVAR_ONLY);
578 pBuf += chars_printed;
579 remaining_buf_size -= chars_printed;
580 }
581
582 if ((mask & DC_HW_STATE_MASK_RQ) && remaining_buf_size > 0) {
583 chars_printed = dcn10_get_rq_states(dc, pBuf, remaining_buf_size);
584 pBuf += chars_printed;
585 remaining_buf_size -= chars_printed;
586 }
587
588 if ((mask & DC_HW_STATE_MASK_DLG) && remaining_buf_size > 0) {
589 chars_printed = dcn10_get_dlg_states(dc, pBuf, remaining_buf_size);
590 pBuf += chars_printed;
591 remaining_buf_size -= chars_printed;
592 }
593
594 if ((mask & DC_HW_STATE_MASK_TTU) && remaining_buf_size > 0) {
595 chars_printed = dcn10_get_ttu_states(dc, pBuf, remaining_buf_size);
596 pBuf += chars_printed;
597 remaining_buf_size -= chars_printed;
598 }
599
600 if ((mask & DC_HW_STATE_MASK_CM) && remaining_buf_size > 0) {
601 chars_printed = dcn10_get_cm_states(dc, pBuf, remaining_buf_size);
602 pBuf += chars_printed;
603 remaining_buf_size -= chars_printed;
604 }
605
606 if ((mask & DC_HW_STATE_MASK_MPCC) && remaining_buf_size > 0) {
607 chars_printed = dcn10_get_mpcc_states(dc, pBuf, remaining_buf_size);
608 pBuf += chars_printed;
609 remaining_buf_size -= chars_printed;
610 }
611
612 if ((mask & DC_HW_STATE_MASK_OTG) && remaining_buf_size > 0) {
613 chars_printed = dcn10_get_otg_states(dc, pBuf, remaining_buf_size);
614 pBuf += chars_printed;
615 remaining_buf_size -= chars_printed;
616 }
617
618 if ((mask & DC_HW_STATE_MASK_CLOCKS) && remaining_buf_size > 0) {
619 chars_printed = dcn10_get_clock_states(dc, pBuf, remaining_buf_size);
620 pBuf += chars_printed;
621 remaining_buf_size -= chars_printed;
622 }
623 }
624