aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_device_info.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_device_info.c')
-rw-r--r--drivers/gpu/drm/i915/intel_device_info.c121
1 files changed, 110 insertions, 11 deletions
diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c
index 875d428ea75f..02f8bf101ccd 100644
--- a/drivers/gpu/drm/i915/intel_device_info.c
+++ b/drivers/gpu/drm/i915/intel_device_info.c
@@ -235,16 +235,6 @@ static void gen9_sseu_info_init(struct drm_i915_private *dev_priv)
235#define IS_SS_DISABLED(ss) (!(sseu->subslice_mask & BIT(ss))) 235#define IS_SS_DISABLED(ss) (!(sseu->subslice_mask & BIT(ss)))
236 info->has_pooled_eu = hweight8(sseu->subslice_mask) == 3; 236 info->has_pooled_eu = hweight8(sseu->subslice_mask) == 3;
237 237
238 /*
239 * There is a HW issue in 2x6 fused down parts that requires
240 * Pooled EU to be enabled as a WA. The pool configuration
241 * changes depending upon which subslice is fused down. This
242 * doesn't affect if the device has all 3 subslices enabled.
243 */
244 /* WaEnablePooledEuFor2x6:bxt */
245 info->has_pooled_eu |= (hweight8(sseu->subslice_mask) == 2 &&
246 IS_BXT_REVID(dev_priv, 0, BXT_REVID_B_LAST));
247
248 sseu->min_eu_in_pool = 0; 238 sseu->min_eu_in_pool = 0;
249 if (info->has_pooled_eu) { 239 if (info->has_pooled_eu) {
250 if (IS_SS_DISABLED(2) || IS_SS_DISABLED(0)) 240 if (IS_SS_DISABLED(2) || IS_SS_DISABLED(0))
@@ -329,6 +319,107 @@ static void broadwell_sseu_info_init(struct drm_i915_private *dev_priv)
329 sseu->has_eu_pg = 0; 319 sseu->has_eu_pg = 0;
330} 320}
331 321
322static u32 read_reference_ts_freq(struct drm_i915_private *dev_priv)
323{
324 u32 ts_override = I915_READ(GEN9_TIMESTAMP_OVERRIDE);
325 u32 base_freq, frac_freq;
326
327 base_freq = ((ts_override & GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DIVIDER_MASK) >>
328 GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DIVIDER_SHIFT) + 1;
329 base_freq *= 1000;
330
331 frac_freq = ((ts_override &
332 GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DENOMINATOR_MASK) >>
333 GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DENOMINATOR_SHIFT);
334 frac_freq = 1000 / (frac_freq + 1);
335
336 return base_freq + frac_freq;
337}
338
339static u32 read_timestamp_frequency(struct drm_i915_private *dev_priv)
340{
341 u32 f12_5_mhz = 12500;
342 u32 f19_2_mhz = 19200;
343 u32 f24_mhz = 24000;
344
345 if (INTEL_GEN(dev_priv) <= 4) {
346 /* PRMs say:
347 *
348 * "The value in this register increments once every 16
349 * hclks." (through the “Clocking Configuration”
350 * (“CLKCFG”) MCHBAR register)
351 */
352 return dev_priv->rawclk_freq / 16;
353 } else if (INTEL_GEN(dev_priv) <= 8) {
354 /* PRMs say:
355 *
356 * "The PCU TSC counts 10ns increments; this timestamp
357 * reflects bits 38:3 of the TSC (i.e. 80ns granularity,
358 * rolling over every 1.5 hours).
359 */
360 return f12_5_mhz;
361 } else if (INTEL_GEN(dev_priv) <= 9) {
362 u32 ctc_reg = I915_READ(CTC_MODE);
363 u32 freq = 0;
364
365 if ((ctc_reg & CTC_SOURCE_PARAMETER_MASK) == CTC_SOURCE_DIVIDE_LOGIC) {
366 freq = read_reference_ts_freq(dev_priv);
367 } else {
368 freq = IS_GEN9_LP(dev_priv) ? f19_2_mhz : f24_mhz;
369
370 /* Now figure out how the command stream's timestamp
371 * register increments from this frequency (it might
372 * increment only every few clock cycle).
373 */
374 freq >>= 3 - ((ctc_reg & CTC_SHIFT_PARAMETER_MASK) >>
375 CTC_SHIFT_PARAMETER_SHIFT);
376 }
377
378 return freq;
379 } else if (INTEL_GEN(dev_priv) <= 10) {
380 u32 ctc_reg = I915_READ(CTC_MODE);
381 u32 freq = 0;
382 u32 rpm_config_reg = 0;
383
384 /* First figure out the reference frequency. There are 2 ways
385 * we can compute the frequency, either through the
386 * TIMESTAMP_OVERRIDE register or through RPM_CONFIG. CTC_MODE
387 * tells us which one we should use.
388 */
389 if ((ctc_reg & CTC_SOURCE_PARAMETER_MASK) == CTC_SOURCE_DIVIDE_LOGIC) {
390 freq = read_reference_ts_freq(dev_priv);
391 } else {
392 u32 crystal_clock;
393
394 rpm_config_reg = I915_READ(RPM_CONFIG0);
395 crystal_clock = (rpm_config_reg &
396 GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_MASK) >>
397 GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_SHIFT;
398 switch (crystal_clock) {
399 case GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_19_2_MHZ:
400 freq = f19_2_mhz;
401 break;
402 case GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_24_MHZ:
403 freq = f24_mhz;
404 break;
405 }
406 }
407
408 /* Now figure out how the command stream's timestamp register
409 * increments from this frequency (it might increment only
410 * every few clock cycle).
411 */
412 freq >>= 3 - ((rpm_config_reg &
413 GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_MASK) >>
414 GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_SHIFT);
415
416 return freq;
417 }
418
419 DRM_ERROR("Unknown gen, unable to compute command stream timestamp frequency\n");
420 return 0;
421}
422
332/* 423/*
333 * Determine various intel_device_info fields at runtime. 424 * Determine various intel_device_info fields at runtime.
334 * 425 *
@@ -347,7 +438,10 @@ void intel_device_info_runtime_init(struct drm_i915_private *dev_priv)
347 struct intel_device_info *info = mkwrite_device_info(dev_priv); 438 struct intel_device_info *info = mkwrite_device_info(dev_priv);
348 enum pipe pipe; 439 enum pipe pipe;
349 440
350 if (INTEL_GEN(dev_priv) >= 9) { 441 if (INTEL_GEN(dev_priv) >= 10) {
442 for_each_pipe(dev_priv, pipe)
443 info->num_scalers[pipe] = 2;
444 } else if (INTEL_GEN(dev_priv) == 9) {
351 info->num_scalers[PIPE_A] = 2; 445 info->num_scalers[PIPE_A] = 2;
352 info->num_scalers[PIPE_B] = 2; 446 info->num_scalers[PIPE_B] = 2;
353 info->num_scalers[PIPE_C] = 1; 447 info->num_scalers[PIPE_C] = 1;
@@ -447,6 +541,9 @@ void intel_device_info_runtime_init(struct drm_i915_private *dev_priv)
447 else if (INTEL_GEN(dev_priv) >= 10) 541 else if (INTEL_GEN(dev_priv) >= 10)
448 gen10_sseu_info_init(dev_priv); 542 gen10_sseu_info_init(dev_priv);
449 543
544 /* Initialize command stream timestamp frequency */
545 info->cs_timestamp_frequency_khz = read_timestamp_frequency(dev_priv);
546
450 DRM_DEBUG_DRIVER("slice mask: %04x\n", info->sseu.slice_mask); 547 DRM_DEBUG_DRIVER("slice mask: %04x\n", info->sseu.slice_mask);
451 DRM_DEBUG_DRIVER("slice total: %u\n", hweight8(info->sseu.slice_mask)); 548 DRM_DEBUG_DRIVER("slice total: %u\n", hweight8(info->sseu.slice_mask));
452 DRM_DEBUG_DRIVER("subslice total: %u\n", 549 DRM_DEBUG_DRIVER("subslice total: %u\n",
@@ -462,4 +559,6 @@ void intel_device_info_runtime_init(struct drm_i915_private *dev_priv)
462 info->sseu.has_subslice_pg ? "y" : "n"); 559 info->sseu.has_subslice_pg ? "y" : "n");
463 DRM_DEBUG_DRIVER("has EU power gating: %s\n", 560 DRM_DEBUG_DRIVER("has EU power gating: %s\n",
464 info->sseu.has_eu_pg ? "y" : "n"); 561 info->sseu.has_eu_pg ? "y" : "n");
562 DRM_DEBUG_DRIVER("CS timestamp frequency: %u kHz\n",
563 info->cs_timestamp_frequency_khz);
465} 564}