dcn10_hw_sequencer_debug.c (21634B)
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 48unsigned 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 71static 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_chanage\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_chanage * frac) / ref_clk_mhz / frac, (s->dram_clk_chanage * frac) / ref_clk_mhz % frac); 102 remaining_buffer -= chars_printed; 103 pBuf += chars_printed; 104 } 105 106 return bufSize - remaining_buffer; 107} 108 109static 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 188static 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 230static 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 287static 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 327static 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 382static 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 413static 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 467static 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 488static 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 504static 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 520void 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 541void 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}