1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2022 Intel Corporation 4 */ 5 6 #include "i915_reg.h" 7 #include "gt/intel_gt_regs.h" 8 9 #include "xe_device.h" 10 #include "xe_gt.h" 11 #include "xe_gt_clock.h" 12 #include "xe_macros.h" 13 #include "xe_mmio.h" 14 15 static u32 read_reference_ts_freq(struct xe_gt *gt) 16 { 17 u32 ts_override = xe_mmio_read32(gt, GEN9_TIMESTAMP_OVERRIDE.reg); 18 u32 base_freq, frac_freq; 19 20 base_freq = ((ts_override & GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DIVIDER_MASK) >> 21 GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DIVIDER_SHIFT) + 1; 22 base_freq *= 1000000; 23 24 frac_freq = ((ts_override & 25 GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DENOMINATOR_MASK) >> 26 GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DENOMINATOR_SHIFT); 27 frac_freq = 1000000 / (frac_freq + 1); 28 29 return base_freq + frac_freq; 30 } 31 32 static u32 get_crystal_clock_freq(u32 rpm_config_reg) 33 { 34 const u32 f19_2_mhz = 19200000; 35 const u32 f24_mhz = 24000000; 36 const u32 f25_mhz = 25000000; 37 const 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 XE_BUG_ON("NOT_POSSIBLE"); 53 return 0; 54 } 55 } 56 57 int xe_gt_clock_init(struct xe_gt *gt) 58 { 59 u32 ctc_reg = xe_mmio_read32(gt, CTC_MODE.reg); 60 u32 freq = 0; 61 62 /* Assuming gen11+ so assert this assumption is correct */ 63 XE_BUG_ON(GRAPHICS_VER(gt_to_xe(gt)) < 11); 64 65 if ((ctc_reg & CTC_SOURCE_PARAMETER_MASK) == CTC_SOURCE_DIVIDE_LOGIC) { 66 freq = read_reference_ts_freq(gt); 67 } else { 68 u32 c0 = xe_mmio_read32(gt, RPM_CONFIG0.reg); 69 70 freq = get_crystal_clock_freq(c0); 71 72 /* 73 * Now figure out how the command stream's timestamp 74 * register increments from this frequency (it might 75 * increment only every few clock cycle). 76 */ 77 freq >>= 3 - ((c0 & GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_MASK) >> 78 GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_SHIFT); 79 } 80 81 gt->info.clock_freq = freq; 82 return 0; 83 } 84