Skip to content

Commit

Permalink
i915/uncore: Acquire fw before loop in intel_uncore_read64_2x32
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
unerlige authored and rodrigovivi committed Nov 23, 2022
1 parent dfa5e6e commit 71b6b25
Showing 1 changed file with 30 additions and 14 deletions.
44 changes: 30 additions & 14 deletions drivers/gpu/drm/i915/intel_uncore.h
Original file line number Diff line number Diff line change
Expand Up @@ -382,20 +382,6 @@ __uncore_write(write_notrace, 32, l, false)
*/
__uncore_read(read64, 64, q, true)

static inline u64
intel_uncore_read64_2x32(struct intel_uncore *uncore,
i915_reg_t lower_reg, i915_reg_t upper_reg)
{
u32 upper, lower, old_upper, loop = 0;
upper = intel_uncore_read(uncore, upper_reg);
do {
old_upper = upper;
lower = intel_uncore_read(uncore, lower_reg);
upper = intel_uncore_read(uncore, upper_reg);
} while (upper != old_upper && loop++ < 2);
return (u64)upper << 32 | lower;
}

#define intel_uncore_posting_read(...) ((void)intel_uncore_read_notrace(__VA_ARGS__))
#define intel_uncore_posting_read16(...) ((void)intel_uncore_read16_notrace(__VA_ARGS__))

Expand Down Expand Up @@ -455,6 +441,36 @@ static inline void intel_uncore_rmw_fw(struct intel_uncore *uncore,
intel_uncore_write_fw(uncore, reg, val);
}

static inline u64
intel_uncore_read64_2x32(struct intel_uncore *uncore,
i915_reg_t lower_reg, i915_reg_t upper_reg)
{
u32 upper, lower, old_upper, loop = 0;
enum forcewake_domains fw_domains;
unsigned long flags;

fw_domains = intel_uncore_forcewake_for_reg(uncore, lower_reg,
FW_REG_READ);

fw_domains |= intel_uncore_forcewake_for_reg(uncore, upper_reg,
FW_REG_READ);

spin_lock_irqsave(&uncore->lock, flags);
intel_uncore_forcewake_get__locked(uncore, fw_domains);

upper = intel_uncore_read_fw(uncore, upper_reg);
do {
old_upper = upper;
lower = intel_uncore_read_fw(uncore, lower_reg);
upper = intel_uncore_read_fw(uncore, upper_reg);
} while (upper != old_upper && loop++ < 2);

intel_uncore_forcewake_put__locked(uncore, fw_domains);
spin_unlock_irqrestore(&uncore->lock, flags);

return (u64)upper << 32 | lower;
}

static inline int intel_uncore_write_and_verify(struct intel_uncore *uncore,
i915_reg_t reg, u32 val,
u32 mask, u32 expected_val)
Expand Down

0 comments on commit 71b6b25

Please sign in to comment.