Line data Source code
1 : /*
2 : * Copyright 2016 Advanced Micro Devices, Inc.
3 : *
4 : * Permission is hereby granted, free of charge, to any person obtaining a
5 : * copy of this software and associated documentation files (the "Software"),
6 : * to deal in the Software without restriction, including without limitation
7 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 : * and/or sell copies of the Software, and to permit persons to whom the
9 : * Software is furnished to do so, subject to the following conditions:
10 : *
11 : * The above copyright notice and this permission notice shall be included in
12 : * all copies or substantial portions of the Software.
13 : *
14 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 : * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 : * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 : * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 : * OTHER DEALINGS IN THE SOFTWARE.
21 : *
22 : * Authors: AMD
23 : *
24 : */
25 :
26 : #include "dm_services.h"
27 : #include "core_types.h"
28 : #include "resource.h"
29 : #include "custom_float.h"
30 : #include "dcn10_hw_sequencer.h"
31 : #include "dce110/dce110_hw_sequencer.h"
32 : #include "dce/dce_hwseq.h"
33 : #include "abm.h"
34 : #include "dmcu.h"
35 : #include "dcn10_optc.h"
36 : #include "dcn10/dcn10_dpp.h"
37 : #include "dcn10/dcn10_mpc.h"
38 : #include "timing_generator.h"
39 : #include "opp.h"
40 : #include "ipp.h"
41 : #include "mpc.h"
42 : #include "reg_helper.h"
43 : #include "dcn10_hubp.h"
44 : #include "dcn10_hubbub.h"
45 : #include "dcn10_cm_common.h"
46 : #include "clk_mgr.h"
47 :
48 0 : unsigned int snprintf_count(char *pBuf, unsigned int bufSize, char *fmt, ...)
49 : {
50 : int ret_vsnprintf;
51 : unsigned int chars_printed;
52 :
53 : va_list args;
54 0 : va_start(args, fmt);
55 :
56 0 : ret_vsnprintf = vsnprintf(pBuf, bufSize, fmt, args);
57 :
58 0 : va_end(args);
59 :
60 0 : if (ret_vsnprintf > 0) {
61 0 : if (ret_vsnprintf < bufSize)
62 : chars_printed = ret_vsnprintf;
63 : else
64 0 : chars_printed = bufSize - 1;
65 : } else
66 : chars_printed = 0;
67 :
68 0 : return chars_printed;
69 : }
70 :
71 0 : static unsigned int dcn10_get_hubbub_state(struct dc *dc, char *pBuf, unsigned int bufSize)
72 : {
73 0 : struct dc_context *dc_ctx = dc->ctx;
74 : struct dcn_hubbub_wm wm;
75 : int i;
76 :
77 0 : unsigned int chars_printed = 0;
78 0 : unsigned int remaining_buffer = bufSize;
79 :
80 0 : 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 0 : memset(&wm, 0, sizeof(struct dcn_hubbub_wm));
84 0 : dc->res_pool->hubbub->funcs->wm_read_state(dc->res_pool->hubbub, &wm);
85 :
86 0 : chars_printed = snprintf_count(pBuf, remaining_buffer, "wm_set_index,data_urgent,pte_meta_urgent,sr_enter,sr_exit,dram_clk_chanage\n");
87 0 : remaining_buffer -= chars_printed;
88 0 : pBuf += chars_printed;
89 :
90 0 : for (i = 0; i < 4; i++) {
91 : struct dcn_hubbub_wm_set *s;
92 :
93 0 : s = &wm.sets[i];
94 :
95 0 : chars_printed = snprintf_count(pBuf, remaining_buffer, "%x,%d.%03d,%d.%03d,%d.%03d,%d.%03d,%d.%03d\n",
96 : s->wm_set,
97 0 : (s->data_urgent * frac) / ref_clk_mhz / frac, (s->data_urgent * frac) / ref_clk_mhz % frac,
98 0 : (s->pte_meta_urgent * frac) / ref_clk_mhz / frac, (s->pte_meta_urgent * frac) / ref_clk_mhz % frac,
99 0 : (s->sr_enter * frac) / ref_clk_mhz / frac, (s->sr_enter * frac) / ref_clk_mhz % frac,
100 0 : (s->sr_exit * frac) / ref_clk_mhz / frac, (s->sr_exit * frac) / ref_clk_mhz % frac,
101 0 : (s->dram_clk_chanage * frac) / ref_clk_mhz / frac, (s->dram_clk_chanage * frac) / ref_clk_mhz % frac);
102 0 : remaining_buffer -= chars_printed;
103 0 : pBuf += chars_printed;
104 : }
105 :
106 0 : return bufSize - remaining_buffer;
107 : }
108 :
109 0 : static unsigned int dcn10_get_hubp_states(struct dc *dc, char *pBuf, unsigned int bufSize, bool invarOnly)
110 : {
111 0 : struct dc_context *dc_ctx = dc->ctx;
112 0 : struct resource_pool *pool = dc->res_pool;
113 : int i;
114 :
115 0 : unsigned int chars_printed = 0;
116 0 : unsigned int remaining_buffer = bufSize;
117 :
118 0 : 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 0 : if (invarOnly)
122 0 : 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 0 : 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 0 : remaining_buffer -= chars_printed;
131 0 : pBuf += chars_printed;
132 :
133 0 : for (i = 0; i < pool->pipe_count; i++) {
134 0 : struct hubp *hubp = pool->hubps[i];
135 0 : struct dcn_hubp_state *s = &(TO_DCN10_HUBP(hubp)->state);
136 :
137 0 : hubp->funcs->hubp_read_state(hubp);
138 :
139 0 : if (!s->blank_en) {
140 0 : if (invarOnly)
141 0 : 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 0 : (s->min_ttu_vblank * frac) / ref_clk_mhz / frac, (s->min_ttu_vblank * frac) / ref_clk_mhz % frac,
157 0 : (s->qos_level_low_wm * frac) / ref_clk_mhz / frac, (s->qos_level_low_wm * frac) / ref_clk_mhz % frac,
158 0 : (s->qos_level_high_wm * frac) / ref_clk_mhz / frac, (s->qos_level_high_wm * frac) / ref_clk_mhz % frac);
159 : else
160 0 : 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 0 : (s->min_ttu_vblank * frac) / ref_clk_mhz / frac, (s->min_ttu_vblank * frac) / ref_clk_mhz % frac,
177 0 : (s->qos_level_low_wm * frac) / ref_clk_mhz / frac, (s->qos_level_low_wm * frac) / ref_clk_mhz % frac,
178 0 : (s->qos_level_high_wm * frac) / ref_clk_mhz / frac, (s->qos_level_high_wm * frac) / ref_clk_mhz % frac);
179 :
180 0 : remaining_buffer -= chars_printed;
181 0 : pBuf += chars_printed;
182 : }
183 : }
184 :
185 0 : return bufSize - remaining_buffer;
186 : }
187 :
188 0 : static unsigned int dcn10_get_rq_states(struct dc *dc, char *pBuf, unsigned int bufSize)
189 : {
190 0 : struct resource_pool *pool = dc->res_pool;
191 : int i;
192 :
193 0 : unsigned int chars_printed = 0;
194 0 : unsigned int remaining_buffer = bufSize;
195 :
196 0 : 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 0 : remaining_buffer -= chars_printed;
201 0 : pBuf += chars_printed;
202 :
203 0 : for (i = 0; i < pool->pipe_count; i++) {
204 0 : struct dcn_hubp_state *s = &(TO_DCN10_HUBP(pool->hubps[i])->state);
205 0 : struct _vcs_dpi_display_rq_regs_st *rq_regs = &s->rq_regs;
206 :
207 0 : if (!s->blank_en) {
208 0 : 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 0 : remaining_buffer -= chars_printed;
223 0 : pBuf += chars_printed;
224 : }
225 : }
226 :
227 0 : return bufSize - remaining_buffer;
228 : }
229 :
230 0 : static unsigned int dcn10_get_dlg_states(struct dc *dc, char *pBuf, unsigned int bufSize)
231 : {
232 0 : struct resource_pool *pool = dc->res_pool;
233 : int i;
234 :
235 0 : unsigned int chars_printed = 0;
236 0 : unsigned int remaining_buffer = bufSize;
237 :
238 0 : 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 0 : remaining_buffer -= chars_printed;
246 0 : pBuf += chars_printed;
247 :
248 0 : for (i = 0; i < pool->pipe_count; i++) {
249 0 : struct dcn_hubp_state *s = &(TO_DCN10_HUBP(pool->hubps[i])->state);
250 0 : struct _vcs_dpi_display_dlg_regs_st *dlg_regs = &s->dlg_attr;
251 :
252 0 : if (!s->blank_en) {
253 0 : 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 0 : remaining_buffer -= chars_printed;
280 0 : pBuf += chars_printed;
281 : }
282 : }
283 :
284 0 : return bufSize - remaining_buffer;
285 : }
286 :
287 0 : static unsigned int dcn10_get_ttu_states(struct dc *dc, char *pBuf, unsigned int bufSize)
288 : {
289 0 : struct resource_pool *pool = dc->res_pool;
290 : int i;
291 :
292 0 : unsigned int chars_printed = 0;
293 0 : unsigned int remaining_buffer = bufSize;
294 :
295 0 : 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 0 : remaining_buffer -= chars_printed;
300 0 : pBuf += chars_printed;
301 :
302 0 : for (i = 0; i < pool->pipe_count; i++) {
303 0 : struct dcn_hubp_state *s = &(TO_DCN10_HUBP(pool->hubps[i])->state);
304 0 : struct _vcs_dpi_display_ttu_regs_st *ttu_regs = &s->ttu_attr;
305 :
306 0 : if (!s->blank_en) {
307 0 : 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 0 : remaining_buffer -= chars_printed;
320 0 : pBuf += chars_printed;
321 : }
322 : }
323 :
324 0 : return bufSize - remaining_buffer;
325 : }
326 :
327 0 : static unsigned int dcn10_get_cm_states(struct dc *dc, char *pBuf, unsigned int bufSize)
328 : {
329 0 : struct resource_pool *pool = dc->res_pool;
330 : int i;
331 :
332 0 : unsigned int chars_printed = 0;
333 0 : unsigned int remaining_buffer = bufSize;
334 :
335 0 : 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 0 : remaining_buffer -= chars_printed;
339 0 : pBuf += chars_printed;
340 :
341 0 : for (i = 0; i < pool->pipe_count; i++) {
342 0 : struct dpp *dpp = pool->dpps[i];
343 0 : struct dcn_dpp_state s = {0};
344 :
345 0 : dpp->funcs->dpp_read_state(dpp, &s);
346 :
347 0 : if (s.is_enabled) {
348 0 : 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 0 : (s.igam_lut_mode == 0) ? "BypassFixed" :
354 0 : ((s.igam_lut_mode == 1) ? "BypassFloat" :
355 0 : ((s.igam_lut_mode == 2) ? "RAM" :
356 0 : ((s.igam_lut_mode == 3) ? "RAM" :
357 : "Unknown"))),
358 0 : (s.dgam_lut_mode == 0) ? "Bypass" :
359 0 : ((s.dgam_lut_mode == 1) ? "sRGB" :
360 0 : ((s.dgam_lut_mode == 2) ? "Ycc" :
361 0 : ((s.dgam_lut_mode == 3) ? "RAM" :
362 0 : ((s.dgam_lut_mode == 4) ? "RAM" :
363 : "Unknown")))),
364 0 : (s.rgam_lut_mode == 0) ? "Bypass" :
365 0 : ((s.rgam_lut_mode == 1) ? "sRGB" :
366 0 : ((s.rgam_lut_mode == 2) ? "Ycc" :
367 0 : ((s.rgam_lut_mode == 3) ? "RAM" :
368 0 : ((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 0 : remaining_buffer -= chars_printed;
375 0 : pBuf += chars_printed;
376 : }
377 : }
378 :
379 0 : return bufSize - remaining_buffer;
380 : }
381 :
382 0 : static unsigned int dcn10_get_mpcc_states(struct dc *dc, char *pBuf, unsigned int bufSize)
383 : {
384 0 : struct resource_pool *pool = dc->res_pool;
385 : int i;
386 :
387 0 : unsigned int chars_printed = 0;
388 0 : unsigned int remaining_buffer = bufSize;
389 :
390 0 : chars_printed = snprintf_count(pBuf, remaining_buffer, "instance,opp,dpp,mpccbot,mode,alpha_mode,premult,overlap_only,idle\n");
391 0 : remaining_buffer -= chars_printed;
392 0 : pBuf += chars_printed;
393 :
394 0 : for (i = 0; i < pool->pipe_count; i++) {
395 0 : struct mpcc_state s = {0};
396 :
397 0 : pool->mpc->funcs->read_mpcc_state(pool->mpc, i, &s);
398 :
399 0 : if (s.opp_id != 0xf) {
400 0 : 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 0 : remaining_buffer -= chars_printed;
406 0 : pBuf += chars_printed;
407 : }
408 : }
409 :
410 0 : return bufSize - remaining_buffer;
411 : }
412 :
413 0 : static unsigned int dcn10_get_otg_states(struct dc *dc, char *pBuf, unsigned int bufSize)
414 : {
415 0 : struct resource_pool *pool = dc->res_pool;
416 : int i;
417 :
418 0 : unsigned int chars_printed = 0;
419 0 : unsigned int remaining_buffer = bufSize;
420 :
421 0 : 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 0 : remaining_buffer -= chars_printed;
424 0 : pBuf += chars_printed;
425 :
426 0 : for (i = 0; i < pool->timing_generator_count; i++) {
427 0 : struct timing_generator *tg = pool->timing_generators[i];
428 0 : struct dcn_otg_state s = {0};
429 0 : int pix_clk = 0;
430 :
431 0 : optc1_read_otg_state(DCN10TG_FROM_TG(tg), &s);
432 0 : 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 0 : if (s.otg_enabled & 1) {
436 0 : 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 0 : remaining_buffer -= chars_printed;
460 0 : pBuf += chars_printed;
461 : }
462 : }
463 :
464 0 : return bufSize - remaining_buffer;
465 : }
466 :
467 0 : static unsigned int dcn10_get_clock_states(struct dc *dc, char *pBuf, unsigned int bufSize)
468 : {
469 0 : unsigned int chars_printed = 0;
470 0 : unsigned int remaining_buffer = bufSize;
471 :
472 0 : 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 0 : dc->current_state->bw_ctx.bw.dcn.clk.socclk_khz);
481 :
482 0 : remaining_buffer -= chars_printed;
483 0 : pBuf += chars_printed;
484 :
485 0 : return bufSize - remaining_buffer;
486 : }
487 :
488 0 : static void dcn10_clear_otpc_underflow(struct dc *dc)
489 : {
490 0 : struct resource_pool *pool = dc->res_pool;
491 : int i;
492 :
493 0 : for (i = 0; i < pool->timing_generator_count; i++) {
494 0 : struct timing_generator *tg = pool->timing_generators[i];
495 0 : struct dcn_otg_state s = {0};
496 :
497 0 : optc1_read_otg_state(DCN10TG_FROM_TG(tg), &s);
498 :
499 0 : if (s.otg_enabled & 1)
500 0 : tg->funcs->clear_optc_underflow(tg);
501 : }
502 0 : }
503 :
504 0 : static void dcn10_clear_hubp_underflow(struct dc *dc)
505 : {
506 0 : struct resource_pool *pool = dc->res_pool;
507 : int i;
508 :
509 0 : for (i = 0; i < pool->pipe_count; i++) {
510 0 : struct hubp *hubp = pool->hubps[i];
511 0 : struct dcn_hubp_state *s = &(TO_DCN10_HUBP(hubp)->state);
512 :
513 0 : hubp->funcs->hubp_read_state(hubp);
514 :
515 0 : if (!s->blank_en)
516 0 : hubp->funcs->hubp_clear_underflow(hubp);
517 : }
518 0 : }
519 :
520 0 : void dcn10_clear_status_bits(struct dc *dc, unsigned int mask)
521 : {
522 : /*
523 : * Mask Format
524 : * Bit 0 - 31: Status bit to clear
525 : *
526 : * Mask = 0x0 means clear all status bits
527 : */
528 0 : const unsigned int DC_HW_STATE_MASK_HUBP_UNDERFLOW = 0x1;
529 0 : const unsigned int DC_HW_STATE_MASK_OTPC_UNDERFLOW = 0x2;
530 :
531 0 : if (mask == 0x0)
532 0 : mask = 0xFFFFFFFF;
533 :
534 0 : if (mask & DC_HW_STATE_MASK_HUBP_UNDERFLOW)
535 0 : dcn10_clear_hubp_underflow(dc);
536 :
537 0 : if (mask & DC_HW_STATE_MASK_OTPC_UNDERFLOW)
538 0 : dcn10_clear_otpc_underflow(dc);
539 0 : }
540 :
541 0 : void dcn10_get_hw_state(struct dc *dc, char *pBuf, unsigned int bufSize, unsigned int mask)
542 : {
543 : /*
544 : * Mask Format
545 : * Bit 0 - 15: Hardware block mask
546 : * Bit 15: 1 = Invariant Only, 0 = All
547 : */
548 0 : const unsigned int DC_HW_STATE_MASK_HUBBUB = 0x1;
549 0 : const unsigned int DC_HW_STATE_MASK_HUBP = 0x2;
550 0 : const unsigned int DC_HW_STATE_MASK_RQ = 0x4;
551 0 : const unsigned int DC_HW_STATE_MASK_DLG = 0x8;
552 0 : const unsigned int DC_HW_STATE_MASK_TTU = 0x10;
553 0 : const unsigned int DC_HW_STATE_MASK_CM = 0x20;
554 0 : const unsigned int DC_HW_STATE_MASK_MPCC = 0x40;
555 0 : const unsigned int DC_HW_STATE_MASK_OTG = 0x80;
556 0 : const unsigned int DC_HW_STATE_MASK_CLOCKS = 0x100;
557 0 : const unsigned int DC_HW_STATE_INVAR_ONLY = 0x8000;
558 :
559 0 : unsigned int chars_printed = 0;
560 0 : unsigned int remaining_buf_size = bufSize;
561 :
562 0 : if (mask == 0x0)
563 0 : mask = 0xFFFF; // Default, capture all, invariant only
564 :
565 0 : if ((mask & DC_HW_STATE_MASK_HUBBUB) && remaining_buf_size > 0) {
566 0 : chars_printed = dcn10_get_hubbub_state(dc, pBuf, remaining_buf_size);
567 0 : pBuf += chars_printed;
568 0 : remaining_buf_size -= chars_printed;
569 : }
570 :
571 0 : if ((mask & DC_HW_STATE_MASK_HUBP) && remaining_buf_size > 0) {
572 0 : chars_printed = dcn10_get_hubp_states(dc, pBuf, remaining_buf_size, mask & DC_HW_STATE_INVAR_ONLY);
573 0 : pBuf += chars_printed;
574 0 : remaining_buf_size -= chars_printed;
575 : }
576 :
577 0 : if ((mask & DC_HW_STATE_MASK_RQ) && remaining_buf_size > 0) {
578 0 : chars_printed = dcn10_get_rq_states(dc, pBuf, remaining_buf_size);
579 0 : pBuf += chars_printed;
580 0 : remaining_buf_size -= chars_printed;
581 : }
582 :
583 0 : if ((mask & DC_HW_STATE_MASK_DLG) && remaining_buf_size > 0) {
584 0 : chars_printed = dcn10_get_dlg_states(dc, pBuf, remaining_buf_size);
585 0 : pBuf += chars_printed;
586 0 : remaining_buf_size -= chars_printed;
587 : }
588 :
589 0 : if ((mask & DC_HW_STATE_MASK_TTU) && remaining_buf_size > 0) {
590 0 : chars_printed = dcn10_get_ttu_states(dc, pBuf, remaining_buf_size);
591 0 : pBuf += chars_printed;
592 0 : remaining_buf_size -= chars_printed;
593 : }
594 :
595 0 : if ((mask & DC_HW_STATE_MASK_CM) && remaining_buf_size > 0) {
596 0 : chars_printed = dcn10_get_cm_states(dc, pBuf, remaining_buf_size);
597 0 : pBuf += chars_printed;
598 0 : remaining_buf_size -= chars_printed;
599 : }
600 :
601 0 : if ((mask & DC_HW_STATE_MASK_MPCC) && remaining_buf_size > 0) {
602 0 : chars_printed = dcn10_get_mpcc_states(dc, pBuf, remaining_buf_size);
603 0 : pBuf += chars_printed;
604 0 : remaining_buf_size -= chars_printed;
605 : }
606 :
607 0 : if ((mask & DC_HW_STATE_MASK_OTG) && remaining_buf_size > 0) {
608 0 : chars_printed = dcn10_get_otg_states(dc, pBuf, remaining_buf_size);
609 0 : pBuf += chars_printed;
610 0 : remaining_buf_size -= chars_printed;
611 : }
612 :
613 0 : if ((mask & DC_HW_STATE_MASK_CLOCKS) && remaining_buf_size > 0) {
614 0 : chars_printed = dcn10_get_clock_states(dc, pBuf, remaining_buf_size);
615 0 : pBuf += chars_printed;
616 0 : remaining_buf_size -= chars_printed;
617 : }
618 0 : }
|