Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2016 Advanced Micro Devices, Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  *
0022  * Authors: AMD
0023  *
0024  */
0025 
0026 #include "dm_services.h"
0027 #include "core_types.h"
0028 #include "resource.h"
0029 #include "custom_float.h"
0030 #include "dcn10_hw_sequencer.h"
0031 #include "dce110/dce110_hw_sequencer.h"
0032 #include "dce/dce_hwseq.h"
0033 #include "abm.h"
0034 #include "dmcu.h"
0035 #include "dcn10_optc.h"
0036 #include "dcn10/dcn10_dpp.h"
0037 #include "dcn10/dcn10_mpc.h"
0038 #include "timing_generator.h"
0039 #include "opp.h"
0040 #include "ipp.h"
0041 #include "mpc.h"
0042 #include "reg_helper.h"
0043 #include "dcn10_hubp.h"
0044 #include "dcn10_hubbub.h"
0045 #include "dcn10_cm_common.h"
0046 #include "clk_mgr.h"
0047 
0048 unsigned int snprintf_count(char *pBuf, unsigned int bufSize, char *fmt, ...)
0049 {
0050     int ret_vsnprintf;
0051     unsigned int chars_printed;
0052 
0053     va_list args;
0054     va_start(args, fmt);
0055 
0056     ret_vsnprintf = vsnprintf(pBuf, bufSize, fmt, args);
0057 
0058     va_end(args);
0059 
0060     if (ret_vsnprintf > 0) {
0061         if (ret_vsnprintf < bufSize)
0062             chars_printed = ret_vsnprintf;
0063         else
0064             chars_printed = bufSize - 1;
0065     } else
0066         chars_printed = 0;
0067 
0068     return chars_printed;
0069 }
0070 
0071 static unsigned int dcn10_get_hubbub_state(struct dc *dc, char *pBuf, unsigned int bufSize)
0072 {
0073     struct dc_context *dc_ctx = dc->ctx;
0074     struct dcn_hubbub_wm wm;
0075     int i;
0076 
0077     unsigned int chars_printed = 0;
0078     unsigned int remaining_buffer = bufSize;
0079 
0080     const uint32_t ref_clk_mhz = dc_ctx->dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000;
0081     static const unsigned int frac = 1000;
0082 
0083     memset(&wm, 0, sizeof(struct dcn_hubbub_wm));
0084     dc->res_pool->hubbub->funcs->wm_read_state(dc->res_pool->hubbub, &wm);
0085 
0086     chars_printed = snprintf_count(pBuf, remaining_buffer, "wm_set_index,data_urgent,pte_meta_urgent,sr_enter,sr_exit,dram_clk_chanage\n");
0087     remaining_buffer -= chars_printed;
0088     pBuf += chars_printed;
0089 
0090     for (i = 0; i < 4; i++) {
0091         struct dcn_hubbub_wm_set *s;
0092 
0093         s = &wm.sets[i];
0094 
0095         chars_printed = snprintf_count(pBuf, remaining_buffer, "%x,%d.%03d,%d.%03d,%d.%03d,%d.%03d,%d.%03d\n",
0096             s->wm_set,
0097             (s->data_urgent * frac) / ref_clk_mhz / frac, (s->data_urgent * frac) / ref_clk_mhz % frac,
0098             (s->pte_meta_urgent * frac) / ref_clk_mhz / frac, (s->pte_meta_urgent * frac) / ref_clk_mhz % frac,
0099             (s->sr_enter * frac) / ref_clk_mhz / frac, (s->sr_enter * frac) / ref_clk_mhz % frac,
0100             (s->sr_exit * frac) / ref_clk_mhz / frac, (s->sr_exit * frac) / ref_clk_mhz % frac,
0101             (s->dram_clk_chanage * frac) / ref_clk_mhz / frac, (s->dram_clk_chanage * frac) / ref_clk_mhz % frac);
0102         remaining_buffer -= chars_printed;
0103         pBuf += chars_printed;
0104     }
0105 
0106     return bufSize - remaining_buffer;
0107 }
0108 
0109 static unsigned int dcn10_get_hubp_states(struct dc *dc, char *pBuf, unsigned int bufSize, bool invarOnly)
0110 {
0111     struct dc_context *dc_ctx = dc->ctx;
0112     struct resource_pool *pool = dc->res_pool;
0113     int i;
0114 
0115     unsigned int chars_printed = 0;
0116     unsigned int remaining_buffer = bufSize;
0117 
0118     const uint32_t ref_clk_mhz = dc_ctx->dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000;
0119     static const unsigned int frac = 1000;
0120 
0121     if (invarOnly)
0122         chars_printed = snprintf_count(pBuf, remaining_buffer, "instance,format,addr_hi,width,height,rotation,mirror,sw_mode,dcc_en,blank_en,ttu_dis,underflow,"
0123             "min_ttu_vblank,qos_low_wm,qos_high_wm"
0124             "\n");
0125     else
0126         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,"
0127                     "min_ttu_vblank,qos_low_wm,qos_high_wm"
0128                     "\n");
0129 
0130     remaining_buffer -= chars_printed;
0131     pBuf += chars_printed;
0132 
0133     for (i = 0; i < pool->pipe_count; i++) {
0134         struct hubp *hubp = pool->hubps[i];
0135         struct dcn_hubp_state *s = &(TO_DCN10_HUBP(hubp)->state);
0136 
0137         hubp->funcs->hubp_read_state(hubp);
0138 
0139         if (!s->blank_en) {
0140             if (invarOnly)
0141                 chars_printed = snprintf_count(pBuf, remaining_buffer, "%x,%x,%x,%d,%d,%x,%x,%x,%x,%x,%x,%x,"
0142                     "%d.%03d,%d.%03d,%d.%03d"
0143                     "\n",
0144                     hubp->inst,
0145                     s->pixel_format,
0146                     s->inuse_addr_hi,
0147                     s->viewport_width,
0148                     s->viewport_height,
0149                     s->rotation_angle,
0150                     s->h_mirror_en,
0151                     s->sw_mode,
0152                     s->dcc_en,
0153                     s->blank_en,
0154                     s->ttu_disable,
0155                     s->underflow_status,
0156                     (s->min_ttu_vblank * frac) / ref_clk_mhz / frac, (s->min_ttu_vblank * frac) / ref_clk_mhz % frac,
0157                     (s->qos_level_low_wm * frac) / ref_clk_mhz / frac, (s->qos_level_low_wm * frac) / ref_clk_mhz % frac,
0158                     (s->qos_level_high_wm * frac) / ref_clk_mhz / frac, (s->qos_level_high_wm * frac) / ref_clk_mhz % frac);
0159             else
0160                 chars_printed = snprintf_count(pBuf, remaining_buffer, "%x,%x,%x,%x,%d,%d,%x,%x,%x,%x,%x,%x,%x,"
0161                     "%d.%03d,%d.%03d,%d.%03d"
0162                     "\n",
0163                     hubp->inst,
0164                     s->pixel_format,
0165                     s->inuse_addr_hi,
0166                     s->inuse_addr_lo,
0167                     s->viewport_width,
0168                     s->viewport_height,
0169                     s->rotation_angle,
0170                     s->h_mirror_en,
0171                     s->sw_mode,
0172                     s->dcc_en,
0173                     s->blank_en,
0174                     s->ttu_disable,
0175                     s->underflow_status,
0176                     (s->min_ttu_vblank * frac) / ref_clk_mhz / frac, (s->min_ttu_vblank * frac) / ref_clk_mhz % frac,
0177                     (s->qos_level_low_wm * frac) / ref_clk_mhz / frac, (s->qos_level_low_wm * frac) / ref_clk_mhz % frac,
0178                     (s->qos_level_high_wm * frac) / ref_clk_mhz / frac, (s->qos_level_high_wm * frac) / ref_clk_mhz % frac);
0179 
0180             remaining_buffer -= chars_printed;
0181             pBuf += chars_printed;
0182         }
0183     }
0184 
0185     return bufSize - remaining_buffer;
0186 }
0187 
0188 static unsigned int dcn10_get_rq_states(struct dc *dc, char *pBuf, unsigned int bufSize)
0189 {
0190     struct resource_pool *pool = dc->res_pool;
0191     int i;
0192 
0193     unsigned int chars_printed = 0;
0194     unsigned int remaining_buffer = bufSize;
0195 
0196     chars_printed = snprintf_count(pBuf, remaining_buffer, "instance,drq_exp_m,prq_exp_m,mrq_exp_m,crq_exp_m,plane1_ba,"
0197         "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,"
0198         "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"
0199         "\n");
0200     remaining_buffer -= chars_printed;
0201     pBuf += chars_printed;
0202 
0203     for (i = 0; i < pool->pipe_count; i++) {
0204         struct dcn_hubp_state *s = &(TO_DCN10_HUBP(pool->hubps[i])->state);
0205         struct _vcs_dpi_display_rq_regs_st *rq_regs = &s->rq_regs;
0206 
0207         if (!s->blank_en) {
0208             chars_printed = snprintf_count(pBuf, remaining_buffer, "%x,%x,%x,%x,%x,%x,"
0209                 "%x,%x,%x,%x,%x,%x,%x,%x,"
0210                 "%x,%x,%x,%x,%x,%x,%x,%x"
0211                 "\n",
0212                 pool->hubps[i]->inst, rq_regs->drq_expansion_mode, rq_regs->prq_expansion_mode, rq_regs->mrq_expansion_mode,
0213                 rq_regs->crq_expansion_mode, rq_regs->plane1_base_address, rq_regs->rq_regs_l.chunk_size,
0214                 rq_regs->rq_regs_l.min_chunk_size, rq_regs->rq_regs_l.meta_chunk_size,
0215                 rq_regs->rq_regs_l.min_meta_chunk_size, rq_regs->rq_regs_l.dpte_group_size,
0216                 rq_regs->rq_regs_l.mpte_group_size, rq_regs->rq_regs_l.swath_height,
0217                 rq_regs->rq_regs_l.pte_row_height_linear, rq_regs->rq_regs_c.chunk_size, rq_regs->rq_regs_c.min_chunk_size,
0218                 rq_regs->rq_regs_c.meta_chunk_size, rq_regs->rq_regs_c.min_meta_chunk_size,
0219                 rq_regs->rq_regs_c.dpte_group_size, rq_regs->rq_regs_c.mpte_group_size,
0220                 rq_regs->rq_regs_c.swath_height, rq_regs->rq_regs_c.pte_row_height_linear);
0221 
0222             remaining_buffer -= chars_printed;
0223             pBuf += chars_printed;
0224         }
0225     }
0226 
0227     return bufSize - remaining_buffer;
0228 }
0229 
0230 static unsigned int dcn10_get_dlg_states(struct dc *dc, char *pBuf, unsigned int bufSize)
0231 {
0232     struct resource_pool *pool = dc->res_pool;
0233     int i;
0234 
0235     unsigned int chars_printed = 0;
0236     unsigned int remaining_buffer = bufSize;
0237 
0238     chars_printed = snprintf_count(pBuf, remaining_buffer, "instance,rc_hbe,dlg_vbe,min_d_y_n,rc_per_ht,rc_x_a_s,"
0239         "dst_y_a_s,dst_y_pf,dst_y_vvb,dst_y_rvb,dst_y_vfl,dst_y_rfl,rf_pix_fq,"
0240         "vratio_pf,vrat_pf_c,rc_pg_vbl,rc_pg_vbc,rc_mc_vbl,rc_mc_vbc,rc_pg_fll,"
0241         "rc_pg_flc,rc_mc_fll,rc_mc_flc,pr_nom_l,pr_nom_c,rc_pg_nl,rc_pg_nc,"
0242         "mr_nom_l,mr_nom_c,rc_mc_nl,rc_mc_nc,rc_ld_pl,rc_ld_pc,rc_ld_l,"
0243         "rc_ld_c,cha_cur0,ofst_cur1,cha_cur1,vr_af_vc0,ddrq_limt,x_rt_dlay,x_rp_dlay,x_rr_sfl"
0244         "\n");
0245     remaining_buffer -= chars_printed;
0246     pBuf += chars_printed;
0247 
0248     for (i = 0; i < pool->pipe_count; i++) {
0249         struct dcn_hubp_state *s = &(TO_DCN10_HUBP(pool->hubps[i])->state);
0250         struct _vcs_dpi_display_dlg_regs_st *dlg_regs = &s->dlg_attr;
0251 
0252         if (!s->blank_en) {
0253             chars_printed = snprintf_count(pBuf, remaining_buffer, "%x,%x,%x,%x,%x,"
0254                 "%x,%x,%x,%x,%x,%x,%x,"
0255                 "%x,%x,%x,%x,%x,%x,%x,"
0256                 "%x,%x,%x,%x,%x,%x,%x,"
0257                 "%x,%x,%x,%x,%x,%x,%x,"
0258                 "%x,%x,%x,%x,%x,%x,%x,%x,%x,%x"
0259                 "\n",
0260                 pool->hubps[i]->inst, dlg_regs->refcyc_h_blank_end, dlg_regs->dlg_vblank_end, dlg_regs->min_dst_y_next_start,
0261                 dlg_regs->refcyc_per_htotal, dlg_regs->refcyc_x_after_scaler, dlg_regs->dst_y_after_scaler,
0262                 dlg_regs->dst_y_prefetch, dlg_regs->dst_y_per_vm_vblank, dlg_regs->dst_y_per_row_vblank,
0263                 dlg_regs->dst_y_per_vm_flip, dlg_regs->dst_y_per_row_flip, dlg_regs->ref_freq_to_pix_freq,
0264                 dlg_regs->vratio_prefetch, dlg_regs->vratio_prefetch_c, dlg_regs->refcyc_per_pte_group_vblank_l,
0265                 dlg_regs->refcyc_per_pte_group_vblank_c, dlg_regs->refcyc_per_meta_chunk_vblank_l,
0266                 dlg_regs->refcyc_per_meta_chunk_vblank_c, dlg_regs->refcyc_per_pte_group_flip_l,
0267                 dlg_regs->refcyc_per_pte_group_flip_c, dlg_regs->refcyc_per_meta_chunk_flip_l,
0268                 dlg_regs->refcyc_per_meta_chunk_flip_c, dlg_regs->dst_y_per_pte_row_nom_l,
0269                 dlg_regs->dst_y_per_pte_row_nom_c, dlg_regs->refcyc_per_pte_group_nom_l,
0270                 dlg_regs->refcyc_per_pte_group_nom_c, dlg_regs->dst_y_per_meta_row_nom_l,
0271                 dlg_regs->dst_y_per_meta_row_nom_c, dlg_regs->refcyc_per_meta_chunk_nom_l,
0272                 dlg_regs->refcyc_per_meta_chunk_nom_c, dlg_regs->refcyc_per_line_delivery_pre_l,
0273                 dlg_regs->refcyc_per_line_delivery_pre_c, dlg_regs->refcyc_per_line_delivery_l,
0274                 dlg_regs->refcyc_per_line_delivery_c, dlg_regs->chunk_hdl_adjust_cur0, dlg_regs->dst_y_offset_cur1,
0275                 dlg_regs->chunk_hdl_adjust_cur1, dlg_regs->vready_after_vcount0, dlg_regs->dst_y_delta_drq_limit,
0276                 dlg_regs->xfc_reg_transfer_delay, dlg_regs->xfc_reg_precharge_delay,
0277                 dlg_regs->xfc_reg_remote_surface_flip_latency);
0278 
0279             remaining_buffer -= chars_printed;
0280             pBuf += chars_printed;
0281         }
0282     }
0283 
0284     return bufSize - remaining_buffer;
0285 }
0286 
0287 static unsigned int dcn10_get_ttu_states(struct dc *dc, char *pBuf, unsigned int bufSize)
0288 {
0289     struct resource_pool *pool = dc->res_pool;
0290     int i;
0291 
0292     unsigned int chars_printed = 0;
0293     unsigned int remaining_buffer = bufSize;
0294 
0295     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,"
0296         "rc_rd_c,rc_rd_c0,rc_rd_pc0,rc_rd_c1,rc_rd_pc1,qos_lf_l,qos_rds_l,"
0297         "qos_lf_c,qos_rds_c,qos_lf_c0,qos_rds_c0,qos_lf_c1,qos_rds_c1"
0298         "\n");
0299     remaining_buffer -= chars_printed;
0300     pBuf += chars_printed;
0301 
0302     for (i = 0; i < pool->pipe_count; i++) {
0303         struct dcn_hubp_state *s = &(TO_DCN10_HUBP(pool->hubps[i])->state);
0304         struct _vcs_dpi_display_ttu_regs_st *ttu_regs = &s->ttu_attr;
0305 
0306         if (!s->blank_en) {
0307             chars_printed = snprintf_count(pBuf, remaining_buffer, "%x,%x,%x,%x,%x,%x,%x,%x,"
0308                 "%x,%x,%x,%x,%x,%x,%x,"
0309                 "%x,%x,%x,%x,%x,%x"
0310                 "\n",
0311                 pool->hubps[i]->inst, ttu_regs->qos_level_low_wm, ttu_regs->qos_level_high_wm, ttu_regs->min_ttu_vblank,
0312                 ttu_regs->qos_level_flip, ttu_regs->refcyc_per_req_delivery_pre_l, ttu_regs->refcyc_per_req_delivery_l,
0313                 ttu_regs->refcyc_per_req_delivery_pre_c, ttu_regs->refcyc_per_req_delivery_c, ttu_regs->refcyc_per_req_delivery_cur0,
0314                 ttu_regs->refcyc_per_req_delivery_pre_cur0, ttu_regs->refcyc_per_req_delivery_cur1,
0315                 ttu_regs->refcyc_per_req_delivery_pre_cur1, ttu_regs->qos_level_fixed_l, ttu_regs->qos_ramp_disable_l,
0316                 ttu_regs->qos_level_fixed_c, ttu_regs->qos_ramp_disable_c, ttu_regs->qos_level_fixed_cur0,
0317                 ttu_regs->qos_ramp_disable_cur0, ttu_regs->qos_level_fixed_cur1, ttu_regs->qos_ramp_disable_cur1);
0318 
0319             remaining_buffer -= chars_printed;
0320             pBuf += chars_printed;
0321         }
0322     }
0323 
0324     return bufSize - remaining_buffer;
0325 }
0326 
0327 static unsigned int dcn10_get_cm_states(struct dc *dc, char *pBuf, unsigned int bufSize)
0328 {
0329     struct resource_pool *pool = dc->res_pool;
0330     int i;
0331 
0332     unsigned int chars_printed = 0;
0333     unsigned int remaining_buffer = bufSize;
0334 
0335     chars_printed = snprintf_count(pBuf, remaining_buffer, "instance,igam_format,igam_mode,dgam_mode,rgam_mode,gamut_mode,"
0336         "c11_c12,c13_c14,c21_c22,c23_c24,c31_c32,c33_c34"
0337         "\n");
0338     remaining_buffer -= chars_printed;
0339     pBuf += chars_printed;
0340 
0341     for (i = 0; i < pool->pipe_count; i++) {
0342         struct dpp *dpp = pool->dpps[i];
0343         struct dcn_dpp_state s = {0};
0344 
0345         dpp->funcs->dpp_read_state(dpp, &s);
0346 
0347         if (s.is_enabled) {
0348             chars_printed = snprintf_count(pBuf, remaining_buffer, "%x,%x,"
0349                     "%s,%s,%s,"
0350                     "%x,%08x,%08x,%08x,%08x,%08x,%08x"
0351                 "\n",
0352                 dpp->inst, s.igam_input_format,
0353                 (s.igam_lut_mode == 0) ? "BypassFixed" :
0354                     ((s.igam_lut_mode == 1) ? "BypassFloat" :
0355                     ((s.igam_lut_mode == 2) ? "RAM" :
0356                     ((s.igam_lut_mode == 3) ? "RAM" :
0357                                  "Unknown"))),
0358                 (s.dgam_lut_mode == 0) ? "Bypass" :
0359                     ((s.dgam_lut_mode == 1) ? "sRGB" :
0360                     ((s.dgam_lut_mode == 2) ? "Ycc" :
0361                     ((s.dgam_lut_mode == 3) ? "RAM" :
0362                     ((s.dgam_lut_mode == 4) ? "RAM" :
0363                                  "Unknown")))),
0364                 (s.rgam_lut_mode == 0) ? "Bypass" :
0365                     ((s.rgam_lut_mode == 1) ? "sRGB" :
0366                     ((s.rgam_lut_mode == 2) ? "Ycc" :
0367                     ((s.rgam_lut_mode == 3) ? "RAM" :
0368                     ((s.rgam_lut_mode == 4) ? "RAM" :
0369                                  "Unknown")))),
0370                 s.gamut_remap_mode, s.gamut_remap_c11_c12,
0371                 s.gamut_remap_c13_c14, s.gamut_remap_c21_c22, s.gamut_remap_c23_c24,
0372                 s.gamut_remap_c31_c32, s.gamut_remap_c33_c34);
0373 
0374             remaining_buffer -= chars_printed;
0375             pBuf += chars_printed;
0376         }
0377     }
0378 
0379     return bufSize - remaining_buffer;
0380 }
0381 
0382 static unsigned int dcn10_get_mpcc_states(struct dc *dc, char *pBuf, unsigned int bufSize)
0383 {
0384     struct resource_pool *pool = dc->res_pool;
0385     int i;
0386 
0387     unsigned int chars_printed = 0;
0388     unsigned int remaining_buffer = bufSize;
0389 
0390     chars_printed = snprintf_count(pBuf, remaining_buffer, "instance,opp,dpp,mpccbot,mode,alpha_mode,premult,overlap_only,idle\n");
0391     remaining_buffer -= chars_printed;
0392     pBuf += chars_printed;
0393 
0394     for (i = 0; i < pool->pipe_count; i++) {
0395         struct mpcc_state s = {0};
0396 
0397         pool->mpc->funcs->read_mpcc_state(pool->mpc, i, &s);
0398 
0399         if (s.opp_id != 0xf) {
0400             chars_printed = snprintf_count(pBuf, remaining_buffer, "%x,%x,%x,%x,%x,%x,%x,%x,%x\n",
0401                 i, s.opp_id, s.dpp_id, s.bot_mpcc_id,
0402                 s.mode, s.alpha_mode, s.pre_multiplied_alpha, s.overlap_only,
0403                 s.idle);
0404 
0405             remaining_buffer -= chars_printed;
0406             pBuf += chars_printed;
0407         }
0408     }
0409 
0410     return bufSize - remaining_buffer;
0411 }
0412 
0413 static unsigned int dcn10_get_otg_states(struct dc *dc, char *pBuf, unsigned int bufSize)
0414 {
0415     struct resource_pool *pool = dc->res_pool;
0416     int i;
0417 
0418     unsigned int chars_printed = 0;
0419     unsigned int remaining_buffer = bufSize;
0420 
0421     chars_printed = snprintf_count(pBuf, remaining_buffer, "instance,v_bs,v_be,v_ss,v_se,vpol,vmax,vmin,vmax_sel,vmin_sel,"
0422             "h_bs,h_be,h_ss,h_se,hpol,htot,vtot,underflow,pixelclk[khz]\n");
0423     remaining_buffer -= chars_printed;
0424     pBuf += chars_printed;
0425 
0426     for (i = 0; i < pool->timing_generator_count; i++) {
0427         struct timing_generator *tg = pool->timing_generators[i];
0428         struct dcn_otg_state s = {0};
0429         int pix_clk = 0;
0430 
0431         optc1_read_otg_state(DCN10TG_FROM_TG(tg), &s);
0432         pix_clk = dc->current_state->res_ctx.pipe_ctx[i].stream_res.pix_clk_params.requested_pix_clk_100hz / 10;
0433 
0434         //only print if OTG master is enabled
0435         if (s.otg_enabled & 1) {
0436             chars_printed = snprintf_count(pBuf, remaining_buffer, "%x,%d,%d,%d,%d,%d,%d,%d,%d,%d,"
0437                 "%d,%d,%d,%d,%d,%d,%d,%d,%d"
0438                 "\n",
0439                 tg->inst,
0440                 s.v_blank_start,
0441                 s.v_blank_end,
0442                 s.v_sync_a_start,
0443                 s.v_sync_a_end,
0444                 s.v_sync_a_pol,
0445                 s.v_total_max,
0446                 s.v_total_min,
0447                 s.v_total_max_sel,
0448                 s.v_total_min_sel,
0449                 s.h_blank_start,
0450                 s.h_blank_end,
0451                 s.h_sync_a_start,
0452                 s.h_sync_a_end,
0453                 s.h_sync_a_pol,
0454                 s.h_total,
0455                 s.v_total,
0456                 s.underflow_occurred_status,
0457                 pix_clk);
0458 
0459             remaining_buffer -= chars_printed;
0460             pBuf += chars_printed;
0461         }
0462     }
0463 
0464     return bufSize - remaining_buffer;
0465 }
0466 
0467 static unsigned int dcn10_get_clock_states(struct dc *dc, char *pBuf, unsigned int bufSize)
0468 {
0469     unsigned int chars_printed = 0;
0470     unsigned int remaining_buffer = bufSize;
0471 
0472     chars_printed = snprintf_count(pBuf, bufSize, "dcfclk,dcfclk_deep_sleep,dispclk,"
0473         "dppclk,fclk,socclk\n"
0474         "%d,%d,%d,%d,%d,%d\n",
0475         dc->current_state->bw_ctx.bw.dcn.clk.dcfclk_khz,
0476         dc->current_state->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz,
0477         dc->current_state->bw_ctx.bw.dcn.clk.dispclk_khz,
0478         dc->current_state->bw_ctx.bw.dcn.clk.dppclk_khz,
0479         dc->current_state->bw_ctx.bw.dcn.clk.fclk_khz,
0480         dc->current_state->bw_ctx.bw.dcn.clk.socclk_khz);
0481 
0482     remaining_buffer -= chars_printed;
0483     pBuf += chars_printed;
0484 
0485     return bufSize - remaining_buffer;
0486 }
0487 
0488 static void dcn10_clear_otpc_underflow(struct dc *dc)
0489 {
0490     struct resource_pool *pool = dc->res_pool;
0491     int i;
0492 
0493     for (i = 0; i < pool->timing_generator_count; i++) {
0494         struct timing_generator *tg = pool->timing_generators[i];
0495         struct dcn_otg_state s = {0};
0496 
0497         optc1_read_otg_state(DCN10TG_FROM_TG(tg), &s);
0498 
0499         if (s.otg_enabled & 1)
0500             tg->funcs->clear_optc_underflow(tg);
0501     }
0502 }
0503 
0504 static void dcn10_clear_hubp_underflow(struct dc *dc)
0505 {
0506     struct resource_pool *pool = dc->res_pool;
0507     int i;
0508 
0509     for (i = 0; i < pool->pipe_count; i++) {
0510         struct hubp *hubp = pool->hubps[i];
0511         struct dcn_hubp_state *s = &(TO_DCN10_HUBP(hubp)->state);
0512 
0513         hubp->funcs->hubp_read_state(hubp);
0514 
0515         if (!s->blank_en)
0516             hubp->funcs->hubp_clear_underflow(hubp);
0517     }
0518 }
0519 
0520 void dcn10_clear_status_bits(struct dc *dc, unsigned int mask)
0521 {
0522     /*
0523      *  Mask Format
0524      *  Bit 0 - 31: Status bit to clear
0525      *
0526      *  Mask = 0x0 means clear all status bits
0527      */
0528     const unsigned int DC_HW_STATE_MASK_HUBP_UNDERFLOW  = 0x1;
0529     const unsigned int DC_HW_STATE_MASK_OTPC_UNDERFLOW  = 0x2;
0530 
0531     if (mask == 0x0)
0532         mask = 0xFFFFFFFF;
0533 
0534     if (mask & DC_HW_STATE_MASK_HUBP_UNDERFLOW)
0535         dcn10_clear_hubp_underflow(dc);
0536 
0537     if (mask & DC_HW_STATE_MASK_OTPC_UNDERFLOW)
0538         dcn10_clear_otpc_underflow(dc);
0539 }
0540 
0541 void dcn10_get_hw_state(struct dc *dc, char *pBuf, unsigned int bufSize, unsigned int mask)
0542 {
0543     /*
0544      *  Mask Format
0545      *  Bit 0 - 15: Hardware block mask
0546      *  Bit 15: 1 = Invariant Only, 0 = All
0547      */
0548     const unsigned int DC_HW_STATE_MASK_HUBBUB          = 0x1;
0549     const unsigned int DC_HW_STATE_MASK_HUBP            = 0x2;
0550     const unsigned int DC_HW_STATE_MASK_RQ              = 0x4;
0551     const unsigned int DC_HW_STATE_MASK_DLG             = 0x8;
0552     const unsigned int DC_HW_STATE_MASK_TTU             = 0x10;
0553     const unsigned int DC_HW_STATE_MASK_CM              = 0x20;
0554     const unsigned int DC_HW_STATE_MASK_MPCC            = 0x40;
0555     const unsigned int DC_HW_STATE_MASK_OTG             = 0x80;
0556     const unsigned int DC_HW_STATE_MASK_CLOCKS          = 0x100;
0557     const unsigned int DC_HW_STATE_INVAR_ONLY           = 0x8000;
0558 
0559     unsigned int chars_printed = 0;
0560     unsigned int remaining_buf_size = bufSize;
0561 
0562     if (mask == 0x0)
0563         mask = 0xFFFF; // Default, capture all, invariant only
0564 
0565     if ((mask & DC_HW_STATE_MASK_HUBBUB) && remaining_buf_size > 0) {
0566         chars_printed = dcn10_get_hubbub_state(dc, pBuf, remaining_buf_size);
0567         pBuf += chars_printed;
0568         remaining_buf_size -= chars_printed;
0569     }
0570 
0571     if ((mask & DC_HW_STATE_MASK_HUBP) && remaining_buf_size > 0) {
0572         chars_printed = dcn10_get_hubp_states(dc, pBuf, remaining_buf_size, mask & DC_HW_STATE_INVAR_ONLY);
0573         pBuf += chars_printed;
0574         remaining_buf_size -= chars_printed;
0575     }
0576 
0577     if ((mask & DC_HW_STATE_MASK_RQ) && remaining_buf_size > 0) {
0578         chars_printed = dcn10_get_rq_states(dc, pBuf, remaining_buf_size);
0579         pBuf += chars_printed;
0580         remaining_buf_size -= chars_printed;
0581     }
0582 
0583     if ((mask & DC_HW_STATE_MASK_DLG) && remaining_buf_size > 0) {
0584         chars_printed = dcn10_get_dlg_states(dc, pBuf, remaining_buf_size);
0585         pBuf += chars_printed;
0586         remaining_buf_size -= chars_printed;
0587     }
0588 
0589     if ((mask & DC_HW_STATE_MASK_TTU) && remaining_buf_size > 0) {
0590         chars_printed = dcn10_get_ttu_states(dc, pBuf, remaining_buf_size);
0591         pBuf += chars_printed;
0592         remaining_buf_size -= chars_printed;
0593     }
0594 
0595     if ((mask & DC_HW_STATE_MASK_CM) && remaining_buf_size > 0) {
0596         chars_printed = dcn10_get_cm_states(dc, pBuf, remaining_buf_size);
0597         pBuf += chars_printed;
0598         remaining_buf_size -= chars_printed;
0599     }
0600 
0601     if ((mask & DC_HW_STATE_MASK_MPCC) && remaining_buf_size > 0) {
0602         chars_printed = dcn10_get_mpcc_states(dc, pBuf, remaining_buf_size);
0603         pBuf += chars_printed;
0604         remaining_buf_size -= chars_printed;
0605     }
0606 
0607     if ((mask & DC_HW_STATE_MASK_OTG) && remaining_buf_size > 0) {
0608         chars_printed = dcn10_get_otg_states(dc, pBuf, remaining_buf_size);
0609         pBuf += chars_printed;
0610         remaining_buf_size -= chars_printed;
0611     }
0612 
0613     if ((mask & DC_HW_STATE_MASK_CLOCKS) && remaining_buf_size > 0) {
0614         chars_printed = dcn10_get_clock_states(dc, pBuf, remaining_buf_size);
0615         pBuf += chars_printed;
0616         remaining_buf_size -= chars_printed;
0617     }
0618 }