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