1 // SPDX-License-Identifier: MIT
3 * Copyright © 2020 Intel Corporation
8 #include "intel_gt_clock_utils.h"
10 #define MHZ_12 12000000 /* 12MHz (24MHz/2), 83.333ns */
11 #define MHZ_12_5 12500000 /* 12.5MHz (25MHz/2), 80ns */
12 #define MHZ_19_2 19200000 /* 19.2MHz, 52.083ns */
14 static u32
read_clock_frequency(const struct intel_gt
*gt
)
16 if (INTEL_GEN(gt
->i915
) >= 11) {
19 config
= intel_uncore_read(gt
->uncore
, RPM_CONFIG0
);
20 config
&= GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_MASK
;
21 config
>>= GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_SHIFT
;
24 case 0: return MHZ_12
;
26 case 2: return MHZ_19_2
;
28 case 3: return MHZ_12_5
;
30 } else if (INTEL_GEN(gt
->i915
) >= 9) {
31 if (IS_GEN9_LP(gt
->i915
))
40 void intel_gt_init_clock_frequency(struct intel_gt
*gt
)
43 * Note that on gen11+, the clock frequency may be reconfigured.
44 * We do not, and we assume nobody else does.
46 gt
->clock_frequency
= read_clock_frequency(gt
);
48 "Using clock frequency: %dkHz\n",
49 gt
->clock_frequency
/ 1000);
52 #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)
53 void intel_gt_check_clock_frequency(const struct intel_gt
*gt
)
55 if (gt
->clock_frequency
!= read_clock_frequency(gt
)) {
56 dev_err(gt
->i915
->drm
.dev
,
57 "GT clock frequency changed, was %uHz, now %uHz!\n",
59 read_clock_frequency(gt
));
64 static u64
div_u64_roundup(u64 nom
, u32 den
)
66 return div_u64(nom
+ den
- 1, den
);
69 u32
intel_gt_clock_interval_to_ns(const struct intel_gt
*gt
, u32 count
)
71 return div_u64_roundup(mul_u32_u32(count
, 1000 * 1000 * 1000),
75 u32
intel_gt_pm_interval_to_ns(const struct intel_gt
*gt
, u32 count
)
77 return intel_gt_clock_interval_to_ns(gt
, 16 * count
);
80 u32
intel_gt_ns_to_clock_interval(const struct intel_gt
*gt
, u32 ns
)
82 return div_u64_roundup(mul_u32_u32(gt
->clock_frequency
, ns
),
86 u32
intel_gt_ns_to_pm_interval(const struct intel_gt
*gt
, u32 ns
)
91 * Make these a multiple of magic 25 to avoid SNB (eg. Dell XPS
92 * 8300) freezing up around GPU hangs. Looks as if even
93 * scheduling/timer interrupts start misbehaving if the RPS
94 * EI/thresholds are "bad", leading to a very sluggish or even
97 val
= DIV_ROUND_UP(intel_gt_ns_to_clock_interval(gt
, ns
), 16);
98 if (IS_GEN(gt
->i915
, 6))
99 val
= roundup(val
, 25);