brintos

brintos / linux-shallow public Read only

0
0
Text · 2.4 KiB · 86c2d62 Raw
102 lines · c
1// SPDX-License-Identifier: MIT2/*3 * Copyright © 2022 Intel Corporation4 */5 6#include <linux/math64.h>7 8#include "xe_gt_clock.h"9 10#include "regs/xe_gt_regs.h"11#include "regs/xe_regs.h"12#include "xe_assert.h"13#include "xe_device.h"14#include "xe_gt.h"15#include "xe_macros.h"16#include "xe_mmio.h"17 18static u32 read_reference_ts_freq(struct xe_gt *gt)19{20	u32 ts_override = xe_mmio_read32(gt, TIMESTAMP_OVERRIDE);21	u32 base_freq, frac_freq;22 23	base_freq = REG_FIELD_GET(TIMESTAMP_OVERRIDE_US_COUNTER_DIVIDER_MASK,24				  ts_override) + 1;25	base_freq *= 1000000;26 27	frac_freq = REG_FIELD_GET(TIMESTAMP_OVERRIDE_US_COUNTER_DENOMINATOR_MASK,28				  ts_override);29	frac_freq = 1000000 / (frac_freq + 1);30 31	return base_freq + frac_freq;32}33 34static u32 get_crystal_clock_freq(u32 rpm_config_reg)35{36	const u32 f19_2_mhz = 19200000;37	const u32 f24_mhz = 24000000;38	const u32 f25_mhz = 25000000;39	const u32 f38_4_mhz = 38400000;40	u32 crystal_clock = REG_FIELD_GET(RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_MASK,41					  rpm_config_reg);42 43	switch (crystal_clock) {44	case RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_24_MHZ:45		return f24_mhz;46	case RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_19_2_MHZ:47		return f19_2_mhz;48	case RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_38_4_MHZ:49		return f38_4_mhz;50	case RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_25_MHZ:51		return f25_mhz;52	default:53		XE_WARN_ON("NOT_POSSIBLE");54		return 0;55	}56}57 58int xe_gt_clock_init(struct xe_gt *gt)59{60	u32 ctc_reg = xe_mmio_read32(gt, CTC_MODE);61	u32 freq = 0;62 63	/* Assuming gen11+ so assert this assumption is correct */64	xe_gt_assert(gt, GRAPHICS_VER(gt_to_xe(gt)) >= 11);65 66	if (ctc_reg & CTC_SOURCE_DIVIDE_LOGIC) {67		freq = read_reference_ts_freq(gt);68	} else {69		u32 c0 = xe_mmio_read32(gt, RPM_CONFIG0);70 71		freq = get_crystal_clock_freq(c0);72 73		/*74		 * Now figure out how the command stream's timestamp75		 * register increments from this frequency (it might76		 * increment only every few clock cycle).77		 */78		freq >>= 3 - REG_FIELD_GET(RPM_CONFIG0_CTC_SHIFT_PARAMETER_MASK, c0);79	}80 81	gt->info.reference_clock = freq;82	return 0;83}84 85static u64 div_u64_roundup(u64 n, u32 d)86{87	return div_u64(n + d - 1, d);88}89 90/**91 * xe_gt_clock_interval_to_ms - Convert sampled GT clock ticks to msec92 *93 * @gt: the &xe_gt94 * @count: count of GT clock ticks95 *96 * Returns: time in msec97 */98u64 xe_gt_clock_interval_to_ms(struct xe_gt *gt, u64 count)99{100	return div_u64_roundup(count * MSEC_PER_SEC, gt->info.reference_clock);101}102