cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

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}