Loading...
Note: File does not exist in v4.6.
1// SPDX-License-Identifier: MIT
2/*
3 * Copyright © 2022 Intel Corporation
4 */
5
6#include "xe_gt_clock.h"
7
8#include "regs/xe_gt_regs.h"
9#include "regs/xe_regs.h"
10#include "xe_device.h"
11#include "xe_gt.h"
12#include "xe_macros.h"
13#include "xe_mmio.h"
14
15static u32 read_reference_ts_freq(struct xe_gt *gt)
16{
17 u32 ts_override = xe_mmio_read32(gt, TIMESTAMP_OVERRIDE);
18 u32 base_freq, frac_freq;
19
20 base_freq = REG_FIELD_GET(TIMESTAMP_OVERRIDE_US_COUNTER_DIVIDER_MASK,
21 ts_override) + 1;
22 base_freq *= 1000000;
23
24 frac_freq = REG_FIELD_GET(TIMESTAMP_OVERRIDE_US_COUNTER_DENOMINATOR_MASK,
25 ts_override);
26 frac_freq = 1000000 / (frac_freq + 1);
27
28 return base_freq + frac_freq;
29}
30
31static u32 get_crystal_clock_freq(u32 rpm_config_reg)
32{
33 const u32 f19_2_mhz = 19200000;
34 const u32 f24_mhz = 24000000;
35 const u32 f25_mhz = 25000000;
36 const u32 f38_4_mhz = 38400000;
37 u32 crystal_clock = REG_FIELD_GET(RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_MASK,
38 rpm_config_reg);
39
40 switch (crystal_clock) {
41 case RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_24_MHZ:
42 return f24_mhz;
43 case RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_19_2_MHZ:
44 return f19_2_mhz;
45 case RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_38_4_MHZ:
46 return f38_4_mhz;
47 case RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_25_MHZ:
48 return f25_mhz;
49 default:
50 XE_WARN_ON("NOT_POSSIBLE");
51 return 0;
52 }
53}
54
55int xe_gt_clock_init(struct xe_gt *gt)
56{
57 u32 ctc_reg = xe_mmio_read32(gt, CTC_MODE);
58 u32 freq = 0;
59
60 /* Assuming gen11+ so assert this assumption is correct */
61 xe_gt_assert(gt, GRAPHICS_VER(gt_to_xe(gt)) >= 11);
62
63 if (ctc_reg & CTC_SOURCE_DIVIDE_LOGIC) {
64 freq = read_reference_ts_freq(gt);
65 } else {
66 u32 c0 = xe_mmio_read32(gt, RPM_CONFIG0);
67
68 freq = get_crystal_clock_freq(c0);
69
70 /*
71 * Now figure out how the command stream's timestamp
72 * register increments from this frequency (it might
73 * increment only every few clock cycle).
74 */
75 freq >>= 3 - REG_FIELD_GET(RPM_CONFIG0_CTC_SHIFT_PARAMETER_MASK, c0);
76 }
77
78 gt->info.reference_clock = freq;
79 return 0;
80}
81
82u64 xe_gt_clock_cycles_to_ns(const struct xe_gt *gt, u64 count)
83{
84 return DIV_ROUND_CLOSEST_ULL(count * NSEC_PER_SEC, gt->info.reference_clock);
85}