Files
linux-stable-mirror/drivers/gpu/drm/i915/display/intel_de.c
T
Jani Nikula e892c68bba drm/i915/display: add typedef for intel_reg_t and use it
Add a typedef alias intel_reg_t for i915_reg_t, and use it exclusively
in display code. The goal is to eventually define a distinct type for
display, but for now just use an alias.

In a handful of places include intel_display_reg_defs.h instead of
i915_reg_defs.h to get the definition, and isolate the i915_reg_defs.h
include there.

Reviewed-by: Michał Grzelak <michal.grzelak@intel.com>
Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patch.msgid.link/f5bb0122143c39ce7f9ce8a1605a7637e569f7f8.1777972548.git.jani.nikula@intel.com
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
2026-05-13 16:03:16 +03:00

187 lines
4.5 KiB
C

// SPDX-License-Identifier: MIT
/*
* Copyright © 2026 Intel Corporation
*/
#include <linux/delay.h>
#include <drm/drm_print.h>
#include "intel_de.h"
static int __intel_de_wait_for_register(struct intel_display *display,
intel_reg_t reg, u32 mask, u32 value,
unsigned int timeout_us,
u32 (*read)(struct intel_display *display, intel_reg_t reg),
u32 *out_val, bool is_atomic)
{
const ktime_t end = ktime_add_us(ktime_get_raw(), timeout_us);
int wait_max = 1000;
int wait = 10;
u32 reg_value;
int ret;
might_sleep_if(!is_atomic);
if (timeout_us <= 10) {
is_atomic = true;
wait = 1;
}
for (;;) {
bool expired = ktime_after(ktime_get_raw(), end);
/* guarantee the condition is evaluated after timeout expired */
barrier();
reg_value = read(display, reg);
if ((reg_value & mask) == value) {
ret = 0;
break;
}
if (expired) {
ret = -ETIMEDOUT;
break;
}
if (is_atomic)
udelay(wait);
else
usleep_range(wait, wait << 1);
if (wait < wait_max)
wait <<= 1;
}
if (out_val)
*out_val = reg_value;
return ret;
}
static int intel_de_wait_for_register(struct intel_display *display,
intel_reg_t reg, u32 mask, u32 value,
unsigned int fast_timeout_us,
unsigned int slow_timeout_us,
u32 (*read)(struct intel_display *display, intel_reg_t reg),
u32 *out_value, bool is_atomic)
{
int ret = -EINVAL;
if (fast_timeout_us)
ret = __intel_de_wait_for_register(display, reg, mask, value,
fast_timeout_us, read,
out_value, is_atomic);
if (ret && slow_timeout_us)
ret = __intel_de_wait_for_register(display, reg, mask, value,
slow_timeout_us, read,
out_value, is_atomic);
return ret;
}
int intel_de_wait_us(struct intel_display *display, intel_reg_t reg,
u32 mask, u32 value, unsigned int timeout_us,
u32 *out_value)
{
int ret;
intel_dmc_wl_get(display, reg);
ret = intel_de_wait_for_register(display, reg, mask, value,
timeout_us, 0,
intel_de_read,
out_value, false);
intel_dmc_wl_put(display, reg);
return ret;
}
int intel_de_wait_ms(struct intel_display *display, intel_reg_t reg,
u32 mask, u32 value, unsigned int timeout_ms,
u32 *out_value)
{
int ret;
intel_dmc_wl_get(display, reg);
ret = intel_de_wait_for_register(display, reg, mask, value,
2, timeout_ms * 1000,
intel_de_read,
out_value, false);
intel_dmc_wl_put(display, reg);
return ret;
}
int intel_de_wait_fw_ms(struct intel_display *display, intel_reg_t reg,
u32 mask, u32 value, unsigned int timeout_ms,
u32 *out_value)
{
return intel_de_wait_for_register(display, reg, mask, value,
2, timeout_ms * 1000,
intel_de_read_fw,
out_value, false);
}
int intel_de_wait_fw_us_atomic(struct intel_display *display, intel_reg_t reg,
u32 mask, u32 value, unsigned int timeout_us,
u32 *out_value)
{
return intel_de_wait_for_register(display, reg, mask, value,
timeout_us, 0,
intel_de_read_fw,
out_value, true);
}
int intel_de_wait_for_set_us(struct intel_display *display, intel_reg_t reg,
u32 mask, unsigned int timeout_us)
{
return intel_de_wait_us(display, reg, mask, mask, timeout_us, NULL);
}
int intel_de_wait_for_clear_us(struct intel_display *display, intel_reg_t reg,
u32 mask, unsigned int timeout_us)
{
return intel_de_wait_us(display, reg, mask, 0, timeout_us, NULL);
}
int intel_de_wait_for_set_ms(struct intel_display *display, intel_reg_t reg,
u32 mask, unsigned int timeout_ms)
{
return intel_de_wait_ms(display, reg, mask, mask, timeout_ms, NULL);
}
int intel_de_wait_for_clear_ms(struct intel_display *display, intel_reg_t reg,
u32 mask, unsigned int timeout_ms)
{
return intel_de_wait_ms(display, reg, mask, 0, timeout_ms, NULL);
}
u8 intel_de_read8(struct intel_display *display, intel_reg_t reg)
{
/* this is only used on VGA registers (possible on pre-g4x) */
drm_WARN_ON(display->drm, DISPLAY_VER(display) >= 5 || display->platform.g4x);
return intel_uncore_read8(__to_uncore(display), reg);
}
void intel_de_write8(struct intel_display *display, intel_reg_t reg, u8 val)
{
drm_WARN_ON(display->drm, DISPLAY_VER(display) >= 5 || display->platform.g4x);
intel_uncore_write8(__to_uncore(display), reg, val);
}
u16 intel_de_read16(struct intel_display *display, intel_reg_t reg)
{
/* this is only used on MCHBAR registers on pre-SNB */
drm_WARN_ON(display->drm, DISPLAY_VER(display) >= 6);
return intel_uncore_read16(__to_uncore(display), reg);
}