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 53unsigned 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 76static 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 114static 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 193static 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 235static 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 292static 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 332static 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 387static 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 418static 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 472static 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 493static 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 509static 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 525void 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 546void 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