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: Dave Airlie <airlied@redhat.com> From: Jani Nikula <jani.nikula@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/87r0m00xew.fsf@intel.com
This commit is contained in:
commit
7971debdfd
@ -267,19 +267,22 @@ i915 driver.
|
||||
Intel GPU Basics
|
||||
----------------
|
||||
|
||||
An Intel GPU has multiple engines. There are several engine types.
|
||||
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.
|
||||
- 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
|
||||
subdir-ccflags-y += -Wno-missing-field-initializers
|
||||
subdir-ccflags-y += -Wno-sign-compare
|
||||
subdir-ccflags-y += -Wno-shift-negative-value
|
||||
# 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-disable-warning, frame-address)
|
||||
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-type-limits
|
||||
subdir-ccflags-y += -Wno-shift-negative-value
|
||||
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;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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)
|
||||
return false;
|
||||
|
||||
if (stride > 16384)
|
||||
if (fb->modifier == DRM_FORMAT_MOD_LINEAR && stride & 511)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool pixel_format_is_valid(const struct intel_plane_state *plane_state)
|
||||
static bool icl_fbc_stride_is_valid(const struct intel_plane_state *plane_state)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
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 ? >->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 */
|
||||
|
@ -11,610 +11,27 @@
|
||||
#include "i915_drv.h"
|
||||
#include "i915_utils.h"
|
||||
#include "intel_hdcp_gsc.h"
|
||||
#include "intel_hdcp_gsc_message.h"
|
||||
|
||||
bool intel_hdcp_gsc_cs_required(struct drm_i915_private *i915)
|
||||
{
|
||||
return DISPLAY_VER(i915) >= 14;
|
||||
}
|
||||
|
||||
static int
|
||||
gsc_hdcp_initiate_session(struct device *dev, struct hdcp_port_data *data,
|
||||
struct hdcp2_ake_init *ake_data)
|
||||
bool intel_hdcp_gsc_check_status(struct drm_i915_private *i915)
|
||||
{
|
||||
struct wired_cmd_initiate_hdcp2_session_in session_init_in = { { 0 } };
|
||||
struct wired_cmd_initiate_hdcp2_session_out
|
||||
session_init_out = { { 0 } };
|
||||
struct drm_i915_private *i915;
|
||||
ssize_t byte;
|
||||
struct intel_gt *gt = i915->media_gt;
|
||||
struct intel_gsc_uc *gsc = gt ? >->uc.gsc : NULL;
|
||||
|
||||
if (!dev || !data || !ake_data)
|
||||
return -EINVAL;
|
||||
|
||||
i915 = kdev_to_i915(dev);
|
||||
if (!i915) {
|
||||
dev_err(dev, "DRM not initialized, aborting HDCP.\n");
|
||||
return -ENODEV;
|
||||
if (!gsc || !intel_uc_fw_is_running(&gsc->fw)) {
|
||||
drm_dbg_kms(&i915->drm,
|
||||
"GSC components required for HDCP2.2 are not ready\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
session_init_in.header.api_version = HDCP_API_VERSION;
|
||||
session_init_in.header.command_id = WIRED_INITIATE_HDCP2_SESSION;
|
||||
session_init_in.header.status = FW_HDCP_STATUS_SUCCESS;
|
||||
session_init_in.header.buffer_len =
|
||||
WIRED_CMD_BUF_LEN_INITIATE_HDCP2_SESSION_IN;
|
||||
|
||||
session_init_in.port.integrated_port_type = data->port_type;
|
||||
session_init_in.port.physical_port = (u8)data->hdcp_ddi;
|
||||
session_init_in.port.attached_transcoder = (u8)data->hdcp_transcoder;
|
||||
session_init_in.protocol = data->protocol;
|
||||
|
||||
byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&session_init_in,
|
||||
sizeof(session_init_in),
|
||||
(u8 *)&session_init_out,
|
||||
sizeof(session_init_out));
|
||||
if (byte < 0) {
|
||||
drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
|
||||
return byte;
|
||||
}
|
||||
|
||||
if (session_init_out.header.status != FW_HDCP_STATUS_SUCCESS) {
|
||||
drm_dbg_kms(&i915->drm, "FW cmd 0x%08X Failed. Status: 0x%X\n",
|
||||
WIRED_INITIATE_HDCP2_SESSION,
|
||||
session_init_out.header.status);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
ake_data->msg_id = HDCP_2_2_AKE_INIT;
|
||||
ake_data->tx_caps = session_init_out.tx_caps;
|
||||
memcpy(ake_data->r_tx, session_init_out.r_tx, HDCP_2_2_RTX_LEN);
|
||||
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int
|
||||
gsc_hdcp_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)
|
||||
{
|
||||
struct wired_cmd_verify_receiver_cert_in verify_rxcert_in = { { 0 } };
|
||||
struct wired_cmd_verify_receiver_cert_out verify_rxcert_out = { { 0 } };
|
||||
struct drm_i915_private *i915;
|
||||
ssize_t byte;
|
||||
|
||||
if (!dev || !data || !rx_cert || !km_stored || !ek_pub_km || !msg_sz)
|
||||
return -EINVAL;
|
||||
|
||||
i915 = kdev_to_i915(dev);
|
||||
if (!i915) {
|
||||
dev_err(dev, "DRM not initialized, aborting HDCP.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
verify_rxcert_in.header.api_version = HDCP_API_VERSION;
|
||||
verify_rxcert_in.header.command_id = WIRED_VERIFY_RECEIVER_CERT;
|
||||
verify_rxcert_in.header.status = FW_HDCP_STATUS_SUCCESS;
|
||||
verify_rxcert_in.header.buffer_len =
|
||||
WIRED_CMD_BUF_LEN_VERIFY_RECEIVER_CERT_IN;
|
||||
|
||||
verify_rxcert_in.port.integrated_port_type = data->port_type;
|
||||
verify_rxcert_in.port.physical_port = (u8)data->hdcp_ddi;
|
||||
verify_rxcert_in.port.attached_transcoder = (u8)data->hdcp_transcoder;
|
||||
|
||||
verify_rxcert_in.cert_rx = rx_cert->cert_rx;
|
||||
memcpy(verify_rxcert_in.r_rx, &rx_cert->r_rx, HDCP_2_2_RRX_LEN);
|
||||
memcpy(verify_rxcert_in.rx_caps, rx_cert->rx_caps, HDCP_2_2_RXCAPS_LEN);
|
||||
|
||||
byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&verify_rxcert_in,
|
||||
sizeof(verify_rxcert_in),
|
||||
(u8 *)&verify_rxcert_out,
|
||||
sizeof(verify_rxcert_out));
|
||||
if (byte < 0) {
|
||||
drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed: %zd\n", byte);
|
||||
return byte;
|
||||
}
|
||||
|
||||
if (verify_rxcert_out.header.status != FW_HDCP_STATUS_SUCCESS) {
|
||||
drm_dbg_kms(&i915->drm, "FW cmd 0x%08X Failed. Status: 0x%X\n",
|
||||
WIRED_VERIFY_RECEIVER_CERT,
|
||||
verify_rxcert_out.header.status);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
*km_stored = !!verify_rxcert_out.km_stored;
|
||||
if (verify_rxcert_out.km_stored) {
|
||||
ek_pub_km->msg_id = HDCP_2_2_AKE_STORED_KM;
|
||||
*msg_sz = sizeof(struct hdcp2_ake_stored_km);
|
||||
} else {
|
||||
ek_pub_km->msg_id = HDCP_2_2_AKE_NO_STORED_KM;
|
||||
*msg_sz = sizeof(struct hdcp2_ake_no_stored_km);
|
||||
}
|
||||
|
||||
memcpy(ek_pub_km->e_kpub_km, &verify_rxcert_out.ekm_buff,
|
||||
sizeof(verify_rxcert_out.ekm_buff));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
gsc_hdcp_verify_hprime(struct device *dev, struct hdcp_port_data *data,
|
||||
struct hdcp2_ake_send_hprime *rx_hprime)
|
||||
{
|
||||
struct wired_cmd_ake_send_hprime_in send_hprime_in = { { 0 } };
|
||||
struct wired_cmd_ake_send_hprime_out send_hprime_out = { { 0 } };
|
||||
struct drm_i915_private *i915;
|
||||
ssize_t byte;
|
||||
|
||||
if (!dev || !data || !rx_hprime)
|
||||
return -EINVAL;
|
||||
|
||||
i915 = kdev_to_i915(dev);
|
||||
if (!i915) {
|
||||
dev_err(dev, "DRM not initialized, aborting HDCP.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
send_hprime_in.header.api_version = HDCP_API_VERSION;
|
||||
send_hprime_in.header.command_id = WIRED_AKE_SEND_HPRIME;
|
||||
send_hprime_in.header.status = FW_HDCP_STATUS_SUCCESS;
|
||||
send_hprime_in.header.buffer_len = WIRED_CMD_BUF_LEN_AKE_SEND_HPRIME_IN;
|
||||
|
||||
send_hprime_in.port.integrated_port_type = data->port_type;
|
||||
send_hprime_in.port.physical_port = (u8)data->hdcp_ddi;
|
||||
send_hprime_in.port.attached_transcoder = (u8)data->hdcp_transcoder;
|
||||
|
||||
memcpy(send_hprime_in.h_prime, rx_hprime->h_prime,
|
||||
HDCP_2_2_H_PRIME_LEN);
|
||||
|
||||
byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&send_hprime_in,
|
||||
sizeof(send_hprime_in),
|
||||
(u8 *)&send_hprime_out,
|
||||
sizeof(send_hprime_out));
|
||||
if (byte < 0) {
|
||||
drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
|
||||
return byte;
|
||||
}
|
||||
|
||||
if (send_hprime_out.header.status != FW_HDCP_STATUS_SUCCESS) {
|
||||
drm_dbg_kms(&i915->drm, "FW cmd 0x%08X Failed. Status: 0x%X\n",
|
||||
WIRED_AKE_SEND_HPRIME, send_hprime_out.header.status);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
gsc_hdcp_store_pairing_info(struct device *dev, struct hdcp_port_data *data,
|
||||
struct hdcp2_ake_send_pairing_info *pairing_info)
|
||||
{
|
||||
struct wired_cmd_ake_send_pairing_info_in pairing_info_in = { { 0 } };
|
||||
struct wired_cmd_ake_send_pairing_info_out pairing_info_out = { { 0 } };
|
||||
struct drm_i915_private *i915;
|
||||
ssize_t byte;
|
||||
|
||||
if (!dev || !data || !pairing_info)
|
||||
return -EINVAL;
|
||||
|
||||
i915 = kdev_to_i915(dev);
|
||||
if (!i915) {
|
||||
dev_err(dev, "DRM not initialized, aborting HDCP.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
pairing_info_in.header.api_version = HDCP_API_VERSION;
|
||||
pairing_info_in.header.command_id = WIRED_AKE_SEND_PAIRING_INFO;
|
||||
pairing_info_in.header.status = FW_HDCP_STATUS_SUCCESS;
|
||||
pairing_info_in.header.buffer_len =
|
||||
WIRED_CMD_BUF_LEN_SEND_PAIRING_INFO_IN;
|
||||
|
||||
pairing_info_in.port.integrated_port_type = data->port_type;
|
||||
pairing_info_in.port.physical_port = (u8)data->hdcp_ddi;
|
||||
pairing_info_in.port.attached_transcoder = (u8)data->hdcp_transcoder;
|
||||
|
||||
memcpy(pairing_info_in.e_kh_km, pairing_info->e_kh_km,
|
||||
HDCP_2_2_E_KH_KM_LEN);
|
||||
|
||||
byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&pairing_info_in,
|
||||
sizeof(pairing_info_in),
|
||||
(u8 *)&pairing_info_out,
|
||||
sizeof(pairing_info_out));
|
||||
if (byte < 0) {
|
||||
drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
|
||||
return byte;
|
||||
}
|
||||
|
||||
if (pairing_info_out.header.status != FW_HDCP_STATUS_SUCCESS) {
|
||||
drm_dbg_kms(&i915->drm, "FW cmd 0x%08X failed. Status: 0x%X\n",
|
||||
WIRED_AKE_SEND_PAIRING_INFO,
|
||||
pairing_info_out.header.status);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
gsc_hdcp_initiate_locality_check(struct device *dev,
|
||||
struct hdcp_port_data *data,
|
||||
struct hdcp2_lc_init *lc_init_data)
|
||||
{
|
||||
struct wired_cmd_init_locality_check_in lc_init_in = { { 0 } };
|
||||
struct wired_cmd_init_locality_check_out lc_init_out = { { 0 } };
|
||||
struct drm_i915_private *i915;
|
||||
ssize_t byte;
|
||||
|
||||
if (!dev || !data || !lc_init_data)
|
||||
return -EINVAL;
|
||||
|
||||
i915 = kdev_to_i915(dev);
|
||||
if (!i915) {
|
||||
dev_err(dev, "DRM not initialized, aborting HDCP.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
lc_init_in.header.api_version = HDCP_API_VERSION;
|
||||
lc_init_in.header.command_id = WIRED_INIT_LOCALITY_CHECK;
|
||||
lc_init_in.header.status = FW_HDCP_STATUS_SUCCESS;
|
||||
lc_init_in.header.buffer_len = WIRED_CMD_BUF_LEN_INIT_LOCALITY_CHECK_IN;
|
||||
|
||||
lc_init_in.port.integrated_port_type = data->port_type;
|
||||
lc_init_in.port.physical_port = (u8)data->hdcp_ddi;
|
||||
lc_init_in.port.attached_transcoder = (u8)data->hdcp_transcoder;
|
||||
|
||||
byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&lc_init_in, sizeof(lc_init_in),
|
||||
(u8 *)&lc_init_out, sizeof(lc_init_out));
|
||||
if (byte < 0) {
|
||||
drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
|
||||
return byte;
|
||||
}
|
||||
|
||||
if (lc_init_out.header.status != FW_HDCP_STATUS_SUCCESS) {
|
||||
drm_dbg_kms(&i915->drm, "FW cmd 0x%08X Failed. status: 0x%X\n",
|
||||
WIRED_INIT_LOCALITY_CHECK, lc_init_out.header.status);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
lc_init_data->msg_id = HDCP_2_2_LC_INIT;
|
||||
memcpy(lc_init_data->r_n, lc_init_out.r_n, HDCP_2_2_RN_LEN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
gsc_hdcp_verify_lprime(struct device *dev, struct hdcp_port_data *data,
|
||||
struct hdcp2_lc_send_lprime *rx_lprime)
|
||||
{
|
||||
struct wired_cmd_validate_locality_in verify_lprime_in = { { 0 } };
|
||||
struct wired_cmd_validate_locality_out verify_lprime_out = { { 0 } };
|
||||
struct drm_i915_private *i915;
|
||||
ssize_t byte;
|
||||
|
||||
if (!dev || !data || !rx_lprime)
|
||||
return -EINVAL;
|
||||
|
||||
i915 = kdev_to_i915(dev);
|
||||
if (!i915) {
|
||||
dev_err(dev, "DRM not initialized, aborting HDCP.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
verify_lprime_in.header.api_version = HDCP_API_VERSION;
|
||||
verify_lprime_in.header.command_id = WIRED_VALIDATE_LOCALITY;
|
||||
verify_lprime_in.header.status = FW_HDCP_STATUS_SUCCESS;
|
||||
verify_lprime_in.header.buffer_len =
|
||||
WIRED_CMD_BUF_LEN_VALIDATE_LOCALITY_IN;
|
||||
|
||||
verify_lprime_in.port.integrated_port_type = data->port_type;
|
||||
verify_lprime_in.port.physical_port = (u8)data->hdcp_ddi;
|
||||
verify_lprime_in.port.attached_transcoder = (u8)data->hdcp_transcoder;
|
||||
|
||||
memcpy(verify_lprime_in.l_prime, rx_lprime->l_prime,
|
||||
HDCP_2_2_L_PRIME_LEN);
|
||||
|
||||
byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&verify_lprime_in,
|
||||
sizeof(verify_lprime_in),
|
||||
(u8 *)&verify_lprime_out,
|
||||
sizeof(verify_lprime_out));
|
||||
if (byte < 0) {
|
||||
drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
|
||||
return byte;
|
||||
}
|
||||
|
||||
if (verify_lprime_out.header.status != FW_HDCP_STATUS_SUCCESS) {
|
||||
drm_dbg_kms(&i915->drm, "FW cmd 0x%08X failed. status: 0x%X\n",
|
||||
WIRED_VALIDATE_LOCALITY,
|
||||
verify_lprime_out.header.status);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gsc_hdcp_get_session_key(struct device *dev,
|
||||
struct hdcp_port_data *data,
|
||||
struct hdcp2_ske_send_eks *ske_data)
|
||||
{
|
||||
struct wired_cmd_get_session_key_in get_skey_in = { { 0 } };
|
||||
struct wired_cmd_get_session_key_out get_skey_out = { { 0 } };
|
||||
struct drm_i915_private *i915;
|
||||
ssize_t byte;
|
||||
|
||||
if (!dev || !data || !ske_data)
|
||||
return -EINVAL;
|
||||
|
||||
i915 = kdev_to_i915(dev);
|
||||
if (!i915) {
|
||||
dev_err(dev, "DRM not initialized, aborting HDCP.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
get_skey_in.header.api_version = HDCP_API_VERSION;
|
||||
get_skey_in.header.command_id = WIRED_GET_SESSION_KEY;
|
||||
get_skey_in.header.status = FW_HDCP_STATUS_SUCCESS;
|
||||
get_skey_in.header.buffer_len = WIRED_CMD_BUF_LEN_GET_SESSION_KEY_IN;
|
||||
|
||||
get_skey_in.port.integrated_port_type = data->port_type;
|
||||
get_skey_in.port.physical_port = (u8)data->hdcp_ddi;
|
||||
get_skey_in.port.attached_transcoder = (u8)data->hdcp_transcoder;
|
||||
|
||||
byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&get_skey_in, sizeof(get_skey_in),
|
||||
(u8 *)&get_skey_out, sizeof(get_skey_out));
|
||||
if (byte < 0) {
|
||||
drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
|
||||
return byte;
|
||||
}
|
||||
|
||||
if (get_skey_out.header.status != FW_HDCP_STATUS_SUCCESS) {
|
||||
drm_dbg_kms(&i915->drm, "FW cmd 0x%08X failed. status: 0x%X\n",
|
||||
WIRED_GET_SESSION_KEY, get_skey_out.header.status);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
ske_data->msg_id = HDCP_2_2_SKE_SEND_EKS;
|
||||
memcpy(ske_data->e_dkey_ks, get_skey_out.e_dkey_ks,
|
||||
HDCP_2_2_E_DKEY_KS_LEN);
|
||||
memcpy(ske_data->riv, get_skey_out.r_iv, HDCP_2_2_RIV_LEN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
gsc_hdcp_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)
|
||||
{
|
||||
struct wired_cmd_verify_repeater_in verify_repeater_in = { { 0 } };
|
||||
struct wired_cmd_verify_repeater_out verify_repeater_out = { { 0 } };
|
||||
struct drm_i915_private *i915;
|
||||
ssize_t byte;
|
||||
|
||||
if (!dev || !rep_topology || !rep_send_ack || !data)
|
||||
return -EINVAL;
|
||||
|
||||
i915 = kdev_to_i915(dev);
|
||||
if (!i915) {
|
||||
dev_err(dev, "DRM not initialized, aborting HDCP.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
verify_repeater_in.header.api_version = HDCP_API_VERSION;
|
||||
verify_repeater_in.header.command_id = WIRED_VERIFY_REPEATER;
|
||||
verify_repeater_in.header.status = FW_HDCP_STATUS_SUCCESS;
|
||||
verify_repeater_in.header.buffer_len =
|
||||
WIRED_CMD_BUF_LEN_VERIFY_REPEATER_IN;
|
||||
|
||||
verify_repeater_in.port.integrated_port_type = data->port_type;
|
||||
verify_repeater_in.port.physical_port = (u8)data->hdcp_ddi;
|
||||
verify_repeater_in.port.attached_transcoder = (u8)data->hdcp_transcoder;
|
||||
|
||||
memcpy(verify_repeater_in.rx_info, rep_topology->rx_info,
|
||||
HDCP_2_2_RXINFO_LEN);
|
||||
memcpy(verify_repeater_in.seq_num_v, rep_topology->seq_num_v,
|
||||
HDCP_2_2_SEQ_NUM_LEN);
|
||||
memcpy(verify_repeater_in.v_prime, rep_topology->v_prime,
|
||||
HDCP_2_2_V_PRIME_HALF_LEN);
|
||||
memcpy(verify_repeater_in.receiver_ids, rep_topology->receiver_ids,
|
||||
HDCP_2_2_RECEIVER_IDS_MAX_LEN);
|
||||
|
||||
byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&verify_repeater_in,
|
||||
sizeof(verify_repeater_in),
|
||||
(u8 *)&verify_repeater_out,
|
||||
sizeof(verify_repeater_out));
|
||||
if (byte < 0) {
|
||||
drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
|
||||
return byte;
|
||||
}
|
||||
|
||||
if (verify_repeater_out.header.status != FW_HDCP_STATUS_SUCCESS) {
|
||||
drm_dbg_kms(&i915->drm, "FW cmd 0x%08X failed. status: 0x%X\n",
|
||||
WIRED_VERIFY_REPEATER,
|
||||
verify_repeater_out.header.status);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
memcpy(rep_send_ack->v, verify_repeater_out.v,
|
||||
HDCP_2_2_V_PRIME_HALF_LEN);
|
||||
rep_send_ack->msg_id = HDCP_2_2_REP_SEND_ACK;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gsc_hdcp_verify_mprime(struct device *dev,
|
||||
struct hdcp_port_data *data,
|
||||
struct hdcp2_rep_stream_ready *stream_ready)
|
||||
{
|
||||
struct wired_cmd_repeater_auth_stream_req_in *verify_mprime_in;
|
||||
struct wired_cmd_repeater_auth_stream_req_out
|
||||
verify_mprime_out = { { 0 } };
|
||||
struct drm_i915_private *i915;
|
||||
ssize_t byte;
|
||||
size_t cmd_size;
|
||||
|
||||
if (!dev || !stream_ready || !data)
|
||||
return -EINVAL;
|
||||
|
||||
i915 = kdev_to_i915(dev);
|
||||
if (!i915) {
|
||||
dev_err(dev, "DRM not initialized, aborting HDCP.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
cmd_size = struct_size(verify_mprime_in, streams, data->k);
|
||||
if (cmd_size == SIZE_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
verify_mprime_in = kzalloc(cmd_size, GFP_KERNEL);
|
||||
if (!verify_mprime_in)
|
||||
return -ENOMEM;
|
||||
|
||||
verify_mprime_in->header.api_version = HDCP_API_VERSION;
|
||||
verify_mprime_in->header.command_id = WIRED_REPEATER_AUTH_STREAM_REQ;
|
||||
verify_mprime_in->header.status = FW_HDCP_STATUS_SUCCESS;
|
||||
verify_mprime_in->header.buffer_len = cmd_size - sizeof(verify_mprime_in->header);
|
||||
|
||||
verify_mprime_in->port.integrated_port_type = data->port_type;
|
||||
verify_mprime_in->port.physical_port = (u8)data->hdcp_ddi;
|
||||
verify_mprime_in->port.attached_transcoder = (u8)data->hdcp_transcoder;
|
||||
|
||||
memcpy(verify_mprime_in->m_prime, stream_ready->m_prime, HDCP_2_2_MPRIME_LEN);
|
||||
drm_hdcp_cpu_to_be24(verify_mprime_in->seq_num_m, data->seq_num_m);
|
||||
|
||||
memcpy(verify_mprime_in->streams, data->streams,
|
||||
array_size(data->k, sizeof(*data->streams)));
|
||||
|
||||
verify_mprime_in->k = cpu_to_be16(data->k);
|
||||
|
||||
byte = intel_hdcp_gsc_msg_send(i915, (u8 *)verify_mprime_in, cmd_size,
|
||||
(u8 *)&verify_mprime_out,
|
||||
sizeof(verify_mprime_out));
|
||||
kfree(verify_mprime_in);
|
||||
if (byte < 0) {
|
||||
drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
|
||||
return byte;
|
||||
}
|
||||
|
||||
if (verify_mprime_out.header.status != FW_HDCP_STATUS_SUCCESS) {
|
||||
drm_dbg_kms(&i915->drm, "FW cmd 0x%08X failed. status: 0x%X\n",
|
||||
WIRED_REPEATER_AUTH_STREAM_REQ,
|
||||
verify_mprime_out.header.status);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gsc_hdcp_enable_authentication(struct device *dev,
|
||||
struct hdcp_port_data *data)
|
||||
{
|
||||
struct wired_cmd_enable_auth_in enable_auth_in = { { 0 } };
|
||||
struct wired_cmd_enable_auth_out enable_auth_out = { { 0 } };
|
||||
struct drm_i915_private *i915;
|
||||
ssize_t byte;
|
||||
|
||||
if (!dev || !data)
|
||||
return -EINVAL;
|
||||
|
||||
i915 = kdev_to_i915(dev);
|
||||
if (!i915) {
|
||||
dev_err(dev, "DRM not initialized, aborting HDCP.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
enable_auth_in.header.api_version = HDCP_API_VERSION;
|
||||
enable_auth_in.header.command_id = WIRED_ENABLE_AUTH;
|
||||
enable_auth_in.header.status = FW_HDCP_STATUS_SUCCESS;
|
||||
enable_auth_in.header.buffer_len = WIRED_CMD_BUF_LEN_ENABLE_AUTH_IN;
|
||||
|
||||
enable_auth_in.port.integrated_port_type = data->port_type;
|
||||
enable_auth_in.port.physical_port = (u8)data->hdcp_ddi;
|
||||
enable_auth_in.port.attached_transcoder = (u8)data->hdcp_transcoder;
|
||||
enable_auth_in.stream_type = data->streams[0].stream_type;
|
||||
|
||||
byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&enable_auth_in,
|
||||
sizeof(enable_auth_in),
|
||||
(u8 *)&enable_auth_out,
|
||||
sizeof(enable_auth_out));
|
||||
if (byte < 0) {
|
||||
drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
|
||||
return byte;
|
||||
}
|
||||
|
||||
if (enable_auth_out.header.status != FW_HDCP_STATUS_SUCCESS) {
|
||||
drm_dbg_kms(&i915->drm, "FW cmd 0x%08X failed. status: 0x%X\n",
|
||||
WIRED_ENABLE_AUTH, enable_auth_out.header.status);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
gsc_hdcp_close_session(struct device *dev, struct hdcp_port_data *data)
|
||||
{
|
||||
struct wired_cmd_close_session_in session_close_in = { { 0 } };
|
||||
struct wired_cmd_close_session_out session_close_out = { { 0 } };
|
||||
struct drm_i915_private *i915;
|
||||
ssize_t byte;
|
||||
|
||||
if (!dev || !data)
|
||||
return -EINVAL;
|
||||
|
||||
i915 = kdev_to_i915(dev);
|
||||
if (!i915) {
|
||||
dev_err(dev, "DRM not initialized, aborting HDCP.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
session_close_in.header.api_version = HDCP_API_VERSION;
|
||||
session_close_in.header.command_id = WIRED_CLOSE_SESSION;
|
||||
session_close_in.header.status = FW_HDCP_STATUS_SUCCESS;
|
||||
session_close_in.header.buffer_len =
|
||||
WIRED_CMD_BUF_LEN_CLOSE_SESSION_IN;
|
||||
|
||||
session_close_in.port.integrated_port_type = data->port_type;
|
||||
session_close_in.port.physical_port = (u8)data->hdcp_ddi;
|
||||
session_close_in.port.attached_transcoder = (u8)data->hdcp_transcoder;
|
||||
|
||||
byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&session_close_in,
|
||||
sizeof(session_close_in),
|
||||
(u8 *)&session_close_out,
|
||||
sizeof(session_close_out));
|
||||
if (byte < 0) {
|
||||
drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
|
||||
return byte;
|
||||
}
|
||||
|
||||
if (session_close_out.header.status != FW_HDCP_STATUS_SUCCESS) {
|
||||
drm_dbg_kms(&i915->drm, "Session Close Failed. status: 0x%X\n",
|
||||
session_close_out.header.status);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i915_hdcp_ops gsc_hdcp_ops = {
|
||||
.initiate_hdcp2_session = gsc_hdcp_initiate_session,
|
||||
.verify_receiver_cert_prepare_km =
|
||||
gsc_hdcp_verify_receiver_cert_prepare_km,
|
||||
.verify_hprime = gsc_hdcp_verify_hprime,
|
||||
.store_pairing_info = gsc_hdcp_store_pairing_info,
|
||||
.initiate_locality_check = gsc_hdcp_initiate_locality_check,
|
||||
.verify_lprime = gsc_hdcp_verify_lprime,
|
||||
.get_session_key = gsc_hdcp_get_session_key,
|
||||
.repeater_check_flow_prepare_ack =
|
||||
gsc_hdcp_repeater_check_flow_prepare_ack,
|
||||
.verify_mprime = gsc_hdcp_verify_mprime,
|
||||
.enable_hdcp_authentication = gsc_hdcp_enable_authentication,
|
||||
.close_hdcp_session = gsc_hdcp_close_session,
|
||||
};
|
||||
|
||||
/*This function helps allocate memory for the command that we will send to gsc cs */
|
||||
static int intel_hdcp_gsc_initialize_message(struct drm_i915_private *i915,
|
||||
struct intel_hdcp_gsc_message *hdcp_message)
|
||||
@ -667,6 +84,22 @@ out_unpin:
|
||||
return err;
|
||||
}
|
||||
|
||||
static const struct i915_hdcp_ops gsc_hdcp_ops = {
|
||||
.initiate_hdcp2_session = intel_hdcp_gsc_initiate_session,
|
||||
.verify_receiver_cert_prepare_km =
|
||||
intel_hdcp_gsc_verify_receiver_cert_prepare_km,
|
||||
.verify_hprime = intel_hdcp_gsc_verify_hprime,
|
||||
.store_pairing_info = intel_hdcp_gsc_store_pairing_info,
|
||||
.initiate_locality_check = intel_hdcp_gsc_initiate_locality_check,
|
||||
.verify_lprime = intel_hdcp_gsc_verify_lprime,
|
||||
.get_session_key = intel_hdcp_gsc_get_session_key,
|
||||
.repeater_check_flow_prepare_ack =
|
||||
intel_hdcp_gsc_repeater_check_flow_prepare_ack,
|
||||
.verify_mprime = intel_hdcp_gsc_verify_mprime,
|
||||
.enable_hdcp_authentication = intel_hdcp_gsc_enable_authentication,
|
||||
.close_hdcp_session = intel_hdcp_gsc_close_session,
|
||||
};
|
||||
|
||||
static int intel_hdcp_gsc_hdcp2_init(struct drm_i915_private *i915)
|
||||
{
|
||||
struct intel_hdcp_gsc_message *hdcp_message;
|
||||
|
@ -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__ */
|
||||
|
592
drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.c
Normal file
592
drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.c
Normal file
@ -0,0 +1,592 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* Copyright 2023, Intel Corporation.
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <drm/i915_hdcp_interface.h>
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "intel_hdcp_gsc_message.h"
|
||||
|
||||
int
|
||||
intel_hdcp_gsc_initiate_session(struct device *dev, struct hdcp_port_data *data,
|
||||
struct hdcp2_ake_init *ake_data)
|
||||
{
|
||||
struct wired_cmd_initiate_hdcp2_session_in session_init_in = { { 0 } };
|
||||
struct wired_cmd_initiate_hdcp2_session_out
|
||||
session_init_out = { { 0 } };
|
||||
struct drm_i915_private *i915;
|
||||
ssize_t byte;
|
||||
|
||||
if (!dev || !data || !ake_data)
|
||||
return -EINVAL;
|
||||
|
||||
i915 = kdev_to_i915(dev);
|
||||
if (!i915) {
|
||||
dev_err(dev, "DRM not initialized, aborting HDCP.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
session_init_in.header.api_version = HDCP_API_VERSION;
|
||||
session_init_in.header.command_id = WIRED_INITIATE_HDCP2_SESSION;
|
||||
session_init_in.header.status = FW_HDCP_STATUS_SUCCESS;
|
||||
session_init_in.header.buffer_len =
|
||||
WIRED_CMD_BUF_LEN_INITIATE_HDCP2_SESSION_IN;
|
||||
|
||||
session_init_in.port.integrated_port_type = data->port_type;
|
||||
session_init_in.port.physical_port = (u8)data->hdcp_ddi;
|
||||
session_init_in.port.attached_transcoder = (u8)data->hdcp_transcoder;
|
||||
session_init_in.protocol = data->protocol;
|
||||
|
||||
byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&session_init_in,
|
||||
sizeof(session_init_in),
|
||||
(u8 *)&session_init_out,
|
||||
sizeof(session_init_out));
|
||||
if (byte < 0) {
|
||||
drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
|
||||
return byte;
|
||||
}
|
||||
|
||||
if (session_init_out.header.status != FW_HDCP_STATUS_SUCCESS) {
|
||||
drm_dbg_kms(&i915->drm, "FW cmd 0x%08X Failed. Status: 0x%X\n",
|
||||
WIRED_INITIATE_HDCP2_SESSION,
|
||||
session_init_out.header.status);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
ake_data->msg_id = HDCP_2_2_AKE_INIT;
|
||||
ake_data->tx_caps = session_init_out.tx_caps;
|
||||
memcpy(ake_data->r_tx, session_init_out.r_tx, HDCP_2_2_RTX_LEN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
struct wired_cmd_verify_receiver_cert_in verify_rxcert_in = { { 0 } };
|
||||
struct wired_cmd_verify_receiver_cert_out verify_rxcert_out = { { 0 } };
|
||||
struct drm_i915_private *i915;
|
||||
ssize_t byte;
|
||||
|
||||
if (!dev || !data || !rx_cert || !km_stored || !ek_pub_km || !msg_sz)
|
||||
return -EINVAL;
|
||||
|
||||
i915 = kdev_to_i915(dev);
|
||||
if (!i915) {
|
||||
dev_err(dev, "DRM not initialized, aborting HDCP.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
verify_rxcert_in.header.api_version = HDCP_API_VERSION;
|
||||
verify_rxcert_in.header.command_id = WIRED_VERIFY_RECEIVER_CERT;
|
||||
verify_rxcert_in.header.status = FW_HDCP_STATUS_SUCCESS;
|
||||
verify_rxcert_in.header.buffer_len =
|
||||
WIRED_CMD_BUF_LEN_VERIFY_RECEIVER_CERT_IN;
|
||||
|
||||
verify_rxcert_in.port.integrated_port_type = data->port_type;
|
||||
verify_rxcert_in.port.physical_port = (u8)data->hdcp_ddi;
|
||||
verify_rxcert_in.port.attached_transcoder = (u8)data->hdcp_transcoder;
|
||||
|
||||
verify_rxcert_in.cert_rx = rx_cert->cert_rx;
|
||||
memcpy(verify_rxcert_in.r_rx, &rx_cert->r_rx, HDCP_2_2_RRX_LEN);
|
||||
memcpy(verify_rxcert_in.rx_caps, rx_cert->rx_caps, HDCP_2_2_RXCAPS_LEN);
|
||||
|
||||
byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&verify_rxcert_in,
|
||||
sizeof(verify_rxcert_in),
|
||||
(u8 *)&verify_rxcert_out,
|
||||
sizeof(verify_rxcert_out));
|
||||
if (byte < 0) {
|
||||
drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed: %zd\n", byte);
|
||||
return byte;
|
||||
}
|
||||
|
||||
if (verify_rxcert_out.header.status != FW_HDCP_STATUS_SUCCESS) {
|
||||
drm_dbg_kms(&i915->drm, "FW cmd 0x%08X Failed. Status: 0x%X\n",
|
||||
WIRED_VERIFY_RECEIVER_CERT,
|
||||
verify_rxcert_out.header.status);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
*km_stored = !!verify_rxcert_out.km_stored;
|
||||
if (verify_rxcert_out.km_stored) {
|
||||
ek_pub_km->msg_id = HDCP_2_2_AKE_STORED_KM;
|
||||
*msg_sz = sizeof(struct hdcp2_ake_stored_km);
|
||||
} else {
|
||||
ek_pub_km->msg_id = HDCP_2_2_AKE_NO_STORED_KM;
|
||||
*msg_sz = sizeof(struct hdcp2_ake_no_stored_km);
|
||||
}
|
||||
|
||||
memcpy(ek_pub_km->e_kpub_km, &verify_rxcert_out.ekm_buff,
|
||||
sizeof(verify_rxcert_out.ekm_buff));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
intel_hdcp_gsc_verify_hprime(struct device *dev, struct hdcp_port_data *data,
|
||||
struct hdcp2_ake_send_hprime *rx_hprime)
|
||||
{
|
||||
struct wired_cmd_ake_send_hprime_in send_hprime_in = { { 0 } };
|
||||
struct wired_cmd_ake_send_hprime_out send_hprime_out = { { 0 } };
|
||||
struct drm_i915_private *i915;
|
||||
ssize_t byte;
|
||||
|
||||
if (!dev || !data || !rx_hprime)
|
||||
return -EINVAL;
|
||||
|
||||
i915 = kdev_to_i915(dev);
|
||||
if (!i915) {
|
||||
dev_err(dev, "DRM not initialized, aborting HDCP.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
send_hprime_in.header.api_version = HDCP_API_VERSION;
|
||||
send_hprime_in.header.command_id = WIRED_AKE_SEND_HPRIME;
|
||||
send_hprime_in.header.status = FW_HDCP_STATUS_SUCCESS;
|
||||
send_hprime_in.header.buffer_len = WIRED_CMD_BUF_LEN_AKE_SEND_HPRIME_IN;
|
||||
|
||||
send_hprime_in.port.integrated_port_type = data->port_type;
|
||||
send_hprime_in.port.physical_port = (u8)data->hdcp_ddi;
|
||||
send_hprime_in.port.attached_transcoder = (u8)data->hdcp_transcoder;
|
||||
|
||||
memcpy(send_hprime_in.h_prime, rx_hprime->h_prime,
|
||||
HDCP_2_2_H_PRIME_LEN);
|
||||
|
||||
byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&send_hprime_in,
|
||||
sizeof(send_hprime_in),
|
||||
(u8 *)&send_hprime_out,
|
||||
sizeof(send_hprime_out));
|
||||
if (byte < 0) {
|
||||
drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
|
||||
return byte;
|
||||
}
|
||||
|
||||
if (send_hprime_out.header.status != FW_HDCP_STATUS_SUCCESS) {
|
||||
drm_dbg_kms(&i915->drm, "FW cmd 0x%08X Failed. Status: 0x%X\n",
|
||||
WIRED_AKE_SEND_HPRIME, send_hprime_out.header.status);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
intel_hdcp_gsc_store_pairing_info(struct device *dev, struct hdcp_port_data *data,
|
||||
struct hdcp2_ake_send_pairing_info *pairing_info)
|
||||
{
|
||||
struct wired_cmd_ake_send_pairing_info_in pairing_info_in = { { 0 } };
|
||||
struct wired_cmd_ake_send_pairing_info_out pairing_info_out = { { 0 } };
|
||||
struct drm_i915_private *i915;
|
||||
ssize_t byte;
|
||||
|
||||
if (!dev || !data || !pairing_info)
|
||||
return -EINVAL;
|
||||
|
||||
i915 = kdev_to_i915(dev);
|
||||
if (!i915) {
|
||||
dev_err(dev, "DRM not initialized, aborting HDCP.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
pairing_info_in.header.api_version = HDCP_API_VERSION;
|
||||
pairing_info_in.header.command_id = WIRED_AKE_SEND_PAIRING_INFO;
|
||||
pairing_info_in.header.status = FW_HDCP_STATUS_SUCCESS;
|
||||
pairing_info_in.header.buffer_len =
|
||||
WIRED_CMD_BUF_LEN_SEND_PAIRING_INFO_IN;
|
||||
|
||||
pairing_info_in.port.integrated_port_type = data->port_type;
|
||||
pairing_info_in.port.physical_port = (u8)data->hdcp_ddi;
|
||||
pairing_info_in.port.attached_transcoder = (u8)data->hdcp_transcoder;
|
||||
|
||||
memcpy(pairing_info_in.e_kh_km, pairing_info->e_kh_km,
|
||||
HDCP_2_2_E_KH_KM_LEN);
|
||||
|
||||
byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&pairing_info_in,
|
||||
sizeof(pairing_info_in),
|
||||
(u8 *)&pairing_info_out,
|
||||
sizeof(pairing_info_out));
|
||||
if (byte < 0) {
|
||||
drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
|
||||
return byte;
|
||||
}
|
||||
|
||||
if (pairing_info_out.header.status != FW_HDCP_STATUS_SUCCESS) {
|
||||
drm_dbg_kms(&i915->drm, "FW cmd 0x%08X failed. Status: 0x%X\n",
|
||||
WIRED_AKE_SEND_PAIRING_INFO,
|
||||
pairing_info_out.header.status);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
intel_hdcp_gsc_initiate_locality_check(struct device *dev,
|
||||
struct hdcp_port_data *data,
|
||||
struct hdcp2_lc_init *lc_init_data)
|
||||
{
|
||||
struct wired_cmd_init_locality_check_in lc_init_in = { { 0 } };
|
||||
struct wired_cmd_init_locality_check_out lc_init_out = { { 0 } };
|
||||
struct drm_i915_private *i915;
|
||||
ssize_t byte;
|
||||
|
||||
if (!dev || !data || !lc_init_data)
|
||||
return -EINVAL;
|
||||
|
||||
i915 = kdev_to_i915(dev);
|
||||
if (!i915) {
|
||||
dev_err(dev, "DRM not initialized, aborting HDCP.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
lc_init_in.header.api_version = HDCP_API_VERSION;
|
||||
lc_init_in.header.command_id = WIRED_INIT_LOCALITY_CHECK;
|
||||
lc_init_in.header.status = FW_HDCP_STATUS_SUCCESS;
|
||||
lc_init_in.header.buffer_len = WIRED_CMD_BUF_LEN_INIT_LOCALITY_CHECK_IN;
|
||||
|
||||
lc_init_in.port.integrated_port_type = data->port_type;
|
||||
lc_init_in.port.physical_port = (u8)data->hdcp_ddi;
|
||||
lc_init_in.port.attached_transcoder = (u8)data->hdcp_transcoder;
|
||||
|
||||
byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&lc_init_in, sizeof(lc_init_in),
|
||||
(u8 *)&lc_init_out, sizeof(lc_init_out));
|
||||
if (byte < 0) {
|
||||
drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
|
||||
return byte;
|
||||
}
|
||||
|
||||
if (lc_init_out.header.status != FW_HDCP_STATUS_SUCCESS) {
|
||||
drm_dbg_kms(&i915->drm, "FW cmd 0x%08X Failed. status: 0x%X\n",
|
||||
WIRED_INIT_LOCALITY_CHECK, lc_init_out.header.status);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
lc_init_data->msg_id = HDCP_2_2_LC_INIT;
|
||||
memcpy(lc_init_data->r_n, lc_init_out.r_n, HDCP_2_2_RN_LEN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
intel_hdcp_gsc_verify_lprime(struct device *dev, struct hdcp_port_data *data,
|
||||
struct hdcp2_lc_send_lprime *rx_lprime)
|
||||
{
|
||||
struct wired_cmd_validate_locality_in verify_lprime_in = { { 0 } };
|
||||
struct wired_cmd_validate_locality_out verify_lprime_out = { { 0 } };
|
||||
struct drm_i915_private *i915;
|
||||
ssize_t byte;
|
||||
|
||||
if (!dev || !data || !rx_lprime)
|
||||
return -EINVAL;
|
||||
|
||||
i915 = kdev_to_i915(dev);
|
||||
if (!i915) {
|
||||
dev_err(dev, "DRM not initialized, aborting HDCP.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
verify_lprime_in.header.api_version = HDCP_API_VERSION;
|
||||
verify_lprime_in.header.command_id = WIRED_VALIDATE_LOCALITY;
|
||||
verify_lprime_in.header.status = FW_HDCP_STATUS_SUCCESS;
|
||||
verify_lprime_in.header.buffer_len =
|
||||
WIRED_CMD_BUF_LEN_VALIDATE_LOCALITY_IN;
|
||||
|
||||
verify_lprime_in.port.integrated_port_type = data->port_type;
|
||||
verify_lprime_in.port.physical_port = (u8)data->hdcp_ddi;
|
||||
verify_lprime_in.port.attached_transcoder = (u8)data->hdcp_transcoder;
|
||||
|
||||
memcpy(verify_lprime_in.l_prime, rx_lprime->l_prime,
|
||||
HDCP_2_2_L_PRIME_LEN);
|
||||
|
||||
byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&verify_lprime_in,
|
||||
sizeof(verify_lprime_in),
|
||||
(u8 *)&verify_lprime_out,
|
||||
sizeof(verify_lprime_out));
|
||||
if (byte < 0) {
|
||||
drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
|
||||
return byte;
|
||||
}
|
||||
|
||||
if (verify_lprime_out.header.status != FW_HDCP_STATUS_SUCCESS) {
|
||||
drm_dbg_kms(&i915->drm, "FW cmd 0x%08X failed. status: 0x%X\n",
|
||||
WIRED_VALIDATE_LOCALITY,
|
||||
verify_lprime_out.header.status);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int intel_hdcp_gsc_get_session_key(struct device *dev,
|
||||
struct hdcp_port_data *data,
|
||||
struct hdcp2_ske_send_eks *ske_data)
|
||||
{
|
||||
struct wired_cmd_get_session_key_in get_skey_in = { { 0 } };
|
||||
struct wired_cmd_get_session_key_out get_skey_out = { { 0 } };
|
||||
struct drm_i915_private *i915;
|
||||
ssize_t byte;
|
||||
|
||||
if (!dev || !data || !ske_data)
|
||||
return -EINVAL;
|
||||
|
||||
i915 = kdev_to_i915(dev);
|
||||
if (!i915) {
|
||||
dev_err(dev, "DRM not initialized, aborting HDCP.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
get_skey_in.header.api_version = HDCP_API_VERSION;
|
||||
get_skey_in.header.command_id = WIRED_GET_SESSION_KEY;
|
||||
get_skey_in.header.status = FW_HDCP_STATUS_SUCCESS;
|
||||
get_skey_in.header.buffer_len = WIRED_CMD_BUF_LEN_GET_SESSION_KEY_IN;
|
||||
|
||||
get_skey_in.port.integrated_port_type = data->port_type;
|
||||
get_skey_in.port.physical_port = (u8)data->hdcp_ddi;
|
||||
get_skey_in.port.attached_transcoder = (u8)data->hdcp_transcoder;
|
||||
|
||||
byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&get_skey_in, sizeof(get_skey_in),
|
||||
(u8 *)&get_skey_out, sizeof(get_skey_out));
|
||||
if (byte < 0) {
|
||||
drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
|
||||
return byte;
|
||||
}
|
||||
|
||||
if (get_skey_out.header.status != FW_HDCP_STATUS_SUCCESS) {
|
||||
drm_dbg_kms(&i915->drm, "FW cmd 0x%08X failed. status: 0x%X\n",
|
||||
WIRED_GET_SESSION_KEY, get_skey_out.header.status);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
ske_data->msg_id = HDCP_2_2_SKE_SEND_EKS;
|
||||
memcpy(ske_data->e_dkey_ks, get_skey_out.e_dkey_ks,
|
||||
HDCP_2_2_E_DKEY_KS_LEN);
|
||||
memcpy(ske_data->riv, get_skey_out.r_iv, HDCP_2_2_RIV_LEN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
struct wired_cmd_verify_repeater_in verify_repeater_in = { { 0 } };
|
||||
struct wired_cmd_verify_repeater_out verify_repeater_out = { { 0 } };
|
||||
struct drm_i915_private *i915;
|
||||
ssize_t byte;
|
||||
|
||||
if (!dev || !rep_topology || !rep_send_ack || !data)
|
||||
return -EINVAL;
|
||||
|
||||
i915 = kdev_to_i915(dev);
|
||||
if (!i915) {
|
||||
dev_err(dev, "DRM not initialized, aborting HDCP.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
verify_repeater_in.header.api_version = HDCP_API_VERSION;
|
||||
verify_repeater_in.header.command_id = WIRED_VERIFY_REPEATER;
|
||||
verify_repeater_in.header.status = FW_HDCP_STATUS_SUCCESS;
|
||||
verify_repeater_in.header.buffer_len =
|
||||
WIRED_CMD_BUF_LEN_VERIFY_REPEATER_IN;
|
||||
|
||||
verify_repeater_in.port.integrated_port_type = data->port_type;
|
||||
verify_repeater_in.port.physical_port = (u8)data->hdcp_ddi;
|
||||
verify_repeater_in.port.attached_transcoder = (u8)data->hdcp_transcoder;
|
||||
|
||||
memcpy(verify_repeater_in.rx_info, rep_topology->rx_info,
|
||||
HDCP_2_2_RXINFO_LEN);
|
||||
memcpy(verify_repeater_in.seq_num_v, rep_topology->seq_num_v,
|
||||
HDCP_2_2_SEQ_NUM_LEN);
|
||||
memcpy(verify_repeater_in.v_prime, rep_topology->v_prime,
|
||||
HDCP_2_2_V_PRIME_HALF_LEN);
|
||||
memcpy(verify_repeater_in.receiver_ids, rep_topology->receiver_ids,
|
||||
HDCP_2_2_RECEIVER_IDS_MAX_LEN);
|
||||
|
||||
byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&verify_repeater_in,
|
||||
sizeof(verify_repeater_in),
|
||||
(u8 *)&verify_repeater_out,
|
||||
sizeof(verify_repeater_out));
|
||||
if (byte < 0) {
|
||||
drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
|
||||
return byte;
|
||||
}
|
||||
|
||||
if (verify_repeater_out.header.status != FW_HDCP_STATUS_SUCCESS) {
|
||||
drm_dbg_kms(&i915->drm, "FW cmd 0x%08X failed. status: 0x%X\n",
|
||||
WIRED_VERIFY_REPEATER,
|
||||
verify_repeater_out.header.status);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
memcpy(rep_send_ack->v, verify_repeater_out.v,
|
||||
HDCP_2_2_V_PRIME_HALF_LEN);
|
||||
rep_send_ack->msg_id = HDCP_2_2_REP_SEND_ACK;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int intel_hdcp_gsc_verify_mprime(struct device *dev,
|
||||
struct hdcp_port_data *data,
|
||||
struct hdcp2_rep_stream_ready *stream_ready)
|
||||
{
|
||||
struct wired_cmd_repeater_auth_stream_req_in *verify_mprime_in;
|
||||
struct wired_cmd_repeater_auth_stream_req_out
|
||||
verify_mprime_out = { { 0 } };
|
||||
struct drm_i915_private *i915;
|
||||
ssize_t byte;
|
||||
size_t cmd_size;
|
||||
|
||||
if (!dev || !stream_ready || !data)
|
||||
return -EINVAL;
|
||||
|
||||
i915 = kdev_to_i915(dev);
|
||||
if (!i915) {
|
||||
dev_err(dev, "DRM not initialized, aborting HDCP.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
cmd_size = struct_size(verify_mprime_in, streams, data->k);
|
||||
if (cmd_size == SIZE_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
verify_mprime_in = kzalloc(cmd_size, GFP_KERNEL);
|
||||
if (!verify_mprime_in)
|
||||
return -ENOMEM;
|
||||
|
||||
verify_mprime_in->header.api_version = HDCP_API_VERSION;
|
||||
verify_mprime_in->header.command_id = WIRED_REPEATER_AUTH_STREAM_REQ;
|
||||
verify_mprime_in->header.status = FW_HDCP_STATUS_SUCCESS;
|
||||
verify_mprime_in->header.buffer_len = cmd_size - sizeof(verify_mprime_in->header);
|
||||
|
||||
verify_mprime_in->port.integrated_port_type = data->port_type;
|
||||
verify_mprime_in->port.physical_port = (u8)data->hdcp_ddi;
|
||||
verify_mprime_in->port.attached_transcoder = (u8)data->hdcp_transcoder;
|
||||
|
||||
memcpy(verify_mprime_in->m_prime, stream_ready->m_prime, HDCP_2_2_MPRIME_LEN);
|
||||
drm_hdcp_cpu_to_be24(verify_mprime_in->seq_num_m, data->seq_num_m);
|
||||
|
||||
memcpy(verify_mprime_in->streams, data->streams,
|
||||
array_size(data->k, sizeof(*data->streams)));
|
||||
|
||||
verify_mprime_in->k = cpu_to_be16(data->k);
|
||||
|
||||
byte = intel_hdcp_gsc_msg_send(i915, (u8 *)verify_mprime_in, cmd_size,
|
||||
(u8 *)&verify_mprime_out,
|
||||
sizeof(verify_mprime_out));
|
||||
kfree(verify_mprime_in);
|
||||
if (byte < 0) {
|
||||
drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
|
||||
return byte;
|
||||
}
|
||||
|
||||
if (verify_mprime_out.header.status != FW_HDCP_STATUS_SUCCESS) {
|
||||
drm_dbg_kms(&i915->drm, "FW cmd 0x%08X failed. status: 0x%X\n",
|
||||
WIRED_REPEATER_AUTH_STREAM_REQ,
|
||||
verify_mprime_out.header.status);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int intel_hdcp_gsc_enable_authentication(struct device *dev,
|
||||
struct hdcp_port_data *data)
|
||||
{
|
||||
struct wired_cmd_enable_auth_in enable_auth_in = { { 0 } };
|
||||
struct wired_cmd_enable_auth_out enable_auth_out = { { 0 } };
|
||||
struct drm_i915_private *i915;
|
||||
ssize_t byte;
|
||||
|
||||
if (!dev || !data)
|
||||
return -EINVAL;
|
||||
|
||||
i915 = kdev_to_i915(dev);
|
||||
if (!i915) {
|
||||
dev_err(dev, "DRM not initialized, aborting HDCP.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
enable_auth_in.header.api_version = HDCP_API_VERSION;
|
||||
enable_auth_in.header.command_id = WIRED_ENABLE_AUTH;
|
||||
enable_auth_in.header.status = FW_HDCP_STATUS_SUCCESS;
|
||||
enable_auth_in.header.buffer_len = WIRED_CMD_BUF_LEN_ENABLE_AUTH_IN;
|
||||
|
||||
enable_auth_in.port.integrated_port_type = data->port_type;
|
||||
enable_auth_in.port.physical_port = (u8)data->hdcp_ddi;
|
||||
enable_auth_in.port.attached_transcoder = (u8)data->hdcp_transcoder;
|
||||
enable_auth_in.stream_type = data->streams[0].stream_type;
|
||||
|
||||
byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&enable_auth_in,
|
||||
sizeof(enable_auth_in),
|
||||
(u8 *)&enable_auth_out,
|
||||
sizeof(enable_auth_out));
|
||||
if (byte < 0) {
|
||||
drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
|
||||
return byte;
|
||||
}
|
||||
|
||||
if (enable_auth_out.header.status != FW_HDCP_STATUS_SUCCESS) {
|
||||
drm_dbg_kms(&i915->drm, "FW cmd 0x%08X failed. status: 0x%X\n",
|
||||
WIRED_ENABLE_AUTH, enable_auth_out.header.status);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
intel_hdcp_gsc_close_session(struct device *dev, struct hdcp_port_data *data)
|
||||
{
|
||||
struct wired_cmd_close_session_in session_close_in = { { 0 } };
|
||||
struct wired_cmd_close_session_out session_close_out = { { 0 } };
|
||||
struct drm_i915_private *i915;
|
||||
ssize_t byte;
|
||||
|
||||
if (!dev || !data)
|
||||
return -EINVAL;
|
||||
|
||||
i915 = kdev_to_i915(dev);
|
||||
if (!i915) {
|
||||
dev_err(dev, "DRM not initialized, aborting HDCP.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
session_close_in.header.api_version = HDCP_API_VERSION;
|
||||
session_close_in.header.command_id = WIRED_CLOSE_SESSION;
|
||||
session_close_in.header.status = FW_HDCP_STATUS_SUCCESS;
|
||||
session_close_in.header.buffer_len =
|
||||
WIRED_CMD_BUF_LEN_CLOSE_SESSION_IN;
|
||||
|
||||
session_close_in.port.integrated_port_type = data->port_type;
|
||||
session_close_in.port.physical_port = (u8)data->hdcp_ddi;
|
||||
session_close_in.port.attached_transcoder = (u8)data->hdcp_transcoder;
|
||||
|
||||
byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&session_close_in,
|
||||
sizeof(session_close_in),
|
||||
(u8 *)&session_close_out,
|
||||
sizeof(session_close_out));
|
||||
if (byte < 0) {
|
||||
drm_dbg_kms(&i915->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
|
||||
return byte;
|
||||
}
|
||||
|
||||
if (session_close_out.header.status != FW_HDCP_STATUS_SUCCESS) {
|
||||
drm_dbg_kms(&i915->drm, "Session Close Failed. status: 0x%X\n",
|
||||
session_close_out.header.status);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
72
drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.h
Normal file
72
drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.h
Normal file
@ -0,0 +1,72 @@
|
||||
/* 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__ */
|
||||
|
@ -13,6 +13,7 @@ struct drm_i915_private;
|
||||
struct intel_overlay;
|
||||
struct intel_overlay_error_state;
|
||||
|
||||
#ifdef I915
|
||||
void intel_overlay_setup(struct drm_i915_private *dev_priv);
|
||||
void intel_overlay_cleanup(struct drm_i915_private *dev_priv);
|
||||
int intel_overlay_switch_off(struct intel_overlay *overlay);
|
||||
@ -25,5 +26,39 @@ struct intel_overlay_error_state *
|
||||
intel_overlay_capture_error_state(struct drm_i915_private *dev_priv);
|
||||
void intel_overlay_print_error_state(struct drm_i915_error_state_buf *e,
|
||||
struct intel_overlay_error_state *error);
|
||||
#else
|
||||
static inline void intel_overlay_setup(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
}
|
||||
static inline void intel_overlay_cleanup(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
}
|
||||
static inline int intel_overlay_switch_off(struct intel_overlay *overlay)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline int intel_overlay_put_image_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline int intel_overlay_attrs_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void intel_overlay_reset(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
}
|
||||
static inline struct intel_overlay_error_state *
|
||||
intel_overlay_capture_error_state(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static inline void intel_overlay_print_error_state(struct drm_i915_error_state_buf *e,
|
||||
struct intel_overlay_error_state *error)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __INTEL_OVERLAY_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;
|
||||
|
@ -15,6 +15,7 @@ struct intel_crtc;
|
||||
struct intel_crtc_state;
|
||||
struct intel_link_m_n;
|
||||
|
||||
#ifdef I915
|
||||
bool intel_has_pch_trancoder(struct drm_i915_private *i915,
|
||||
enum pipe pch_transcoder);
|
||||
enum pipe intel_crtc_pch_transcoder(struct intel_crtc *crtc);
|
||||
@ -41,5 +42,57 @@ void intel_pch_transcoder_get_m2_n2(struct intel_crtc *crtc,
|
||||
struct intel_link_m_n *m_n);
|
||||
|
||||
void intel_pch_sanitize(struct drm_i915_private *i915);
|
||||
#else
|
||||
static inline bool intel_has_pch_trancoder(struct drm_i915_private *i915,
|
||||
enum pipe pch_transcoder)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
static inline int intel_crtc_pch_transcoder(struct intel_crtc *crtc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void ilk_pch_pre_enable(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
}
|
||||
static inline void ilk_pch_enable(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
}
|
||||
static inline void ilk_pch_disable(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
}
|
||||
static inline void ilk_pch_post_disable(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
}
|
||||
static inline void ilk_pch_get_config(struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
}
|
||||
static inline void lpt_pch_enable(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
}
|
||||
static inline void lpt_pch_disable(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
}
|
||||
static inline void lpt_pch_get_config(struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
}
|
||||
static inline void intel_pch_transcoder_get_m1_n1(struct intel_crtc *crtc,
|
||||
struct intel_link_m_n *m_n)
|
||||
{
|
||||
}
|
||||
static inline void intel_pch_transcoder_get_m2_n2(struct intel_crtc *crtc,
|
||||
struct intel_link_m_n *m_n)
|
||||
{
|
||||
}
|
||||
static inline void intel_pch_sanitize(struct drm_i915_private *i915)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -492,6 +492,7 @@ static void lpt_init_pch_refclk(struct drm_i915_private *dev_priv)
|
||||
static void ilk_init_pch_refclk(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct intel_encoder *encoder;
|
||||
struct intel_shared_dpll *pll;
|
||||
int i;
|
||||
u32 val, final;
|
||||
bool has_lvds = false;
|
||||
@ -527,8 +528,10 @@ static void ilk_init_pch_refclk(struct drm_i915_private *dev_priv)
|
||||
}
|
||||
|
||||
/* Check if any DPLLs are using the SSC source */
|
||||
for (i = 0; i < dev_priv->display.dpll.num_shared_dpll; i++) {
|
||||
u32 temp = intel_de_read(dev_priv, PCH_DPLL(i));
|
||||
for_each_shared_dpll(dev_priv, pll, i) {
|
||||
u32 temp;
|
||||
|
||||
temp = intel_de_read(dev_priv, PCH_DPLL(pll->info->id));
|
||||
|
||||
if (!(temp & DPLL_VCO_ENABLE))
|
||||
continue;
|
||||
|
@ -11,6 +11,7 @@
|
||||
struct drm_i915_private;
|
||||
struct intel_crtc_state;
|
||||
|
||||
#ifdef I915
|
||||
void lpt_program_iclkip(const struct intel_crtc_state *crtc_state);
|
||||
void lpt_disable_iclkip(struct drm_i915_private *dev_priv);
|
||||
int lpt_get_iclkip(struct drm_i915_private *dev_priv);
|
||||
@ -18,5 +19,27 @@ int lpt_iclkip(const struct intel_crtc_state *crtc_state);
|
||||
|
||||
void intel_init_pch_refclk(struct drm_i915_private *dev_priv);
|
||||
void lpt_disable_clkout_dp(struct drm_i915_private *dev_priv);
|
||||
#else
|
||||
static inline void lpt_program_iclkip(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
}
|
||||
static inline void lpt_disable_iclkip(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
}
|
||||
static inline int lpt_get_iclkip(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline int lpt_iclkip(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void intel_init_pch_refclk(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
}
|
||||
static inline void lpt_disable_clkout_dp(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -2195,10 +2195,12 @@ void intel_psr_pre_plane_update(struct intel_atomic_state *state,
|
||||
}
|
||||
}
|
||||
|
||||
static void _intel_psr_post_plane_update(const struct intel_atomic_state *state,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
void intel_psr_post_plane_update(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
|
||||
const struct intel_crtc_state *crtc_state =
|
||||
intel_atomic_get_new_crtc_state(state, crtc);
|
||||
struct intel_encoder *encoder;
|
||||
|
||||
if (!crtc_state->has_psr)
|
||||
@ -2241,20 +2243,6 @@ static void _intel_psr_post_plane_update(const struct intel_atomic_state *state,
|
||||
}
|
||||
}
|
||||
|
||||
void intel_psr_post_plane_update(const struct intel_atomic_state *state)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
|
||||
struct intel_crtc_state *crtc_state;
|
||||
struct intel_crtc *crtc;
|
||||
int i;
|
||||
|
||||
if (!HAS_PSR(dev_priv))
|
||||
return;
|
||||
|
||||
for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i)
|
||||
_intel_psr_post_plane_update(state, crtc_state);
|
||||
}
|
||||
|
||||
static int _psr2_ready_for_pipe_update_locked(struct intel_dp *intel_dp)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
|
||||
|
@ -24,7 +24,8 @@ struct intel_plane_state;
|
||||
void intel_psr_init_dpcd(struct intel_dp *intel_dp);
|
||||
void intel_psr_pre_plane_update(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc);
|
||||
void intel_psr_post_plane_update(const struct intel_atomic_state *state);
|
||||
void intel_psr_post_plane_update(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc);
|
||||
void intel_psr_disable(struct intel_dp *intel_dp,
|
||||
const struct intel_crtc_state *old_crtc_state);
|
||||
int intel_psr_debug_set(struct intel_dp *intel_dp, u64 value);
|
||||
|
@ -2121,7 +2121,7 @@ intel_sdvo_detect(struct drm_connector *connector, bool force)
|
||||
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
|
||||
connector->base.id, connector->name);
|
||||
|
||||
if (!INTEL_DISPLAY_ENABLED(i915))
|
||||
if (!intel_display_device_enabled(i915))
|
||||
return connector_status_disconnected;
|
||||
|
||||
if (!intel_sdvo_set_target_output(intel_sdvo,
|
||||
|
@ -14,9 +14,22 @@ struct drm_i915_private;
|
||||
enum pipe;
|
||||
enum port;
|
||||
|
||||
#ifdef I915
|
||||
bool intel_sdvo_port_enabled(struct drm_i915_private *dev_priv,
|
||||
i915_reg_t sdvo_reg, enum pipe *pipe);
|
||||
bool intel_sdvo_init(struct drm_i915_private *dev_priv,
|
||||
i915_reg_t reg, enum port port);
|
||||
#else
|
||||
static inline bool intel_sdvo_port_enabled(struct drm_i915_private *dev_priv,
|
||||
i915_reg_t sdvo_reg, enum pipe *pipe)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
static inline bool intel_sdvo_init(struct drm_i915_private *dev_priv,
|
||||
i915_reg_t reg, enum port port)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __INTEL_SDVO_H__ */
|
||||
|
@ -1993,12 +1993,13 @@ int intel_snps_phy_check_hdmi_link_rate(int clock)
|
||||
}
|
||||
|
||||
void intel_mpllb_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_mpllb_state mpllb_hw_state = { 0 };
|
||||
struct intel_mpllb_state *mpllb_sw_state = &new_crtc_state->mpllb_state;
|
||||
struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
|
||||
const struct intel_mpllb_state *mpllb_sw_state = &new_crtc_state->mpllb_state;
|
||||
struct intel_encoder *encoder;
|
||||
|
||||
if (!IS_DG2(i915))
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
struct drm_i915_private;
|
||||
struct intel_atomic_state;
|
||||
struct intel_crtc;
|
||||
struct intel_crtc_state;
|
||||
struct intel_encoder;
|
||||
struct intel_mpllb_state;
|
||||
@ -33,6 +34,6 @@ int intel_snps_phy_check_hdmi_link_rate(int clock);
|
||||
void intel_snps_phy_set_signal_levels(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state);
|
||||
void intel_mpllb_state_verify(struct intel_atomic_state *state,
|
||||
struct intel_crtc_state *new_crtc_state);
|
||||
struct intel_crtc *crtc);
|
||||
|
||||
#endif /* __INTEL_SNPS_PHY_H__ */
|
||||
|
@ -16,6 +16,7 @@ struct intel_crtc_state;
|
||||
struct intel_plane_state;
|
||||
enum pipe;
|
||||
|
||||
#ifdef I915
|
||||
struct intel_plane *intel_sprite_plane_create(struct drm_i915_private *dev_priv,
|
||||
enum pipe pipe, int plane);
|
||||
int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data,
|
||||
@ -29,5 +30,12 @@ int hsw_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
|
||||
const struct intel_plane_state *plane_state);
|
||||
int vlv_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
|
||||
const struct intel_plane_state *plane_state);
|
||||
#else
|
||||
static inline struct intel_plane *intel_sprite_plane_create(struct drm_i915_private *dev_priv,
|
||||
int pipe, int plane)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __INTEL_SPRITE_H__ */
|
||||
|
@ -1720,7 +1720,7 @@ intel_tv_detect(struct drm_connector *connector,
|
||||
drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] force=%d\n",
|
||||
connector->base.id, connector->name, force);
|
||||
|
||||
if (!INTEL_DISPLAY_ENABLED(i915))
|
||||
if (!intel_display_device_enabled(i915))
|
||||
return connector_status_disconnected;
|
||||
|
||||
if (force) {
|
||||
|
@ -8,6 +8,12 @@
|
||||
|
||||
struct drm_i915_private;
|
||||
|
||||
#ifdef I915
|
||||
void intel_tv_init(struct drm_i915_private *dev_priv);
|
||||
#else
|
||||
static inline void intel_tv_init(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __INTEL_TV_H__ */
|
||||
|
@ -3,11 +3,9 @@
|
||||
* Copyright © 2019 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/pci.h>
|
||||
#include <linux/vgaarb.h>
|
||||
|
||||
#include <video/vga.h>
|
||||
|
||||
#include "soc/intel_gmch.h"
|
||||
|
||||
#include "i915_drv.h"
|
||||
@ -99,20 +97,6 @@ void intel_vga_reset_io_mem(struct drm_i915_private *i915)
|
||||
vga_put(pdev, VGA_RSRC_LEGACY_IO);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
intel_vga_set_decode(struct pci_dev *pdev, bool enable_decode)
|
||||
{
|
||||
struct drm_i915_private *i915 = pdev_to_i915(pdev);
|
||||
|
||||
intel_gmch_vga_set_state(i915, enable_decode);
|
||||
|
||||
if (enable_decode)
|
||||
return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
|
||||
VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
|
||||
else
|
||||
return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
|
||||
}
|
||||
|
||||
int intel_vga_register(struct drm_i915_private *i915)
|
||||
{
|
||||
|
||||
@ -127,7 +111,7 @@ int intel_vga_register(struct drm_i915_private *i915)
|
||||
* then we do not take part in VGA arbitration and the
|
||||
* vga_client_register() fails with -ENODEV.
|
||||
*/
|
||||
ret = vga_client_register(pdev, intel_vga_set_decode);
|
||||
ret = vga_client_register(pdev, intel_gmch_vga_set_decode);
|
||||
if (ret && ret != -ENODEV)
|
||||
return ret;
|
||||
|
||||
|
@ -1943,13 +1943,16 @@ static enum intel_fbc_id skl_fbc_id_for_pipe(enum pipe pipe)
|
||||
return pipe - PIPE_A + INTEL_FBC_A;
|
||||
}
|
||||
|
||||
static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv,
|
||||
static bool skl_plane_has_fbc(struct drm_i915_private *i915,
|
||||
enum intel_fbc_id fbc_id, enum plane_id plane_id)
|
||||
{
|
||||
if ((DISPLAY_RUNTIME_INFO(dev_priv)->fbc_mask & BIT(fbc_id)) == 0)
|
||||
if ((DISPLAY_RUNTIME_INFO(i915)->fbc_mask & BIT(fbc_id)) == 0)
|
||||
return false;
|
||||
|
||||
return plane_id == PLANE_PRIMARY;
|
||||
if (DISPLAY_VER(i915) >= 20)
|
||||
return icl_is_hdr_plane(i915, plane_id);
|
||||
else
|
||||
return plane_id == PLANE_PRIMARY;
|
||||
}
|
||||
|
||||
static struct intel_fbc *skl_plane_fbc(struct drm_i915_private *dev_priv,
|
||||
|
@ -3134,10 +3134,12 @@ static void skl_wm_get_hw_state_and_sanitize(struct drm_i915_private *i915)
|
||||
skl_wm_sanitize(i915);
|
||||
}
|
||||
|
||||
void intel_wm_state_verify(struct intel_crtc *crtc,
|
||||
struct intel_crtc_state *new_crtc_state)
|
||||
void intel_wm_state_verify(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
|
||||
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 skl_hw_state {
|
||||
struct skl_ddb_entry ddb[I915_MAX_PLANES];
|
||||
struct skl_ddb_entry ddb_y[I915_MAX_PLANES];
|
||||
|
@ -38,8 +38,8 @@ bool skl_ddb_allocation_overlaps(const struct skl_ddb_entry *ddb,
|
||||
const struct skl_ddb_entry *entries,
|
||||
int num_entries, int ignore_idx);
|
||||
|
||||
void intel_wm_state_verify(struct intel_crtc *crtc,
|
||||
struct intel_crtc_state *new_crtc_state);
|
||||
void intel_wm_state_verify(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc);
|
||||
|
||||
void skl_watermark_ipc_init(struct drm_i915_private *i915);
|
||||
void skl_watermark_ipc_update(struct drm_i915_private *i915);
|
||||
|
@ -23,6 +23,7 @@
|
||||
* Author: Jani Nikula <jani.nikula@intel.com>
|
||||
*/
|
||||
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
@ -1744,6 +1745,126 @@ static void vlv_dphy_param_init(struct intel_dsi *intel_dsi)
|
||||
intel_dsi_log_params(intel_dsi);
|
||||
}
|
||||
|
||||
typedef void (*vlv_dsi_dmi_quirk_func)(struct intel_dsi *intel_dsi);
|
||||
|
||||
/*
|
||||
* Vtotal is wrong on the Asus TF103C leading to the last line of the display
|
||||
* being shown as the first line. The factory installed Android has a hardcoded
|
||||
* modeline, causing it to not suffer from this BIOS bug.
|
||||
*
|
||||
* Original mode: "1280x800": 60 67700 1280 1312 1328 1376 800 808 812 820 0x8 0xa
|
||||
* Fixed mode: "1280x800": 60 67700 1280 1312 1328 1376 800 808 812 816 0x8 0xa
|
||||
*
|
||||
* https://gitlab.freedesktop.org/drm/intel/-/issues/9381
|
||||
*/
|
||||
static void vlv_dsi_asus_tf103c_mode_fixup(struct intel_dsi *intel_dsi)
|
||||
{
|
||||
/* Cast away the const as we want to fixup the mode */
|
||||
struct drm_display_mode *fixed_mode = (struct drm_display_mode *)
|
||||
intel_panel_preferred_fixed_mode(intel_dsi->attached_connector);
|
||||
|
||||
if (fixed_mode->vtotal == 820)
|
||||
fixed_mode->vtotal -= 4;
|
||||
}
|
||||
|
||||
/*
|
||||
* On the Lenovo Yoga Tablet 2 830 / 1050 there are 2 problems:
|
||||
* 1. The I2C MIPI sequence elements reference bus 3. ACPI has I2C1 - I2C7
|
||||
* which under Linux become bus 0 - 6. And the MIPI sequence reference
|
||||
* to bus 3 is indented for I2C3 which is bus 2 under Linux.
|
||||
*
|
||||
* Note mipi_exec_i2c() cannot just subtract 1 from the bus
|
||||
* given in the I2C MIPI sequence element. Since on other
|
||||
* devices the I2C bus-numbers used in the MIPI sequences do
|
||||
* actually start at 0.
|
||||
*
|
||||
* 2. width_/height_mm contain a bogus 192mm x 120mm size. This is
|
||||
* especially a problem on the 8" 830 version which uses a 10:16
|
||||
* portrait screen where as the bogus size is 16:10.
|
||||
*
|
||||
* https://gitlab.freedesktop.org/drm/intel/-/issues/9379
|
||||
*/
|
||||
static void vlv_dsi_lenovo_yoga_tab2_size_fixup(struct intel_dsi *intel_dsi)
|
||||
{
|
||||
const struct drm_display_mode *fixed_mode =
|
||||
intel_panel_preferred_fixed_mode(intel_dsi->attached_connector);
|
||||
struct drm_display_info *info = &intel_dsi->attached_connector->base.display_info;
|
||||
|
||||
intel_dsi->i2c_bus_num = 2;
|
||||
|
||||
/*
|
||||
* The 10" 1050 uses a 1920x1200 landscape screen, where as the 8" 830
|
||||
* uses a 1200x1920 portrait screen.
|
||||
*/
|
||||
if (fixed_mode->hdisplay == 1920) {
|
||||
info->width_mm = 216;
|
||||
info->height_mm = 135;
|
||||
} else {
|
||||
info->width_mm = 107;
|
||||
info->height_mm = 171;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* On the Lenovo Yoga Tab 3 Pro YT3-X90F there are 2 problems:
|
||||
* 1. i2c_acpi_find_adapter() picks the wrong adapter causing mipi_exec_i2c()
|
||||
* to not work. Fix this by setting i2c_bus_num.
|
||||
* 2. There is no backlight off MIPI sequence, causing the backlight to stay on.
|
||||
* Add a backlight off sequence mirroring the existing backlight on sequence.
|
||||
*
|
||||
* https://gitlab.freedesktop.org/drm/intel/-/issues/9380
|
||||
*/
|
||||
static void vlv_dsi_lenovo_yoga_tab3_backlight_fixup(struct intel_dsi *intel_dsi)
|
||||
{
|
||||
static const u8 backlight_off_sequence[16] = {
|
||||
/* Header Seq-id 7, length after header 11 bytes */
|
||||
0x07, 0x0b, 0x00, 0x00, 0x00,
|
||||
/* MIPI_SEQ_ELEM_I2C bus 0 addr 0x2c reg 0x00 data-len 1 data 0x00 */
|
||||
0x04, 0x08, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x01, 0x00,
|
||||
/* MIPI_SEQ_ELEM_END */
|
||||
0x00
|
||||
};
|
||||
struct intel_connector *connector = intel_dsi->attached_connector;
|
||||
|
||||
intel_dsi->i2c_bus_num = 0;
|
||||
connector->panel.vbt.dsi.sequence[MIPI_SEQ_BACKLIGHT_OFF] = backlight_off_sequence;
|
||||
}
|
||||
|
||||
static const struct dmi_system_id vlv_dsi_dmi_quirk_table[] = {
|
||||
{
|
||||
/* Asus Transformer Pad TF103C */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "TF103C"),
|
||||
},
|
||||
.driver_data = (void *)vlv_dsi_asus_tf103c_mode_fixup,
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Lenovo Yoga Tablet 2 830F/L or 1050F/L (The 8" and 10"
|
||||
* Lenovo Yoga Tablet 2 use the same mainboard)
|
||||
*/
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Intel Corp."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "VALLEYVIEW C0 PLATFORM"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "BYT-T FFD8"),
|
||||
/* Partial match on beginning of BIOS version */
|
||||
DMI_MATCH(DMI_BIOS_VERSION, "BLADE_21"),
|
||||
},
|
||||
.driver_data = (void *)vlv_dsi_lenovo_yoga_tab2_size_fixup,
|
||||
},
|
||||
{
|
||||
/* Lenovo Yoga Tab 3 Pro YT3-X90F */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"),
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "Blade3-10A-001"),
|
||||
},
|
||||
.driver_data = (void *)vlv_dsi_lenovo_yoga_tab3_backlight_fixup,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
void vlv_dsi_init(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct intel_dsi *intel_dsi;
|
||||
@ -1752,6 +1873,7 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv)
|
||||
struct intel_connector *intel_connector;
|
||||
struct drm_connector *connector;
|
||||
struct drm_display_mode *current_mode;
|
||||
const struct dmi_system_id *dmi_id;
|
||||
enum port port;
|
||||
enum pipe pipe;
|
||||
|
||||
@ -1883,6 +2005,14 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv)
|
||||
goto err_cleanup_connector;
|
||||
}
|
||||
|
||||
dmi_id = dmi_first_match(vlv_dsi_dmi_quirk_table);
|
||||
if (dmi_id) {
|
||||
vlv_dsi_dmi_quirk_func quirk_func =
|
||||
(vlv_dsi_dmi_quirk_func)dmi_id->driver_data;
|
||||
|
||||
quirk_func(intel_dsi);
|
||||
}
|
||||
|
||||
intel_panel_init(intel_connector, NULL);
|
||||
|
||||
intel_backlight_setup(intel_connector, INVALID_PIPE);
|
||||
|
@ -12,8 +12,21 @@ enum port;
|
||||
struct drm_i915_private;
|
||||
struct intel_dsi;
|
||||
|
||||
#ifdef I915
|
||||
void vlv_dsi_wait_for_fifo_empty(struct intel_dsi *intel_dsi, enum port port);
|
||||
enum mipi_dsi_pixel_format pixel_format_from_register_bits(u32 fmt);
|
||||
void vlv_dsi_init(struct drm_i915_private *dev_priv);
|
||||
#else
|
||||
static inline void vlv_dsi_wait_for_fifo_empty(struct intel_dsi *intel_dsi, enum port port)
|
||||
{
|
||||
}
|
||||
static inline enum mipi_dsi_pixel_format pixel_format_from_register_bits(u32 fmt)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void vlv_dsi_init(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __VLV_DSI_H__ */
|
||||
|
@ -32,7 +32,16 @@ u32 bxt_dsi_get_pclk(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *config);
|
||||
void bxt_dsi_reset_clocks(struct intel_encoder *encoder, enum port port);
|
||||
|
||||
#ifdef I915
|
||||
void assert_dsi_pll_enabled(struct drm_i915_private *i915);
|
||||
void assert_dsi_pll_disabled(struct drm_i915_private *i915);
|
||||
#else
|
||||
static inline void assert_dsi_pll_enabled(struct drm_i915_private *i915)
|
||||
{
|
||||
}
|
||||
static inline void assert_dsi_pll_disabled(struct drm_i915_private *i915)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __VLV_DSI_PLL_H__ */
|
||||
|
@ -62,7 +62,13 @@ void intel_gt_common_init_early(struct intel_gt *gt)
|
||||
/* Preliminary initialization of Tile 0 */
|
||||
int intel_root_gt_init_early(struct drm_i915_private *i915)
|
||||
{
|
||||
struct intel_gt *gt = to_gt(i915);
|
||||
struct intel_gt *gt;
|
||||
|
||||
gt = drmm_kzalloc(&i915->drm, sizeof(*gt), GFP_KERNEL);
|
||||
if (!gt)
|
||||
return -ENOMEM;
|
||||
|
||||
i915->gt[0] = gt;
|
||||
|
||||
gt->i915 = i915;
|
||||
gt->uncore = &i915->uncore;
|
||||
@ -911,8 +917,6 @@ int intel_gt_probe_all(struct drm_i915_private *i915)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
i915->gt[0] = gt;
|
||||
|
||||
if (!HAS_EXTRA_GT_LIST(i915))
|
||||
return 0;
|
||||
|
||||
|
@ -487,7 +487,7 @@ static bool has_mocs(const struct drm_i915_private *i915)
|
||||
return !IS_DGFX(i915);
|
||||
}
|
||||
|
||||
static unsigned int get_mocs_settings(const struct drm_i915_private *i915,
|
||||
static unsigned int get_mocs_settings(struct drm_i915_private *i915,
|
||||
struct drm_i915_mocs_table *table)
|
||||
{
|
||||
unsigned int flags;
|
||||
@ -495,7 +495,7 @@ static unsigned int get_mocs_settings(const struct drm_i915_private *i915,
|
||||
memset(table, 0, sizeof(struct drm_i915_mocs_table));
|
||||
|
||||
table->unused_entries_index = I915_MOCS_PTE;
|
||||
if (IS_GFX_GT_IP_RANGE(&i915->gt0, IP_VER(12, 70), IP_VER(12, 71))) {
|
||||
if (IS_GFX_GT_IP_RANGE(to_gt(i915), IP_VER(12, 70), IP_VER(12, 71))) {
|
||||
table->size = ARRAY_SIZE(mtl_mocs_table);
|
||||
table->table = mtl_mocs_table;
|
||||
table->n_entries = MTL_NUM_MOCS_ENTRIES;
|
||||
|
@ -39,7 +39,7 @@
|
||||
|
||||
#include <asm/kvm_page_track.h>
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "gt/intel_gt.h"
|
||||
#include "intel_gvt.h"
|
||||
|
||||
#include "debug.h"
|
||||
@ -60,6 +60,8 @@
|
||||
|
||||
#define GVT_MAX_VGPU 8
|
||||
|
||||
struct engine_mmio;
|
||||
|
||||
/* Describe per-platform limitations. */
|
||||
struct intel_gvt_device_info {
|
||||
u32 max_support_vgpus;
|
||||
@ -368,11 +370,6 @@ struct intel_gvt {
|
||||
struct dentry *debugfs_root;
|
||||
};
|
||||
|
||||
static inline struct intel_gvt *to_gvt(struct drm_i915_private *i915)
|
||||
{
|
||||
return i915->gvt;
|
||||
}
|
||||
|
||||
enum {
|
||||
/* Scheduling trigger by timer */
|
||||
INTEL_GVT_REQUEST_SCHED = 0,
|
||||
|
@ -36,6 +36,23 @@
|
||||
#include "gvt.h"
|
||||
#include "trace.h"
|
||||
|
||||
struct intel_gvt_irq_info {
|
||||
char *name;
|
||||
i915_reg_t reg_base;
|
||||
enum intel_gvt_event_type bit_to_event[INTEL_GVT_IRQ_BITWIDTH];
|
||||
unsigned long warned;
|
||||
int group;
|
||||
DECLARE_BITMAP(downstream_irq_bitmap, INTEL_GVT_IRQ_BITWIDTH);
|
||||
bool has_upstream_irq;
|
||||
};
|
||||
|
||||
struct intel_gvt_irq_map {
|
||||
int up_irq_group;
|
||||
int up_irq_bit;
|
||||
int down_irq_group;
|
||||
u32 down_irq_bitmask;
|
||||
};
|
||||
|
||||
/* common offset among interrupt control registers */
|
||||
#define regbase_to_isr(base) (base)
|
||||
#define regbase_to_imr(base) (base + 0x4)
|
||||
|
@ -32,10 +32,13 @@
|
||||
#ifndef _GVT_INTERRUPT_H_
|
||||
#define _GVT_INTERRUPT_H_
|
||||
|
||||
#include <linux/hrtimer.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/bitops.h>
|
||||
|
||||
#include "i915_reg_defs.h"
|
||||
struct intel_gvt;
|
||||
struct intel_gvt_irq;
|
||||
struct intel_gvt_irq_info;
|
||||
struct intel_gvt_irq_map;
|
||||
struct intel_vgpu;
|
||||
|
||||
enum intel_gvt_event_type {
|
||||
RCS_MI_USER_INTERRUPT = 0,
|
||||
@ -138,10 +141,6 @@ enum intel_gvt_event_type {
|
||||
INTEL_GVT_EVENT_MAX,
|
||||
};
|
||||
|
||||
struct intel_gvt_irq;
|
||||
struct intel_gvt;
|
||||
struct intel_vgpu;
|
||||
|
||||
typedef void (*gvt_event_virt_handler_t)(struct intel_gvt_irq *irq,
|
||||
enum intel_gvt_event_type event, struct intel_vgpu *vgpu);
|
||||
|
||||
@ -175,17 +174,6 @@ enum intel_gvt_irq_type {
|
||||
|
||||
#define INTEL_GVT_IRQ_BITWIDTH 32
|
||||
|
||||
/* device specific interrupt bit definitions */
|
||||
struct intel_gvt_irq_info {
|
||||
char *name;
|
||||
i915_reg_t reg_base;
|
||||
enum intel_gvt_event_type bit_to_event[INTEL_GVT_IRQ_BITWIDTH];
|
||||
unsigned long warned;
|
||||
int group;
|
||||
DECLARE_BITMAP(downstream_irq_bitmap, INTEL_GVT_IRQ_BITWIDTH);
|
||||
bool has_upstream_irq;
|
||||
};
|
||||
|
||||
/* per-event information */
|
||||
struct intel_gvt_event_info {
|
||||
int bit; /* map to register bit */
|
||||
@ -194,13 +182,6 @@ struct intel_gvt_event_info {
|
||||
gvt_event_virt_handler_t v_handler; /* for v_event */
|
||||
};
|
||||
|
||||
struct intel_gvt_irq_map {
|
||||
int up_irq_group;
|
||||
int up_irq_bit;
|
||||
int down_irq_group;
|
||||
u32 down_irq_bitmask;
|
||||
};
|
||||
|
||||
/* structure containing device specific IRQ state */
|
||||
struct intel_gvt_irq {
|
||||
const struct intel_gvt_irq_ops *ops;
|
||||
|
@ -45,6 +45,14 @@
|
||||
|
||||
#define GEN9_MOCS_SIZE 64
|
||||
|
||||
struct engine_mmio {
|
||||
enum intel_engine_id id;
|
||||
i915_reg_t reg;
|
||||
u32 mask;
|
||||
bool in_context;
|
||||
u32 value;
|
||||
};
|
||||
|
||||
/* Raw offset is appened to each line for convenience. */
|
||||
static struct engine_mmio gen8_engine_mmio_list[] __cacheline_aligned = {
|
||||
{RCS0, RING_MODE_GEN7(RENDER_RING_BASE), 0xffff, false}, /* 0x229c */
|
||||
|
@ -39,8 +39,6 @@
|
||||
#include <linux/types.h>
|
||||
|
||||
#include "gt/intel_engine_regs.h"
|
||||
#include "gt/intel_engine_types.h"
|
||||
#include "gt/intel_lrc_reg.h"
|
||||
|
||||
struct i915_request;
|
||||
struct intel_context;
|
||||
@ -48,14 +46,6 @@ struct intel_engine_cs;
|
||||
struct intel_gvt;
|
||||
struct intel_vgpu;
|
||||
|
||||
struct engine_mmio {
|
||||
enum intel_engine_id id;
|
||||
i915_reg_t reg;
|
||||
u32 mask;
|
||||
bool in_context;
|
||||
u32 value;
|
||||
};
|
||||
|
||||
void intel_gvt_switch_mmio(struct intel_vgpu *pre,
|
||||
struct intel_vgpu *next,
|
||||
const struct intel_engine_cs *engine);
|
||||
|
@ -338,6 +338,7 @@ static int i915_driver_mmio_probe(struct drm_i915_private *dev_priv)
|
||||
/* Try to make sure MCHBAR is enabled before poking at it */
|
||||
intel_gmch_bar_setup(dev_priv);
|
||||
intel_device_info_runtime_init(dev_priv);
|
||||
intel_display_device_info_runtime_init(dev_priv);
|
||||
|
||||
for_each_gt(gt, dev_priv, i) {
|
||||
ret = intel_gt_init_mmio(gt);
|
||||
|
@ -317,12 +317,6 @@ struct drm_i915_private {
|
||||
|
||||
struct i915_hwmon *hwmon;
|
||||
|
||||
/* Abstract the submission mechanism (legacy ringbuffer or execlists) away */
|
||||
struct intel_gt gt0;
|
||||
|
||||
/*
|
||||
* i915->gt[0] == &i915->gt0
|
||||
*/
|
||||
struct intel_gt *gt[I915_MAX_GT];
|
||||
|
||||
struct kobject *sysfs_gt;
|
||||
@ -382,9 +376,9 @@ static inline struct drm_i915_private *pdev_to_i915(struct pci_dev *pdev)
|
||||
return pci_get_drvdata(pdev);
|
||||
}
|
||||
|
||||
static inline struct intel_gt *to_gt(struct drm_i915_private *i915)
|
||||
static inline struct intel_gt *to_gt(const struct drm_i915_private *i915)
|
||||
{
|
||||
return &i915->gt0;
|
||||
return i915->gt[0];
|
||||
}
|
||||
|
||||
/* Simple iterator over all initialised engines */
|
||||
@ -416,8 +410,6 @@ static inline struct intel_gt *to_gt(struct drm_i915_private *i915)
|
||||
|
||||
#define INTEL_INFO(i915) ((i915)->__info)
|
||||
#define RUNTIME_INFO(i915) (&(i915)->__runtime)
|
||||
#define DISPLAY_INFO(i915) ((i915)->display.info.__device_info)
|
||||
#define DISPLAY_RUNTIME_INFO(i915) (&(i915)->display.info.__runtime_info)
|
||||
#define DRIVER_CAPS(i915) (&(i915)->caps)
|
||||
|
||||
#define INTEL_DEVID(i915) (RUNTIME_INFO(i915)->device_id)
|
||||
@ -436,12 +428,6 @@ static inline struct intel_gt *to_gt(struct drm_i915_private *i915)
|
||||
#define IS_MEDIA_VER(i915, from, until) \
|
||||
(MEDIA_VER(i915) >= (from) && MEDIA_VER(i915) <= (until))
|
||||
|
||||
#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))
|
||||
|
||||
#define INTEL_REVID(i915) (to_pci_dev((i915)->drm.dev)->revision)
|
||||
|
||||
#define INTEL_DISPLAY_STEP(__i915) (RUNTIME_INFO(__i915)->step.display_step)
|
||||
@ -790,12 +776,6 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
|
||||
#define NUM_L3_SLICES(i915) (IS_HASWELL_GT3(i915) ? \
|
||||
2 : HAS_L3_DPF(i915))
|
||||
|
||||
/* Only valid when HAS_DISPLAY() is true */
|
||||
#define INTEL_DISPLAY_ENABLED(i915) \
|
||||
(drm_WARN_ON(&(i915)->drm, !HAS_DISPLAY(i915)), \
|
||||
!(i915)->params.disable_display && \
|
||||
!intel_opregion_headless_sku(i915))
|
||||
|
||||
#define HAS_GUC_DEPRIVILEGE(i915) \
|
||||
(INTEL_INFO(i915)->has_guc_deprivilege)
|
||||
|
||||
|
@ -137,11 +137,6 @@ i915_param_named_unsafe(enable_ips, int, 0400, "Enable IPS (default: true)");
|
||||
i915_param_named_unsafe(enable_dpt, bool, 0400,
|
||||
"Enable display page table (DPT) (default: true)");
|
||||
|
||||
i915_param_named(fastboot, int, 0400,
|
||||
"Try to skip unnecessary mode sets at boot time "
|
||||
"(0=disabled, 1=enabled) "
|
||||
"Default: -1 (use per-chip default)");
|
||||
|
||||
i915_param_named_unsafe(load_detect_test, bool, 0400,
|
||||
"Force-enable the VGA load detect code for testing (default:false). "
|
||||
"For developers only.");
|
||||
|
@ -72,7 +72,6 @@ struct drm_printer;
|
||||
param(int, edp_vswing, 0, 0400) \
|
||||
param(unsigned int, reset, 3, 0600) \
|
||||
param(unsigned int, inject_probe_failure, 0, 0) \
|
||||
param(int, fastboot, -1, 0600) \
|
||||
param(int, enable_dpcd_backlight, -1, 0600) \
|
||||
param(char *, force_probe, CONFIG_DRM_I915_FORCE_PROBE, 0400) \
|
||||
param(unsigned int, request_timeout_ms, CONFIG_DRM_I915_REQUEST_TIMEOUT, CONFIG_DRM_I915_REQUEST_TIMEOUT ? 0600 : 0) \
|
||||
|
@ -696,12 +696,11 @@ static void i915_pmu_event_read(struct perf_event *event)
|
||||
event->hw.state = PERF_HES_STOPPED;
|
||||
return;
|
||||
}
|
||||
again:
|
||||
prev = local64_read(&hwc->prev_count);
|
||||
new = __i915_pmu_event_read(event);
|
||||
|
||||
if (local64_cmpxchg(&hwc->prev_count, prev, new) != prev)
|
||||
goto again;
|
||||
prev = local64_read(&hwc->prev_count);
|
||||
do {
|
||||
new = __i915_pmu_event_read(event);
|
||||
} while (!local64_try_cmpxchg(&hwc->prev_count, &prev, new));
|
||||
|
||||
local64_add(new - prev, &event->count);
|
||||
}
|
||||
|
@ -1327,6 +1327,8 @@
|
||||
#define DPFC_CTL_PLANE_IVB(i9xx_plane) REG_FIELD_PREP(DPFC_CTL_PLANE_MASK_IVB, (i9xx_plane))
|
||||
#define DPFC_CTL_FENCE_EN_IVB REG_BIT(28) /* ivb+ */
|
||||
#define DPFC_CTL_PERSISTENT_MODE REG_BIT(25) /* g4x-snb */
|
||||
#define DPFC_CTL_PLANE_BINDING_MASK REG_GENMASK(12, 11) /* lnl+ */
|
||||
#define DPFC_CTL_PLANE_BINDING(plane_id) REG_FIELD_PREP(DPFC_CTL_PLANE_BINDING_MASK, (plane_id))
|
||||
#define DPFC_CTL_FALSE_COLOR REG_BIT(10) /* ivb+ */
|
||||
#define DPFC_CTL_SR_EN REG_BIT(10) /* g4x only */
|
||||
#define DPFC_CTL_SR_EXIT_DIS REG_BIT(9) /* g4x only */
|
||||
@ -4678,6 +4680,13 @@
|
||||
#define TGL_DFSM_PIPE_D_DISABLE (1 << 22)
|
||||
#define GLK_DFSM_DISPLAY_DSC_DISABLE (1 << 7)
|
||||
|
||||
#define XE2LPD_DE_CAP _MMIO(0x41100)
|
||||
#define XE2LPD_DE_CAP_3DLUT_MASK REG_GENMASK(31, 30)
|
||||
#define XE2LPD_DE_CAP_DSC_MASK REG_GENMASK(29, 28)
|
||||
#define XE2LPD_DE_CAP_DSC_REMOVED 1
|
||||
#define XE2LPD_DE_CAP_SCALER_MASK REG_GENMASK(27, 26)
|
||||
#define XE2LPD_DE_CAP_SCALER_SINGLE 1
|
||||
|
||||
#define SKL_DSSM _MMIO(0x51004)
|
||||
#define ICL_DSSM_CDCLK_PLL_REFCLK_MASK (7 << 29)
|
||||
#define ICL_DSSM_CDCLK_PLL_REFCLK_24MHz (0 << 29)
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include <drm/drm_print.h>
|
||||
#include <drm/i915_pciids.h>
|
||||
|
||||
#include "display/intel_display_device.h"
|
||||
#include "gt/intel_gt_regs.h"
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
@ -232,19 +231,15 @@ static void intel_device_info_subplatform_init(struct drm_i915_private *i915)
|
||||
if (find_devid(devid, subplatform_ult_ids,
|
||||
ARRAY_SIZE(subplatform_ult_ids))) {
|
||||
mask = BIT(INTEL_SUBPLATFORM_ULT);
|
||||
if (IS_HASWELL(i915) || IS_BROADWELL(i915))
|
||||
DISPLAY_RUNTIME_INFO(i915)->port_mask &= ~BIT(PORT_D);
|
||||
} else if (find_devid(devid, subplatform_ulx_ids,
|
||||
ARRAY_SIZE(subplatform_ulx_ids))) {
|
||||
mask = BIT(INTEL_SUBPLATFORM_ULX);
|
||||
if (IS_HASWELL(i915) || IS_BROADWELL(i915)) {
|
||||
/* ULX machines are also considered ULT. */
|
||||
mask |= BIT(INTEL_SUBPLATFORM_ULT);
|
||||
DISPLAY_RUNTIME_INFO(i915)->port_mask &= ~BIT(PORT_D);
|
||||
}
|
||||
} else if (find_devid(devid, subplatform_portf_ids,
|
||||
ARRAY_SIZE(subplatform_portf_ids))) {
|
||||
DISPLAY_RUNTIME_INFO(i915)->port_mask |= BIT(PORT_F);
|
||||
mask = BIT(INTEL_SUBPLATFORM_PORTF);
|
||||
} else if (find_devid(devid, subplatform_uy_ids,
|
||||
ARRAY_SIZE(subplatform_uy_ids))) {
|
||||
@ -350,8 +345,6 @@ void intel_device_info_runtime_init_early(struct drm_i915_private *i915)
|
||||
intel_device_info_subplatform_init(i915);
|
||||
}
|
||||
|
||||
static const struct intel_display_device_info no_display = {};
|
||||
|
||||
/**
|
||||
* intel_device_info_runtime_init - initialize runtime info
|
||||
* @dev_priv: the i915 device
|
||||
@ -372,21 +365,6 @@ void intel_device_info_runtime_init(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct intel_runtime_info *runtime = RUNTIME_INFO(dev_priv);
|
||||
|
||||
if (HAS_DISPLAY(dev_priv))
|
||||
intel_display_device_info_runtime_init(dev_priv);
|
||||
|
||||
/* Display may have been disabled by runtime init */
|
||||
if (!HAS_DISPLAY(dev_priv)) {
|
||||
dev_priv->drm.driver_features &= ~(DRIVER_MODESET |
|
||||
DRIVER_ATOMIC);
|
||||
dev_priv->display.info.__device_info = &no_display;
|
||||
}
|
||||
|
||||
/* Disable nuclear pageflip by default on pre-g4x */
|
||||
if (!dev_priv->params.nuclear_pageflip &&
|
||||
DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv))
|
||||
dev_priv->drm.driver_features &= ~DRIVER_ATOMIC;
|
||||
|
||||
BUILD_BUG_ON(BITS_PER_TYPE(intel_engine_mask_t) < I915_NUM_ENGINES);
|
||||
|
||||
if (GRAPHICS_VER(dev_priv) == 6 && i915_vtd_active(dev_priv)) {
|
||||
|
@ -15,8 +15,9 @@
|
||||
#include "display/intel_psr_regs.h"
|
||||
#include "display/skl_watermark_regs.h"
|
||||
#include "display/vlv_dsi_pll_regs.h"
|
||||
#include "gt/intel_engine_regs.h"
|
||||
#include "gt/intel_gt_regs.h"
|
||||
#include "gvt/gvt.h"
|
||||
#include "gvt/reg.h"
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_pvinfo.h"
|
||||
|
@ -353,3 +353,8 @@ const char *intel_step_name(enum intel_step step)
|
||||
return "**";
|
||||
}
|
||||
}
|
||||
|
||||
const char *intel_display_step_name(struct drm_i915_private *i915)
|
||||
{
|
||||
return intel_step_name(RUNTIME_INFO(i915)->step.display_step);
|
||||
}
|
||||
|
@ -78,5 +78,6 @@ enum intel_step {
|
||||
|
||||
void intel_step_init(struct drm_i915_private *i915);
|
||||
const char *intel_step_name(enum intel_step step);
|
||||
const char *intel_display_step_name(struct drm_i915_private *i915);
|
||||
|
||||
#endif /* __INTEL_STEP_H__ */
|
||||
|
@ -114,7 +114,6 @@ static struct dev_pm_domain pm_domain = {
|
||||
|
||||
static void mock_gt_probe(struct drm_i915_private *i915)
|
||||
{
|
||||
i915->gt[0] = to_gt(i915);
|
||||
i915->gt[0]->name = "Mock GT";
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include <linux/pci.h>
|
||||
#include <linux/pnp.h>
|
||||
#include <linux/vgaarb.h>
|
||||
|
||||
#include <drm/drm_managed.h>
|
||||
#include <drm/i915_drm.h>
|
||||
@ -167,3 +168,16 @@ int intel_gmch_vga_set_state(struct drm_i915_private *i915, bool enable_decode)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int intel_gmch_vga_set_decode(struct pci_dev *pdev, bool enable_decode)
|
||||
{
|
||||
struct drm_i915_private *i915 = pdev_to_i915(pdev);
|
||||
|
||||
intel_gmch_vga_set_state(i915, enable_decode);
|
||||
|
||||
if (enable_decode)
|
||||
return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
|
||||
VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
|
||||
else
|
||||
return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
|
||||
}
|
||||
|
@ -8,11 +8,13 @@
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct pci_dev;
|
||||
struct drm_i915_private;
|
||||
|
||||
int intel_gmch_bridge_setup(struct drm_i915_private *i915);
|
||||
void intel_gmch_bar_setup(struct drm_i915_private *i915);
|
||||
void intel_gmch_bar_teardown(struct drm_i915_private *i915);
|
||||
int intel_gmch_vga_set_state(struct drm_i915_private *i915, bool enable_decode);
|
||||
unsigned int intel_gmch_vga_set_decode(struct pci_dev *pdev, bool enable_decode);
|
||||
|
||||
#endif /* __INTEL_GMCH_H__ */
|
||||
|
@ -38,13 +38,13 @@ extern "C" {
|
||||
*/
|
||||
|
||||
/**
|
||||
* DOC: uevents generated by i915 on it's device node
|
||||
* DOC: uevents generated by i915 on its device node
|
||||
*
|
||||
* I915_L3_PARITY_UEVENT - Generated when the driver receives a parity mismatch
|
||||
* event from the gpu l3 cache. Additional information supplied is ROW,
|
||||
* event from the GPU L3 cache. Additional information supplied is ROW,
|
||||
* BANK, SUBBANK, SLICE of the affected cacheline. Userspace should keep
|
||||
* track of these events and if a specific cache-line seems to have a
|
||||
* persistent error remap it with the l3 remapping tool supplied in
|
||||
* track of these events, and if a specific cache-line seems to have a
|
||||
* persistent error, remap it with the L3 remapping tool supplied in
|
||||
* intel-gpu-tools. The value supplied with the event is always 1.
|
||||
*
|
||||
* I915_ERROR_UEVENT - Generated upon error detection, currently only via
|
||||
|
Loading…
x
Reference in New Issue
Block a user