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