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/dcn10_hwseq.h" |
31 | #include "dce110/dce110_hwseq.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 | __printf(3, 4) |
49 | unsigned int snprintf_count(char *pbuf, unsigned int bufsize, char *fmt, ...) |
50 | { |
51 | int ret_vsnprintf; |
52 | unsigned int chars_printed; |
53 | |
54 | va_list args; |
55 | va_start(args, fmt); |
56 | |
57 | ret_vsnprintf = vsnprintf(buf: pbuf, size: bufsize, fmt, args); |
58 | |
59 | va_end(args); |
60 | |
61 | if (ret_vsnprintf > 0) { |
62 | if (ret_vsnprintf < bufsize) |
63 | chars_printed = ret_vsnprintf; |
64 | else |
65 | chars_printed = bufsize - 1; |
66 | } else |
67 | chars_printed = 0; |
68 | |
69 | return chars_printed; |
70 | } |
71 | |
72 | static unsigned int dcn10_get_hubbub_state(struct dc *dc, char *pBuf, unsigned int bufSize) |
73 | { |
74 | struct dc_context *dc_ctx = dc->ctx; |
75 | struct dcn_hubbub_wm wm; |
76 | int i; |
77 | |
78 | unsigned int chars_printed = 0; |
79 | unsigned int remaining_buffer = bufSize; |
80 | |
81 | const uint32_t ref_clk_mhz = dc_ctx->dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000; |
82 | static const unsigned int frac = 1000; |
83 | |
84 | memset(&wm, 0, sizeof(struct dcn_hubbub_wm)); |
85 | dc->res_pool->hubbub->funcs->wm_read_state(dc->res_pool->hubbub, &wm); |
86 | |
87 | chars_printed = snprintf_count(pbuf: pBuf, bufsize: remaining_buffer, fmt: "wm_set_index,data_urgent,pte_meta_urgent,sr_enter,sr_exit,dram_clk_change\n" ); |
88 | remaining_buffer -= chars_printed; |
89 | pBuf += chars_printed; |
90 | |
91 | for (i = 0; i < 4; i++) { |
92 | struct dcn_hubbub_wm_set *s; |
93 | |
94 | s = &wm.sets[i]; |
95 | |
96 | chars_printed = snprintf_count(pbuf: pBuf, bufsize: remaining_buffer, fmt: "%x,%d.%03d,%d.%03d,%d.%03d,%d.%03d,%d.%03d\n" , |
97 | s->wm_set, |
98 | (s->data_urgent * frac) / ref_clk_mhz / frac, (s->data_urgent * frac) / ref_clk_mhz % frac, |
99 | (s->pte_meta_urgent * frac) / ref_clk_mhz / frac, (s->pte_meta_urgent * frac) / ref_clk_mhz % frac, |
100 | (s->sr_enter * frac) / ref_clk_mhz / frac, (s->sr_enter * frac) / ref_clk_mhz % frac, |
101 | (s->sr_exit * frac) / ref_clk_mhz / frac, (s->sr_exit * frac) / ref_clk_mhz % frac, |
102 | (s->dram_clk_change * frac) / ref_clk_mhz / frac, (s->dram_clk_change * frac) / ref_clk_mhz % frac); |
103 | remaining_buffer -= chars_printed; |
104 | pBuf += chars_printed; |
105 | } |
106 | |
107 | return bufSize - remaining_buffer; |
108 | } |
109 | |
110 | static unsigned int dcn10_get_hubp_states(struct dc *dc, char *pBuf, unsigned int bufSize, bool invarOnly) |
111 | { |
112 | struct dc_context *dc_ctx = dc->ctx; |
113 | struct resource_pool *pool = dc->res_pool; |
114 | int i; |
115 | |
116 | unsigned int chars_printed = 0; |
117 | unsigned int remaining_buffer = bufSize; |
118 | |
119 | const uint32_t ref_clk_mhz = dc_ctx->dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000; |
120 | static const unsigned int frac = 1000; |
121 | |
122 | if (invarOnly) |
123 | chars_printed = snprintf_count(pbuf: pBuf, bufsize: remaining_buffer, fmt: "instance,format,addr_hi,width,height,rotation,mirror,sw_mode,dcc_en,blank_en,ttu_dis,underflow," |
124 | "min_ttu_vblank,qos_low_wm,qos_high_wm" |
125 | "\n" ); |
126 | else |
127 | chars_printed = snprintf_count(pbuf: pBuf, bufsize: remaining_buffer, fmt: "instance,format,addr_hi,addr_lo,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 | |
131 | remaining_buffer -= chars_printed; |
132 | pBuf += chars_printed; |
133 | |
134 | for (i = 0; i < pool->pipe_count; i++) { |
135 | struct hubp *hubp = pool->hubps[i]; |
136 | struct dcn_hubp_state *s = &(TO_DCN10_HUBP(hubp)->state); |
137 | |
138 | hubp->funcs->hubp_read_state(hubp); |
139 | |
140 | if (!s->blank_en) { |
141 | if (invarOnly) |
142 | chars_printed = snprintf_count(pbuf: pBuf, bufsize: remaining_buffer, fmt: "%x,%x,%x,%d,%d,%x,%x,%x,%x,%x,%x,%x," |
143 | "%d.%03d,%d.%03d,%d.%03d" |
144 | "\n" , |
145 | hubp->inst, |
146 | s->pixel_format, |
147 | s->inuse_addr_hi, |
148 | s->viewport_width, |
149 | s->viewport_height, |
150 | s->rotation_angle, |
151 | s->h_mirror_en, |
152 | s->sw_mode, |
153 | s->dcc_en, |
154 | s->blank_en, |
155 | s->ttu_disable, |
156 | s->underflow_status, |
157 | (s->min_ttu_vblank * frac) / ref_clk_mhz / frac, (s->min_ttu_vblank * frac) / ref_clk_mhz % frac, |
158 | (s->qos_level_low_wm * frac) / ref_clk_mhz / frac, (s->qos_level_low_wm * frac) / ref_clk_mhz % frac, |
159 | (s->qos_level_high_wm * frac) / ref_clk_mhz / frac, (s->qos_level_high_wm * frac) / ref_clk_mhz % frac); |
160 | else |
161 | chars_printed = snprintf_count(pbuf: pBuf, bufsize: remaining_buffer, fmt: "%x,%x,%x,%x,%d,%d,%x,%x,%x,%x,%x,%x,%x," |
162 | "%d.%03d,%d.%03d,%d.%03d" |
163 | "\n" , |
164 | hubp->inst, |
165 | s->pixel_format, |
166 | s->inuse_addr_hi, |
167 | s->inuse_addr_lo, |
168 | s->viewport_width, |
169 | s->viewport_height, |
170 | s->rotation_angle, |
171 | s->h_mirror_en, |
172 | s->sw_mode, |
173 | s->dcc_en, |
174 | s->blank_en, |
175 | s->ttu_disable, |
176 | s->underflow_status, |
177 | (s->min_ttu_vblank * frac) / ref_clk_mhz / frac, (s->min_ttu_vblank * frac) / ref_clk_mhz % frac, |
178 | (s->qos_level_low_wm * frac) / ref_clk_mhz / frac, (s->qos_level_low_wm * frac) / ref_clk_mhz % frac, |
179 | (s->qos_level_high_wm * frac) / ref_clk_mhz / frac, (s->qos_level_high_wm * frac) / ref_clk_mhz % frac); |
180 | |
181 | remaining_buffer -= chars_printed; |
182 | pBuf += chars_printed; |
183 | } |
184 | } |
185 | |
186 | return bufSize - remaining_buffer; |
187 | } |
188 | |
189 | static unsigned int dcn10_get_rq_states(struct dc *dc, char *pBuf, unsigned int bufSize) |
190 | { |
191 | struct resource_pool *pool = dc->res_pool; |
192 | int i; |
193 | |
194 | unsigned int chars_printed = 0; |
195 | unsigned int remaining_buffer = bufSize; |
196 | |
197 | chars_printed = snprintf_count(pbuf: pBuf, bufsize: remaining_buffer, fmt: "instance,drq_exp_m,prq_exp_m,mrq_exp_m,crq_exp_m,plane1_ba," |
198 | "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," |
199 | "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" |
200 | "\n" ); |
201 | remaining_buffer -= chars_printed; |
202 | pBuf += chars_printed; |
203 | |
204 | for (i = 0; i < pool->pipe_count; i++) { |
205 | struct dcn_hubp_state *s = &(TO_DCN10_HUBP(pool->hubps[i])->state); |
206 | struct _vcs_dpi_display_rq_regs_st *rq_regs = &s->rq_regs; |
207 | |
208 | if (!s->blank_en) { |
209 | chars_printed = snprintf_count(pbuf: pBuf, bufsize: remaining_buffer, fmt: "%x,%x,%x,%x,%x,%x," |
210 | "%x,%x,%x,%x,%x,%x,%x,%x," |
211 | "%x,%x,%x,%x,%x,%x,%x,%x" |
212 | "\n" , |
213 | pool->hubps[i]->inst, rq_regs->drq_expansion_mode, rq_regs->prq_expansion_mode, rq_regs->mrq_expansion_mode, |
214 | rq_regs->crq_expansion_mode, rq_regs->plane1_base_address, rq_regs->rq_regs_l.chunk_size, |
215 | rq_regs->rq_regs_l.min_chunk_size, rq_regs->rq_regs_l.meta_chunk_size, |
216 | rq_regs->rq_regs_l.min_meta_chunk_size, rq_regs->rq_regs_l.dpte_group_size, |
217 | rq_regs->rq_regs_l.mpte_group_size, rq_regs->rq_regs_l.swath_height, |
218 | rq_regs->rq_regs_l.pte_row_height_linear, rq_regs->rq_regs_c.chunk_size, rq_regs->rq_regs_c.min_chunk_size, |
219 | rq_regs->rq_regs_c.meta_chunk_size, rq_regs->rq_regs_c.min_meta_chunk_size, |
220 | rq_regs->rq_regs_c.dpte_group_size, rq_regs->rq_regs_c.mpte_group_size, |
221 | rq_regs->rq_regs_c.swath_height, rq_regs->rq_regs_c.pte_row_height_linear); |
222 | |
223 | remaining_buffer -= chars_printed; |
224 | pBuf += chars_printed; |
225 | } |
226 | } |
227 | |
228 | return bufSize - remaining_buffer; |
229 | } |
230 | |
231 | static unsigned int dcn10_get_dlg_states(struct dc *dc, char *pBuf, unsigned int bufSize) |
232 | { |
233 | struct resource_pool *pool = dc->res_pool; |
234 | int i; |
235 | |
236 | unsigned int chars_printed = 0; |
237 | unsigned int remaining_buffer = bufSize; |
238 | |
239 | chars_printed = snprintf_count(pbuf: pBuf, bufsize: remaining_buffer, fmt: "instance,rc_hbe,dlg_vbe,min_d_y_n,rc_per_ht,rc_x_a_s," |
240 | "dst_y_a_s,dst_y_pf,dst_y_vvb,dst_y_rvb,dst_y_vfl,dst_y_rfl,rf_pix_fq," |
241 | "vratio_pf,vrat_pf_c,rc_pg_vbl,rc_pg_vbc,rc_mc_vbl,rc_mc_vbc,rc_pg_fll," |
242 | "rc_pg_flc,rc_mc_fll,rc_mc_flc,pr_nom_l,pr_nom_c,rc_pg_nl,rc_pg_nc," |
243 | "mr_nom_l,mr_nom_c,rc_mc_nl,rc_mc_nc,rc_ld_pl,rc_ld_pc,rc_ld_l," |
244 | "rc_ld_c,cha_cur0,ofst_cur1,cha_cur1,vr_af_vc0,ddrq_limt,x_rt_dlay,x_rp_dlay,x_rr_sfl" |
245 | "\n" ); |
246 | remaining_buffer -= chars_printed; |
247 | pBuf += chars_printed; |
248 | |
249 | for (i = 0; i < pool->pipe_count; i++) { |
250 | struct dcn_hubp_state *s = &(TO_DCN10_HUBP(pool->hubps[i])->state); |
251 | struct _vcs_dpi_display_dlg_regs_st *dlg_regs = &s->dlg_attr; |
252 | |
253 | if (!s->blank_en) { |
254 | chars_printed = snprintf_count(pbuf: pBuf, bufsize: remaining_buffer, fmt: "%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," |
259 | "%x,%x,%x,%x,%x,%x,%x,%x,%x,%x" |
260 | "\n" , |
261 | pool->hubps[i]->inst, dlg_regs->refcyc_h_blank_end, dlg_regs->dlg_vblank_end, dlg_regs->min_dst_y_next_start, |
262 | dlg_regs->refcyc_per_htotal, dlg_regs->refcyc_x_after_scaler, dlg_regs->dst_y_after_scaler, |
263 | dlg_regs->dst_y_prefetch, dlg_regs->dst_y_per_vm_vblank, dlg_regs->dst_y_per_row_vblank, |
264 | dlg_regs->dst_y_per_vm_flip, dlg_regs->dst_y_per_row_flip, dlg_regs->ref_freq_to_pix_freq, |
265 | dlg_regs->vratio_prefetch, dlg_regs->vratio_prefetch_c, dlg_regs->refcyc_per_pte_group_vblank_l, |
266 | dlg_regs->refcyc_per_pte_group_vblank_c, dlg_regs->refcyc_per_meta_chunk_vblank_l, |
267 | dlg_regs->refcyc_per_meta_chunk_vblank_c, dlg_regs->refcyc_per_pte_group_flip_l, |
268 | dlg_regs->refcyc_per_pte_group_flip_c, dlg_regs->refcyc_per_meta_chunk_flip_l, |
269 | dlg_regs->refcyc_per_meta_chunk_flip_c, dlg_regs->dst_y_per_pte_row_nom_l, |
270 | dlg_regs->dst_y_per_pte_row_nom_c, dlg_regs->refcyc_per_pte_group_nom_l, |
271 | dlg_regs->refcyc_per_pte_group_nom_c, dlg_regs->dst_y_per_meta_row_nom_l, |
272 | dlg_regs->dst_y_per_meta_row_nom_c, dlg_regs->refcyc_per_meta_chunk_nom_l, |
273 | dlg_regs->refcyc_per_meta_chunk_nom_c, dlg_regs->refcyc_per_line_delivery_pre_l, |
274 | dlg_regs->refcyc_per_line_delivery_pre_c, dlg_regs->refcyc_per_line_delivery_l, |
275 | dlg_regs->refcyc_per_line_delivery_c, dlg_regs->chunk_hdl_adjust_cur0, dlg_regs->dst_y_offset_cur1, |
276 | dlg_regs->chunk_hdl_adjust_cur1, dlg_regs->vready_after_vcount0, dlg_regs->dst_y_delta_drq_limit, |
277 | dlg_regs->xfc_reg_transfer_delay, dlg_regs->xfc_reg_precharge_delay, |
278 | dlg_regs->xfc_reg_remote_surface_flip_latency); |
279 | |
280 | remaining_buffer -= chars_printed; |
281 | pBuf += chars_printed; |
282 | } |
283 | } |
284 | |
285 | return bufSize - remaining_buffer; |
286 | } |
287 | |
288 | static unsigned int dcn10_get_ttu_states(struct dc *dc, char *pBuf, unsigned int bufSize) |
289 | { |
290 | struct resource_pool *pool = dc->res_pool; |
291 | int i; |
292 | |
293 | unsigned int chars_printed = 0; |
294 | unsigned int remaining_buffer = bufSize; |
295 | |
296 | chars_printed = snprintf_count(pbuf: pBuf, bufsize: remaining_buffer, fmt: "instance,qos_ll_wm,qos_lh_wm,mn_ttu_vb,qos_l_flp,rc_rd_p_l,rc_rd_l,rc_rd_p_c," |
297 | "rc_rd_c,rc_rd_c0,rc_rd_pc0,rc_rd_c1,rc_rd_pc1,qos_lf_l,qos_rds_l," |
298 | "qos_lf_c,qos_rds_c,qos_lf_c0,qos_rds_c0,qos_lf_c1,qos_rds_c1" |
299 | "\n" ); |
300 | remaining_buffer -= chars_printed; |
301 | pBuf += chars_printed; |
302 | |
303 | for (i = 0; i < pool->pipe_count; i++) { |
304 | struct dcn_hubp_state *s = &(TO_DCN10_HUBP(pool->hubps[i])->state); |
305 | struct _vcs_dpi_display_ttu_regs_st *ttu_regs = &s->ttu_attr; |
306 | |
307 | if (!s->blank_en) { |
308 | chars_printed = snprintf_count(pbuf: pBuf, bufsize: remaining_buffer, fmt: "%x,%x,%x,%x,%x,%x,%x,%x," |
309 | "%x,%x,%x,%x,%x,%x,%x," |
310 | "%x,%x,%x,%x,%x,%x" |
311 | "\n" , |
312 | pool->hubps[i]->inst, ttu_regs->qos_level_low_wm, ttu_regs->qos_level_high_wm, ttu_regs->min_ttu_vblank, |
313 | ttu_regs->qos_level_flip, ttu_regs->refcyc_per_req_delivery_pre_l, ttu_regs->refcyc_per_req_delivery_l, |
314 | ttu_regs->refcyc_per_req_delivery_pre_c, ttu_regs->refcyc_per_req_delivery_c, ttu_regs->refcyc_per_req_delivery_cur0, |
315 | ttu_regs->refcyc_per_req_delivery_pre_cur0, ttu_regs->refcyc_per_req_delivery_cur1, |
316 | ttu_regs->refcyc_per_req_delivery_pre_cur1, ttu_regs->qos_level_fixed_l, ttu_regs->qos_ramp_disable_l, |
317 | ttu_regs->qos_level_fixed_c, ttu_regs->qos_ramp_disable_c, ttu_regs->qos_level_fixed_cur0, |
318 | ttu_regs->qos_ramp_disable_cur0, ttu_regs->qos_level_fixed_cur1, ttu_regs->qos_ramp_disable_cur1); |
319 | |
320 | remaining_buffer -= chars_printed; |
321 | pBuf += chars_printed; |
322 | } |
323 | } |
324 | |
325 | return bufSize - remaining_buffer; |
326 | } |
327 | |
328 | static unsigned int dcn10_get_cm_states(struct dc *dc, char *pBuf, unsigned int bufSize) |
329 | { |
330 | struct resource_pool *pool = dc->res_pool; |
331 | int i; |
332 | |
333 | unsigned int chars_printed = 0; |
334 | unsigned int remaining_buffer = bufSize; |
335 | |
336 | chars_printed = snprintf_count(pbuf: pBuf, bufsize: remaining_buffer, fmt: "instance,igam_format,igam_mode,dgam_mode,rgam_mode,gamut_mode," |
337 | "c11_c12,c13_c14,c21_c22,c23_c24,c31_c32,c33_c34" |
338 | "\n" ); |
339 | remaining_buffer -= chars_printed; |
340 | pBuf += chars_printed; |
341 | |
342 | for (i = 0; i < pool->pipe_count; i++) { |
343 | struct dpp *dpp = pool->dpps[i]; |
344 | struct dcn_dpp_state s = {0}; |
345 | |
346 | dpp->funcs->dpp_read_state(dpp, &s); |
347 | |
348 | if (s.is_enabled) { |
349 | chars_printed = snprintf_count(pbuf: pBuf, bufsize: remaining_buffer, fmt: "%x,%x," |
350 | "%s,%s,%s," |
351 | "%x,%08x,%08x,%08x,%08x,%08x,%08x" |
352 | "\n" , |
353 | dpp->inst, s.igam_input_format, |
354 | (s.igam_lut_mode == 0) ? "BypassFixed" : |
355 | ((s.igam_lut_mode == 1) ? "BypassFloat" : |
356 | ((s.igam_lut_mode == 2) ? "RAM" : |
357 | ((s.igam_lut_mode == 3) ? "RAM" : |
358 | "Unknown" ))), |
359 | (s.dgam_lut_mode == 0) ? "Bypass" : |
360 | ((s.dgam_lut_mode == 1) ? "sRGB" : |
361 | ((s.dgam_lut_mode == 2) ? "Ycc" : |
362 | ((s.dgam_lut_mode == 3) ? "RAM" : |
363 | ((s.dgam_lut_mode == 4) ? "RAM" : |
364 | "Unknown" )))), |
365 | (s.rgam_lut_mode == 0) ? "Bypass" : |
366 | ((s.rgam_lut_mode == 1) ? "sRGB" : |
367 | ((s.rgam_lut_mode == 2) ? "Ycc" : |
368 | ((s.rgam_lut_mode == 3) ? "RAM" : |
369 | ((s.rgam_lut_mode == 4) ? "RAM" : |
370 | "Unknown" )))), |
371 | s.gamut_remap_mode, s.gamut_remap_c11_c12, |
372 | s.gamut_remap_c13_c14, s.gamut_remap_c21_c22, s.gamut_remap_c23_c24, |
373 | s.gamut_remap_c31_c32, s.gamut_remap_c33_c34); |
374 | |
375 | remaining_buffer -= chars_printed; |
376 | pBuf += chars_printed; |
377 | } |
378 | } |
379 | |
380 | return bufSize - remaining_buffer; |
381 | } |
382 | |
383 | static unsigned int dcn10_get_mpcc_states(struct dc *dc, char *pBuf, unsigned int bufSize) |
384 | { |
385 | struct resource_pool *pool = dc->res_pool; |
386 | int i; |
387 | |
388 | unsigned int chars_printed = 0; |
389 | unsigned int remaining_buffer = bufSize; |
390 | |
391 | chars_printed = snprintf_count(pbuf: pBuf, bufsize: remaining_buffer, fmt: "instance,opp,dpp,mpccbot,mode,alpha_mode,premult,overlap_only,idle\n" ); |
392 | remaining_buffer -= chars_printed; |
393 | pBuf += chars_printed; |
394 | |
395 | for (i = 0; i < pool->pipe_count; i++) { |
396 | struct mpcc_state s = {0}; |
397 | |
398 | pool->mpc->funcs->read_mpcc_state(pool->mpc, i, &s); |
399 | |
400 | if (s.opp_id != 0xf) { |
401 | chars_printed = snprintf_count(pbuf: pBuf, bufsize: remaining_buffer, fmt: "%x,%x,%x,%x,%x,%x,%x,%x,%x\n" , |
402 | i, s.opp_id, s.dpp_id, s.bot_mpcc_id, |
403 | s.mode, s.alpha_mode, s.pre_multiplied_alpha, s.overlap_only, |
404 | s.idle); |
405 | |
406 | remaining_buffer -= chars_printed; |
407 | pBuf += chars_printed; |
408 | } |
409 | } |
410 | |
411 | return bufSize - remaining_buffer; |
412 | } |
413 | |
414 | static unsigned int dcn10_get_otg_states(struct dc *dc, char *pBuf, unsigned int bufSize) |
415 | { |
416 | struct resource_pool *pool = dc->res_pool; |
417 | int i; |
418 | |
419 | unsigned int chars_printed = 0; |
420 | unsigned int remaining_buffer = bufSize; |
421 | |
422 | chars_printed = snprintf_count(pbuf: pBuf, bufsize: remaining_buffer, fmt: "instance,v_bs,v_be,v_ss,v_se,vpol,vmax,vmin,vmax_sel,vmin_sel," |
423 | "h_bs,h_be,h_ss,h_se,hpol,htot,vtot,underflow,pixelclk[khz]\n" ); |
424 | remaining_buffer -= chars_printed; |
425 | pBuf += chars_printed; |
426 | |
427 | for (i = 0; i < pool->timing_generator_count; i++) { |
428 | struct timing_generator *tg = pool->timing_generators[i]; |
429 | struct dcn_otg_state s = {0}; |
430 | int pix_clk = 0; |
431 | |
432 | optc1_read_otg_state(DCN10TG_FROM_TG(tg), s: &s); |
433 | pix_clk = dc->current_state->res_ctx.pipe_ctx[i].stream_res.pix_clk_params.requested_pix_clk_100hz / 10; |
434 | |
435 | //only print if OTG master is enabled |
436 | if (s.otg_enabled & 1) { |
437 | chars_printed = snprintf_count(pbuf: pBuf, bufsize: remaining_buffer, fmt: "%x,%d,%d,%d,%d,%d,%d,%d,%d,%d," |
438 | "%d,%d,%d,%d,%d,%d,%d,%d,%d" |
439 | "\n" , |
440 | tg->inst, |
441 | s.v_blank_start, |
442 | s.v_blank_end, |
443 | s.v_sync_a_start, |
444 | s.v_sync_a_end, |
445 | s.v_sync_a_pol, |
446 | s.v_total_max, |
447 | s.v_total_min, |
448 | s.v_total_max_sel, |
449 | s.v_total_min_sel, |
450 | s.h_blank_start, |
451 | s.h_blank_end, |
452 | s.h_sync_a_start, |
453 | s.h_sync_a_end, |
454 | s.h_sync_a_pol, |
455 | s.h_total, |
456 | s.v_total, |
457 | s.underflow_occurred_status, |
458 | pix_clk); |
459 | |
460 | remaining_buffer -= chars_printed; |
461 | pBuf += chars_printed; |
462 | } |
463 | } |
464 | |
465 | return bufSize - remaining_buffer; |
466 | } |
467 | |
468 | static unsigned int dcn10_get_clock_states(struct dc *dc, char *pBuf, unsigned int bufSize) |
469 | { |
470 | unsigned int chars_printed = 0; |
471 | unsigned int remaining_buffer = bufSize; |
472 | |
473 | chars_printed = snprintf_count(pbuf: pBuf, bufsize: bufSize, fmt: "dcfclk,dcfclk_deep_sleep,dispclk," |
474 | "dppclk,fclk,socclk\n" |
475 | "%d,%d,%d,%d,%d,%d\n" , |
476 | dc->current_state->bw_ctx.bw.dcn.clk.dcfclk_khz, |
477 | dc->current_state->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz, |
478 | dc->current_state->bw_ctx.bw.dcn.clk.dispclk_khz, |
479 | dc->current_state->bw_ctx.bw.dcn.clk.dppclk_khz, |
480 | dc->current_state->bw_ctx.bw.dcn.clk.fclk_khz, |
481 | dc->current_state->bw_ctx.bw.dcn.clk.socclk_khz); |
482 | |
483 | remaining_buffer -= chars_printed; |
484 | pBuf += chars_printed; |
485 | |
486 | return bufSize - remaining_buffer; |
487 | } |
488 | |
489 | static void dcn10_clear_otpc_underflow(struct dc *dc) |
490 | { |
491 | struct resource_pool *pool = dc->res_pool; |
492 | int i; |
493 | |
494 | for (i = 0; i < pool->timing_generator_count; i++) { |
495 | struct timing_generator *tg = pool->timing_generators[i]; |
496 | struct dcn_otg_state s = {0}; |
497 | |
498 | optc1_read_otg_state(DCN10TG_FROM_TG(tg), s: &s); |
499 | |
500 | if (s.otg_enabled & 1) |
501 | tg->funcs->clear_optc_underflow(tg); |
502 | } |
503 | } |
504 | |
505 | static void dcn10_clear_hubp_underflow(struct dc *dc) |
506 | { |
507 | struct resource_pool *pool = dc->res_pool; |
508 | int i; |
509 | |
510 | for (i = 0; i < pool->pipe_count; i++) { |
511 | struct hubp *hubp = pool->hubps[i]; |
512 | struct dcn_hubp_state *s = &(TO_DCN10_HUBP(hubp)->state); |
513 | |
514 | hubp->funcs->hubp_read_state(hubp); |
515 | |
516 | if (!s->blank_en) |
517 | hubp->funcs->hubp_clear_underflow(hubp); |
518 | } |
519 | } |
520 | |
521 | void dcn10_clear_status_bits(struct dc *dc, unsigned int mask) |
522 | { |
523 | /* |
524 | * Mask Format |
525 | * Bit 0 - 31: Status bit to clear |
526 | * |
527 | * Mask = 0x0 means clear all status bits |
528 | */ |
529 | const unsigned int DC_HW_STATE_MASK_HUBP_UNDERFLOW = 0x1; |
530 | const unsigned int DC_HW_STATE_MASK_OTPC_UNDERFLOW = 0x2; |
531 | |
532 | if (mask == 0x0) |
533 | mask = 0xFFFFFFFF; |
534 | |
535 | if (mask & DC_HW_STATE_MASK_HUBP_UNDERFLOW) |
536 | dcn10_clear_hubp_underflow(dc); |
537 | |
538 | if (mask & DC_HW_STATE_MASK_OTPC_UNDERFLOW) |
539 | dcn10_clear_otpc_underflow(dc); |
540 | } |
541 | |
542 | void dcn10_get_hw_state(struct dc *dc, char *pBuf, unsigned int bufSize, unsigned int mask) |
543 | { |
544 | /* |
545 | * Mask Format |
546 | * Bit 0 - 15: Hardware block mask |
547 | * Bit 15: 1 = Invariant Only, 0 = All |
548 | */ |
549 | const unsigned int DC_HW_STATE_MASK_HUBBUB = 0x1; |
550 | const unsigned int DC_HW_STATE_MASK_HUBP = 0x2; |
551 | const unsigned int DC_HW_STATE_MASK_RQ = 0x4; |
552 | const unsigned int DC_HW_STATE_MASK_DLG = 0x8; |
553 | const unsigned int DC_HW_STATE_MASK_TTU = 0x10; |
554 | const unsigned int DC_HW_STATE_MASK_CM = 0x20; |
555 | const unsigned int DC_HW_STATE_MASK_MPCC = 0x40; |
556 | const unsigned int DC_HW_STATE_MASK_OTG = 0x80; |
557 | const unsigned int DC_HW_STATE_MASK_CLOCKS = 0x100; |
558 | const unsigned int DC_HW_STATE_INVAR_ONLY = 0x8000; |
559 | |
560 | unsigned int chars_printed = 0; |
561 | unsigned int remaining_buf_size = bufSize; |
562 | |
563 | if (mask == 0x0) |
564 | mask = 0xFFFF; // Default, capture all, invariant only |
565 | |
566 | if ((mask & DC_HW_STATE_MASK_HUBBUB) && remaining_buf_size > 0) { |
567 | chars_printed = dcn10_get_hubbub_state(dc, pBuf, bufSize: remaining_buf_size); |
568 | pBuf += chars_printed; |
569 | remaining_buf_size -= chars_printed; |
570 | } |
571 | |
572 | if ((mask & DC_HW_STATE_MASK_HUBP) && remaining_buf_size > 0) { |
573 | chars_printed = dcn10_get_hubp_states(dc, pBuf, bufSize: remaining_buf_size, invarOnly: mask & DC_HW_STATE_INVAR_ONLY); |
574 | pBuf += chars_printed; |
575 | remaining_buf_size -= chars_printed; |
576 | } |
577 | |
578 | if ((mask & DC_HW_STATE_MASK_RQ) && remaining_buf_size > 0) { |
579 | chars_printed = dcn10_get_rq_states(dc, pBuf, bufSize: remaining_buf_size); |
580 | pBuf += chars_printed; |
581 | remaining_buf_size -= chars_printed; |
582 | } |
583 | |
584 | if ((mask & DC_HW_STATE_MASK_DLG) && remaining_buf_size > 0) { |
585 | chars_printed = dcn10_get_dlg_states(dc, pBuf, bufSize: remaining_buf_size); |
586 | pBuf += chars_printed; |
587 | remaining_buf_size -= chars_printed; |
588 | } |
589 | |
590 | if ((mask & DC_HW_STATE_MASK_TTU) && remaining_buf_size > 0) { |
591 | chars_printed = dcn10_get_ttu_states(dc, pBuf, bufSize: remaining_buf_size); |
592 | pBuf += chars_printed; |
593 | remaining_buf_size -= chars_printed; |
594 | } |
595 | |
596 | if ((mask & DC_HW_STATE_MASK_CM) && remaining_buf_size > 0) { |
597 | chars_printed = dcn10_get_cm_states(dc, pBuf, bufSize: remaining_buf_size); |
598 | pBuf += chars_printed; |
599 | remaining_buf_size -= chars_printed; |
600 | } |
601 | |
602 | if ((mask & DC_HW_STATE_MASK_MPCC) && remaining_buf_size > 0) { |
603 | chars_printed = dcn10_get_mpcc_states(dc, pBuf, bufSize: remaining_buf_size); |
604 | pBuf += chars_printed; |
605 | remaining_buf_size -= chars_printed; |
606 | } |
607 | |
608 | if ((mask & DC_HW_STATE_MASK_OTG) && remaining_buf_size > 0) { |
609 | chars_printed = dcn10_get_otg_states(dc, pBuf, bufSize: remaining_buf_size); |
610 | pBuf += chars_printed; |
611 | remaining_buf_size -= chars_printed; |
612 | } |
613 | |
614 | if ((mask & DC_HW_STATE_MASK_CLOCKS) && remaining_buf_size > 0) { |
615 | chars_printed = dcn10_get_clock_states(dc, pBuf, bufSize: remaining_buf_size); |
616 | pBuf += chars_printed; |
617 | remaining_buf_size -= chars_printed; |
618 | } |
619 | } |
620 | |