1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2020 Intel Corporation 4 */ 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_regs.h" 11 12 static u32 read_reference_ts_freq(struct intel_uncore *uncore) 13 { 14 u32 ts_override = intel_uncore_read(uncore, GEN9_TIMESTAMP_OVERRIDE); 15 u32 base_freq, frac_freq; 16 17 base_freq = ((ts_override & GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DIVIDER_MASK) >> 18 GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DIVIDER_SHIFT) + 1; 19 base_freq *= 1000000; 20 21 frac_freq = ((ts_override & 22 GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DENOMINATOR_MASK) >> 23 GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DENOMINATOR_SHIFT); 24 frac_freq = 1000000 / (frac_freq + 1); 25 26 return base_freq + frac_freq; 27 } 28 29 static u32 gen9_get_crystal_clock_freq(struct intel_uncore *uncore, 30 u32 rpm_config_reg) 31 { 32 u32 f19_2_mhz = 19200000; 33 u32 f24_mhz = 24000000; 34 u32 crystal_clock = 35 (rpm_config_reg & GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_MASK) >> 36 GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_SHIFT; 37 38 switch (crystal_clock) { 39 case GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_19_2_MHZ: 40 return f19_2_mhz; 41 case GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_24_MHZ: 42 return f24_mhz; 43 default: 44 MISSING_CASE(crystal_clock); 45 return 0; 46 } 47 } 48 49 static u32 gen11_get_crystal_clock_freq(struct intel_uncore *uncore, 50 u32 rpm_config_reg) 51 { 52 u32 f19_2_mhz = 19200000; 53 u32 f24_mhz = 24000000; 54 u32 f25_mhz = 25000000; 55 u32 f38_4_mhz = 38400000; 56 u32 crystal_clock = 57 (rpm_config_reg & GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_MASK) >> 58 GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_SHIFT; 59 60 switch (crystal_clock) { 61 case GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_24_MHZ: 62 return f24_mhz; 63 case GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_19_2_MHZ: 64 return f19_2_mhz; 65 case GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_38_4_MHZ: 66 return f38_4_mhz; 67 case GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_25_MHZ: 68 return f25_mhz; 69 default: 70 MISSING_CASE(crystal_clock); 71 return 0; 72 } 73 } 74 75 static u32 read_clock_frequency(struct intel_uncore *uncore) 76 { 77 u32 f12_5_mhz = 12500000; 78 u32 f19_2_mhz = 19200000; 79 u32 f24_mhz = 24000000; 80 81 if (GRAPHICS_VER(uncore->i915) <= 4) { 82 /* 83 * PRMs say: 84 * 85 * "The value in this register increments once every 16 86 * hclks." (through the “Clocking Configuration” 87 * (“CLKCFG”) MCHBAR register) 88 */ 89 return RUNTIME_INFO(uncore->i915)->rawclk_freq * 1000 / 16; 90 } else if (GRAPHICS_VER(uncore->i915) <= 8) { 91 /* 92 * PRMs say: 93 * 94 * "The PCU TSC counts 10ns increments; this timestamp 95 * reflects bits 38:3 of the TSC (i.e. 80ns granularity, 96 * rolling over every 1.5 hours). 97 */ 98 return f12_5_mhz; 99 } else if (GRAPHICS_VER(uncore->i915) <= 9) { 100 u32 ctc_reg = intel_uncore_read(uncore, CTC_MODE); 101 u32 freq = 0; 102 103 if ((ctc_reg & CTC_SOURCE_PARAMETER_MASK) == CTC_SOURCE_DIVIDE_LOGIC) { 104 freq = read_reference_ts_freq(uncore); 105 } else { 106 freq = IS_GEN9_LP(uncore->i915) ? f19_2_mhz : f24_mhz; 107 108 /* 109 * Now figure out how the command stream's timestamp 110 * register increments from this frequency (it might 111 * increment only every few clock cycle). 112 */ 113 freq >>= 3 - ((ctc_reg & CTC_SHIFT_PARAMETER_MASK) >> 114 CTC_SHIFT_PARAMETER_SHIFT); 115 } 116 117 return freq; 118 } else if (GRAPHICS_VER(uncore->i915) <= 12) { 119 u32 ctc_reg = intel_uncore_read(uncore, CTC_MODE); 120 u32 freq = 0; 121 122 /* 123 * First figure out the reference frequency. There are 2 ways 124 * we can compute the frequency, either through the 125 * TIMESTAMP_OVERRIDE register or through RPM_CONFIG. CTC_MODE 126 * tells us which one we should use. 127 */ 128 if ((ctc_reg & CTC_SOURCE_PARAMETER_MASK) == CTC_SOURCE_DIVIDE_LOGIC) { 129 freq = read_reference_ts_freq(uncore); 130 } else { 131 u32 c0 = intel_uncore_read(uncore, RPM_CONFIG0); 132 133 if (GRAPHICS_VER(uncore->i915) >= 11) 134 freq = gen11_get_crystal_clock_freq(uncore, c0); 135 else 136 freq = gen9_get_crystal_clock_freq(uncore, c0); 137 138 /* 139 * Now figure out how the command stream's timestamp 140 * register increments from this frequency (it might 141 * increment only every few clock cycle). 142 */ 143 freq >>= 3 - ((c0 & GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_MASK) >> 144 GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_SHIFT); 145 } 146 147 return freq; 148 } 149 150 MISSING_CASE("Unknown gen, unable to read command streamer timestamp frequency\n"); 151 return 0; 152 } 153 154 void intel_gt_init_clock_frequency(struct intel_gt *gt) 155 { 156 /* 157 * Note that on gen11+, the clock frequency may be reconfigured. 158 * We do not, and we assume nobody else does. 159 */ 160 gt->clock_frequency = read_clock_frequency(gt->uncore); 161 if (gt->clock_frequency) 162 gt->clock_period_ns = intel_gt_clock_interval_to_ns(gt, 1); 163 164 GT_TRACE(gt, 165 "Using clock frequency: %dkHz, period: %dns, wrap: %lldms\n", 166 gt->clock_frequency / 1000, 167 gt->clock_period_ns, 168 div_u64(mul_u32_u32(gt->clock_period_ns, S32_MAX), 169 USEC_PER_SEC)); 170 } 171 172 #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM) 173 void intel_gt_check_clock_frequency(const struct intel_gt *gt) 174 { 175 if (gt->clock_frequency != read_clock_frequency(gt->uncore)) { 176 dev_err(gt->i915->drm.dev, 177 "GT clock frequency changed, was %uHz, now %uHz!\n", 178 gt->clock_frequency, 179 read_clock_frequency(gt->uncore)); 180 } 181 } 182 #endif 183 184 static u64 div_u64_roundup(u64 nom, u32 den) 185 { 186 return div_u64(nom + den - 1, den); 187 } 188 189 u64 intel_gt_clock_interval_to_ns(const struct intel_gt *gt, u64 count) 190 { 191 return div_u64_roundup(count * NSEC_PER_SEC, gt->clock_frequency); 192 } 193 194 u64 intel_gt_pm_interval_to_ns(const struct intel_gt *gt, u64 count) 195 { 196 return intel_gt_clock_interval_to_ns(gt, 16 * count); 197 } 198 199 u64 intel_gt_ns_to_clock_interval(const struct intel_gt *gt, u64 ns) 200 { 201 return div_u64_roundup(gt->clock_frequency * ns, NSEC_PER_SEC); 202 } 203 204 u64 intel_gt_ns_to_pm_interval(const struct intel_gt *gt, u64 ns) 205 { 206 u64 val; 207 208 /* 209 * Make these a multiple of magic 25 to avoid SNB (eg. Dell XPS 210 * 8300) freezing up around GPU hangs. Looks as if even 211 * scheduling/timer interrupts start misbehaving if the RPS 212 * EI/thresholds are "bad", leading to a very sluggish or even 213 * frozen machine. 214 */ 215 val = div_u64_roundup(intel_gt_ns_to_clock_interval(gt, ns), 16); 216 if (GRAPHICS_VER(gt->i915) == 6) 217 val = div_u64_roundup(val, 25) * 25; 218 219 return val; 220 } 221