Skip to content

Commit 71b6b25

Browse files
unerligerodrigovivi
authored andcommitted
i915/uncore: Acquire fw before loop in intel_uncore_read64_2x32
PMU reads the GT timestamp as a 2x32 mmio read and since upper and lower 32 bit registers are read in a loop, there is a latency involved between getting the GT timestamp and the CPU timestamp. As part of the resolution, refactor intel_uncore_read64_2x32 to acquire forcewake and uncore lock prior to reading upper and lower regs. Signed-off-by: Umesh Nerlige Ramappa <[email protected]> Reviewed-by: Tvrtko Ursulin <[email protected]> Reviewed-by: Ashutosh Dixit <[email protected]> Signed-off-by: John Harrison <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] (cherry picked from commit e746f84) Signed-off-by: Rodrigo Vivi <[email protected]>
1 parent dfa5e6e commit 71b6b25

File tree

1 file changed

+30
-14
lines changed

1 file changed

+30
-14
lines changed

drivers/gpu/drm/i915/intel_uncore.h

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -382,20 +382,6 @@ __uncore_write(write_notrace, 32, l, false)
382382
*/
383383
__uncore_read(read64, 64, q, true)
384384

385-
static inline u64
386-
intel_uncore_read64_2x32(struct intel_uncore *uncore,
387-
i915_reg_t lower_reg, i915_reg_t upper_reg)
388-
{
389-
u32 upper, lower, old_upper, loop = 0;
390-
upper = intel_uncore_read(uncore, upper_reg);
391-
do {
392-
old_upper = upper;
393-
lower = intel_uncore_read(uncore, lower_reg);
394-
upper = intel_uncore_read(uncore, upper_reg);
395-
} while (upper != old_upper && loop++ < 2);
396-
return (u64)upper << 32 | lower;
397-
}
398-
399385
#define intel_uncore_posting_read(...) ((void)intel_uncore_read_notrace(__VA_ARGS__))
400386
#define intel_uncore_posting_read16(...) ((void)intel_uncore_read16_notrace(__VA_ARGS__))
401387

@@ -455,6 +441,36 @@ static inline void intel_uncore_rmw_fw(struct intel_uncore *uncore,
455441
intel_uncore_write_fw(uncore, reg, val);
456442
}
457443

444+
static inline u64
445+
intel_uncore_read64_2x32(struct intel_uncore *uncore,
446+
i915_reg_t lower_reg, i915_reg_t upper_reg)
447+
{
448+
u32 upper, lower, old_upper, loop = 0;
449+
enum forcewake_domains fw_domains;
450+
unsigned long flags;
451+
452+
fw_domains = intel_uncore_forcewake_for_reg(uncore, lower_reg,
453+
FW_REG_READ);
454+
455+
fw_domains |= intel_uncore_forcewake_for_reg(uncore, upper_reg,
456+
FW_REG_READ);
457+
458+
spin_lock_irqsave(&uncore->lock, flags);
459+
intel_uncore_forcewake_get__locked(uncore, fw_domains);
460+
461+
upper = intel_uncore_read_fw(uncore, upper_reg);
462+
do {
463+
old_upper = upper;
464+
lower = intel_uncore_read_fw(uncore, lower_reg);
465+
upper = intel_uncore_read_fw(uncore, upper_reg);
466+
} while (upper != old_upper && loop++ < 2);
467+
468+
intel_uncore_forcewake_put__locked(uncore, fw_domains);
469+
spin_unlock_irqrestore(&uncore->lock, flags);
470+
471+
return (u64)upper << 32 | lower;
472+
}
473+
458474
static inline int intel_uncore_write_and_verify(struct intel_uncore *uncore,
459475
i915_reg_t reg, u32 val,
460476
u32 mask, u32 expected_val)

0 commit comments

Comments
 (0)