1 | // SPDX-License-Identifier: MIT |
2 | /* |
3 | * Copyright © 2019 Intel Corporation |
4 | */ |
5 | |
6 | #include <drm/drm_atomic_state_helper.h> |
7 | |
8 | #include "i915_drv.h" |
9 | #include "i915_reg.h" |
10 | #include "i915_utils.h" |
11 | #include "intel_atomic.h" |
12 | #include "intel_bw.h" |
13 | #include "intel_cdclk.h" |
14 | #include "intel_display_core.h" |
15 | #include "intel_display_types.h" |
16 | #include "skl_watermark.h" |
17 | #include "intel_mchbar_regs.h" |
18 | #include "intel_pcode.h" |
19 | |
20 | /* Parameters for Qclk Geyserville (QGV) */ |
21 | struct intel_qgv_point { |
22 | u16 dclk, t_rp, t_rdpre, t_rc, t_ras, t_rcd; |
23 | }; |
24 | |
25 | struct intel_psf_gv_point { |
26 | u8 clk; /* clock in multiples of 16.6666 MHz */ |
27 | }; |
28 | |
29 | struct intel_qgv_info { |
30 | struct intel_qgv_point points[I915_NUM_QGV_POINTS]; |
31 | struct intel_psf_gv_point psf_points[I915_NUM_PSF_GV_POINTS]; |
32 | u8 num_points; |
33 | u8 num_psf_points; |
34 | u8 t_bl; |
35 | u8 max_numchannels; |
36 | u8 channel_width; |
37 | u8 deinterleave; |
38 | }; |
39 | |
40 | static int dg1_mchbar_read_qgv_point_info(struct drm_i915_private *dev_priv, |
41 | struct intel_qgv_point *sp, |
42 | int point) |
43 | { |
44 | u32 dclk_ratio, dclk_reference; |
45 | u32 val; |
46 | |
47 | val = intel_uncore_read(uncore: &dev_priv->uncore, SA_PERF_STATUS_0_0_0_MCHBAR_PC); |
48 | dclk_ratio = REG_FIELD_GET(DG1_QCLK_RATIO_MASK, val); |
49 | if (val & DG1_QCLK_REFERENCE) |
50 | dclk_reference = 6; /* 6 * 16.666 MHz = 100 MHz */ |
51 | else |
52 | dclk_reference = 8; /* 8 * 16.666 MHz = 133 MHz */ |
53 | sp->dclk = DIV_ROUND_UP((16667 * dclk_ratio * dclk_reference) + 500, 1000); |
54 | |
55 | val = intel_uncore_read(uncore: &dev_priv->uncore, SKL_MC_BIOS_DATA_0_0_0_MCHBAR_PCU); |
56 | if (val & DG1_GEAR_TYPE) |
57 | sp->dclk *= 2; |
58 | |
59 | if (sp->dclk == 0) |
60 | return -EINVAL; |
61 | |
62 | val = intel_uncore_read(uncore: &dev_priv->uncore, MCHBAR_CH0_CR_TC_PRE_0_0_0_MCHBAR); |
63 | sp->t_rp = REG_FIELD_GET(DG1_DRAM_T_RP_MASK, val); |
64 | sp->t_rdpre = REG_FIELD_GET(DG1_DRAM_T_RDPRE_MASK, val); |
65 | |
66 | val = intel_uncore_read(uncore: &dev_priv->uncore, MCHBAR_CH0_CR_TC_PRE_0_0_0_MCHBAR_HIGH); |
67 | sp->t_rcd = REG_FIELD_GET(DG1_DRAM_T_RCD_MASK, val); |
68 | sp->t_ras = REG_FIELD_GET(DG1_DRAM_T_RAS_MASK, val); |
69 | |
70 | sp->t_rc = sp->t_rp + sp->t_ras; |
71 | |
72 | return 0; |
73 | } |
74 | |
75 | static int icl_pcode_read_qgv_point_info(struct drm_i915_private *dev_priv, |
76 | struct intel_qgv_point *sp, |
77 | int point) |
78 | { |
79 | u32 val = 0, val2 = 0; |
80 | u16 dclk; |
81 | int ret; |
82 | |
83 | ret = snb_pcode_read(uncore: &dev_priv->uncore, ICL_PCODE_MEM_SUBSYSYSTEM_INFO | |
84 | ICL_PCODE_MEM_SS_READ_QGV_POINT_INFO(point), |
85 | val: &val, val1: &val2); |
86 | if (ret) |
87 | return ret; |
88 | |
89 | dclk = val & 0xffff; |
90 | sp->dclk = DIV_ROUND_UP((16667 * dclk) + (DISPLAY_VER(dev_priv) >= 12 ? 500 : 0), |
91 | 1000); |
92 | sp->t_rp = (val & 0xff0000) >> 16; |
93 | sp->t_rcd = (val & 0xff000000) >> 24; |
94 | |
95 | sp->t_rdpre = val2 & 0xff; |
96 | sp->t_ras = (val2 & 0xff00) >> 8; |
97 | |
98 | sp->t_rc = sp->t_rp + sp->t_ras; |
99 | |
100 | return 0; |
101 | } |
102 | |
103 | static int adls_pcode_read_psf_gv_point_info(struct drm_i915_private *dev_priv, |
104 | struct intel_psf_gv_point *points) |
105 | { |
106 | u32 val = 0; |
107 | int ret; |
108 | int i; |
109 | |
110 | ret = snb_pcode_read(uncore: &dev_priv->uncore, ICL_PCODE_MEM_SUBSYSYSTEM_INFO | |
111 | ADL_PCODE_MEM_SS_READ_PSF_GV_INFO, val: &val, NULL); |
112 | if (ret) |
113 | return ret; |
114 | |
115 | for (i = 0; i < I915_NUM_PSF_GV_POINTS; i++) { |
116 | points[i].clk = val & 0xff; |
117 | val >>= 8; |
118 | } |
119 | |
120 | return 0; |
121 | } |
122 | |
123 | static u16 icl_qgv_points_mask(struct drm_i915_private *i915) |
124 | { |
125 | unsigned int num_psf_gv_points = i915->display.bw.max[0].num_psf_gv_points; |
126 | unsigned int num_qgv_points = i915->display.bw.max[0].num_qgv_points; |
127 | u16 qgv_points = 0, psf_points = 0; |
128 | |
129 | /* |
130 | * We can _not_ use the whole ADLS_QGV_PT_MASK here, as PCode rejects |
131 | * it with failure if we try masking any unadvertised points. |
132 | * So need to operate only with those returned from PCode. |
133 | */ |
134 | if (num_qgv_points > 0) |
135 | qgv_points = GENMASK(num_qgv_points - 1, 0); |
136 | |
137 | if (num_psf_gv_points > 0) |
138 | psf_points = GENMASK(num_psf_gv_points - 1, 0); |
139 | |
140 | return ICL_PCODE_REQ_QGV_PT(qgv_points) | ADLS_PCODE_REQ_PSF_PT(psf_points); |
141 | } |
142 | |
143 | static bool is_sagv_enabled(struct drm_i915_private *i915, u16 points_mask) |
144 | { |
145 | return !is_power_of_2(n: ~points_mask & icl_qgv_points_mask(i915) & |
146 | ICL_PCODE_REQ_QGV_PT_MASK); |
147 | } |
148 | |
149 | int icl_pcode_restrict_qgv_points(struct drm_i915_private *dev_priv, |
150 | u32 points_mask) |
151 | { |
152 | int ret; |
153 | |
154 | if (DISPLAY_VER(dev_priv) >= 14) |
155 | return 0; |
156 | |
157 | /* bspec says to keep retrying for at least 1 ms */ |
158 | ret = skl_pcode_request(uncore: &dev_priv->uncore, ICL_PCODE_SAGV_DE_MEM_SS_CONFIG, |
159 | request: points_mask, |
160 | ICL_PCODE_REP_QGV_MASK | ADLS_PCODE_REP_PSF_MASK, |
161 | ICL_PCODE_REP_QGV_SAFE | ADLS_PCODE_REP_PSF_SAFE, |
162 | timeout_base_ms: 1); |
163 | |
164 | if (ret < 0) { |
165 | drm_err(&dev_priv->drm, "Failed to disable qgv points (%d) points: 0x%x\n" , ret, points_mask); |
166 | return ret; |
167 | } |
168 | |
169 | dev_priv->display.sagv.status = is_sagv_enabled(i915: dev_priv, points_mask) ? |
170 | I915_SAGV_ENABLED : I915_SAGV_DISABLED; |
171 | |
172 | return 0; |
173 | } |
174 | |
175 | static int mtl_read_qgv_point_info(struct drm_i915_private *dev_priv, |
176 | struct intel_qgv_point *sp, int point) |
177 | { |
178 | u32 val, val2; |
179 | u16 dclk; |
180 | |
181 | val = intel_uncore_read(uncore: &dev_priv->uncore, |
182 | MTL_MEM_SS_INFO_QGV_POINT_LOW(point)); |
183 | val2 = intel_uncore_read(uncore: &dev_priv->uncore, |
184 | MTL_MEM_SS_INFO_QGV_POINT_HIGH(point)); |
185 | dclk = REG_FIELD_GET(MTL_DCLK_MASK, val); |
186 | sp->dclk = DIV_ROUND_CLOSEST(16667 * dclk, 1000); |
187 | sp->t_rp = REG_FIELD_GET(MTL_TRP_MASK, val); |
188 | sp->t_rcd = REG_FIELD_GET(MTL_TRCD_MASK, val); |
189 | |
190 | sp->t_rdpre = REG_FIELD_GET(MTL_TRDPRE_MASK, val2); |
191 | sp->t_ras = REG_FIELD_GET(MTL_TRAS_MASK, val2); |
192 | |
193 | sp->t_rc = sp->t_rp + sp->t_ras; |
194 | |
195 | return 0; |
196 | } |
197 | |
198 | static int |
199 | intel_read_qgv_point_info(struct drm_i915_private *dev_priv, |
200 | struct intel_qgv_point *sp, |
201 | int point) |
202 | { |
203 | if (DISPLAY_VER(dev_priv) >= 14) |
204 | return mtl_read_qgv_point_info(dev_priv, sp, point); |
205 | else if (IS_DG1(dev_priv)) |
206 | return dg1_mchbar_read_qgv_point_info(dev_priv, sp, point); |
207 | else |
208 | return icl_pcode_read_qgv_point_info(dev_priv, sp, point); |
209 | } |
210 | |
211 | static int icl_get_qgv_points(struct drm_i915_private *dev_priv, |
212 | struct intel_qgv_info *qi, |
213 | bool is_y_tile) |
214 | { |
215 | const struct dram_info *dram_info = &dev_priv->dram_info; |
216 | int i, ret; |
217 | |
218 | qi->num_points = dram_info->num_qgv_points; |
219 | qi->num_psf_points = dram_info->num_psf_gv_points; |
220 | |
221 | if (DISPLAY_VER(dev_priv) >= 14) { |
222 | switch (dram_info->type) { |
223 | case INTEL_DRAM_DDR4: |
224 | qi->t_bl = 4; |
225 | qi->max_numchannels = 2; |
226 | qi->channel_width = 64; |
227 | qi->deinterleave = 2; |
228 | break; |
229 | case INTEL_DRAM_DDR5: |
230 | qi->t_bl = 8; |
231 | qi->max_numchannels = 4; |
232 | qi->channel_width = 32; |
233 | qi->deinterleave = 2; |
234 | break; |
235 | case INTEL_DRAM_LPDDR4: |
236 | case INTEL_DRAM_LPDDR5: |
237 | qi->t_bl = 16; |
238 | qi->max_numchannels = 8; |
239 | qi->channel_width = 16; |
240 | qi->deinterleave = 4; |
241 | break; |
242 | default: |
243 | MISSING_CASE(dram_info->type); |
244 | return -EINVAL; |
245 | } |
246 | } else if (DISPLAY_VER(dev_priv) >= 12) { |
247 | switch (dram_info->type) { |
248 | case INTEL_DRAM_DDR4: |
249 | qi->t_bl = is_y_tile ? 8 : 4; |
250 | qi->max_numchannels = 2; |
251 | qi->channel_width = 64; |
252 | qi->deinterleave = is_y_tile ? 1 : 2; |
253 | break; |
254 | case INTEL_DRAM_DDR5: |
255 | qi->t_bl = is_y_tile ? 16 : 8; |
256 | qi->max_numchannels = 4; |
257 | qi->channel_width = 32; |
258 | qi->deinterleave = is_y_tile ? 1 : 2; |
259 | break; |
260 | case INTEL_DRAM_LPDDR4: |
261 | if (IS_ROCKETLAKE(dev_priv)) { |
262 | qi->t_bl = 8; |
263 | qi->max_numchannels = 4; |
264 | qi->channel_width = 32; |
265 | qi->deinterleave = 2; |
266 | break; |
267 | } |
268 | fallthrough; |
269 | case INTEL_DRAM_LPDDR5: |
270 | qi->t_bl = 16; |
271 | qi->max_numchannels = 8; |
272 | qi->channel_width = 16; |
273 | qi->deinterleave = is_y_tile ? 2 : 4; |
274 | break; |
275 | default: |
276 | qi->t_bl = 16; |
277 | qi->max_numchannels = 1; |
278 | break; |
279 | } |
280 | } else if (DISPLAY_VER(dev_priv) == 11) { |
281 | qi->t_bl = dev_priv->dram_info.type == INTEL_DRAM_DDR4 ? 4 : 8; |
282 | qi->max_numchannels = 1; |
283 | } |
284 | |
285 | if (drm_WARN_ON(&dev_priv->drm, |
286 | qi->num_points > ARRAY_SIZE(qi->points))) |
287 | qi->num_points = ARRAY_SIZE(qi->points); |
288 | |
289 | for (i = 0; i < qi->num_points; i++) { |
290 | struct intel_qgv_point *sp = &qi->points[i]; |
291 | |
292 | ret = intel_read_qgv_point_info(dev_priv, sp, point: i); |
293 | if (ret) |
294 | return ret; |
295 | |
296 | drm_dbg_kms(&dev_priv->drm, |
297 | "QGV %d: DCLK=%d tRP=%d tRDPRE=%d tRAS=%d tRCD=%d tRC=%d\n" , |
298 | i, sp->dclk, sp->t_rp, sp->t_rdpre, sp->t_ras, |
299 | sp->t_rcd, sp->t_rc); |
300 | } |
301 | |
302 | if (qi->num_psf_points > 0) { |
303 | ret = adls_pcode_read_psf_gv_point_info(dev_priv, points: qi->psf_points); |
304 | if (ret) { |
305 | drm_err(&dev_priv->drm, "Failed to read PSF point data; PSF points will not be considered in bandwidth calculations.\n" ); |
306 | qi->num_psf_points = 0; |
307 | } |
308 | |
309 | for (i = 0; i < qi->num_psf_points; i++) |
310 | drm_dbg_kms(&dev_priv->drm, |
311 | "PSF GV %d: CLK=%d \n" , |
312 | i, qi->psf_points[i].clk); |
313 | } |
314 | |
315 | return 0; |
316 | } |
317 | |
318 | static int adl_calc_psf_bw(int clk) |
319 | { |
320 | /* |
321 | * clk is multiples of 16.666MHz (100/6) |
322 | * According to BSpec PSF GV bandwidth is |
323 | * calculated as BW = 64 * clk * 16.666Mhz |
324 | */ |
325 | return DIV_ROUND_CLOSEST(64 * clk * 100, 6); |
326 | } |
327 | |
328 | static int icl_sagv_max_dclk(const struct intel_qgv_info *qi) |
329 | { |
330 | u16 dclk = 0; |
331 | int i; |
332 | |
333 | for (i = 0; i < qi->num_points; i++) |
334 | dclk = max(dclk, qi->points[i].dclk); |
335 | |
336 | return dclk; |
337 | } |
338 | |
339 | struct intel_sa_info { |
340 | u16 displayrtids; |
341 | u8 deburst, deprogbwlimit, derating; |
342 | }; |
343 | |
344 | static const struct intel_sa_info icl_sa_info = { |
345 | .deburst = 8, |
346 | .deprogbwlimit = 25, /* GB/s */ |
347 | .displayrtids = 128, |
348 | .derating = 10, |
349 | }; |
350 | |
351 | static const struct intel_sa_info tgl_sa_info = { |
352 | .deburst = 16, |
353 | .deprogbwlimit = 34, /* GB/s */ |
354 | .displayrtids = 256, |
355 | .derating = 10, |
356 | }; |
357 | |
358 | static const struct intel_sa_info rkl_sa_info = { |
359 | .deburst = 8, |
360 | .deprogbwlimit = 20, /* GB/s */ |
361 | .displayrtids = 128, |
362 | .derating = 10, |
363 | }; |
364 | |
365 | static const struct intel_sa_info adls_sa_info = { |
366 | .deburst = 16, |
367 | .deprogbwlimit = 38, /* GB/s */ |
368 | .displayrtids = 256, |
369 | .derating = 10, |
370 | }; |
371 | |
372 | static const struct intel_sa_info adlp_sa_info = { |
373 | .deburst = 16, |
374 | .deprogbwlimit = 38, /* GB/s */ |
375 | .displayrtids = 256, |
376 | .derating = 20, |
377 | }; |
378 | |
379 | static const struct intel_sa_info mtl_sa_info = { |
380 | .deburst = 32, |
381 | .deprogbwlimit = 38, /* GB/s */ |
382 | .displayrtids = 256, |
383 | .derating = 10, |
384 | }; |
385 | |
386 | static int icl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel_sa_info *sa) |
387 | { |
388 | struct intel_qgv_info qi = {}; |
389 | bool is_y_tile = true; /* assume y tile may be used */ |
390 | int num_channels = max_t(u8, 1, dev_priv->dram_info.num_channels); |
391 | int ipqdepth, ipqdepthpch = 16; |
392 | int dclk_max; |
393 | int maxdebw; |
394 | int num_groups = ARRAY_SIZE(dev_priv->display.bw.max); |
395 | int i, ret; |
396 | |
397 | ret = icl_get_qgv_points(dev_priv, qi: &qi, is_y_tile); |
398 | if (ret) { |
399 | drm_dbg_kms(&dev_priv->drm, |
400 | "Failed to get memory subsystem information, ignoring bandwidth limits" ); |
401 | return ret; |
402 | } |
403 | |
404 | dclk_max = icl_sagv_max_dclk(qi: &qi); |
405 | maxdebw = min(sa->deprogbwlimit * 1000, dclk_max * 16 * 6 / 10); |
406 | ipqdepth = min(ipqdepthpch, sa->displayrtids / num_channels); |
407 | qi.deinterleave = DIV_ROUND_UP(num_channels, is_y_tile ? 4 : 2); |
408 | |
409 | for (i = 0; i < num_groups; i++) { |
410 | struct intel_bw_info *bi = &dev_priv->display.bw.max[i]; |
411 | int clpchgroup; |
412 | int j; |
413 | |
414 | clpchgroup = (sa->deburst * qi.deinterleave / num_channels) << i; |
415 | bi->num_planes = (ipqdepth - clpchgroup) / clpchgroup + 1; |
416 | |
417 | bi->num_qgv_points = qi.num_points; |
418 | bi->num_psf_gv_points = qi.num_psf_points; |
419 | |
420 | for (j = 0; j < qi.num_points; j++) { |
421 | const struct intel_qgv_point *sp = &qi.points[j]; |
422 | int ct, bw; |
423 | |
424 | /* |
425 | * Max row cycle time |
426 | * |
427 | * FIXME what is the logic behind the |
428 | * assumed burst length? |
429 | */ |
430 | ct = max_t(int, sp->t_rc, sp->t_rp + sp->t_rcd + |
431 | (clpchgroup - 1) * qi.t_bl + sp->t_rdpre); |
432 | bw = DIV_ROUND_UP(sp->dclk * clpchgroup * 32 * num_channels, ct); |
433 | |
434 | bi->deratedbw[j] = min(maxdebw, |
435 | bw * (100 - sa->derating) / 100); |
436 | |
437 | drm_dbg_kms(&dev_priv->drm, |
438 | "BW%d / QGV %d: num_planes=%d deratedbw=%u\n" , |
439 | i, j, bi->num_planes, bi->deratedbw[j]); |
440 | } |
441 | } |
442 | /* |
443 | * In case if SAGV is disabled in BIOS, we always get 1 |
444 | * SAGV point, but we can't send PCode commands to restrict it |
445 | * as it will fail and pointless anyway. |
446 | */ |
447 | if (qi.num_points == 1) |
448 | dev_priv->display.sagv.status = I915_SAGV_NOT_CONTROLLED; |
449 | else |
450 | dev_priv->display.sagv.status = I915_SAGV_ENABLED; |
451 | |
452 | return 0; |
453 | } |
454 | |
455 | static int tgl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel_sa_info *sa) |
456 | { |
457 | struct intel_qgv_info qi = {}; |
458 | const struct dram_info *dram_info = &dev_priv->dram_info; |
459 | bool is_y_tile = true; /* assume y tile may be used */ |
460 | int num_channels = max_t(u8, 1, dev_priv->dram_info.num_channels); |
461 | int ipqdepth, ipqdepthpch = 16; |
462 | int dclk_max; |
463 | int maxdebw, peakbw; |
464 | int clperchgroup; |
465 | int num_groups = ARRAY_SIZE(dev_priv->display.bw.max); |
466 | int i, ret; |
467 | |
468 | ret = icl_get_qgv_points(dev_priv, qi: &qi, is_y_tile); |
469 | if (ret) { |
470 | drm_dbg_kms(&dev_priv->drm, |
471 | "Failed to get memory subsystem information, ignoring bandwidth limits" ); |
472 | return ret; |
473 | } |
474 | |
475 | if (DISPLAY_VER(dev_priv) < 14 && |
476 | (dram_info->type == INTEL_DRAM_LPDDR4 || dram_info->type == INTEL_DRAM_LPDDR5)) |
477 | num_channels *= 2; |
478 | |
479 | qi.deinterleave = qi.deinterleave ? : DIV_ROUND_UP(num_channels, is_y_tile ? 4 : 2); |
480 | |
481 | if (num_channels < qi.max_numchannels && DISPLAY_VER(dev_priv) >= 12) |
482 | qi.deinterleave = max(DIV_ROUND_UP(qi.deinterleave, 2), 1); |
483 | |
484 | if (DISPLAY_VER(dev_priv) >= 12 && num_channels > qi.max_numchannels) |
485 | drm_warn(&dev_priv->drm, "Number of channels exceeds max number of channels." ); |
486 | if (qi.max_numchannels != 0) |
487 | num_channels = min_t(u8, num_channels, qi.max_numchannels); |
488 | |
489 | dclk_max = icl_sagv_max_dclk(qi: &qi); |
490 | |
491 | peakbw = num_channels * DIV_ROUND_UP(qi.channel_width, 8) * dclk_max; |
492 | maxdebw = min(sa->deprogbwlimit * 1000, peakbw * 6 / 10); /* 60% */ |
493 | |
494 | ipqdepth = min(ipqdepthpch, sa->displayrtids / num_channels); |
495 | /* |
496 | * clperchgroup = 4kpagespermempage * clperchperblock, |
497 | * clperchperblock = 8 / num_channels * interleave |
498 | */ |
499 | clperchgroup = 4 * DIV_ROUND_UP(8, num_channels) * qi.deinterleave; |
500 | |
501 | for (i = 0; i < num_groups; i++) { |
502 | struct intel_bw_info *bi = &dev_priv->display.bw.max[i]; |
503 | struct intel_bw_info *bi_next; |
504 | int clpchgroup; |
505 | int j; |
506 | |
507 | clpchgroup = (sa->deburst * qi.deinterleave / num_channels) << i; |
508 | |
509 | if (i < num_groups - 1) { |
510 | bi_next = &dev_priv->display.bw.max[i + 1]; |
511 | |
512 | if (clpchgroup < clperchgroup) |
513 | bi_next->num_planes = (ipqdepth - clpchgroup) / |
514 | clpchgroup + 1; |
515 | else |
516 | bi_next->num_planes = 0; |
517 | } |
518 | |
519 | bi->num_qgv_points = qi.num_points; |
520 | bi->num_psf_gv_points = qi.num_psf_points; |
521 | |
522 | for (j = 0; j < qi.num_points; j++) { |
523 | const struct intel_qgv_point *sp = &qi.points[j]; |
524 | int ct, bw; |
525 | |
526 | /* |
527 | * Max row cycle time |
528 | * |
529 | * FIXME what is the logic behind the |
530 | * assumed burst length? |
531 | */ |
532 | ct = max_t(int, sp->t_rc, sp->t_rp + sp->t_rcd + |
533 | (clpchgroup - 1) * qi.t_bl + sp->t_rdpre); |
534 | bw = DIV_ROUND_UP(sp->dclk * clpchgroup * 32 * num_channels, ct); |
535 | |
536 | bi->deratedbw[j] = min(maxdebw, |
537 | bw * (100 - sa->derating) / 100); |
538 | bi->peakbw[j] = DIV_ROUND_CLOSEST(sp->dclk * |
539 | num_channels * |
540 | qi.channel_width, 8); |
541 | |
542 | drm_dbg_kms(&dev_priv->drm, |
543 | "BW%d / QGV %d: num_planes=%d deratedbw=%u peakbw: %u\n" , |
544 | i, j, bi->num_planes, bi->deratedbw[j], |
545 | bi->peakbw[j]); |
546 | } |
547 | |
548 | for (j = 0; j < qi.num_psf_points; j++) { |
549 | const struct intel_psf_gv_point *sp = &qi.psf_points[j]; |
550 | |
551 | bi->psf_bw[j] = adl_calc_psf_bw(clk: sp->clk); |
552 | |
553 | drm_dbg_kms(&dev_priv->drm, |
554 | "BW%d / PSF GV %d: num_planes=%d bw=%u\n" , |
555 | i, j, bi->num_planes, bi->psf_bw[j]); |
556 | } |
557 | } |
558 | |
559 | /* |
560 | * In case if SAGV is disabled in BIOS, we always get 1 |
561 | * SAGV point, but we can't send PCode commands to restrict it |
562 | * as it will fail and pointless anyway. |
563 | */ |
564 | if (qi.num_points == 1) |
565 | dev_priv->display.sagv.status = I915_SAGV_NOT_CONTROLLED; |
566 | else |
567 | dev_priv->display.sagv.status = I915_SAGV_ENABLED; |
568 | |
569 | return 0; |
570 | } |
571 | |
572 | static void dg2_get_bw_info(struct drm_i915_private *i915) |
573 | { |
574 | unsigned int deratedbw = IS_DG2_G11(i915) ? 38000 : 50000; |
575 | int num_groups = ARRAY_SIZE(i915->display.bw.max); |
576 | int i; |
577 | |
578 | /* |
579 | * DG2 doesn't have SAGV or QGV points, just a constant max bandwidth |
580 | * that doesn't depend on the number of planes enabled. So fill all the |
581 | * plane group with constant bw information for uniformity with other |
582 | * platforms. DG2-G10 platforms have a constant 50 GB/s bandwidth, |
583 | * whereas DG2-G11 platforms have 38 GB/s. |
584 | */ |
585 | for (i = 0; i < num_groups; i++) { |
586 | struct intel_bw_info *bi = &i915->display.bw.max[i]; |
587 | |
588 | bi->num_planes = 1; |
589 | /* Need only one dummy QGV point per group */ |
590 | bi->num_qgv_points = 1; |
591 | bi->deratedbw[0] = deratedbw; |
592 | } |
593 | |
594 | i915->display.sagv.status = I915_SAGV_NOT_CONTROLLED; |
595 | } |
596 | |
597 | static unsigned int icl_max_bw_index(struct drm_i915_private *dev_priv, |
598 | int num_planes, int qgv_point) |
599 | { |
600 | int i; |
601 | |
602 | /* |
603 | * Let's return max bw for 0 planes |
604 | */ |
605 | num_planes = max(1, num_planes); |
606 | |
607 | for (i = 0; i < ARRAY_SIZE(dev_priv->display.bw.max); i++) { |
608 | const struct intel_bw_info *bi = |
609 | &dev_priv->display.bw.max[i]; |
610 | |
611 | /* |
612 | * Pcode will not expose all QGV points when |
613 | * SAGV is forced to off/min/med/max. |
614 | */ |
615 | if (qgv_point >= bi->num_qgv_points) |
616 | return UINT_MAX; |
617 | |
618 | if (num_planes >= bi->num_planes) |
619 | return i; |
620 | } |
621 | |
622 | return UINT_MAX; |
623 | } |
624 | |
625 | static unsigned int tgl_max_bw_index(struct drm_i915_private *dev_priv, |
626 | int num_planes, int qgv_point) |
627 | { |
628 | int i; |
629 | |
630 | /* |
631 | * Let's return max bw for 0 planes |
632 | */ |
633 | num_planes = max(1, num_planes); |
634 | |
635 | for (i = ARRAY_SIZE(dev_priv->display.bw.max) - 1; i >= 0; i--) { |
636 | const struct intel_bw_info *bi = |
637 | &dev_priv->display.bw.max[i]; |
638 | |
639 | /* |
640 | * Pcode will not expose all QGV points when |
641 | * SAGV is forced to off/min/med/max. |
642 | */ |
643 | if (qgv_point >= bi->num_qgv_points) |
644 | return UINT_MAX; |
645 | |
646 | if (num_planes <= bi->num_planes) |
647 | return i; |
648 | } |
649 | |
650 | return 0; |
651 | } |
652 | |
653 | static unsigned int adl_psf_bw(struct drm_i915_private *dev_priv, |
654 | int psf_gv_point) |
655 | { |
656 | const struct intel_bw_info *bi = |
657 | &dev_priv->display.bw.max[0]; |
658 | |
659 | return bi->psf_bw[psf_gv_point]; |
660 | } |
661 | |
662 | void intel_bw_init_hw(struct drm_i915_private *dev_priv) |
663 | { |
664 | if (!HAS_DISPLAY(dev_priv)) |
665 | return; |
666 | |
667 | if (DISPLAY_VER(dev_priv) >= 14) |
668 | tgl_get_bw_info(dev_priv, sa: &mtl_sa_info); |
669 | else if (IS_DG2(dev_priv)) |
670 | dg2_get_bw_info(i915: dev_priv); |
671 | else if (IS_ALDERLAKE_P(dev_priv)) |
672 | tgl_get_bw_info(dev_priv, sa: &adlp_sa_info); |
673 | else if (IS_ALDERLAKE_S(dev_priv)) |
674 | tgl_get_bw_info(dev_priv, sa: &adls_sa_info); |
675 | else if (IS_ROCKETLAKE(dev_priv)) |
676 | tgl_get_bw_info(dev_priv, sa: &rkl_sa_info); |
677 | else if (DISPLAY_VER(dev_priv) == 12) |
678 | tgl_get_bw_info(dev_priv, sa: &tgl_sa_info); |
679 | else if (DISPLAY_VER(dev_priv) == 11) |
680 | icl_get_bw_info(dev_priv, sa: &icl_sa_info); |
681 | } |
682 | |
683 | static unsigned int intel_bw_crtc_num_active_planes(const struct intel_crtc_state *crtc_state) |
684 | { |
685 | /* |
686 | * We assume cursors are small enough |
687 | * to not not cause bandwidth problems. |
688 | */ |
689 | return hweight8(crtc_state->active_planes & ~BIT(PLANE_CURSOR)); |
690 | } |
691 | |
692 | static unsigned int intel_bw_crtc_data_rate(const struct intel_crtc_state *crtc_state) |
693 | { |
694 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); |
695 | struct drm_i915_private *i915 = to_i915(dev: crtc->base.dev); |
696 | unsigned int data_rate = 0; |
697 | enum plane_id plane_id; |
698 | |
699 | for_each_plane_id_on_crtc(crtc, plane_id) { |
700 | /* |
701 | * We assume cursors are small enough |
702 | * to not not cause bandwidth problems. |
703 | */ |
704 | if (plane_id == PLANE_CURSOR) |
705 | continue; |
706 | |
707 | data_rate += crtc_state->data_rate[plane_id]; |
708 | |
709 | if (DISPLAY_VER(i915) < 11) |
710 | data_rate += crtc_state->data_rate_y[plane_id]; |
711 | } |
712 | |
713 | return data_rate; |
714 | } |
715 | |
716 | /* "Maximum Pipe Read Bandwidth" */ |
717 | static int intel_bw_crtc_min_cdclk(const struct intel_crtc_state *crtc_state) |
718 | { |
719 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); |
720 | struct drm_i915_private *i915 = to_i915(dev: crtc->base.dev); |
721 | |
722 | if (DISPLAY_VER(i915) < 12) |
723 | return 0; |
724 | |
725 | return DIV_ROUND_UP_ULL(mul_u32_u32(intel_bw_crtc_data_rate(crtc_state), 10), 512); |
726 | } |
727 | |
728 | void intel_bw_crtc_update(struct intel_bw_state *bw_state, |
729 | const struct intel_crtc_state *crtc_state) |
730 | { |
731 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); |
732 | struct drm_i915_private *i915 = to_i915(dev: crtc->base.dev); |
733 | |
734 | bw_state->data_rate[crtc->pipe] = |
735 | intel_bw_crtc_data_rate(crtc_state); |
736 | bw_state->num_active_planes[crtc->pipe] = |
737 | intel_bw_crtc_num_active_planes(crtc_state); |
738 | |
739 | drm_dbg_kms(&i915->drm, "pipe %c data rate %u num active planes %u\n" , |
740 | pipe_name(crtc->pipe), |
741 | bw_state->data_rate[crtc->pipe], |
742 | bw_state->num_active_planes[crtc->pipe]); |
743 | } |
744 | |
745 | static unsigned int intel_bw_num_active_planes(struct drm_i915_private *dev_priv, |
746 | const struct intel_bw_state *bw_state) |
747 | { |
748 | unsigned int num_active_planes = 0; |
749 | enum pipe pipe; |
750 | |
751 | for_each_pipe(dev_priv, pipe) |
752 | num_active_planes += bw_state->num_active_planes[pipe]; |
753 | |
754 | return num_active_planes; |
755 | } |
756 | |
757 | static unsigned int intel_bw_data_rate(struct drm_i915_private *dev_priv, |
758 | const struct intel_bw_state *bw_state) |
759 | { |
760 | unsigned int data_rate = 0; |
761 | enum pipe pipe; |
762 | |
763 | for_each_pipe(dev_priv, pipe) |
764 | data_rate += bw_state->data_rate[pipe]; |
765 | |
766 | if (DISPLAY_VER(dev_priv) >= 13 && i915_vtd_active(i915: dev_priv)) |
767 | data_rate = DIV_ROUND_UP(data_rate * 105, 100); |
768 | |
769 | return data_rate; |
770 | } |
771 | |
772 | struct intel_bw_state * |
773 | intel_atomic_get_old_bw_state(struct intel_atomic_state *state) |
774 | { |
775 | struct drm_i915_private *dev_priv = to_i915(dev: state->base.dev); |
776 | struct intel_global_state *bw_state; |
777 | |
778 | bw_state = intel_atomic_get_old_global_obj_state(state, obj: &dev_priv->display.bw.obj); |
779 | |
780 | return to_intel_bw_state(bw_state); |
781 | } |
782 | |
783 | struct intel_bw_state * |
784 | intel_atomic_get_new_bw_state(struct intel_atomic_state *state) |
785 | { |
786 | struct drm_i915_private *dev_priv = to_i915(dev: state->base.dev); |
787 | struct intel_global_state *bw_state; |
788 | |
789 | bw_state = intel_atomic_get_new_global_obj_state(state, obj: &dev_priv->display.bw.obj); |
790 | |
791 | return to_intel_bw_state(bw_state); |
792 | } |
793 | |
794 | struct intel_bw_state * |
795 | intel_atomic_get_bw_state(struct intel_atomic_state *state) |
796 | { |
797 | struct drm_i915_private *dev_priv = to_i915(dev: state->base.dev); |
798 | struct intel_global_state *bw_state; |
799 | |
800 | bw_state = intel_atomic_get_global_obj_state(state, obj: &dev_priv->display.bw.obj); |
801 | if (IS_ERR(ptr: bw_state)) |
802 | return ERR_CAST(ptr: bw_state); |
803 | |
804 | return to_intel_bw_state(bw_state); |
805 | } |
806 | |
807 | static int mtl_find_qgv_points(struct drm_i915_private *i915, |
808 | unsigned int data_rate, |
809 | unsigned int num_active_planes, |
810 | struct intel_bw_state *new_bw_state) |
811 | { |
812 | unsigned int best_rate = UINT_MAX; |
813 | unsigned int num_qgv_points = i915->display.bw.max[0].num_qgv_points; |
814 | unsigned int qgv_peak_bw = 0; |
815 | int i; |
816 | int ret; |
817 | |
818 | ret = intel_atomic_lock_global_state(obj_state: &new_bw_state->base); |
819 | if (ret) |
820 | return ret; |
821 | |
822 | /* |
823 | * If SAGV cannot be enabled, disable the pcode SAGV by passing all 1's |
824 | * for qgv peak bw in PM Demand request. So assign UINT_MAX if SAGV is |
825 | * not enabled. PM Demand code will clamp the value for the register |
826 | */ |
827 | if (!intel_can_enable_sagv(i915, bw_state: new_bw_state)) { |
828 | new_bw_state->qgv_point_peakbw = U16_MAX; |
829 | drm_dbg_kms(&i915->drm, "No SAGV, use UINT_MAX as peak bw." ); |
830 | return 0; |
831 | } |
832 | |
833 | /* |
834 | * Find the best QGV point by comparing the data_rate with max data rate |
835 | * offered per plane group |
836 | */ |
837 | for (i = 0; i < num_qgv_points; i++) { |
838 | unsigned int bw_index = |
839 | tgl_max_bw_index(dev_priv: i915, num_planes: num_active_planes, qgv_point: i); |
840 | unsigned int max_data_rate; |
841 | |
842 | if (bw_index >= ARRAY_SIZE(i915->display.bw.max)) |
843 | continue; |
844 | |
845 | max_data_rate = i915->display.bw.max[bw_index].deratedbw[i]; |
846 | |
847 | if (max_data_rate < data_rate) |
848 | continue; |
849 | |
850 | if (max_data_rate - data_rate < best_rate) { |
851 | best_rate = max_data_rate - data_rate; |
852 | qgv_peak_bw = i915->display.bw.max[bw_index].peakbw[i]; |
853 | } |
854 | |
855 | drm_dbg_kms(&i915->drm, "QGV point %d: max bw %d required %d qgv_peak_bw: %d\n" , |
856 | i, max_data_rate, data_rate, qgv_peak_bw); |
857 | } |
858 | |
859 | drm_dbg_kms(&i915->drm, "Matching peaks QGV bw: %d for required data rate: %d\n" , |
860 | qgv_peak_bw, data_rate); |
861 | |
862 | /* |
863 | * The display configuration cannot be supported if no QGV point |
864 | * satisfying the required data rate is found |
865 | */ |
866 | if (qgv_peak_bw == 0) { |
867 | drm_dbg_kms(&i915->drm, "No QGV points for bw %d for display configuration(%d active planes).\n" , |
868 | data_rate, num_active_planes); |
869 | return -EINVAL; |
870 | } |
871 | |
872 | /* MTL PM DEMAND expects QGV BW parameter in multiples of 100 mbps */ |
873 | new_bw_state->qgv_point_peakbw = DIV_ROUND_CLOSEST(qgv_peak_bw, 100); |
874 | |
875 | return 0; |
876 | } |
877 | |
878 | static int icl_find_qgv_points(struct drm_i915_private *i915, |
879 | unsigned int data_rate, |
880 | unsigned int num_active_planes, |
881 | const struct intel_bw_state *old_bw_state, |
882 | struct intel_bw_state *new_bw_state) |
883 | { |
884 | unsigned int max_bw_point = 0; |
885 | unsigned int max_bw = 0; |
886 | unsigned int num_psf_gv_points = i915->display.bw.max[0].num_psf_gv_points; |
887 | unsigned int num_qgv_points = i915->display.bw.max[0].num_qgv_points; |
888 | u16 psf_points = 0; |
889 | u16 qgv_points = 0; |
890 | int i; |
891 | int ret; |
892 | |
893 | ret = intel_atomic_lock_global_state(obj_state: &new_bw_state->base); |
894 | if (ret) |
895 | return ret; |
896 | |
897 | for (i = 0; i < num_qgv_points; i++) { |
898 | unsigned int idx; |
899 | unsigned int max_data_rate; |
900 | |
901 | if (DISPLAY_VER(i915) >= 12) |
902 | idx = tgl_max_bw_index(dev_priv: i915, num_planes: num_active_planes, qgv_point: i); |
903 | else |
904 | idx = icl_max_bw_index(dev_priv: i915, num_planes: num_active_planes, qgv_point: i); |
905 | |
906 | if (idx >= ARRAY_SIZE(i915->display.bw.max)) |
907 | continue; |
908 | |
909 | max_data_rate = i915->display.bw.max[idx].deratedbw[i]; |
910 | |
911 | /* |
912 | * We need to know which qgv point gives us |
913 | * maximum bandwidth in order to disable SAGV |
914 | * if we find that we exceed SAGV block time |
915 | * with watermarks. By that moment we already |
916 | * have those, as it is calculated earlier in |
917 | * intel_atomic_check, |
918 | */ |
919 | if (max_data_rate > max_bw) { |
920 | max_bw_point = i; |
921 | max_bw = max_data_rate; |
922 | } |
923 | if (max_data_rate >= data_rate) |
924 | qgv_points |= BIT(i); |
925 | |
926 | drm_dbg_kms(&i915->drm, "QGV point %d: max bw %d required %d\n" , |
927 | i, max_data_rate, data_rate); |
928 | } |
929 | |
930 | for (i = 0; i < num_psf_gv_points; i++) { |
931 | unsigned int max_data_rate = adl_psf_bw(dev_priv: i915, psf_gv_point: i); |
932 | |
933 | if (max_data_rate >= data_rate) |
934 | psf_points |= BIT(i); |
935 | |
936 | drm_dbg_kms(&i915->drm, "PSF GV point %d: max bw %d" |
937 | " required %d\n" , |
938 | i, max_data_rate, data_rate); |
939 | } |
940 | |
941 | /* |
942 | * BSpec states that we always should have at least one allowed point |
943 | * left, so if we couldn't - simply reject the configuration for obvious |
944 | * reasons. |
945 | */ |
946 | if (qgv_points == 0) { |
947 | drm_dbg_kms(&i915->drm, "No QGV points provide sufficient memory" |
948 | " bandwidth %d for display configuration(%d active planes).\n" , |
949 | data_rate, num_active_planes); |
950 | return -EINVAL; |
951 | } |
952 | |
953 | if (num_psf_gv_points > 0 && psf_points == 0) { |
954 | drm_dbg_kms(&i915->drm, "No PSF GV points provide sufficient memory" |
955 | " bandwidth %d for display configuration(%d active planes).\n" , |
956 | data_rate, num_active_planes); |
957 | return -EINVAL; |
958 | } |
959 | |
960 | /* |
961 | * Leave only single point with highest bandwidth, if |
962 | * we can't enable SAGV due to the increased memory latency it may |
963 | * cause. |
964 | */ |
965 | if (!intel_can_enable_sagv(i915, bw_state: new_bw_state)) { |
966 | qgv_points = BIT(max_bw_point); |
967 | drm_dbg_kms(&i915->drm, "No SAGV, using single QGV point %d\n" , |
968 | max_bw_point); |
969 | } |
970 | |
971 | /* |
972 | * We store the ones which need to be masked as that is what PCode |
973 | * actually accepts as a parameter. |
974 | */ |
975 | new_bw_state->qgv_points_mask = |
976 | ~(ICL_PCODE_REQ_QGV_PT(qgv_points) | |
977 | ADLS_PCODE_REQ_PSF_PT(psf_points)) & |
978 | icl_qgv_points_mask(i915); |
979 | |
980 | /* |
981 | * If the actual mask had changed we need to make sure that |
982 | * the commits are serialized(in case this is a nomodeset, nonblocking) |
983 | */ |
984 | if (new_bw_state->qgv_points_mask != old_bw_state->qgv_points_mask) { |
985 | ret = intel_atomic_serialize_global_state(obj_state: &new_bw_state->base); |
986 | if (ret) |
987 | return ret; |
988 | } |
989 | |
990 | return 0; |
991 | } |
992 | |
993 | static int intel_bw_check_qgv_points(struct drm_i915_private *i915, |
994 | const struct intel_bw_state *old_bw_state, |
995 | struct intel_bw_state *new_bw_state) |
996 | { |
997 | unsigned int data_rate = intel_bw_data_rate(dev_priv: i915, bw_state: new_bw_state); |
998 | unsigned int num_active_planes = |
999 | intel_bw_num_active_planes(dev_priv: i915, bw_state: new_bw_state); |
1000 | |
1001 | data_rate = DIV_ROUND_UP(data_rate, 1000); |
1002 | |
1003 | if (DISPLAY_VER(i915) >= 14) |
1004 | return mtl_find_qgv_points(i915, data_rate, num_active_planes, |
1005 | new_bw_state); |
1006 | else |
1007 | return icl_find_qgv_points(i915, data_rate, num_active_planes, |
1008 | old_bw_state, new_bw_state); |
1009 | } |
1010 | |
1011 | static bool intel_bw_state_changed(struct drm_i915_private *i915, |
1012 | const struct intel_bw_state *old_bw_state, |
1013 | const struct intel_bw_state *new_bw_state) |
1014 | { |
1015 | enum pipe pipe; |
1016 | |
1017 | for_each_pipe(i915, pipe) { |
1018 | const struct intel_dbuf_bw *old_crtc_bw = |
1019 | &old_bw_state->dbuf_bw[pipe]; |
1020 | const struct intel_dbuf_bw *new_crtc_bw = |
1021 | &new_bw_state->dbuf_bw[pipe]; |
1022 | enum dbuf_slice slice; |
1023 | |
1024 | for_each_dbuf_slice(i915, slice) { |
1025 | if (old_crtc_bw->max_bw[slice] != new_crtc_bw->max_bw[slice] || |
1026 | old_crtc_bw->active_planes[slice] != new_crtc_bw->active_planes[slice]) |
1027 | return true; |
1028 | } |
1029 | |
1030 | if (old_bw_state->min_cdclk[pipe] != new_bw_state->min_cdclk[pipe]) |
1031 | return true; |
1032 | } |
1033 | |
1034 | return false; |
1035 | } |
1036 | |
1037 | static void skl_plane_calc_dbuf_bw(struct intel_bw_state *bw_state, |
1038 | struct intel_crtc *crtc, |
1039 | enum plane_id plane_id, |
1040 | const struct skl_ddb_entry *ddb, |
1041 | unsigned int data_rate) |
1042 | { |
1043 | struct drm_i915_private *i915 = to_i915(dev: crtc->base.dev); |
1044 | struct intel_dbuf_bw *crtc_bw = &bw_state->dbuf_bw[crtc->pipe]; |
1045 | unsigned int dbuf_mask = skl_ddb_dbuf_slice_mask(i915, entry: ddb); |
1046 | enum dbuf_slice slice; |
1047 | |
1048 | /* |
1049 | * The arbiter can only really guarantee an |
1050 | * equal share of the total bw to each plane. |
1051 | */ |
1052 | for_each_dbuf_slice_in_mask(i915, slice, dbuf_mask) { |
1053 | crtc_bw->max_bw[slice] = max(crtc_bw->max_bw[slice], data_rate); |
1054 | crtc_bw->active_planes[slice] |= BIT(plane_id); |
1055 | } |
1056 | } |
1057 | |
1058 | static void skl_crtc_calc_dbuf_bw(struct intel_bw_state *bw_state, |
1059 | const struct intel_crtc_state *crtc_state) |
1060 | { |
1061 | struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); |
1062 | struct drm_i915_private *i915 = to_i915(dev: crtc->base.dev); |
1063 | struct intel_dbuf_bw *crtc_bw = &bw_state->dbuf_bw[crtc->pipe]; |
1064 | enum plane_id plane_id; |
1065 | |
1066 | memset(crtc_bw, 0, sizeof(*crtc_bw)); |
1067 | |
1068 | if (!crtc_state->hw.active) |
1069 | return; |
1070 | |
1071 | for_each_plane_id_on_crtc(crtc, plane_id) { |
1072 | /* |
1073 | * We assume cursors are small enough |
1074 | * to not cause bandwidth problems. |
1075 | */ |
1076 | if (plane_id == PLANE_CURSOR) |
1077 | continue; |
1078 | |
1079 | skl_plane_calc_dbuf_bw(bw_state, crtc, plane_id, |
1080 | ddb: &crtc_state->wm.skl.plane_ddb[plane_id], |
1081 | data_rate: crtc_state->data_rate[plane_id]); |
1082 | |
1083 | if (DISPLAY_VER(i915) < 11) |
1084 | skl_plane_calc_dbuf_bw(bw_state, crtc, plane_id, |
1085 | ddb: &crtc_state->wm.skl.plane_ddb_y[plane_id], |
1086 | data_rate: crtc_state->data_rate[plane_id]); |
1087 | } |
1088 | } |
1089 | |
1090 | /* "Maximum Data Buffer Bandwidth" */ |
1091 | static int |
1092 | intel_bw_dbuf_min_cdclk(struct drm_i915_private *i915, |
1093 | const struct intel_bw_state *bw_state) |
1094 | { |
1095 | unsigned int total_max_bw = 0; |
1096 | enum dbuf_slice slice; |
1097 | |
1098 | for_each_dbuf_slice(i915, slice) { |
1099 | int num_active_planes = 0; |
1100 | unsigned int max_bw = 0; |
1101 | enum pipe pipe; |
1102 | |
1103 | /* |
1104 | * The arbiter can only really guarantee an |
1105 | * equal share of the total bw to each plane. |
1106 | */ |
1107 | for_each_pipe(i915, pipe) { |
1108 | const struct intel_dbuf_bw *crtc_bw = &bw_state->dbuf_bw[pipe]; |
1109 | |
1110 | max_bw = max(crtc_bw->max_bw[slice], max_bw); |
1111 | num_active_planes += hweight8(crtc_bw->active_planes[slice]); |
1112 | } |
1113 | max_bw *= num_active_planes; |
1114 | |
1115 | total_max_bw = max(total_max_bw, max_bw); |
1116 | } |
1117 | |
1118 | return DIV_ROUND_UP(total_max_bw, 64); |
1119 | } |
1120 | |
1121 | int intel_bw_min_cdclk(struct drm_i915_private *i915, |
1122 | const struct intel_bw_state *bw_state) |
1123 | { |
1124 | enum pipe pipe; |
1125 | int min_cdclk; |
1126 | |
1127 | min_cdclk = intel_bw_dbuf_min_cdclk(i915, bw_state); |
1128 | |
1129 | for_each_pipe(i915, pipe) |
1130 | min_cdclk = max(bw_state->min_cdclk[pipe], min_cdclk); |
1131 | |
1132 | return min_cdclk; |
1133 | } |
1134 | |
1135 | int intel_bw_calc_min_cdclk(struct intel_atomic_state *state, |
1136 | bool *need_cdclk_calc) |
1137 | { |
1138 | struct drm_i915_private *dev_priv = to_i915(dev: state->base.dev); |
1139 | struct intel_bw_state *new_bw_state = NULL; |
1140 | const struct intel_bw_state *old_bw_state = NULL; |
1141 | const struct intel_cdclk_state *cdclk_state; |
1142 | const struct intel_crtc_state *crtc_state; |
1143 | int old_min_cdclk, new_min_cdclk; |
1144 | struct intel_crtc *crtc; |
1145 | int i; |
1146 | |
1147 | if (DISPLAY_VER(dev_priv) < 9) |
1148 | return 0; |
1149 | |
1150 | for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) { |
1151 | new_bw_state = intel_atomic_get_bw_state(state); |
1152 | if (IS_ERR(ptr: new_bw_state)) |
1153 | return PTR_ERR(ptr: new_bw_state); |
1154 | |
1155 | old_bw_state = intel_atomic_get_old_bw_state(state); |
1156 | |
1157 | skl_crtc_calc_dbuf_bw(bw_state: new_bw_state, crtc_state); |
1158 | |
1159 | new_bw_state->min_cdclk[crtc->pipe] = |
1160 | intel_bw_crtc_min_cdclk(crtc_state); |
1161 | } |
1162 | |
1163 | if (!old_bw_state) |
1164 | return 0; |
1165 | |
1166 | if (intel_bw_state_changed(i915: dev_priv, old_bw_state, new_bw_state)) { |
1167 | int ret = intel_atomic_lock_global_state(obj_state: &new_bw_state->base); |
1168 | if (ret) |
1169 | return ret; |
1170 | } |
1171 | |
1172 | old_min_cdclk = intel_bw_min_cdclk(i915: dev_priv, bw_state: old_bw_state); |
1173 | new_min_cdclk = intel_bw_min_cdclk(i915: dev_priv, bw_state: new_bw_state); |
1174 | |
1175 | /* |
1176 | * No need to check against the cdclk state if |
1177 | * the min cdclk doesn't increase. |
1178 | * |
1179 | * Ie. we only ever increase the cdclk due to bandwidth |
1180 | * requirements. This can reduce back and forth |
1181 | * display blinking due to constant cdclk changes. |
1182 | */ |
1183 | if (new_min_cdclk <= old_min_cdclk) |
1184 | return 0; |
1185 | |
1186 | cdclk_state = intel_atomic_get_cdclk_state(state); |
1187 | if (IS_ERR(ptr: cdclk_state)) |
1188 | return PTR_ERR(ptr: cdclk_state); |
1189 | |
1190 | /* |
1191 | * No need to recalculate the cdclk state if |
1192 | * the min cdclk doesn't increase. |
1193 | * |
1194 | * Ie. we only ever increase the cdclk due to bandwidth |
1195 | * requirements. This can reduce back and forth |
1196 | * display blinking due to constant cdclk changes. |
1197 | */ |
1198 | if (new_min_cdclk <= cdclk_state->bw_min_cdclk) |
1199 | return 0; |
1200 | |
1201 | drm_dbg_kms(&dev_priv->drm, |
1202 | "new bandwidth min cdclk (%d kHz) > old min cdclk (%d kHz)\n" , |
1203 | new_min_cdclk, cdclk_state->bw_min_cdclk); |
1204 | *need_cdclk_calc = true; |
1205 | |
1206 | return 0; |
1207 | } |
1208 | |
1209 | static int intel_bw_check_data_rate(struct intel_atomic_state *state, bool *changed) |
1210 | { |
1211 | struct drm_i915_private *i915 = to_i915(dev: state->base.dev); |
1212 | const struct intel_crtc_state *new_crtc_state, *old_crtc_state; |
1213 | struct intel_crtc *crtc; |
1214 | int i; |
1215 | |
1216 | for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, |
1217 | new_crtc_state, i) { |
1218 | unsigned int old_data_rate = |
1219 | intel_bw_crtc_data_rate(crtc_state: old_crtc_state); |
1220 | unsigned int new_data_rate = |
1221 | intel_bw_crtc_data_rate(crtc_state: new_crtc_state); |
1222 | unsigned int old_active_planes = |
1223 | intel_bw_crtc_num_active_planes(crtc_state: old_crtc_state); |
1224 | unsigned int new_active_planes = |
1225 | intel_bw_crtc_num_active_planes(crtc_state: new_crtc_state); |
1226 | struct intel_bw_state *new_bw_state; |
1227 | |
1228 | /* |
1229 | * Avoid locking the bw state when |
1230 | * nothing significant has changed. |
1231 | */ |
1232 | if (old_data_rate == new_data_rate && |
1233 | old_active_planes == new_active_planes) |
1234 | continue; |
1235 | |
1236 | new_bw_state = intel_atomic_get_bw_state(state); |
1237 | if (IS_ERR(ptr: new_bw_state)) |
1238 | return PTR_ERR(ptr: new_bw_state); |
1239 | |
1240 | new_bw_state->data_rate[crtc->pipe] = new_data_rate; |
1241 | new_bw_state->num_active_planes[crtc->pipe] = new_active_planes; |
1242 | |
1243 | *changed = true; |
1244 | |
1245 | drm_dbg_kms(&i915->drm, |
1246 | "[CRTC:%d:%s] data rate %u num active planes %u\n" , |
1247 | crtc->base.base.id, crtc->base.name, |
1248 | new_bw_state->data_rate[crtc->pipe], |
1249 | new_bw_state->num_active_planes[crtc->pipe]); |
1250 | } |
1251 | |
1252 | return 0; |
1253 | } |
1254 | |
1255 | int intel_bw_atomic_check(struct intel_atomic_state *state) |
1256 | { |
1257 | bool changed = false; |
1258 | struct drm_i915_private *i915 = to_i915(dev: state->base.dev); |
1259 | struct intel_bw_state *new_bw_state; |
1260 | const struct intel_bw_state *old_bw_state; |
1261 | int ret; |
1262 | |
1263 | /* FIXME earlier gens need some checks too */ |
1264 | if (DISPLAY_VER(i915) < 11) |
1265 | return 0; |
1266 | |
1267 | ret = intel_bw_check_data_rate(state, changed: &changed); |
1268 | if (ret) |
1269 | return ret; |
1270 | |
1271 | old_bw_state = intel_atomic_get_old_bw_state(state); |
1272 | new_bw_state = intel_atomic_get_new_bw_state(state); |
1273 | |
1274 | if (new_bw_state && |
1275 | intel_can_enable_sagv(i915, bw_state: old_bw_state) != |
1276 | intel_can_enable_sagv(i915, bw_state: new_bw_state)) |
1277 | changed = true; |
1278 | |
1279 | /* |
1280 | * If none of our inputs (data rates, number of active |
1281 | * planes, SAGV yes/no) changed then nothing to do here. |
1282 | */ |
1283 | if (!changed) |
1284 | return 0; |
1285 | |
1286 | ret = intel_bw_check_qgv_points(i915, old_bw_state, new_bw_state); |
1287 | if (ret) |
1288 | return ret; |
1289 | |
1290 | return 0; |
1291 | } |
1292 | |
1293 | static struct intel_global_state * |
1294 | intel_bw_duplicate_state(struct intel_global_obj *obj) |
1295 | { |
1296 | struct intel_bw_state *state; |
1297 | |
1298 | state = kmemdup(p: obj->state, size: sizeof(*state), GFP_KERNEL); |
1299 | if (!state) |
1300 | return NULL; |
1301 | |
1302 | return &state->base; |
1303 | } |
1304 | |
1305 | static void intel_bw_destroy_state(struct intel_global_obj *obj, |
1306 | struct intel_global_state *state) |
1307 | { |
1308 | kfree(objp: state); |
1309 | } |
1310 | |
1311 | static const struct intel_global_state_funcs intel_bw_funcs = { |
1312 | .atomic_duplicate_state = intel_bw_duplicate_state, |
1313 | .atomic_destroy_state = intel_bw_destroy_state, |
1314 | }; |
1315 | |
1316 | int intel_bw_init(struct drm_i915_private *dev_priv) |
1317 | { |
1318 | struct intel_bw_state *state; |
1319 | |
1320 | state = kzalloc(size: sizeof(*state), GFP_KERNEL); |
1321 | if (!state) |
1322 | return -ENOMEM; |
1323 | |
1324 | intel_atomic_global_obj_init(dev_priv, obj: &dev_priv->display.bw.obj, |
1325 | state: &state->base, funcs: &intel_bw_funcs); |
1326 | |
1327 | return 0; |
1328 | } |
1329 | |