242 lines · c
1// SPDX-License-Identifier: MIT2/*3 * Copyright © 2020 Intel Corporation4 */5 6#include "i915_drv.h"7#include "i915_reg.h"8#include "intel_gt.h"9#include "intel_gt_clock_utils.h"10#include "intel_gt_print.h"11#include "intel_gt_regs.h"12#include "soc/intel_dram.h"13 14static u32 read_reference_ts_freq(struct intel_uncore *uncore)15{16 u32 ts_override = intel_uncore_read(uncore, GEN9_TIMESTAMP_OVERRIDE);17 u32 base_freq, frac_freq;18 19 base_freq = ((ts_override & GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DIVIDER_MASK) >>20 GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DIVIDER_SHIFT) + 1;21 base_freq *= 1000000;22 23 frac_freq = ((ts_override &24 GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DENOMINATOR_MASK) >>25 GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DENOMINATOR_SHIFT);26 frac_freq = 1000000 / (frac_freq + 1);27 28 return base_freq + frac_freq;29}30 31static u32 gen11_get_crystal_clock_freq(struct intel_uncore *uncore,32 u32 rpm_config_reg)33{34 u32 f19_2_mhz = 19200000;35 u32 f24_mhz = 24000000;36 u32 f25_mhz = 25000000;37 u32 f38_4_mhz = 38400000;38 u32 crystal_clock =39 (rpm_config_reg & GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_MASK) >>40 GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_SHIFT;41 42 switch (crystal_clock) {43 case GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_24_MHZ:44 return f24_mhz;45 case GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_19_2_MHZ:46 return f19_2_mhz;47 case GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_38_4_MHZ:48 return f38_4_mhz;49 case GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_25_MHZ:50 return f25_mhz;51 default:52 MISSING_CASE(crystal_clock);53 return 0;54 }55}56 57static u32 gen11_read_clock_frequency(struct intel_uncore *uncore)58{59 u32 ctc_reg = intel_uncore_read(uncore, CTC_MODE);60 u32 freq = 0;61 62 /*63 * Note that on gen11+, the clock frequency may be reconfigured.64 * We do not, and we assume nobody else does.65 *66 * First figure out the reference frequency. There are 2 ways67 * we can compute the frequency, either through the68 * TIMESTAMP_OVERRIDE register or through RPM_CONFIG. CTC_MODE69 * tells us which one we should use.70 */71 if ((ctc_reg & CTC_SOURCE_PARAMETER_MASK) == CTC_SOURCE_DIVIDE_LOGIC) {72 freq = read_reference_ts_freq(uncore);73 } else {74 u32 c0 = intel_uncore_read(uncore, RPM_CONFIG0);75 76 freq = gen11_get_crystal_clock_freq(uncore, c0);77 78 /*79 * Now figure out how the command stream's timestamp80 * register increments from this frequency (it might81 * increment only every few clock cycle).82 */83 freq >>= 3 - ((c0 & GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_MASK) >>84 GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_SHIFT);85 }86 87 return freq;88}89 90static u32 gen9_read_clock_frequency(struct intel_uncore *uncore)91{92 u32 ctc_reg = intel_uncore_read(uncore, CTC_MODE);93 u32 freq = 0;94 95 if ((ctc_reg & CTC_SOURCE_PARAMETER_MASK) == CTC_SOURCE_DIVIDE_LOGIC) {96 freq = read_reference_ts_freq(uncore);97 } else {98 freq = IS_GEN9_LP(uncore->i915) ? 19200000 : 24000000;99 100 /*101 * Now figure out how the command stream's timestamp102 * register increments from this frequency (it might103 * increment only every few clock cycle).104 */105 freq >>= 3 - ((ctc_reg & CTC_SHIFT_PARAMETER_MASK) >>106 CTC_SHIFT_PARAMETER_SHIFT);107 }108 109 return freq;110}111 112static u32 gen6_read_clock_frequency(struct intel_uncore *uncore)113{114 /*115 * PRMs say:116 *117 * "The PCU TSC counts 10ns increments; this timestamp118 * reflects bits 38:3 of the TSC (i.e. 80ns granularity,119 * rolling over every 1.5 hours).120 */121 return 12500000;122}123 124static u32 gen5_read_clock_frequency(struct intel_uncore *uncore)125{126 /*127 * 63:32 increments every 1000 ns128 * 31:0 mbz129 */130 return 1000000000 / 1000;131}132 133static u32 g4x_read_clock_frequency(struct intel_uncore *uncore)134{135 /*136 * 63:20 increments every 1/4 ns137 * 19:0 mbz138 *139 * -> 63:32 increments every 1024 ns140 */141 return 1000000000 / 1024;142}143 144static u32 gen4_read_clock_frequency(struct intel_uncore *uncore)145{146 /*147 * PRMs say:148 *149 * "The value in this register increments once every 16150 * hclks." (through the “Clocking Configuration”151 * (“CLKCFG”) MCHBAR register)152 *153 * Testing on actual hardware has shown there is no /16.154 */155 return DIV_ROUND_CLOSEST(i9xx_fsb_freq(uncore->i915), 4) * 1000;156}157 158static u32 read_clock_frequency(struct intel_uncore *uncore)159{160 if (GRAPHICS_VER(uncore->i915) >= 11)161 return gen11_read_clock_frequency(uncore);162 else if (GRAPHICS_VER(uncore->i915) >= 9)163 return gen9_read_clock_frequency(uncore);164 else if (GRAPHICS_VER(uncore->i915) >= 6)165 return gen6_read_clock_frequency(uncore);166 else if (GRAPHICS_VER(uncore->i915) == 5)167 return gen5_read_clock_frequency(uncore);168 else if (IS_G4X(uncore->i915))169 return g4x_read_clock_frequency(uncore);170 else if (GRAPHICS_VER(uncore->i915) == 4)171 return gen4_read_clock_frequency(uncore);172 else173 return 0;174}175 176void intel_gt_init_clock_frequency(struct intel_gt *gt)177{178 gt->clock_frequency = read_clock_frequency(gt->uncore);179 180 /* Icelake appears to use another fixed frequency for CTX_TIMESTAMP */181 if (GRAPHICS_VER(gt->i915) == 11)182 gt->clock_period_ns = NSEC_PER_SEC / 13750000;183 else if (gt->clock_frequency)184 gt->clock_period_ns = intel_gt_clock_interval_to_ns(gt, 1);185 186 GT_TRACE(gt,187 "Using clock frequency: %dkHz, period: %dns, wrap: %lldms\n",188 gt->clock_frequency / 1000,189 gt->clock_period_ns,190 div_u64(mul_u32_u32(gt->clock_period_ns, S32_MAX),191 USEC_PER_SEC));192}193 194#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)195void intel_gt_check_clock_frequency(const struct intel_gt *gt)196{197 if (gt->clock_frequency != read_clock_frequency(gt->uncore)) {198 gt_err(gt, "GT clock frequency changed, was %uHz, now %uHz!\n",199 gt->clock_frequency,200 read_clock_frequency(gt->uncore));201 }202}203#endif204 205static u64 div_u64_roundup(u64 nom, u32 den)206{207 return div_u64(nom + den - 1, den);208}209 210u64 intel_gt_clock_interval_to_ns(const struct intel_gt *gt, u64 count)211{212 return div_u64_roundup(count * NSEC_PER_SEC, gt->clock_frequency);213}214 215u64 intel_gt_pm_interval_to_ns(const struct intel_gt *gt, u64 count)216{217 return intel_gt_clock_interval_to_ns(gt, 16 * count);218}219 220u64 intel_gt_ns_to_clock_interval(const struct intel_gt *gt, u64 ns)221{222 return div_u64_roundup(gt->clock_frequency * ns, NSEC_PER_SEC);223}224 225u64 intel_gt_ns_to_pm_interval(const struct intel_gt *gt, u64 ns)226{227 u64 val;228 229 /*230 * Make these a multiple of magic 25 to avoid SNB (eg. Dell XPS231 * 8300) freezing up around GPU hangs. Looks as if even232 * scheduling/timer interrupts start misbehaving if the RPS233 * EI/thresholds are "bad", leading to a very sluggish or even234 * frozen machine.235 */236 val = div_u64_roundup(intel_gt_ns_to_clock_interval(gt, ns), 16);237 if (GRAPHICS_VER(gt->i915) == 6)238 val = div_u64_roundup(val, 25) * 25;239 240 return val;241}242