Commit 7971debd authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-intel-next-2023-10-12' of git://anongit.freedesktop.org/drm/drm-intel into drm-next

drm/i915 feature pull #2 for v6.7:

Features and functionality:
- Preparation for i915 display code reuse in upcoming Xe driver (Jani)
- Drop the fastboot module parameter and use the platform defaults (Arun)
- Enable new LNL FBC features (Vinod)
- Add LNL display feature capability reads (Vinod)

Refactoring and cleanups:
- Locally enable W=1 warnings by default in i915 (Jani)
- Move HDCP GSC message code to a separate file (Suraj)
- GVT include cleanups (Jani)
- Move more display init under display/ (Jani)
- DPLL ID refactoring (Ville)
- Better abstraction of GT0 (Jani)
- Move VGA decode function to GMCH code (Uma)
- Use local64_try_cmpxchg() to optimize PMU event read (Uros Bizjak)
- Clean up FBC checks (Ville)
- Constify and unify state checker calling conventions (Ville)
- Add display step name helper (Chaitanya)

Documentation:
- Update CCS and GSC CS documentation (Rodrigo)
- Fix a number of documentation typos (Randy Dunlap)

Fixes:
- VLV DSI fixes and quirks (Hans)
- Fix crtc state memory leaks (Suraj)
- Increase LSPCON mode settle timeout (Niko Tsirakis)
- Stop clobbering old crtc state during state check (Ville)
- Fix VLV color state readout (Ville)
- Fix cx0 PHY pipe reset to allow S0iX (Khaled)
- Ensure DP MST pbn_div is up-to-date after sink reconnect (Imre)
- Drop an unnecessary NULL check to fix static analyzer warning (Suraj)
- Use an explicit rather than implicit include for frontbuffer tracking (Jouni)

Merges:
- Backmerge drm-next to fix a conflict (Jani)
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/87r0m00xew.fsf@intel.com
parents d32ce5ab a6028afe
......@@ -267,19 +267,22 @@ i915 driver.
Intel GPU Basics
----------------
An Intel GPU has multiple engines. There are several engine types.
- RCS engine is for rendering 3D and performing compute, this is named
`I915_EXEC_RENDER` in user space.
- BCS is a blitting (copy) engine, this is named `I915_EXEC_BLT` in user
space.
- VCS is a video encode and decode engine, this is named `I915_EXEC_BSD`
in user space
- VECS is video enhancement engine, this is named `I915_EXEC_VEBOX` in user
space.
- The enumeration `I915_EXEC_DEFAULT` does not refer to specific engine;
instead it is to be used by user space to specify a default rendering
engine (for 3D) that may or may not be the same as RCS.
An Intel GPU has multiple engines. There are several engine types:
- Render Command Streamer (RCS). An engine for rendering 3D and
performing compute.
- Blitting Command Streamer (BCS). An engine for performing blitting and/or
copying operations.
- Video Command Streamer. An engine used for video encoding and decoding. Also
sometimes called 'BSD' in hardware documentation.
- Video Enhancement Command Streamer (VECS). An engine for video enhancement.
Also sometimes called 'VEBOX' in hardware documentation.
- Compute Command Streamer (CCS). An engine that has access to the media and
GPGPU pipelines, but not the 3D pipeline.
- Graphics Security Controller (GSCCS). A dedicated engine for internal
communication with GSC controller on security related tasks like
High-bandwidth Digital Content Protection (HDCP), Protected Xe Path (PXP),
and HuC firmware authentication.
The Intel GPU family is a family of integrated GPU's using Unified
Memory Access. For having the GPU "do work", user space will feed the
......
......@@ -3,24 +3,34 @@
# Makefile for the drm device driver. This driver provides support for the
# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
# Add a set of useful warning flags and enable -Werror for CI to prevent
# trivial mistakes from creeping in. We have to do this piecemeal as we reject
# any patch that isn't warning clean, so turning on -Wall -Wextra (or W=1) we
# need to filter out dubious warnings. Still it is our interest
# to keep running locally with W=1 C=1 until we are completely clean.
#
# Note the danger in using -Wall -Wextra is that when CI updates gcc we
# will most likely get a sudden build breakage... Hopefully we will fix
# new warnings before CI updates!
subdir-ccflags-y := -Wall -Wextra
subdir-ccflags-y += -Wno-format-security
subdir-ccflags-y += -Wno-unused-parameter
subdir-ccflags-y += -Wno-type-limits
# Unconditionally enable W=1 warnings locally
# --- begin copy-paste W=1 warnings from scripts/Makefile.extrawarn
subdir-ccflags-y += -Wextra -Wunused -Wno-unused-parameter
subdir-ccflags-y += -Wmissing-declarations
subdir-ccflags-y += $(call cc-option, -Wrestrict)
subdir-ccflags-y += -Wmissing-format-attribute
subdir-ccflags-y += -Wmissing-prototypes
subdir-ccflags-y += -Wold-style-definition
subdir-ccflags-y += -Wmissing-include-dirs
subdir-ccflags-y += $(call cc-option, -Wunused-but-set-variable)
subdir-ccflags-y += $(call cc-option, -Wunused-const-variable)
subdir-ccflags-y += $(call cc-option, -Wpacked-not-aligned)
subdir-ccflags-y += $(call cc-option, -Wformat-overflow)
subdir-ccflags-y += $(call cc-option, -Wformat-truncation)
subdir-ccflags-y += $(call cc-option, -Wstringop-overflow)
subdir-ccflags-y += $(call cc-option, -Wstringop-truncation)
# The following turn off the warnings enabled by -Wextra
ifeq ($(findstring 2, $(KBUILD_EXTRA_WARN)),)
subdir-ccflags-y += -Wno-missing-field-initializers
subdir-ccflags-y += -Wno-sign-compare
subdir-ccflags-y += -Wno-type-limits
subdir-ccflags-y += -Wno-shift-negative-value
subdir-ccflags-y += $(call cc-option, -Wunused-but-set-variable)
subdir-ccflags-y += $(call cc-disable-warning, frame-address)
endif
ifeq ($(findstring 3, $(KBUILD_EXTRA_WARN)),)
subdir-ccflags-y += -Wno-sign-compare
endif
# --- end copy-paste
# Enable -Werror in CI and development
subdir-ccflags-$(CONFIG_DRM_I915_WERROR) += -Werror
# Fine grained warnings disable
......@@ -28,6 +38,10 @@ CFLAGS_i915_pci.o = $(call cc-disable-warning, override-init)
CFLAGS_display/intel_display_device.o = $(call cc-disable-warning, override-init)
CFLAGS_display/intel_fbdev.o = $(call cc-disable-warning, override-init)
# Support compiling the display code separately for both i915 and xe
# drivers. Define I915 when building i915.
subdir-ccflags-y += -DI915
subdir-ccflags-y += -I$(srctree)/$(src)
# Please keep these build lists sorted!
......@@ -265,6 +279,7 @@ i915-y += \
display/intel_global_state.o \
display/intel_hdcp.o \
display/intel_hdcp_gsc.o \
display/intel_hdcp_gsc_message.o \
display/intel_hotplug.o \
display/intel_hotplug_irq.o \
display/intel_hti.o \
......
......@@ -17,6 +17,7 @@ struct intel_crtc_state;
struct intel_dp;
struct intel_encoder;
#ifdef I915
const struct dpll *vlv_get_dpll(struct drm_i915_private *i915);
enum pipe vlv_active_pipe(struct intel_dp *intel_dp);
void g4x_dp_set_clock(struct intel_encoder *encoder,
......@@ -26,5 +27,30 @@ bool g4x_dp_port_enabled(struct drm_i915_private *dev_priv,
enum pipe *pipe);
bool g4x_dp_init(struct drm_i915_private *dev_priv,
i915_reg_t output_reg, enum port port);
#else
static inline const struct dpll *vlv_get_dpll(struct drm_i915_private *i915)
{
return NULL;
}
static inline int vlv_active_pipe(struct intel_dp *intel_dp)
{
return 0;
}
static inline void g4x_dp_set_clock(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config)
{
}
static inline bool g4x_dp_port_enabled(struct drm_i915_private *dev_priv,
i915_reg_t dp_reg, int port,
enum pipe *pipe)
{
return false;
}
static inline bool g4x_dp_init(struct drm_i915_private *dev_priv,
i915_reg_t output_reg, int port)
{
return false;
}
#endif
#endif
......@@ -15,9 +15,21 @@ struct drm_atomic_state;
struct drm_connector;
struct drm_i915_private;
#ifdef I915
void g4x_hdmi_init(struct drm_i915_private *dev_priv,
i915_reg_t hdmi_reg, enum port port);
int g4x_hdmi_connector_atomic_check(struct drm_connector *connector,
struct drm_atomic_state *state);
#else
static inline void g4x_hdmi_init(struct drm_i915_private *dev_priv,
i915_reg_t hdmi_reg, int port)
{
}
static inline int g4x_hdmi_connector_atomic_check(struct drm_connector *connector,
struct drm_atomic_state *state)
{
return 0;
}
#endif
#endif
......@@ -12,6 +12,7 @@ struct intel_atomic_state;
struct intel_crtc;
struct intel_crtc_state;
#ifdef I915
bool hsw_ips_disable(const struct intel_crtc_state *crtc_state);
bool hsw_ips_pre_update(struct intel_atomic_state *state,
struct intel_crtc *crtc);
......@@ -23,5 +24,39 @@ int hsw_ips_compute_config(struct intel_atomic_state *state,
struct intel_crtc *crtc);
void hsw_ips_get_config(struct intel_crtc_state *crtc_state);
void hsw_ips_crtc_debugfs_add(struct intel_crtc *crtc);
#else
static inline bool hsw_ips_disable(const struct intel_crtc_state *crtc_state)
{
return false;
}
static inline bool hsw_ips_pre_update(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
return false;
}
static inline void hsw_ips_post_update(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
}
static inline bool hsw_crtc_supports_ips(struct intel_crtc *crtc)
{
return false;
}
static inline bool hsw_crtc_state_ips_capable(const struct intel_crtc_state *crtc_state)
{
return false;
}
static inline int hsw_ips_compute_config(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
return 0;
}
static inline void hsw_ips_get_config(struct intel_crtc_state *crtc_state)
{
}
static inline void hsw_ips_crtc_debugfs_add(struct intel_crtc *crtc)
{
}
#endif
#endif /* __HSW_IPS_H__ */
......@@ -15,6 +15,7 @@ struct intel_initial_plane_config;
struct intel_plane;
struct intel_plane_state;
#ifdef I915
unsigned int i965_plane_max_stride(struct intel_plane *plane,
u32 pixel_format, u64 modifier,
unsigned int rotation);
......@@ -25,4 +26,26 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe);
void i9xx_get_initial_plane_config(struct intel_crtc *crtc,
struct intel_initial_plane_config *plane_config);
#else
static inline unsigned int i965_plane_max_stride(struct intel_plane *plane,
u32 pixel_format, u64 modifier,
unsigned int rotation)
{
return 0;
}
static inline int i9xx_check_plane_surface(struct intel_plane_state *plane_state)
{
return 0;
}
static inline struct intel_plane *
intel_primary_plane_create(struct drm_i915_private *dev_priv, int pipe)
{
return NULL;
}
static inline void i9xx_get_initial_plane_config(struct intel_crtc *crtc,
struct intel_initial_plane_config *plane_config)
{
}
#endif
#endif
......@@ -12,9 +12,26 @@ struct drm_i915_private;
struct intel_crtc_state;
struct intel_plane_state;
#ifdef I915
bool ilk_disable_lp_wm(struct drm_i915_private *i915);
void ilk_wm_sanitize(struct drm_i915_private *i915);
bool intel_set_memory_cxsr(struct drm_i915_private *i915, bool enable);
void i9xx_wm_init(struct drm_i915_private *i915);
#else
static inline bool ilk_disable_lp_wm(struct drm_i915_private *i915)
{
return false;
}
static inline void ilk_wm_sanitize(struct drm_i915_private *i915)
{
}
static inline bool intel_set_memory_cxsr(struct drm_i915_private *i915, bool enable)
{
return false;
}
static inline void i9xx_wm_init(struct drm_i915_private *i915)
{
}
#endif
#endif /* __I9XX_WM_H__ */
......@@ -3702,6 +3702,7 @@ static const struct intel_color_funcs vlv_color_funcs = {
.read_luts = i965_read_luts,
.lut_equal = i965_lut_equal,
.read_csc = vlv_read_csc,
.get_config = i9xx_get_config,
};
static const struct intel_color_funcs i965_color_funcs = {
......
......@@ -838,7 +838,7 @@ intel_crt_detect(struct drm_connector *connector,
connector->base.id, connector->name,
force);
if (!INTEL_DISPLAY_ENABLED(dev_priv))
if (!intel_display_device_enabled(dev_priv))
return connector_status_disconnected;
if (dev_priv->params.load_detect_test) {
......
......@@ -12,9 +12,23 @@ enum pipe;
struct drm_encoder;
struct drm_i915_private;
#ifdef I915
bool intel_crt_port_enabled(struct drm_i915_private *dev_priv,
i915_reg_t adpa_reg, enum pipe *pipe);
void intel_crt_init(struct drm_i915_private *dev_priv);
void intel_crt_reset(struct drm_encoder *encoder);
#else
static inline bool intel_crt_port_enabled(struct drm_i915_private *dev_priv,
i915_reg_t adpa_reg, enum pipe *pipe)
{
return false;
}
static inline void intel_crt_init(struct drm_i915_private *dev_priv)
{
}
static inline void intel_crt_reset(struct drm_encoder *encoder)
{
}
#endif
#endif /* __INTEL_CRT_H__ */
......@@ -2596,8 +2596,7 @@ static void intel_cx0_phy_lane_reset(struct drm_i915_private *i915,
drm_warn(&i915->drm, "PHY %c failed to bring out of SOC reset after %dus.\n",
phy_name(phy), XELPDP_PORT_BUF_SOC_READY_TIMEOUT_US);
intel_de_rmw(i915, XELPDP_PORT_BUF_CTL2(port),
XELPDP_LANE_PIPE_RESET(0) | XELPDP_LANE_PIPE_RESET(1),
intel_de_rmw(i915, XELPDP_PORT_BUF_CTL2(port), lane_pipe_reset,
lane_pipe_reset);
if (__intel_de_wait_for_register(i915, XELPDP_PORT_BUF_CTL2(port),
......@@ -3005,12 +3004,13 @@ intel_mtl_port_pll_type(struct intel_encoder *encoder,
}
void intel_c10pll_state_verify(struct intel_atomic_state *state,
struct intel_crtc_state *new_crtc_state)
struct intel_crtc *crtc)
{
struct drm_i915_private *i915 = to_i915(state->base.dev);
const struct intel_crtc_state *new_crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
struct intel_c10pll_state mpllb_hw_state = { 0 };
struct intel_c10pll_state *mpllb_sw_state = &new_crtc_state->cx0pll_state.c10;
struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
const struct intel_c10pll_state *mpllb_sw_state = &new_crtc_state->cx0pll_state.c10;
struct intel_encoder *encoder;
enum phy phy;
int i;
......
......@@ -16,6 +16,7 @@ struct drm_i915_private;
struct intel_atomic_state;
struct intel_c10pll_state;
struct intel_c20pll_state;
struct intel_crtc;
struct intel_crtc_state;
struct intel_encoder;
struct intel_hdmi;
......@@ -34,7 +35,7 @@ void intel_c10pll_dump_hw_state(struct drm_i915_private *dev_priv,
int intel_c10pll_calc_port_clock(struct intel_encoder *encoder,
const struct intel_c10pll_state *pll_state);
void intel_c10pll_state_verify(struct intel_atomic_state *state,
struct intel_crtc_state *new_crtc_state);
struct intel_crtc *crtc);
void intel_c20pll_readout_hw_state(struct intel_encoder *encoder,
struct intel_c20pll_state *pll_state);
void intel_c20pll_dump_hw_state(struct drm_i915_private *i915,
......
......@@ -4333,7 +4333,7 @@ static int intel_hdmi_reset_link(struct intel_encoder *encoder,
u8 config;
int ret;
if (!connector || connector->base.status != connector_status_connected)
if (connector->base.status != connector_status_connected)
return 0;
ret = drm_modeset_lock(&dev_priv->drm.mode_config.connection_mutex,
......
......@@ -956,6 +956,8 @@ static void intel_post_plane_update(struct intel_atomic_state *state,
intel_atomic_get_new_crtc_state(state, crtc);
enum pipe pipe = crtc->pipe;
intel_psr_post_plane_update(state, crtc);
intel_frontbuffer_flip(dev_priv, new_crtc_state->fb_bits);
if (new_crtc_state->update_wm_post && new_crtc_state->hw.active)
......@@ -3997,7 +3999,7 @@ intel_encoder_current_mode(struct intel_encoder *encoder)
}
if (!intel_crtc_get_pipe_config(crtc_state)) {
kfree(crtc_state);
intel_crtc_destroy_state(&crtc->base, &crtc_state->uapi);
kfree(mode);
return NULL;
}
......@@ -4006,7 +4008,7 @@ intel_encoder_current_mode(struct intel_encoder *encoder)
intel_mode_from_crtc_timings(mode, &crtc_state->hw.adjusted_mode);
kfree(crtc_state);
intel_crtc_destroy_state(&crtc->base, &crtc_state->uapi);
return mode;
}
......@@ -4986,9 +4988,6 @@ pipe_config_mismatch(bool fastset, const struct intel_crtc *crtc,
static bool fastboot_enabled(struct drm_i915_private *dev_priv)
{
if (dev_priv->params.fastboot != -1)
return dev_priv->params.fastboot;
/* Enable fastboot by default on Skylake and newer */
if (DISPLAY_VER(dev_priv) >= 9)
return true;
......@@ -7216,7 +7215,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
intel_set_cdclk_pre_plane_update(state);
intel_modeset_verify_disabled(dev_priv, state);
intel_modeset_verify_disabled(state);
}
intel_sagv_pre_plane_update(state);
......@@ -7296,14 +7295,13 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
}
intel_dbuf_post_plane_update(state);
intel_psr_post_plane_update(state);
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
intel_post_plane_update(state, crtc);
intel_modeset_put_crtc_power_domains(crtc, &put_domains[crtc->pipe]);
intel_modeset_verify_crtc(crtc, state, old_crtc_state, new_crtc_state);
intel_modeset_verify_crtc(state, crtc);
/* Must be done after gamma readout due to HSW split gamma vs. IPS w/a */
hsw_ips_post_update(state, crtc);
......
......@@ -644,6 +644,7 @@ static int i915_display_info(struct seq_file *m, void *unused)
static int i915_shared_dplls_info(struct seq_file *m, void *unused)
{
struct drm_i915_private *dev_priv = node_to_i915(m->private);
struct intel_shared_dpll *pll;
int i;
drm_modeset_lock_all(&dev_priv->drm);
......@@ -652,11 +653,9 @@ static int i915_shared_dplls_info(struct seq_file *m, void *unused)
dev_priv->display.dpll.ref_clks.nssc,
dev_priv->display.dpll.ref_clks.ssc);
for (i = 0; i < dev_priv->display.dpll.num_shared_dpll; i++) {
struct intel_shared_dpll *pll = &dev_priv->display.dpll.shared_dplls[i];
seq_printf(m, "DPLL%i: %s, id: %i\n", i, pll->info->name,
pll->info->id);
for_each_shared_dpll(dev_priv, pll, i) {
seq_printf(m, "DPLL%i: %s, id: %i\n", pll->index,
pll->info->name, pll->info->id);
seq_printf(m, " pipe_mask: 0x%x, active: 0x%x, on: %s\n",
pll->state.pipe_mask, pll->active_mask,
str_yes_no(pll->on));
......
......@@ -926,7 +926,7 @@ void intel_display_device_probe(struct drm_i915_private *i915)
else
info = probe_display(i915);
i915->display.info.__device_info = info;
DISPLAY_INFO(i915) = info;
memcpy(DISPLAY_RUNTIME_INFO(i915),
&DISPLAY_INFO(i915)->__runtime_defaults,
......@@ -939,7 +939,7 @@ void intel_display_device_probe(struct drm_i915_private *i915)
}
}
void intel_display_device_info_runtime_init(struct drm_i915_private *i915)
static void __intel_display_device_info_runtime_init(struct drm_i915_private *i915)
{
struct intel_display_runtime_info *display_runtime = DISPLAY_RUNTIME_INFO(i915);
enum pipe pipe;
......@@ -948,6 +948,13 @@ void intel_display_device_info_runtime_init(struct drm_i915_private *i915)
BUILD_BUG_ON(BITS_PER_TYPE(display_runtime->cpu_transcoder_mask) < I915_MAX_TRANSCODERS);
BUILD_BUG_ON(BITS_PER_TYPE(display_runtime->port_mask) < I915_MAX_PORTS);
/* This covers both ULT and ULX */
if (IS_HASWELL_ULT(i915) || IS_BROADWELL_ULT(i915))
display_runtime->port_mask &= ~BIT(PORT_D);
if (IS_ICL_WITH_PORT_F(i915))
display_runtime->port_mask |= BIT(PORT_F);
/* Wa_14011765242: adl-s A0,A1 */
if (IS_ALDERLAKE_S(i915) && IS_DISPLAY_STEP(i915, STEP_A0, STEP_A2))
for_each_pipe(i915, pipe)
......@@ -1065,12 +1072,44 @@ void intel_display_device_info_runtime_init(struct drm_i915_private *i915)
display_runtime->has_dsc = 0;
}
if (DISPLAY_VER(i915) >= 20) {
u32 cap = intel_de_read(i915, XE2LPD_DE_CAP);
if (REG_FIELD_GET(XE2LPD_DE_CAP_DSC_MASK, cap) ==
XE2LPD_DE_CAP_DSC_REMOVED)
display_runtime->has_dsc = 0;
if (REG_FIELD_GET(XE2LPD_DE_CAP_SCALER_MASK, cap) ==
XE2LPD_DE_CAP_SCALER_SINGLE) {
for_each_pipe(i915, pipe)
if (display_runtime->num_scalers[pipe])
display_runtime->num_scalers[pipe] = 1;
}
}
return;
display_fused_off:
memset(display_runtime, 0, sizeof(*display_runtime));
}
void intel_display_device_info_runtime_init(struct drm_i915_private *i915)
{
if (HAS_DISPLAY(i915))
__intel_display_device_info_runtime_init(i915);
/* Display may have been disabled by runtime init */
if (!HAS_DISPLAY(i915)) {
i915->drm.driver_features &= ~(DRIVER_MODESET | DRIVER_ATOMIC);
i915->display.info.__device_info = &no_display;
}
/* Disable nuclear pageflip by default on pre-g4x */
if (!i915->params.nuclear_pageflip &&
DISPLAY_VER(i915) < 5 && !IS_G4X(i915))
i915->drm.driver_features &= ~DRIVER_ATOMIC;
}
void intel_display_device_info_print(const struct intel_display_device_info *info,
const struct intel_display_runtime_info *runtime,
struct drm_printer *p)
......@@ -1091,3 +1130,20 @@ void intel_display_device_info_print(const struct intel_display_device_info *inf
drm_printf(p, "has_dmc: %s\n", str_yes_no(runtime->has_dmc));
drm_printf(p, "has_dsc: %s\n", str_yes_no(runtime->has_dsc));
}
/*
* Assuming the device has display hardware, should it be enabled?
*
* It's an error to call this function if the device does not have display
* hardware.
*
* Disabling display means taking over the display hardware, putting it to
* sleep, and preventing connectors from being connected via any means.
*/
bool intel_display_device_enabled(struct drm_i915_private *i915)
{
/* Only valid when HAS_DISPLAY() is true */
drm_WARN_ON(&i915->drm, !HAS_DISPLAY(i915));
return !i915->params.disable_display && !intel_opregion_headless_sku(i915);
}
......@@ -98,6 +98,15 @@ struct drm_printer;
(IS_DISPLAY_IP_RANGE((__i915), (ipver), (ipver)) && \
IS_DISPLAY_STEP((__i915), (from), (until)))
#define DISPLAY_INFO(i915) ((i915)->display.info.__device_info)
#define DISPLAY_RUNTIME_INFO(i915) (&(i915)->display.info.__runtime_info)
#define DISPLAY_VER(i915) (DISPLAY_RUNTIME_INFO(i915)->ip.ver)
#define DISPLAY_VER_FULL(i915) IP_VER(DISPLAY_RUNTIME_INFO(i915)->ip.ver, \
DISPLAY_RUNTIME_INFO(i915)->ip.rel)
#define IS_DISPLAY_VER(i915, from, until) \
(DISPLAY_VER(i915) >= (from) && DISPLAY_VER(i915) <= (until))
struct intel_display_runtime_info {
struct {
u16 ver;
......@@ -150,6 +159,7 @@ struct intel_display_device_info {
} color;
};
bool intel_display_device_enabled(struct drm_i915_private *i915);
void intel_display_device_probe(struct drm_i915_private *i915);
void intel_display_device_info_runtime_init(struct drm_i915_private *i915);
......
......@@ -309,7 +309,7 @@ static const struct stepping_info *
intel_get_stepping_info(struct drm_i915_private *i915,
struct stepping_info *si)
{
const char *step_name = intel_step_name(RUNTIME_INFO(i915)->step.display_step);
const char *step_name = intel_display_step_name(i915);
si->stepping = step_name[0];
si->substepping = step_name[1];
......
......@@ -5354,7 +5354,7 @@ intel_dp_detect(struct drm_connector *connector,
drm_WARN_ON(&dev_priv->drm,
!drm_modeset_is_locked(&dev_priv->drm.mode_config.connection_mutex));
if (!INTEL_DISPLAY_ENABLED(dev_priv))
if (!intel_display_device_enabled(dev_priv))
return connector_status_disconnected;
/* Can't disconnect eDP */
......
......@@ -94,12 +94,9 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder,
crtc_state->lane_count = limits->max_lane_count;
crtc_state->port_clock = limits->max_rate;
// TODO: Handle pbn_div changes by adding a new MST helper
if (!mst_state->pbn_div) {
mst_state->pbn_div = drm_dp_get_vc_payload_bw(&intel_dp->mst_mgr,
crtc_state->port_clock,
crtc_state->lane_count);
}
mst_state->pbn_div = drm_dp_get_vc_payload_bw(&intel_dp->mst_mgr,
crtc_state->port_clock,
crtc_state->lane_count);
for (bpp = max_bpp; bpp >= min_bpp; bpp -= step) {
drm_dbg_kms(&i915->drm, "Trying bpp %d\n", bpp);
......@@ -1062,7 +1059,7 @@ intel_dp_mst_detect(struct drm_connector *connector,
struct intel_connector *intel_connector = to_intel_connector(connector);
struct intel_dp *intel_dp = intel_connector->mst_port;
if (!INTEL_DISPLAY_ENABLED(i915))
if (!intel_display_device_enabled(i915))
return connector_status_disconnected;
if (drm_connector_is_unregistered(connector))
......
......@@ -26,6 +26,7 @@ enum dpio_phy {
DPIO_PHY2,
};
#ifdef I915
void bxt_port_to_phy_channel(struct drm_i915_private *dev_priv, enum port port,
enum dpio_phy *phy, enum dpio_channel *ch);
void bxt_ddi_phy_set_signal_levels(struct intel_encoder *encoder,
......@@ -70,5 +71,100 @@ void vlv_phy_pre_encoder_enable(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state);
void vlv_phy_reset_lanes(struct intel_encoder *encoder,
const struct intel_crtc_state *old_crtc_state);
#else
static inline void bxt_port_to_phy_channel(struct drm_i915_private *dev_priv, enum port port,
enum dpio_phy *phy, enum dpio_channel *ch)
{
}
static inline void bxt_ddi_phy_set_signal_levels(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state)
{
}
static inline void bxt_ddi_phy_init(struct drm_i915_private *dev_priv, enum dpio_phy phy)
{
}
static inline void bxt_ddi_phy_uninit(struct drm_i915_private *dev_priv, enum dpio_phy phy)
{
}
static inline bool bxt_ddi_phy_is_enabled(struct drm_i915_private *dev_priv,
enum dpio_phy phy)
{
return false;
}
static inline bool bxt_ddi_phy_verify_state(struct drm_i915_private *dev_priv,
enum dpio_phy phy)
{
return true;
}
static inline u8 bxt_ddi_phy_calc_lane_lat_optim_mask(u8 lane_count)
{
return 0;
}
static inline void bxt_ddi_phy_set_lane_optim_mask(struct intel_encoder *encoder,
u8 lane_lat_optim_mask)
{
}
static inline u8 bxt_ddi_phy_get_lane_lat_optim_mask(struct intel_encoder *encoder)
{
return 0;
}
static inline enum dpio_channel vlv_dig_port_to_channel(struct intel_digital_port *dig_port)
{
return DPIO_CH0;
}
static inline enum dpio_phy vlv_dig_port_to_phy(struct intel_digital_port *dig_port)
{
return DPIO_PHY0;
}
static inline enum dpio_channel vlv_pipe_to_channel(enum pipe pipe)
{
return DPIO_CH0;
}
static inline void chv_set_phy_signal_level(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
u32 deemph_reg_value, u32 margin_reg_value,
bool uniq_trans_scale)
{
}
static inline void chv_data_lane_soft_reset(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
bool reset)
{
}
static inline void chv_phy_pre_pll_enable(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state)
{
}
static inline void chv_phy_pre_encoder_enable(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state)
{
}
static inline void chv_phy_release_cl2_override(struct intel_encoder *encoder)
{
}
static inline void chv_phy_post_pll_disable(struct intel_encoder *encoder,
const struct intel_crtc_state *old_crtc_state)
{
}
static inline void vlv_set_phy_signal_level(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
u32 demph_reg_value, u32 preemph_reg_value,
u32 uniqtranscale_reg_value, u32 tx3_demph)
{
}
static inline void vlv_phy_pre_pll_enable(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state)
{
}
static inline void vlv_phy_pre_encoder_enable(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state)
{
}
static inline void vlv_phy_reset_lanes(struct intel_encoder *encoder,
const struct intel_crtc_state *old_crtc_state)
{
}
#endif
#endif /* __INTEL_DPIO_PHY_H__ */
......@@ -7,6 +7,7 @@
#include <linux/string_helpers.h>
#include "i915_reg.h"
#include "intel_atomic.h"
#include "intel_crtc.h"
#include "intel_cx0_phy.h"
#include "intel_de.h"
......@@ -2006,7 +2007,7 @@ int vlv_force_pll_on(struct drm_i915_private *dev_priv, enum pipe pipe,
vlv_enable_pll(crtc_state);
}
kfree(crtc_state);
intel_crtc_destroy_state(&crtc->base, &crtc_state->uapi);
return 0;
}
......
......@@ -29,6 +29,10 @@
#include "intel_wakeref.h"
#define for_each_shared_dpll(__i915, __pll, __i) \
for ((__i) = 0; (__i) < (__i915)->display.dpll.num_shared_dpll && \
((__pll) = &(__i915)->display.dpll.shared_dplls[(__i)]) ; (__i)++)
enum tc_port;
struct drm_i915_private;
struct intel_atomic_state;
......@@ -262,8 +266,7 @@ struct dpll_info {
const struct intel_shared_dpll_funcs *funcs;
/**
* @id: unique indentifier for this DPLL; should match the index in the
* dev_priv->shared_dplls array
* @id: unique indentifier for this DPLL
*/
enum intel_dpll_id id;
......@@ -290,6 +293,11 @@ struct intel_shared_dpll {
*/
struct intel_shared_dpll_state state;
/**
* @index: index for atomic state
*/
u8 index;
/**
* @active_mask: mask of active pipes (i.e. DPMS on) using this DPLL
*/
......@@ -319,9 +327,9 @@ struct intel_shared_dpll {
/* shared dpll functions */
struct intel_shared_dpll *
intel_get_shared_dpll_by_id(struct drm_i915_private *dev_priv,
intel_get_shared_dpll_by_id(struct drm_i915_private *i915,
enum intel_dpll_id id);
void assert_shared_dpll(struct drm_i915_private *dev_priv,
void assert_shared_dpll(struct drm_i915_private *i915,
struct intel_shared_dpll *pll,
bool state);
#define assert_shared_dpll_enabled(d, p) assert_shared_dpll(d, p, true)
......@@ -351,19 +359,18 @@ bool intel_dpll_get_hw_state(struct drm_i915_private *i915,
void intel_enable_shared_dpll(const struct intel_crtc_state *crtc_state);
void intel_disable_shared_dpll(const struct intel_crtc_state *crtc_state);
void intel_shared_dpll_swap_state(struct intel_atomic_state *state);
void intel_shared_dpll_init(struct drm_i915_private *dev_priv);
void intel_dpll_update_ref_clks(struct drm_i915_private *dev_priv);
void intel_dpll_readout_hw_state(struct drm_i915_private *dev_priv);
void intel_dpll_sanitize_state(struct drm_i915_private *dev_priv);
void intel_shared_dpll_init(struct drm_i915_private *i915);
void intel_dpll_update_ref_clks(struct drm_i915_private *i915);
void intel_dpll_readout_hw_state(struct drm_i915_private *i915);
void intel_dpll_sanitize_state(struct drm_i915_private *i915);
void intel_dpll_dump_hw_state(struct drm_i915_private *dev_priv,
void intel_dpll_dump_hw_state(struct drm_i915_private *i915,
const struct intel_dpll_hw_state *hw_state);
enum intel_dpll_id icl_tc_port_to_pll_id(enum tc_port tc_port);
bool intel_dpll_is_combophy(enum intel_dpll_id id);
void intel_shared_dpll_state_verify(struct intel_crtc *crtc,
struct intel_crtc_state *old_crtc_state,
struct intel_crtc_state *new_crtc_state);
void intel_shared_dpll_verify_disabled(struct drm_i915_private *i915);
void intel_shared_dpll_state_verify(struct intel_atomic_state *state,
struct intel_crtc *crtc);
void intel_shared_dpll_verify_disabled(struct intel_atomic_state *state);
#endif /* _INTEL_DPLL_MGR_H_ */
......@@ -565,6 +565,9 @@ static const u8 *mipi_exec_i2c(struct intel_dsi *intel_dsi, const u8 *data)
u8 payload_size = *(data + 6);
u8 *payload_data;
drm_dbg_kms(&i915->drm, "bus %d client-addr 0x%02x reg 0x%02x data %*ph\n",
vbt_i2c_bus_num, slave_addr, reg_offset, payload_size, data + 7);
if (intel_dsi->i2c_bus_num < 0) {
intel_dsi->i2c_bus_num = vbt_i2c_bus_num;
i2c_acpi_find_adapter(intel_dsi, slave_addr);
......
......@@ -319,7 +319,7 @@ intel_dvo_detect(struct drm_connector *_connector, bool force)
drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s]\n",
connector->base.base.id, connector->base.name);
if (!INTEL_DISPLAY_ENABLED(i915))
if (!intel_display_device_enabled(i915))
return connector_status_disconnected;
return intel_dvo->dev.dev_ops->detect(&intel_dvo->dev);
......
......@@ -8,6 +8,12 @@
struct drm_i915_private;
#ifdef I915
void intel_dvo_init(struct drm_i915_private *dev_priv);
#else
static inline void intel_dvo_init(struct drm_i915_private *dev_priv)
{
}
#endif
#endif /* __INTEL_DVO_H__ */
......@@ -593,6 +593,9 @@ static u32 ivb_dpfc_ctl(struct intel_fbc *fbc)
if (IS_IVYBRIDGE(i915))
dpfc_ctl |= DPFC_CTL_PLANE_IVB(fbc_state->plane->i9xx_plane);
if (DISPLAY_VER(i915) >= 20)
dpfc_ctl |= DPFC_CTL_PLANE_BINDING(fbc_state->plane->id);
if (fbc_state->fence_id >= 0)
dpfc_ctl |= DPFC_CTL_FENCE_EN_IVB;
......@@ -850,39 +853,64 @@ void intel_fbc_cleanup(struct drm_i915_private *i915)
}
}
static bool stride_is_valid(const struct intel_plane_state *plane_state)
static bool i8xx_fbc_stride_is_valid(const struct intel_plane_state *plane_state)
{
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
const struct drm_framebuffer *fb = plane_state->hw.fb;
unsigned int stride = intel_fbc_plane_stride(plane_state) *
fb->format->cpp[0];
/* This should have been caught earlier. */
if (drm_WARN_ON_ONCE(&i915->drm, (stride & (64 - 1)) != 0))
return false;
return stride == 4096 || stride == 8192;
}
/* Below are the additional FBC restrictions. */
if (stride < 512)
return false;
static bool i965_fbc_stride_is_valid(const struct intel_plane_state *plane_state)
{
const struct drm_framebuffer *fb = plane_state->hw.fb;
unsigned int stride = intel_fbc_plane_stride(plane_state) *
fb->format->cpp[0];
if (DISPLAY_VER(i915) == 2 || DISPLAY_VER(i915) == 3)
return stride == 4096 || stride == 8192;
return stride >= 2048 && stride <= 16384;
}
if (DISPLAY_VER(i915) == 4 && !IS_G4X(i915) && stride < 2048)
return false;
static bool g4x_fbc_stride_is_valid(const struct intel_plane_state *plane_state)
{
return true;
}
static bool skl_fbc_stride_is_valid(const struct intel_plane_state *plane_state)
{
const struct drm_framebuffer *fb = plane_state->hw.fb;
unsigned int stride = intel_fbc_plane_stride(plane_state) *
fb->format->cpp[0];
/* Display WA #1105: skl,bxt,kbl,cfl,glk */
if ((DISPLAY_VER(i915) == 9 || IS_GEMINILAKE(i915)) &&
fb->modifier == DRM_FORMAT_MOD_LINEAR && stride & 511)
if (fb->modifier == DRM_FORMAT_MOD_LINEAR && stride & 511)
return false;
if (stride > 16384)
return false;
return true;
}
static bool icl_fbc_stride_is_valid(const struct intel_plane_state *plane_state)
{
return true;
}
static bool pixel_format_is_valid(const struct intel_plane_state *plane_state)
static bool stride_is_valid(const struct intel_plane_state *plane_state)
{
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
if (DISPLAY_VER(i915) >= 11)
return icl_fbc_stride_is_valid(plane_state);
else if (DISPLAY_VER(i915) >= 9)
return skl_fbc_stride_is_valid(plane_state);
else if (DISPLAY_VER(i915) >= 5 || IS_G4X(i915))
return g4x_fbc_stride_is_valid(plane_state);
else if (DISPLAY_VER(i915) == 4)
return i965_fbc_stride_is_valid(plane_state);
else
return i8xx_fbc_stride_is_valid(plane_state);
}
static bool i8xx_fbc_pixel_format_is_valid(const struct intel_plane_state *plane_state)
{
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
const struct drm_framebuffer *fb = plane_state->hw.fb;
......@@ -896,6 +924,22 @@ static bool pixel_format_is_valid(const struct intel_plane_state *plane_state)
/* 16bpp not supported on gen2 */
if (DISPLAY_VER(i915) == 2)
return false;
return true;
default:
return false;
}
}
static bool g4x_fbc_pixel_format_is_valid(const struct intel_plane_state *plane_state)
{
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
const struct drm_framebuffer *fb = plane_state->hw.fb;
switch (fb->format->format) {
case DRM_FORMAT_XRGB8888:
case DRM_FORMAT_XBGR8888:
return true;
case DRM_FORMAT_RGB565:
/* WaFbcOnly1to1Ratio:ctg */
if (IS_G4X(i915))
return false;
......@@ -905,22 +949,68 @@ static bool pixel_format_is_valid(const struct intel_plane_state *plane_state)
}
}
static bool rotation_is_valid(const struct intel_plane_state *plane_state)
static bool lnl_fbc_pixel_format_is_valid(const struct intel_plane_state *plane_state)
{
const struct drm_framebuffer *fb = plane_state->hw.fb;
switch (fb->format->format) {
case DRM_FORMAT_XRGB8888:
case DRM_FORMAT_XBGR8888:
case DRM_FORMAT_ARGB8888:
case DRM_FORMAT_ABGR8888:
case DRM_FORMAT_RGB565:
return true;
default:
return false;
}
}
static bool pixel_format_is_valid(const struct intel_plane_state *plane_state)
{
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
if (DISPLAY_VER(i915) >= 20)
return lnl_fbc_pixel_format_is_valid(plane_state);
else if (DISPLAY_VER(i915) >= 5 || IS_G4X(i915))
return g4x_fbc_pixel_format_is_valid(plane_state);
else
return i8xx_fbc_pixel_format_is_valid(plane_state);
}
static bool i8xx_fbc_rotation_is_valid(const struct intel_plane_state *plane_state)
{
return plane_state->hw.rotation == DRM_MODE_ROTATE_0;
}
static bool g4x_fbc_rotation_is_valid(const struct intel_plane_state *plane_state)
{
return true;
}
static bool skl_fbc_rotation_is_valid(const struct intel_plane_state *plane_state)
{
const struct drm_framebuffer *fb = plane_state->hw.fb;
unsigned int rotation = plane_state->hw.rotation;
if (DISPLAY_VER(i915) >= 9 && fb->format->format == DRM_FORMAT_RGB565 &&
if (fb->format->format == DRM_FORMAT_RGB565 &&
drm_rotation_90_or_270(rotation))
return false;
else if (DISPLAY_VER(i915) <= 4 && !IS_G4X(i915) &&
rotation != DRM_MODE_ROTATE_0)
return false;
return true;
}
static bool rotation_is_valid(const struct intel_plane_state *plane_state)
{
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
if (DISPLAY_VER(i915) >= 9)
return skl_fbc_rotation_is_valid(plane_state);
else if (DISPLAY_VER(i915) >= 5 || IS_G4X(i915))
return g4x_fbc_rotation_is_valid(plane_state);
else
return i8xx_fbc_rotation_is_valid(plane_state);
}
/*
* For some reason, the hardware tracking starts looking at whatever we
* programmed as the display plane base address register. It does not look at
......@@ -954,16 +1044,21 @@ static bool intel_fbc_hw_tracking_covers_screen(const struct intel_plane_state *
return effective_w <= max_w && effective_h <= max_h;
}
static bool tiling_is_valid(const struct intel_plane_state *plane_state)
static bool i8xx_fbc_tiling_valid(const struct intel_plane_state *plane_state)
{
const struct drm_framebuffer *fb = plane_state->hw.fb;
return fb->modifier == I915_FORMAT_MOD_X_TILED;
}
static bool skl_fbc_tiling_valid(const struct intel_plane_state *plane_state)
{
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
const struct drm_framebuffer *fb = plane_state->hw.fb;
switch (fb->modifier) {
case DRM_FORMAT_MOD_LINEAR:
case I915_FORMAT_MOD_Y_TILED:
case I915_FORMAT_MOD_Yf_TILED:
return DISPLAY_VER(i915) >= 9;
case I915_FORMAT_MOD_4_TILED:
case I915_FORMAT_MOD_X_TILED:
return true;
......@@ -972,6 +1067,16 @@ static bool tiling_is_valid(const struct intel_plane_state *plane_state)
}
}
static bool tiling_is_valid(const struct intel_plane_state *plane_state)
{
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
if (DISPLAY_VER(i915) >= 9)
return skl_fbc_tiling_valid(plane_state);
else
return i8xx_fbc_tiling_valid(plane_state);
}
static void intel_fbc_update_state(struct intel_atomic_state *state,
struct intel_crtc *crtc,
struct intel_plane *plane)
......@@ -1129,7 +1234,8 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state,
return 0;
}
if (plane_state->hw.pixel_blend_mode != DRM_MODE_BLEND_PIXEL_NONE &&
if (DISPLAY_VER(i915) < 20 &&
plane_state->hw.pixel_blend_mode != DRM_MODE_BLEND_PIXEL_NONE &&
fb->format->has_alpha) {
plane_state->no_fbc_reason = "per-pixel alpha not supported";
return 0;
......
......@@ -56,6 +56,7 @@
*/
#include "gem/i915_gem_object_frontbuffer.h"
#include "i915_active.h"
#include "i915_drv.h"
#include "intel_display_trace.h"
#include "intel_display_types.h"
......
......@@ -173,14 +173,8 @@ bool intel_hdcp2_capable(struct intel_connector *connector)
/* If MTL+ make sure gsc is loaded and proxy is setup */
if (intel_hdcp_gsc_cs_required(i915)) {
struct intel_gt *gt = i915->media_gt;
struct intel_gsc_uc *gsc = gt ? &gt->uc.gsc : NULL;
if (!gsc || !intel_uc_fw_is_running(&gsc->fw)) {
drm_dbg_kms(&i915->drm,
"GSC components required for HDCP2.2 are not ready\n");
if (!intel_hdcp_gsc_check_status(i915))
return false;
}
}
/* MEI/GSC interface is solid depending on which is used */
......
......@@ -23,5 +23,6 @@ ssize_t intel_hdcp_gsc_msg_send(struct drm_i915_private *i915, u8 *msg_in,
size_t msg_out_len);
int intel_hdcp_gsc_init(struct drm_i915_private *i915);
void intel_hdcp_gsc_fini(struct drm_i915_private *i915);
bool intel_hdcp_gsc_check_status(struct drm_i915_private *i915);
#endif /* __INTEL_HDCP_GCS_H__ */
This diff is collapsed.
/* SPDX-License-Identifier: MIT */
/*
* Copyright © 2023 Intel Corporation
*/
#ifndef __INTEL_HDCP_GSC_MESSAGE_H__
#define __INTEL_HDCP_GSC_MESSAGE_H__
#include <linux/types.h>
struct device;
struct drm_i915_private;
struct hdcp_port_data;
struct hdcp2_ake_init;
struct hdcp2_ake_send_cert;
struct hdcp2_ake_no_stored_km;
struct hdcp2_ake_send_hprime;
struct hdcp2_ake_send_pairing_info;
struct hdcp2_lc_init;
struct hdcp2_lc_send_lprime;
struct hdcp2_ske_send_eks;
struct hdcp2_rep_send_receiverid_list;
struct hdcp2_rep_send_ack;
struct hdcp2_rep_stream_ready;
ssize_t intel_hdcp_gsc_msg_send(struct drm_i915_private *i915, u8 *msg_in,
size_t msg_in_len, u8 *msg_out,
size_t msg_out_len);
bool intel_hdcp_gsc_check_status(struct drm_i915_private *i915);
int
intel_hdcp_gsc_initiate_session(struct device *dev, struct hdcp_port_data *data,
struct hdcp2_ake_init *ake_data);
int
intel_hdcp_gsc_verify_receiver_cert_prepare_km(struct device *dev,
struct hdcp_port_data *data,
struct hdcp2_ake_send_cert *rx_cert,
bool *km_stored,
struct hdcp2_ake_no_stored_km
*ek_pub_km,
size_t *msg_sz);
int
intel_hdcp_gsc_verify_hprime(struct device *dev, struct hdcp_port_data *data,
struct hdcp2_ake_send_hprime *rx_hprime);
int
intel_hdcp_gsc_store_pairing_info(struct device *dev, struct hdcp_port_data *data,
struct hdcp2_ake_send_pairing_info *pairing_info);
int
intel_hdcp_gsc_initiate_locality_check(struct device *dev,
struct hdcp_port_data *data,
struct hdcp2_lc_init *lc_init_data);
int
intel_hdcp_gsc_verify_lprime(struct device *dev, struct hdcp_port_data *data,
struct hdcp2_lc_send_lprime *rx_lprime);
int intel_hdcp_gsc_get_session_key(struct device *dev,
struct hdcp_port_data *data,
struct hdcp2_ske_send_eks *ske_data);
int
intel_hdcp_gsc_repeater_check_flow_prepare_ack(struct device *dev,
struct hdcp_port_data *data,
struct hdcp2_rep_send_receiverid_list
*rep_topology,
struct hdcp2_rep_send_ack
*rep_send_ack);
int intel_hdcp_gsc_verify_mprime(struct device *dev,
struct hdcp_port_data *data,
struct hdcp2_rep_stream_ready *stream_ready);
int intel_hdcp_gsc_enable_authentication(struct device *dev,
struct hdcp_port_data *data);
int
intel_hdcp_gsc_close_session(struct device *dev, struct hdcp_port_data *data);
#endif /* __INTEL_HDCP_GSC_MESSAGE_H__ */
......@@ -2496,7 +2496,7 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
drm_dbg_kms(&dev_priv->drm, "[CONNECTOR:%d:%s]\n",
connector->base.id, connector->name);
if (!INTEL_DISPLAY_ENABLED(dev_priv))
if (!intel_display_device_enabled(dev_priv))
return connector_status_disconnected;
wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
......
......@@ -763,7 +763,7 @@ static void i915_hpd_poll_init_work(struct work_struct *work)
void intel_hpd_poll_enable(struct drm_i915_private *dev_priv)
{
if (!HAS_DISPLAY(dev_priv) ||
!INTEL_DISPLAY_ENABLED(dev_priv))
!intel_display_device_enabled(dev_priv))
return;
WRITE_ONCE(dev_priv->display.hotplug.poll_enabled, true);
......
......@@ -12,11 +12,29 @@ enum port;
enum transcoder;
struct drm_i915_private;
#ifdef I915
int intel_lpe_audio_init(struct drm_i915_private *dev_priv);
void intel_lpe_audio_teardown(struct drm_i915_private *dev_priv);
void intel_lpe_audio_irq_handler(struct drm_i915_private *dev_priv);
void intel_lpe_audio_notify(struct drm_i915_private *dev_priv,
enum transcoder cpu_transcoder, enum port port,
const void *eld, int ls_clock, bool dp_output);
#else
static inline int intel_lpe_audio_init(struct drm_i915_private *dev_priv)
{
return -ENODEV;
}
static inline void intel_lpe_audio_teardown(struct drm_i915_private *dev_priv)
{
}
static inline void intel_lpe_audio_irq_handler(struct drm_i915_private *dev_priv)
{
}
static inline void intel_lpe_audio_notify(struct drm_i915_private *dev_priv,
enum transcoder cpu_transcoder, enum port port,
const void *eld, int ls_clock, bool dp_output)
{
}
#endif
#endif /* __INTEL_LPE_AUDIO_H__ */
......@@ -153,6 +153,18 @@ static enum drm_lspcon_mode lspcon_get_current_mode(struct intel_lspcon *lspcon)
return current_mode;
}
static int lspcon_get_mode_settle_timeout(struct intel_lspcon *lspcon)
{
/*
* On some CometLake-based device designs the Parade PS175 takes more
* than 400ms to settle in PCON mode. 100 reboot trials on one device
* resulted in a median settle time of 440ms and a maximum of 444ms.
* Even after increasing the timeout to 500ms, 2% of devices still had
* this error. So this sets the timeout to 800ms.
*/
return lspcon->vendor == LSPCON_VENDOR_PARADE ? 800 : 400;
}
static enum drm_lspcon_mode lspcon_wait_mode(struct intel_lspcon *lspcon,
enum drm_lspcon_mode mode)
{
......@@ -167,7 +179,8 @@ static enum drm_lspcon_mode lspcon_wait_mode(struct intel_lspcon *lspcon,
drm_dbg_kms(&i915->drm, "Waiting for LSPCON mode %s to settle\n",
lspcon_mode_name(mode));
wait_for((current_mode = lspcon_get_current_mode(lspcon)) == mode, 400);
wait_for((current_mode = lspcon_get_current_mode(lspcon)) == mode,
lspcon_get_mode_settle_timeout(lspcon));
if (current_mode != mode)
drm_err(&i915->drm, "LSPCON mode hasn't settled\n");
......
......@@ -13,10 +13,29 @@
enum pipe;
struct drm_i915_private;
#ifdef I915
bool intel_lvds_port_enabled(struct drm_i915_private *dev_priv,
i915_reg_t lvds_reg, enum pipe *pipe);
void intel_lvds_init(struct drm_i915_private *dev_priv);
struct intel_encoder *intel_get_lvds_encoder(struct drm_i915_private *dev_priv);
bool intel_is_dual_link_lvds(struct drm_i915_private *dev_priv);
#else
static inline bool intel_lvds_port_enabled(struct drm_i915_private *dev_priv,
i915_reg_t lvds_reg, enum pipe *pipe)
{
return false;
}
static inline void intel_lvds_init(struct drm_i915_private *dev_priv)
{
}
static inline struct intel_encoder *intel_get_lvds_encoder(struct drm_i915_private *dev_priv)
{
return NULL;
}
static inline bool intel_is_dual_link_lvds(struct drm_i915_private *dev_priv)
{
return false;
}
#endif
#endif /* __INTEL_LVDS_H__ */
......@@ -23,8 +23,8 @@
* Cross check the actual hw state with our own modeset state tracking (and its
* internal consistency).
*/
static void intel_connector_verify_state(struct intel_crtc_state *crtc_state,
struct drm_connector_state *conn_state)
static void intel_connector_verify_state(const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state)
{
struct intel_connector *connector = to_intel_connector(conn_state->connector);
struct drm_i915_private *i915 = to_i915(connector->base.dev);
......@@ -66,12 +66,12 @@ verify_connector_state(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
struct drm_connector *connector;
struct drm_connector_state *new_conn_state;
const struct drm_connector_state *new_conn_state;
int i;
for_each_new_connector_in_state(&state->base, connector, new_conn_state, i) {
struct drm_encoder *encoder = connector->encoder;
struct intel_crtc_state *crtc_state = NULL;
const struct intel_crtc_state *crtc_state = NULL;
if (new_conn_state->crtc != &crtc->base)
continue;
......@@ -86,38 +86,40 @@ verify_connector_state(struct intel_atomic_state *state,
}
}
static void intel_pipe_config_sanity_check(struct drm_i915_private *dev_priv,
const struct intel_crtc_state *pipe_config)
static void intel_pipe_config_sanity_check(const struct intel_crtc_state *crtc_state)
{
if (pipe_config->has_pch_encoder) {
int fdi_dotclock = intel_dotclock_calculate(intel_fdi_link_freq(dev_priv, pipe_config),
&pipe_config->fdi_m_n);
int dotclock = pipe_config->hw.adjusted_mode.crtc_clock;
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
if (crtc_state->has_pch_encoder) {
int fdi_dotclock = intel_dotclock_calculate(intel_fdi_link_freq(i915, crtc_state),
&crtc_state->fdi_m_n);
int dotclock = crtc_state->hw.adjusted_mode.crtc_clock;
/*
* FDI already provided one idea for the dotclock.
* Yell if the encoder disagrees. Allow for slight
* rounding differences.
*/
drm_WARN(&dev_priv->drm, abs(fdi_dotclock - dotclock) > 1,
drm_WARN(&i915->drm, abs(fdi_dotclock - dotclock) > 1,
"FDI dotclock and encoder dotclock mismatch, fdi: %i, encoder: %i\n",
fdi_dotclock, dotclock);
}
}
static void
verify_encoder_state(struct drm_i915_private *dev_priv, struct intel_atomic_state *state)
verify_encoder_state(struct intel_atomic_state *state)
{
struct drm_i915_private *i915 = to_i915(state->base.dev);
struct intel_encoder *encoder;
struct drm_connector *connector;
struct drm_connector_state *old_conn_state, *new_conn_state;
const struct drm_connector_state *old_conn_state, *new_conn_state;
int i;
for_each_intel_encoder(&dev_priv->drm, encoder) {
for_each_intel_encoder(&i915->drm, encoder) {
bool enabled = false, found = false;
enum pipe pipe;
drm_dbg_kms(&dev_priv->drm, "[ENCODER:%d:%s]\n",
drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s]\n",
encoder->base.base.id,
encoder->base.name);
......@@ -132,7 +134,7 @@ verify_encoder_state(struct drm_i915_private *dev_priv, struct intel_atomic_stat
found = true;
enabled = true;
I915_STATE_WARN(dev_priv,
I915_STATE_WARN(i915,
new_conn_state->crtc != encoder->base.crtc,
"connector's crtc doesn't match encoder crtc\n");
}
......@@ -140,7 +142,7 @@ verify_encoder_state(struct drm_i915_private *dev_priv, struct intel_atomic_stat
if (!found)
continue;
I915_STATE_WARN(dev_priv, !!encoder->base.crtc != enabled,
I915_STATE_WARN(i915, !!encoder->base.crtc != enabled,
"encoder's enabled state mismatch (expected %i, found %i)\n",
!!encoder->base.crtc, enabled);
......@@ -148,7 +150,7 @@ verify_encoder_state(struct drm_i915_private *dev_priv, struct intel_atomic_stat
bool active;
active = encoder->get_hw_state(encoder, &pipe);
I915_STATE_WARN(dev_priv, active,
I915_STATE_WARN(i915, active,
"encoder detached but still enabled on pipe %c.\n",
pipe_name(pipe));
}
......@@ -156,96 +158,98 @@ verify_encoder_state(struct drm_i915_private *dev_priv, struct intel_atomic_stat
}
static void
verify_crtc_state(struct intel_crtc *crtc,
struct intel_crtc_state *old_crtc_state,
struct intel_crtc_state *new_crtc_state)
verify_crtc_state(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = to_i915(dev);
struct intel_encoder *encoder;
struct intel_crtc_state *pipe_config = old_crtc_state;
struct drm_atomic_state *state = old_crtc_state->uapi.state;
struct drm_i915_private *i915 = to_i915(dev);
const struct intel_crtc_state *sw_crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
struct intel_crtc_state *hw_crtc_state;
struct intel_crtc *master_crtc;
struct intel_encoder *encoder;
__drm_atomic_helper_crtc_destroy_state(&old_crtc_state->uapi);
intel_crtc_free_hw_state(old_crtc_state);
intel_crtc_state_reset(old_crtc_state, crtc);
old_crtc_state->uapi.state = state;
hw_crtc_state = intel_crtc_state_alloc(crtc);
if (!hw_crtc_state)
return;
drm_dbg_kms(&dev_priv->drm, "[CRTC:%d:%s]\n", crtc->base.base.id,
drm_dbg_kms(&i915->drm, "[CRTC:%d:%s]\n", crtc->base.base.id,
crtc->base.name);
pipe_config->hw.enable = new_crtc_state->hw.enable;
hw_crtc_state->hw.enable = sw_crtc_state->hw.enable;
intel_crtc_get_pipe_config(pipe_config);
intel_crtc_get_pipe_config(hw_crtc_state);
/* we keep both pipes enabled on 830 */
if (IS_I830(dev_priv) && pipe_config->hw.active)
pipe_config->hw.active = new_crtc_state->hw.active;
if (IS_I830(i915) && hw_crtc_state->hw.active)
hw_crtc_state->hw.active = sw_crtc_state->hw.active;
I915_STATE_WARN(dev_priv,
new_crtc_state->hw.active != pipe_config->hw.active,
I915_STATE_WARN(i915,
sw_crtc_state->hw.active != hw_crtc_state->hw.active,
"crtc active state doesn't match with hw state (expected %i, found %i)\n",
new_crtc_state->hw.active, pipe_config->hw.active);
sw_crtc_state->hw.active, hw_crtc_state->hw.active);
I915_STATE_WARN(dev_priv, crtc->active != new_crtc_state->hw.active,
I915_STATE_WARN(i915, crtc->active != sw_crtc_state->hw.active,
"transitional active state does not match atomic hw state (expected %i, found %i)\n",
new_crtc_state->hw.active, crtc->active);
sw_crtc_state->hw.active, crtc->active);
master_crtc = intel_master_crtc(new_crtc_state);
master_crtc = intel_master_crtc(sw_crtc_state);
for_each_encoder_on_crtc(dev, &master_crtc->base, encoder) {
enum pipe pipe;
bool active;
active = encoder->get_hw_state(encoder, &pipe);
I915_STATE_WARN(dev_priv, active != new_crtc_state->hw.active,
I915_STATE_WARN(i915, active != sw_crtc_state->hw.active,
"[ENCODER:%i] active %i with crtc active %i\n",
encoder->base.base.id, active,
new_crtc_state->hw.active);
sw_crtc_state->hw.active);
I915_STATE_WARN(dev_priv, active && master_crtc->pipe != pipe,
I915_STATE_WARN(i915, active && master_crtc->pipe != pipe,
"Encoder connected to wrong pipe %c\n",
pipe_name(pipe));
if (active)
intel_encoder_get_config(encoder, pipe_config);
intel_encoder_get_config(encoder, hw_crtc_state);
}
if (!new_crtc_state->hw.active)
return;
if (!sw_crtc_state->hw.active)
goto destroy_state;
intel_pipe_config_sanity_check(dev_priv, pipe_config);
intel_pipe_config_sanity_check(hw_crtc_state);
if (!intel_pipe_config_compare(new_crtc_state,
pipe_config, false)) {
I915_STATE_WARN(dev_priv, 1, "pipe state doesn't match!\n");
intel_crtc_state_dump(pipe_config, NULL, "hw state");
intel_crtc_state_dump(new_crtc_state, NULL, "sw state");
if (!intel_pipe_config_compare(sw_crtc_state,
hw_crtc_state, false)) {
I915_STATE_WARN(i915, 1, "pipe state doesn't match!\n");
intel_crtc_state_dump(hw_crtc_state, NULL, "hw state");
intel_crtc_state_dump(sw_crtc_state, NULL, "sw state");
}
destroy_state:
intel_crtc_destroy_state(&crtc->base, &hw_crtc_state->uapi);
}
void intel_modeset_verify_crtc(struct intel_crtc *crtc,
struct intel_atomic_state *state,
struct intel_crtc_state *old_crtc_state,
struct intel_crtc_state *new_crtc_state)
void intel_modeset_verify_crtc(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
const struct intel_crtc_state *new_crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
if (!intel_crtc_needs_modeset(new_crtc_state) &&
!intel_crtc_needs_fastset(new_crtc_state))
return;
intel_wm_state_verify(crtc, new_crtc_state);
intel_wm_state_verify(state, crtc);
verify_connector_state(state, crtc);
verify_crtc_state(crtc, old_crtc_state, new_crtc_state);
intel_shared_dpll_state_verify(crtc, old_crtc_state, new_crtc_state);
intel_mpllb_state_verify(state, new_crtc_state);
intel_c10pll_state_verify(state, new_crtc_state);
verify_crtc_state(state, crtc);
intel_shared_dpll_state_verify(state, crtc);
intel_mpllb_state_verify(state, crtc);
intel_c10pll_state_verify(state, crtc);
}
void intel_modeset_verify_disabled(struct drm_i915_private *dev_priv,
struct intel_atomic_state *state)
void intel_modeset_verify_disabled(struct intel_atomic_state *state)
{
verify_encoder_state(dev_priv, state);
verify_encoder_state(state);
verify_connector_state(state, NULL);
intel_shared_dpll_verify_disabled(dev_priv);
intel_shared_dpll_verify_disabled(state);
}
......@@ -6,16 +6,11 @@
#ifndef __INTEL_MODESET_VERIFY_H__
#define __INTEL_MODESET_VERIFY_H__
struct drm_i915_private;
struct intel_atomic_state;
struct intel_crtc;
struct intel_crtc_state;
void intel_modeset_verify_crtc(struct intel_crtc *crtc,
struct intel_atomic_state *state,
struct intel_crtc_state *old_crtc_state,
struct intel_crtc_state *new_crtc_state);
void intel_modeset_verify_disabled(struct drm_i915_private *dev_priv,
struct intel_atomic_state *state);
void intel_modeset_verify_crtc(struct intel_atomic_state *state,
struct intel_crtc *crtc);
void intel_modeset_verify_disabled(struct intel_atomic_state *state);
#endif /* __INTEL_MODESET_VERIFY_H__ */
......@@ -680,7 +680,7 @@ intel_panel_detect(struct drm_connector *connector, bool force)
{
struct drm_i915_private *i915 = to_i915(connector->dev);
if (!INTEL_DISPLAY_ENABLED(i915))
if (!intel_display_device_enabled(i915))
return connector_status_disconnected;
return connector_status_connected;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment