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_assert.h" 11 #include "xe_device.h" 12 #include "xe_gt.h" 13 #include "xe_macros.h" 14 #include "xe_mmio.h" 15 16 static u32 read_reference_ts_freq(struct xe_gt *gt) 17 { 18 u32 ts_override = xe_mmio_read32(gt, TIMESTAMP_OVERRIDE); 19 u32 base_freq, frac_freq; 20 21 base_freq = REG_FIELD_GET(TIMESTAMP_OVERRIDE_US_COUNTER_DIVIDER_MASK, 22 ts_override) + 1; 23 base_freq *= 1000000; 24 25 frac_freq = REG_FIELD_GET(TIMESTAMP_OVERRIDE_US_COUNTER_DENOMINATOR_MASK, 26 ts_override); 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 = REG_FIELD_GET(RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_MASK, 39 rpm_config_reg); 40 41 switch (crystal_clock) { 42 case RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_24_MHZ: 43 return f24_mhz; 44 case RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_19_2_MHZ: 45 return f19_2_mhz; 46 case RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_38_4_MHZ: 47 return f38_4_mhz; 48 case RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_25_MHZ: 49 return f25_mhz; 50 default: 51 XE_WARN_ON("NOT_POSSIBLE"); 52 return 0; 53 } 54 } 55 56 int xe_gt_clock_init(struct xe_gt *gt) 57 { 58 u32 ctc_reg = xe_mmio_read32(gt, CTC_MODE); 59 u32 freq = 0; 60 61 /* Assuming gen11+ so assert this assumption is correct */ 62 xe_gt_assert(gt, GRAPHICS_VER(gt_to_xe(gt)) >= 11); 63 64 if (ctc_reg & CTC_SOURCE_DIVIDE_LOGIC) { 65 freq = read_reference_ts_freq(gt); 66 } else { 67 u32 c0 = xe_mmio_read32(gt, RPM_CONFIG0); 68 69 freq = get_crystal_clock_freq(c0); 70 71 /* 72 * Now figure out how the command stream's timestamp 73 * register increments from this frequency (it might 74 * increment only every few clock cycle). 75 */ 76 freq >>= 3 - REG_FIELD_GET(RPM_CONFIG0_CTC_SHIFT_PARAMETER_MASK, c0); 77 } 78 79 gt->info.reference_clock = freq; 80 return 0; 81 } 82