cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

intel_gt_clock_utils.c (6414B)


      1// SPDX-License-Identifier: MIT
      2/*
      3 * Copyright © 2020 Intel Corporation
      4 */
      5
      6#include "i915_drv.h"
      7#include "i915_reg.h"
      8#include "intel_gt.h"
      9#include "intel_gt_clock_utils.h"
     10#include "intel_gt_regs.h"
     11
     12static u32 read_reference_ts_freq(struct intel_uncore *uncore)
     13{
     14	u32 ts_override = intel_uncore_read(uncore, GEN9_TIMESTAMP_OVERRIDE);
     15	u32 base_freq, frac_freq;
     16
     17	base_freq = ((ts_override & GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DIVIDER_MASK) >>
     18		     GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DIVIDER_SHIFT) + 1;
     19	base_freq *= 1000000;
     20
     21	frac_freq = ((ts_override &
     22		      GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DENOMINATOR_MASK) >>
     23		     GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DENOMINATOR_SHIFT);
     24	frac_freq = 1000000 / (frac_freq + 1);
     25
     26	return base_freq + frac_freq;
     27}
     28
     29static u32 gen9_get_crystal_clock_freq(struct intel_uncore *uncore,
     30				       u32 rpm_config_reg)
     31{
     32	u32 f19_2_mhz = 19200000;
     33	u32 f24_mhz = 24000000;
     34	u32 crystal_clock =
     35		(rpm_config_reg & GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_MASK) >>
     36		GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_SHIFT;
     37
     38	switch (crystal_clock) {
     39	case GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_19_2_MHZ:
     40		return f19_2_mhz;
     41	case GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_24_MHZ:
     42		return f24_mhz;
     43	default:
     44		MISSING_CASE(crystal_clock);
     45		return 0;
     46	}
     47}
     48
     49static u32 gen11_get_crystal_clock_freq(struct intel_uncore *uncore,
     50					u32 rpm_config_reg)
     51{
     52	u32 f19_2_mhz = 19200000;
     53	u32 f24_mhz = 24000000;
     54	u32 f25_mhz = 25000000;
     55	u32 f38_4_mhz = 38400000;
     56	u32 crystal_clock =
     57		(rpm_config_reg & GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_MASK) >>
     58		GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_SHIFT;
     59
     60	switch (crystal_clock) {
     61	case GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_24_MHZ:
     62		return f24_mhz;
     63	case GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_19_2_MHZ:
     64		return f19_2_mhz;
     65	case GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_38_4_MHZ:
     66		return f38_4_mhz;
     67	case GEN11_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_25_MHZ:
     68		return f25_mhz;
     69	default:
     70		MISSING_CASE(crystal_clock);
     71		return 0;
     72	}
     73}
     74
     75static u32 read_clock_frequency(struct intel_uncore *uncore)
     76{
     77	u32 f12_5_mhz = 12500000;
     78	u32 f19_2_mhz = 19200000;
     79	u32 f24_mhz = 24000000;
     80
     81	if (GRAPHICS_VER(uncore->i915) <= 4) {
     82		/*
     83		 * PRMs say:
     84		 *
     85		 *     "The value in this register increments once every 16
     86		 *      hclks." (through the “Clocking Configuration”
     87		 *      (“CLKCFG”) MCHBAR register)
     88		 */
     89		return RUNTIME_INFO(uncore->i915)->rawclk_freq * 1000 / 16;
     90	} else if (GRAPHICS_VER(uncore->i915) <= 8) {
     91		/*
     92		 * PRMs say:
     93		 *
     94		 *     "The PCU TSC counts 10ns increments; this timestamp
     95		 *      reflects bits 38:3 of the TSC (i.e. 80ns granularity,
     96		 *      rolling over every 1.5 hours).
     97		 */
     98		return f12_5_mhz;
     99	} else if (GRAPHICS_VER(uncore->i915) <= 9) {
    100		u32 ctc_reg = intel_uncore_read(uncore, CTC_MODE);
    101		u32 freq = 0;
    102
    103		if ((ctc_reg & CTC_SOURCE_PARAMETER_MASK) == CTC_SOURCE_DIVIDE_LOGIC) {
    104			freq = read_reference_ts_freq(uncore);
    105		} else {
    106			freq = IS_GEN9_LP(uncore->i915) ? f19_2_mhz : f24_mhz;
    107
    108			/*
    109			 * Now figure out how the command stream's timestamp
    110			 * register increments from this frequency (it might
    111			 * increment only every few clock cycle).
    112			 */
    113			freq >>= 3 - ((ctc_reg & CTC_SHIFT_PARAMETER_MASK) >>
    114				      CTC_SHIFT_PARAMETER_SHIFT);
    115		}
    116
    117		return freq;
    118	} else if (GRAPHICS_VER(uncore->i915) <= 12) {
    119		u32 ctc_reg = intel_uncore_read(uncore, CTC_MODE);
    120		u32 freq = 0;
    121
    122		/*
    123		 * First figure out the reference frequency. There are 2 ways
    124		 * we can compute the frequency, either through the
    125		 * TIMESTAMP_OVERRIDE register or through RPM_CONFIG. CTC_MODE
    126		 * tells us which one we should use.
    127		 */
    128		if ((ctc_reg & CTC_SOURCE_PARAMETER_MASK) == CTC_SOURCE_DIVIDE_LOGIC) {
    129			freq = read_reference_ts_freq(uncore);
    130		} else {
    131			u32 c0 = intel_uncore_read(uncore, RPM_CONFIG0);
    132
    133			if (GRAPHICS_VER(uncore->i915) >= 11)
    134				freq = gen11_get_crystal_clock_freq(uncore, c0);
    135			else
    136				freq = gen9_get_crystal_clock_freq(uncore, c0);
    137
    138			/*
    139			 * Now figure out how the command stream's timestamp
    140			 * register increments from this frequency (it might
    141			 * increment only every few clock cycle).
    142			 */
    143			freq >>= 3 - ((c0 & GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_MASK) >>
    144				      GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_SHIFT);
    145		}
    146
    147		return freq;
    148	}
    149
    150	MISSING_CASE("Unknown gen, unable to read command streamer timestamp frequency\n");
    151	return 0;
    152}
    153
    154void intel_gt_init_clock_frequency(struct intel_gt *gt)
    155{
    156	/*
    157	 * Note that on gen11+, the clock frequency may be reconfigured.
    158	 * We do not, and we assume nobody else does.
    159	 */
    160	gt->clock_frequency = read_clock_frequency(gt->uncore);
    161	if (gt->clock_frequency)
    162		gt->clock_period_ns = intel_gt_clock_interval_to_ns(gt, 1);
    163
    164	/* Icelake appears to use another fixed frequency for CTX_TIMESTAMP */
    165	if (GRAPHICS_VER(gt->i915) == 11)
    166		gt->clock_period_ns = NSEC_PER_SEC / 13750000;
    167
    168	GT_TRACE(gt,
    169		 "Using clock frequency: %dkHz, period: %dns, wrap: %lldms\n",
    170		 gt->clock_frequency / 1000,
    171		 gt->clock_period_ns,
    172		 div_u64(mul_u32_u32(gt->clock_period_ns, S32_MAX),
    173			 USEC_PER_SEC));
    174}
    175
    176#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)
    177void intel_gt_check_clock_frequency(const struct intel_gt *gt)
    178{
    179	if (gt->clock_frequency != read_clock_frequency(gt->uncore)) {
    180		dev_err(gt->i915->drm.dev,
    181			"GT clock frequency changed, was %uHz, now %uHz!\n",
    182			gt->clock_frequency,
    183			read_clock_frequency(gt->uncore));
    184	}
    185}
    186#endif
    187
    188static u64 div_u64_roundup(u64 nom, u32 den)
    189{
    190	return div_u64(nom + den - 1, den);
    191}
    192
    193u64 intel_gt_clock_interval_to_ns(const struct intel_gt *gt, u64 count)
    194{
    195	return div_u64_roundup(count * NSEC_PER_SEC, gt->clock_frequency);
    196}
    197
    198u64 intel_gt_pm_interval_to_ns(const struct intel_gt *gt, u64 count)
    199{
    200	return intel_gt_clock_interval_to_ns(gt, 16 * count);
    201}
    202
    203u64 intel_gt_ns_to_clock_interval(const struct intel_gt *gt, u64 ns)
    204{
    205	return div_u64_roundup(gt->clock_frequency * ns, NSEC_PER_SEC);
    206}
    207
    208u64 intel_gt_ns_to_pm_interval(const struct intel_gt *gt, u64 ns)
    209{
    210	u64 val;
    211
    212	/*
    213	 * Make these a multiple of magic 25 to avoid SNB (eg. Dell XPS
    214	 * 8300) freezing up around GPU hangs. Looks as if even
    215	 * scheduling/timer interrupts start misbehaving if the RPS
    216	 * EI/thresholds are "bad", leading to a very sluggish or even
    217	 * frozen machine.
    218	 */
    219	val = div_u64_roundup(intel_gt_ns_to_clock_interval(gt, ns), 16);
    220	if (GRAPHICS_VER(gt->i915) == 6)
    221		val = div_u64_roundup(val, 25) * 25;
    222
    223	return val;
    224}