brintos

brintos / linux-shallow public Read only

0
0
Text · 6.5 KiB · 6e63505 Raw
242 lines · c
1// SPDX-License-Identifier: MIT2/*3 * Copyright © 2020 Intel Corporation4 */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_print.h"11#include "intel_gt_regs.h"12#include "soc/intel_dram.h"13 14static u32 read_reference_ts_freq(struct intel_uncore *uncore)15{16	u32 ts_override = intel_uncore_read(uncore, GEN9_TIMESTAMP_OVERRIDE);17	u32 base_freq, frac_freq;18 19	base_freq = ((ts_override & GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DIVIDER_MASK) >>20		     GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DIVIDER_SHIFT) + 1;21	base_freq *= 1000000;22 23	frac_freq = ((ts_override &24		      GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DENOMINATOR_MASK) >>25		     GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DENOMINATOR_SHIFT);26	frac_freq = 1000000 / (frac_freq + 1);27 28	return base_freq + frac_freq;29}30 31static u32 gen11_get_crystal_clock_freq(struct intel_uncore *uncore,32					u32 rpm_config_reg)33{34	u32 f19_2_mhz = 19200000;35	u32 f24_mhz = 24000000;36	u32 f25_mhz = 25000000;37	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		MISSING_CASE(crystal_clock);53		return 0;54	}55}56 57static u32 gen11_read_clock_frequency(struct intel_uncore *uncore)58{59	u32 ctc_reg = intel_uncore_read(uncore, CTC_MODE);60	u32 freq = 0;61 62	/*63	 * Note that on gen11+, the clock frequency may be reconfigured.64	 * We do not, and we assume nobody else does.65	 *66	 * First figure out the reference frequency. There are 2 ways67	 * we can compute the frequency, either through the68	 * TIMESTAMP_OVERRIDE register or through RPM_CONFIG. CTC_MODE69	 * tells us which one we should use.70	 */71	if ((ctc_reg & CTC_SOURCE_PARAMETER_MASK) == CTC_SOURCE_DIVIDE_LOGIC) {72		freq = read_reference_ts_freq(uncore);73	} else {74		u32 c0 = intel_uncore_read(uncore, RPM_CONFIG0);75 76		freq = gen11_get_crystal_clock_freq(uncore, c0);77 78		/*79		 * Now figure out how the command stream's timestamp80		 * register increments from this frequency (it might81		 * increment only every few clock cycle).82		 */83		freq >>= 3 - ((c0 & GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_MASK) >>84			      GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_SHIFT);85	}86 87	return freq;88}89 90static u32 gen9_read_clock_frequency(struct intel_uncore *uncore)91{92	u32 ctc_reg = intel_uncore_read(uncore, CTC_MODE);93	u32 freq = 0;94 95	if ((ctc_reg & CTC_SOURCE_PARAMETER_MASK) == CTC_SOURCE_DIVIDE_LOGIC) {96		freq = read_reference_ts_freq(uncore);97	} else {98		freq = IS_GEN9_LP(uncore->i915) ? 19200000 : 24000000;99 100		/*101		 * Now figure out how the command stream's timestamp102		 * register increments from this frequency (it might103		 * increment only every few clock cycle).104		 */105		freq >>= 3 - ((ctc_reg & CTC_SHIFT_PARAMETER_MASK) >>106			      CTC_SHIFT_PARAMETER_SHIFT);107	}108 109	return freq;110}111 112static u32 gen6_read_clock_frequency(struct intel_uncore *uncore)113{114	/*115	 * PRMs say:116	 *117	 *     "The PCU TSC counts 10ns increments; this timestamp118	 *      reflects bits 38:3 of the TSC (i.e. 80ns granularity,119	 *      rolling over every 1.5 hours).120	 */121	return 12500000;122}123 124static u32 gen5_read_clock_frequency(struct intel_uncore *uncore)125{126	/*127	 * 63:32 increments every 1000 ns128	 * 31:0 mbz129	 */130	return 1000000000 / 1000;131}132 133static u32 g4x_read_clock_frequency(struct intel_uncore *uncore)134{135	/*136	 * 63:20 increments every 1/4 ns137	 * 19:0 mbz138	 *139	 * -> 63:32 increments every 1024 ns140	 */141	return 1000000000 / 1024;142}143 144static u32 gen4_read_clock_frequency(struct intel_uncore *uncore)145{146	/*147	 * PRMs say:148	 *149	 *     "The value in this register increments once every 16150	 *      hclks." (through the “Clocking Configuration”151	 *      (“CLKCFG”) MCHBAR register)152	 *153	 * Testing on actual hardware has shown there is no /16.154	 */155	return DIV_ROUND_CLOSEST(i9xx_fsb_freq(uncore->i915), 4) * 1000;156}157 158static u32 read_clock_frequency(struct intel_uncore *uncore)159{160	if (GRAPHICS_VER(uncore->i915) >= 11)161		return gen11_read_clock_frequency(uncore);162	else if (GRAPHICS_VER(uncore->i915) >= 9)163		return gen9_read_clock_frequency(uncore);164	else if (GRAPHICS_VER(uncore->i915) >= 6)165		return gen6_read_clock_frequency(uncore);166	else if (GRAPHICS_VER(uncore->i915) == 5)167		return gen5_read_clock_frequency(uncore);168	else if (IS_G4X(uncore->i915))169		return g4x_read_clock_frequency(uncore);170	else if (GRAPHICS_VER(uncore->i915) == 4)171		return gen4_read_clock_frequency(uncore);172	else173		return 0;174}175 176void intel_gt_init_clock_frequency(struct intel_gt *gt)177{178	gt->clock_frequency = read_clock_frequency(gt->uncore);179 180	/* Icelake appears to use another fixed frequency for CTX_TIMESTAMP */181	if (GRAPHICS_VER(gt->i915) == 11)182		gt->clock_period_ns = NSEC_PER_SEC / 13750000;183	else if (gt->clock_frequency)184		gt->clock_period_ns = intel_gt_clock_interval_to_ns(gt, 1);185 186	GT_TRACE(gt,187		 "Using clock frequency: %dkHz, period: %dns, wrap: %lldms\n",188		 gt->clock_frequency / 1000,189		 gt->clock_period_ns,190		 div_u64(mul_u32_u32(gt->clock_period_ns, S32_MAX),191			 USEC_PER_SEC));192}193 194#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)195void intel_gt_check_clock_frequency(const struct intel_gt *gt)196{197	if (gt->clock_frequency != read_clock_frequency(gt->uncore)) {198		gt_err(gt, "GT clock frequency changed, was %uHz, now %uHz!\n",199		       gt->clock_frequency,200		       read_clock_frequency(gt->uncore));201	}202}203#endif204 205static u64 div_u64_roundup(u64 nom, u32 den)206{207	return div_u64(nom + den - 1, den);208}209 210u64 intel_gt_clock_interval_to_ns(const struct intel_gt *gt, u64 count)211{212	return div_u64_roundup(count * NSEC_PER_SEC, gt->clock_frequency);213}214 215u64 intel_gt_pm_interval_to_ns(const struct intel_gt *gt, u64 count)216{217	return intel_gt_clock_interval_to_ns(gt, 16 * count);218}219 220u64 intel_gt_ns_to_clock_interval(const struct intel_gt *gt, u64 ns)221{222	return div_u64_roundup(gt->clock_frequency * ns, NSEC_PER_SEC);223}224 225u64 intel_gt_ns_to_pm_interval(const struct intel_gt *gt, u64 ns)226{227	u64 val;228 229	/*230	 * Make these a multiple of magic 25 to avoid SNB (eg. Dell XPS231	 * 8300) freezing up around GPU hangs. Looks as if even232	 * scheduling/timer interrupts start misbehaving if the RPS233	 * EI/thresholds are "bad", leading to a very sluggish or even234	 * frozen machine.235	 */236	val = div_u64_roundup(intel_gt_ns_to_clock_interval(gt, ns), 16);237	if (GRAPHICS_VER(gt->i915) == 6)238		val = div_u64_roundup(val, 25) * 25;239 240	return val;241}242