1
0

Merge tag 'drm-intel-next-2025-05-08' of https://gitlab.freedesktop.org/drm/i915/kernel into drm-next

Non-display related:
- Fix undefined reference to `intel_pxp_gsccs_is_ready_for_sessions'

Display related:
- More work towards display separation (Jani)
- Stop writing VRR_CTL_IGN_MAX_SHIFT for MTL onwards (Jouni)
- DSC checks for 3 engines (Ankit)
- Add link rate and lane count to i915_display_info (Khaled)
- PSR fixes and workaround for underrun on idle (Jouni)
- LOBF enablement and ALMP fixes (Animesh)
- Clean up VGA plane handling (Ville)
- Use an intel_connector pointer everywhere (Imre)
- Fix warning for coffeelake on SunrisePoint PCH (Jiajia)
- Rework/Correction on minimum hblank calculation (Arun)
- Dmesg clean up (Jani)
- Add a couple of simple display workarounds (Ankit, Vinod)
- Refactor HDCP GSC (Jani)

Signed-off-by: Dave Airlie <airlied@redhat.com>

From: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://lore.kernel.org/r/aByyL3bEufPu79OM@intel.com
This commit is contained in:
Dave Airlie
2025-05-10 06:10:04 +10:00
118 changed files with 2636 additions and 2317 deletions

View File

@@ -4393,8 +4393,9 @@ EXPORT_SYMBOL(drm_panel_dp_aux_backlight);
#endif
/* See DP Standard v2.1 2.6.4.4.1.1, 2.8.4.4, 2.8.7 */
static int drm_dp_link_symbol_cycles(int lane_count, int pixels, int bpp_x16,
int symbol_size, bool is_mst)
static int drm_dp_link_data_symbol_cycles(int lane_count, int pixels,
int bpp_x16, int symbol_size,
bool is_mst)
{
int cycles = DIV_ROUND_UP(pixels * bpp_x16, 16 * symbol_size * lane_count);
int align = is_mst ? 4 / lane_count : 1;
@@ -4402,22 +4403,42 @@ static int drm_dp_link_symbol_cycles(int lane_count, int pixels, int bpp_x16,
return ALIGN(cycles, align);
}
static int drm_dp_link_dsc_symbol_cycles(int lane_count, int pixels, int slice_count,
int bpp_x16, int symbol_size, bool is_mst)
/**
* drm_dp_link_symbol_cycles - calculate the link symbol count with/without dsc
* @lane_count: DP link lane count
* @pixels: number of pixels in a scanline
* @dsc_slice_count: number of slices for DSC or '0' for non-DSC
* @bpp_x16: bits per pixel in .4 binary fixed format
* @symbol_size: DP symbol size
* @is_mst: %true for MST and %false for SST
*
* Calculate the link symbol cycles for both DSC (@dsc_slice_count !=0) and
* non-DSC case (@dsc_slice_count == 0) and return the count.
*/
int drm_dp_link_symbol_cycles(int lane_count, int pixels, int dsc_slice_count,
int bpp_x16, int symbol_size, bool is_mst)
{
int slice_count = dsc_slice_count ? : 1;
int slice_pixels = DIV_ROUND_UP(pixels, slice_count);
int slice_data_cycles = drm_dp_link_symbol_cycles(lane_count, slice_pixels,
bpp_x16, symbol_size, is_mst);
int slice_eoc_cycles = is_mst ? 4 / lane_count : 1;
int slice_data_cycles = drm_dp_link_data_symbol_cycles(lane_count,
slice_pixels,
bpp_x16,
symbol_size,
is_mst);
int slice_eoc_cycles = 0;
if (dsc_slice_count)
slice_eoc_cycles = is_mst ? 4 / lane_count : 1;
return slice_count * (slice_data_cycles + slice_eoc_cycles);
}
EXPORT_SYMBOL(drm_dp_link_symbol_cycles);
/**
* drm_dp_bw_overhead - Calculate the BW overhead of a DP link stream
* @lane_count: DP link lane count
* @hactive: pixel count of the active period in one scanline of the stream
* @dsc_slice_count: DSC slice count if @flags/DRM_DP_LINK_BW_OVERHEAD_DSC is set
* @dsc_slice_count: number of slices for DSC or '0' for non-DSC
* @bpp_x16: bits per pixel in .4 binary fixed point
* @flags: DRM_DP_OVERHEAD_x flags
*
@@ -4431,7 +4452,7 @@ static int drm_dp_link_dsc_symbol_cycles(int lane_count, int pixels, int slice_c
* as well as the stream's
* - @hactive timing
* - @bpp_x16 color depth
* - compression mode (@flags / %DRM_DP_OVERHEAD_DSC).
* - compression mode (@dsc_slice_count != 0)
* Note that this overhead doesn't account for the 8b/10b, 128b/132b
* channel coding efficiency, for that see
* @drm_dp_link_bw_channel_coding_efficiency().
@@ -4486,15 +4507,10 @@ int drm_dp_bw_overhead(int lane_count, int hactive,
WARN_ON((flags & DRM_DP_BW_OVERHEAD_UHBR) &&
(flags & DRM_DP_BW_OVERHEAD_FEC));
if (flags & DRM_DP_BW_OVERHEAD_DSC)
symbol_cycles = drm_dp_link_dsc_symbol_cycles(lane_count, hactive,
dsc_slice_count,
bpp_x16, symbol_size,
is_mst);
else
symbol_cycles = drm_dp_link_symbol_cycles(lane_count, hactive,
bpp_x16, symbol_size,
is_mst);
symbol_cycles = drm_dp_link_symbol_cycles(lane_count, hactive,
dsc_slice_count,
bpp_x16, symbol_size,
is_mst);
return DIV_ROUND_UP_ULL(mul_u32_u32(symbol_cycles * symbol_size * lane_count,
overhead * 16),

View File

@@ -52,7 +52,6 @@ i915-y += \
i915-y += \
soc/intel_dram.o \
soc/intel_gmch.o \
soc/intel_pch.o \
soc/intel_rom.o
# core library code
@@ -282,6 +281,7 @@ i915-y += \
display/intel_modeset_setup.o \
display/intel_modeset_verify.o \
display/intel_overlay.o \
display/intel_pch.o \
display/intel_pch_display.o \
display/intel_pch_refclk.o \
display/intel_plane_initial.o \

View File

@@ -7,9 +7,11 @@
#include <linux/string_helpers.h>
#include <drm/drm_print.h>
#include "g4x_dp.h"
#include "i915_drv.h"
#include "i915_reg.h"
#include "i915_utils.h"
#include "intel_audio.h"
#include "intel_backlight.h"
#include "intel_connector.h"
@@ -28,7 +30,6 @@
#include "intel_hotplug.h"
#include "intel_pch_display.h"
#include "intel_pps.h"
#include "vlv_sideband.h"
static const struct dpll g4x_dpll[] = {
{ .dot = 162000, .p1 = 2, .p2 = 10, .n = 2, .m1 = 23, .m2 = 8, },
@@ -60,14 +61,13 @@ static void g4x_dp_set_clock(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config)
{
struct intel_display *display = to_intel_display(encoder);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
const struct dpll *divisor = NULL;
int i, count = 0;
if (display->platform.g4x) {
divisor = g4x_dpll;
count = ARRAY_SIZE(g4x_dpll);
} else if (HAS_PCH_SPLIT(dev_priv)) {
} else if (HAS_PCH_SPLIT(display)) {
divisor = pch_dpll;
count = ARRAY_SIZE(pch_dpll);
} else if (display->platform.cherryview) {
@@ -93,7 +93,6 @@ static void intel_dp_prepare(struct intel_encoder *encoder,
const struct intel_crtc_state *pipe_config)
{
struct intel_display *display = to_intel_display(encoder);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
enum port port = encoder->port;
struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
@@ -141,7 +140,7 @@ static void intel_dp_prepare(struct intel_encoder *encoder,
intel_dp->DP |= DP_ENHANCED_FRAMING;
intel_dp->DP |= DP_PIPE_SEL_IVB(crtc->pipe);
} else if (HAS_PCH_CPT(dev_priv) && port != PORT_A) {
} else if (HAS_PCH_CPT(display) && port != PORT_A) {
intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT;
intel_de_rmw(display, TRANS_DP_CTL(crtc->pipe),
@@ -183,7 +182,7 @@ static void assert_dp_port(struct intel_dp *intel_dp, bool state)
static void assert_edp_pll(struct intel_display *display, bool state)
{
bool cur_state = intel_de_read(display, DP_A) & DP_PLL_ENABLE;
bool cur_state = intel_de_read(display, DP_A) & EDP_PLL_ENABLE;
INTEL_DISPLAY_STATE_WARN(display, cur_state != state,
"eDP PLL state assertion failure (expected %s, current %s)\n",
@@ -205,12 +204,12 @@ static void ilk_edp_pll_on(struct intel_dp *intel_dp,
drm_dbg_kms(display->drm, "enabling eDP PLL for clock %d\n",
pipe_config->port_clock);
intel_dp->DP &= ~DP_PLL_FREQ_MASK;
intel_dp->DP &= ~EDP_PLL_FREQ_MASK;
if (pipe_config->port_clock == 162000)
intel_dp->DP |= DP_PLL_FREQ_162MHZ;
intel_dp->DP |= EDP_PLL_FREQ_162MHZ;
else
intel_dp->DP |= DP_PLL_FREQ_270MHZ;
intel_dp->DP |= EDP_PLL_FREQ_270MHZ;
intel_de_write(display, DP_A, intel_dp->DP);
intel_de_posting_read(display, DP_A);
@@ -225,7 +224,7 @@ static void ilk_edp_pll_on(struct intel_dp *intel_dp,
if (display->platform.ironlake)
intel_wait_for_vblank_if_active(display, !crtc->pipe);
intel_dp->DP |= DP_PLL_ENABLE;
intel_dp->DP |= EDP_PLL_ENABLE;
intel_de_write(display, DP_A, intel_dp->DP);
intel_de_posting_read(display, DP_A);
@@ -243,7 +242,7 @@ static void ilk_edp_pll_off(struct intel_dp *intel_dp,
drm_dbg_kms(display->drm, "disabling eDP PLL\n");
intel_dp->DP &= ~DP_PLL_ENABLE;
intel_dp->DP &= ~EDP_PLL_ENABLE;
intel_de_write(display, DP_A, intel_dp->DP);
intel_de_posting_read(display, DP_A);
@@ -277,7 +276,6 @@ bool g4x_dp_port_enabled(struct intel_display *display,
i915_reg_t dp_reg, enum port port,
enum pipe *pipe)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
bool ret;
u32 val;
@@ -287,13 +285,13 @@ bool g4x_dp_port_enabled(struct intel_display *display,
/* asserts want to know the pipe even if the port is disabled */
if (display->platform.ivybridge && port == PORT_A)
*pipe = (val & DP_PIPE_SEL_MASK_IVB) >> DP_PIPE_SEL_SHIFT_IVB;
else if (HAS_PCH_CPT(dev_priv) && port != PORT_A)
*pipe = REG_FIELD_GET(DP_PIPE_SEL_MASK_IVB, val);
else if (HAS_PCH_CPT(display) && port != PORT_A)
ret &= cpt_dp_port_selected(display, port, pipe);
else if (display->platform.cherryview)
*pipe = (val & DP_PIPE_SEL_MASK_CHV) >> DP_PIPE_SEL_SHIFT_CHV;
*pipe = REG_FIELD_GET(DP_PIPE_SEL_MASK_CHV, val);
else
*pipe = (val & DP_PIPE_SEL_MASK) >> DP_PIPE_SEL_SHIFT;
*pipe = REG_FIELD_GET(DP_PIPE_SEL_MASK, val);
return ret;
}
@@ -338,7 +336,6 @@ static void intel_dp_get_config(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config)
{
struct intel_display *display = to_intel_display(encoder);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
u32 tmp, flags = 0;
enum port port = encoder->port;
@@ -353,7 +350,7 @@ static void intel_dp_get_config(struct intel_encoder *encoder,
pipe_config->has_audio = tmp & DP_AUDIO_OUTPUT_ENABLE && port != PORT_A;
if (HAS_PCH_CPT(dev_priv) && port != PORT_A) {
if (HAS_PCH_CPT(display) && port != PORT_A) {
u32 trans_dp = intel_de_read(display,
TRANS_DP_CTL(crtc->pipe));
@@ -389,13 +386,12 @@ static void intel_dp_get_config(struct intel_encoder *encoder,
if (display->platform.g4x && tmp & DP_COLOR_RANGE_16_235)
pipe_config->limited_color_range = true;
pipe_config->lane_count =
((tmp & DP_PORT_WIDTH_MASK) >> DP_PORT_WIDTH_SHIFT) + 1;
pipe_config->lane_count = REG_FIELD_GET(DP_PORT_WIDTH_MASK, tmp) + 1;
g4x_dp_get_m_n(pipe_config);
if (port == PORT_A) {
if ((intel_de_read(display, DP_A) & DP_PLL_FREQ_MASK) == DP_PLL_FREQ_162MHZ)
if ((intel_de_read(display, DP_A) & EDP_PLL_FREQ_MASK) == EDP_PLL_FREQ_162MHZ)
pipe_config->port_clock = 162000;
else
pipe_config->port_clock = 270000;
@@ -416,7 +412,6 @@ intel_dp_link_down(struct intel_encoder *encoder,
const struct intel_crtc_state *old_crtc_state)
{
struct intel_display *display = to_intel_display(encoder);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
enum port port = encoder->port;
@@ -429,7 +424,7 @@ intel_dp_link_down(struct intel_encoder *encoder,
drm_dbg_kms(display->drm, "\n");
if ((display->platform.ivybridge && port == PORT_A) ||
(HAS_PCH_CPT(dev_priv) && port != PORT_A)) {
(HAS_PCH_CPT(display) && port != PORT_A)) {
intel_dp->DP &= ~DP_LINK_TRAIN_MASK_CPT;
intel_dp->DP |= DP_LINK_TRAIN_PAT_IDLE_CPT;
} else {
@@ -448,7 +443,7 @@ intel_dp_link_down(struct intel_encoder *encoder,
* to transcoder A after disabling it to allow the
* matching HDMI port to be enabled on transcoder A.
*/
if (HAS_PCH_IBX(dev_priv) && crtc->pipe == PIPE_B && port != PORT_A) {
if (HAS_PCH_IBX(display) && crtc->pipe == PIPE_B && port != PORT_A) {
/*
* We get CPU/PCH FIFO underruns on the other pipe when
* doing the workaround. Sweep them under the rug.
@@ -581,16 +576,10 @@ static void chv_post_disable_dp(struct intel_atomic_state *state,
const struct intel_crtc_state *old_crtc_state,
const struct drm_connector_state *old_conn_state)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
intel_dp_link_down(encoder, old_crtc_state);
vlv_dpio_get(dev_priv);
/* Assert data lane reset */
chv_data_lane_soft_reset(encoder, old_crtc_state, true);
vlv_dpio_put(dev_priv);
}
static void
@@ -1223,10 +1212,10 @@ static int g4x_dp_compute_config(struct intel_encoder *encoder,
struct intel_crtc_state *crtc_state,
struct drm_connector_state *conn_state)
{
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
struct intel_display *display = to_intel_display(encoder);
int ret;
if (HAS_PCH_SPLIT(i915) && encoder->port != PORT_A)
if (HAS_PCH_SPLIT(display) && encoder->port != PORT_A)
crtc_state->has_pch_encoder = true;
ret = intel_dp_compute_config(encoder, crtc_state, conn_state);
@@ -1279,7 +1268,6 @@ static const struct drm_encoder_funcs intel_dp_enc_funcs = {
bool g4x_dp_init(struct intel_display *display,
i915_reg_t output_reg, enum port port)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
const struct intel_bios_encoder_data *devdata;
struct intel_digital_port *dig_port;
struct intel_encoder *intel_encoder;
@@ -1353,7 +1341,7 @@ bool g4x_dp_init(struct intel_display *display,
intel_encoder->audio_disable = g4x_dp_audio_disable;
if ((display->platform.ivybridge && port == PORT_A) ||
(HAS_PCH_CPT(dev_priv) && port != PORT_A))
(HAS_PCH_CPT(display) && port != PORT_A))
dig_port->dp.set_link_train = cpt_set_link_train;
else
dig_port->dp.set_link_train = g4x_set_link_train;
@@ -1370,7 +1358,7 @@ bool g4x_dp_init(struct intel_display *display,
intel_encoder->set_signal_levels = g4x_set_signal_levels;
if (display->platform.valleyview || display->platform.cherryview ||
(HAS_PCH_SPLIT(dev_priv) && port != PORT_A)) {
(HAS_PCH_SPLIT(display) && port != PORT_A)) {
dig_port->dp.preemph_max = intel_dp_preemph_max_3;
dig_port->dp.voltage_max = intel_dp_voltage_max_3;
} else {

View File

@@ -5,8 +5,9 @@
* HDMI support for G4x,ILK,SNB,IVB,VLV,CHV (HSW+ handled by the DDI code).
*/
#include <drm/drm_print.h>
#include "g4x_hdmi.h"
#include "i915_drv.h"
#include "i915_reg.h"
#include "intel_atomic.h"
#include "intel_audio.h"
@@ -22,13 +23,11 @@
#include "intel_hdmi.h"
#include "intel_hotplug.h"
#include "intel_sdvo.h"
#include "vlv_sideband.h"
static void intel_hdmi_prepare(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(encoder);
struct drm_i915_private *dev_priv = to_i915(display->drm);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
@@ -37,7 +36,7 @@ static void intel_hdmi_prepare(struct intel_encoder *encoder,
intel_dp_dual_mode_set_tmds_output(intel_hdmi, true);
hdmi_val = SDVO_ENCODING_HDMI;
if (!HAS_PCH_SPLIT(dev_priv) && crtc_state->limited_color_range)
if (!HAS_PCH_SPLIT(display) && crtc_state->limited_color_range)
hdmi_val |= HDMI_COLOR_RANGE_16_235;
if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
hdmi_val |= SDVO_VSYNC_ACTIVE_HIGH;
@@ -52,7 +51,7 @@ static void intel_hdmi_prepare(struct intel_encoder *encoder,
if (crtc_state->has_hdmi_sink)
hdmi_val |= HDMI_MODE_SELECT_HDMI;
if (HAS_PCH_CPT(dev_priv))
if (HAS_PCH_CPT(display))
hdmi_val |= SDVO_PIPE_SEL_CPT(crtc->pipe);
else if (display->platform.cherryview)
hdmi_val |= SDVO_PIPE_SEL_CHV(crtc->pipe);
@@ -134,9 +133,8 @@ static int g4x_hdmi_compute_config(struct intel_encoder *encoder,
struct intel_display *display = to_intel_display(encoder);
struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->uapi.state);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
if (HAS_PCH_SPLIT(i915)) {
if (HAS_PCH_SPLIT(display)) {
crtc_state->has_pch_encoder = true;
if (!intel_fdi_compute_pipe_bpp(crtc_state))
return -EINVAL;
@@ -155,7 +153,6 @@ static void intel_hdmi_get_config(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config)
{
struct intel_display *display = to_intel_display(encoder);
struct drm_i915_private *dev_priv = to_i915(display->drm);
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
u32 tmp, flags = 0;
int dotclock;
@@ -186,7 +183,7 @@ static void intel_hdmi_get_config(struct intel_encoder *encoder,
if (tmp & HDMI_AUDIO_ENABLE)
pipe_config->has_audio = true;
if (!HAS_PCH_SPLIT(dev_priv) &&
if (!HAS_PCH_SPLIT(display) &&
tmp & HDMI_COLOR_RANGE_16_235)
pipe_config->limited_color_range = true;
@@ -383,7 +380,6 @@ static void intel_disable_hdmi(struct intel_atomic_state *state,
const struct drm_connector_state *old_conn_state)
{
struct intel_display *display = to_intel_display(encoder);
struct drm_i915_private *dev_priv = to_i915(display->drm);
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
struct intel_digital_port *dig_port =
hdmi_to_dig_port(intel_hdmi);
@@ -401,7 +397,7 @@ static void intel_disable_hdmi(struct intel_atomic_state *state,
* to transcoder A after disabling it to allow the
* matching DP port to be enabled on transcoder A.
*/
if (HAS_PCH_IBX(dev_priv) && crtc->pipe == PIPE_B) {
if (HAS_PCH_IBX(display) && crtc->pipe == PIPE_B) {
/*
* We get CPU/PCH FIFO underruns on the other pipe when
* doing the workaround. Sweep them under the rug.
@@ -539,15 +535,8 @@ static void chv_hdmi_post_disable(struct intel_atomic_state *state,
const struct intel_crtc_state *old_crtc_state,
const struct drm_connector_state *old_conn_state)
{
struct intel_display *display = to_intel_display(encoder);
struct drm_i915_private *dev_priv = to_i915(display->drm);
vlv_dpio_get(dev_priv);
/* Assert data lane reset */
chv_data_lane_soft_reset(encoder, old_crtc_state, true);
vlv_dpio_put(dev_priv);
}
static void chv_hdmi_pre_enable(struct intel_atomic_state *state,
@@ -682,7 +671,6 @@ static bool assert_hdmi_port_valid(struct intel_display *display, enum port port
bool g4x_hdmi_init(struct intel_display *display,
i915_reg_t hdmi_reg, enum port port)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
const struct intel_bios_encoder_data *devdata;
struct intel_digital_port *dig_port;
struct intel_encoder *intel_encoder;
@@ -724,7 +712,7 @@ bool g4x_hdmi_init(struct intel_display *display,
intel_encoder->hotplug = intel_hdmi_hotplug;
intel_encoder->compute_config = g4x_hdmi_compute_config;
if (HAS_PCH_SPLIT(dev_priv)) {
if (HAS_PCH_SPLIT(display)) {
intel_encoder->disable = pch_disable_hdmi;
intel_encoder->post_disable = pch_post_disable_hdmi;
} else {
@@ -745,9 +733,9 @@ bool g4x_hdmi_init(struct intel_display *display,
intel_encoder->post_disable = vlv_hdmi_post_disable;
} else {
intel_encoder->pre_enable = intel_hdmi_pre_enable;
if (HAS_PCH_CPT(dev_priv))
if (HAS_PCH_CPT(display))
intel_encoder->enable = cpt_enable_hdmi;
else if (HAS_PCH_IBX(dev_priv))
else if (HAS_PCH_IBX(display))
intel_encoder->enable = ibx_enable_hdmi;
else
intel_encoder->enable = g4x_enable_hdmi;

View File

@@ -7,9 +7,10 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_blend.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_print.h>
#include "i915_drv.h"
#include "i915_reg.h"
#include "i915_utils.h"
#include "i9xx_plane.h"
#include "i9xx_plane_regs.h"
#include "intel_atomic.h"
@@ -631,92 +632,84 @@ static void
bdw_primary_enable_flip_done(struct intel_plane *plane)
{
struct intel_display *display = to_intel_display(plane);
struct drm_i915_private *i915 = to_i915(plane->base.dev);
enum pipe pipe = plane->pipe;
spin_lock_irq(&i915->irq_lock);
spin_lock_irq(&display->irq.lock);
bdw_enable_pipe_irq(display, pipe, GEN8_PIPE_PRIMARY_FLIP_DONE);
spin_unlock_irq(&i915->irq_lock);
spin_unlock_irq(&display->irq.lock);
}
static void
bdw_primary_disable_flip_done(struct intel_plane *plane)
{
struct intel_display *display = to_intel_display(plane);
struct drm_i915_private *i915 = to_i915(plane->base.dev);
enum pipe pipe = plane->pipe;
spin_lock_irq(&i915->irq_lock);
spin_lock_irq(&display->irq.lock);
bdw_disable_pipe_irq(display, pipe, GEN8_PIPE_PRIMARY_FLIP_DONE);
spin_unlock_irq(&i915->irq_lock);
spin_unlock_irq(&display->irq.lock);
}
static void
ivb_primary_enable_flip_done(struct intel_plane *plane)
{
struct intel_display *display = to_intel_display(plane);
struct drm_i915_private *i915 = to_i915(plane->base.dev);
spin_lock_irq(&i915->irq_lock);
spin_lock_irq(&display->irq.lock);
ilk_enable_display_irq(display, DE_PLANE_FLIP_DONE_IVB(plane->i9xx_plane));
spin_unlock_irq(&i915->irq_lock);
spin_unlock_irq(&display->irq.lock);
}
static void
ivb_primary_disable_flip_done(struct intel_plane *plane)
{
struct intel_display *display = to_intel_display(plane);
struct drm_i915_private *i915 = to_i915(plane->base.dev);
spin_lock_irq(&i915->irq_lock);
spin_lock_irq(&display->irq.lock);
ilk_disable_display_irq(display, DE_PLANE_FLIP_DONE_IVB(plane->i9xx_plane));
spin_unlock_irq(&i915->irq_lock);
spin_unlock_irq(&display->irq.lock);
}
static void
ilk_primary_enable_flip_done(struct intel_plane *plane)
{
struct intel_display *display = to_intel_display(plane);
struct drm_i915_private *i915 = to_i915(plane->base.dev);
spin_lock_irq(&i915->irq_lock);
spin_lock_irq(&display->irq.lock);
ilk_enable_display_irq(display, DE_PLANE_FLIP_DONE(plane->i9xx_plane));
spin_unlock_irq(&i915->irq_lock);
spin_unlock_irq(&display->irq.lock);
}
static void
ilk_primary_disable_flip_done(struct intel_plane *plane)
{
struct intel_display *display = to_intel_display(plane);
struct drm_i915_private *i915 = to_i915(plane->base.dev);
spin_lock_irq(&i915->irq_lock);
spin_lock_irq(&display->irq.lock);
ilk_disable_display_irq(display, DE_PLANE_FLIP_DONE(plane->i9xx_plane));
spin_unlock_irq(&i915->irq_lock);
spin_unlock_irq(&display->irq.lock);
}
static void
vlv_primary_enable_flip_done(struct intel_plane *plane)
{
struct intel_display *display = to_intel_display(plane);
struct drm_i915_private *i915 = to_i915(plane->base.dev);
enum pipe pipe = plane->pipe;
spin_lock_irq(&i915->irq_lock);
spin_lock_irq(&display->irq.lock);
i915_enable_pipestat(display, pipe, PLANE_FLIP_DONE_INT_STATUS_VLV);
spin_unlock_irq(&i915->irq_lock);
spin_unlock_irq(&display->irq.lock);
}
static void
vlv_primary_disable_flip_done(struct intel_plane *plane)
{
struct intel_display *display = to_intel_display(plane);
struct drm_i915_private *i915 = to_i915(plane->base.dev);
enum pipe pipe = plane->pipe;
spin_lock_irq(&i915->irq_lock);
spin_lock_irq(&display->irq.lock);
i915_disable_pipestat(display, pipe, PLANE_FLIP_DONE_INT_STATUS_VLV);
spin_unlock_irq(&i915->irq_lock);
spin_unlock_irq(&display->irq.lock);
}
static bool i9xx_plane_can_async_flip(u64 modifier)

View File

@@ -4143,10 +4143,8 @@ static const struct intel_wm_funcs nop_funcs = {
void i9xx_wm_init(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
/* For FIFO watermark updates */
if (HAS_PCH_SPLIT(dev_priv)) {
if (HAS_PCH_SPLIT(display)) {
ilk_setup_wm_latency(display);
display->funcs.wm = &ilk_wm_funcs;
} else if (display->platform.valleyview || display->platform.cherryview) {

View File

@@ -5,12 +5,15 @@
#include <linux/debugfs.h>
#include <drm/drm_print.h>
#include "intel_alpm.h"
#include "intel_crtc.h"
#include "intel_de.h"
#include "intel_display_types.h"
#include "intel_dp.h"
#include "intel_dp_aux.h"
#include "intel_psr.h"
#include "intel_psr_regs.h"
bool intel_alpm_aux_wake_supported(struct intel_dp *intel_dp)
@@ -23,7 +26,7 @@ bool intel_alpm_aux_less_wake_supported(struct intel_dp *intel_dp)
return intel_dp->alpm_dpcd & DP_ALPM_AUX_LESS_CAP;
}
void intel_alpm_init_dpcd(struct intel_dp *intel_dp)
void intel_alpm_init(struct intel_dp *intel_dp)
{
u8 dpcd;
@@ -31,6 +34,7 @@ void intel_alpm_init_dpcd(struct intel_dp *intel_dp)
return;
intel_dp->alpm_dpcd = dpcd;
mutex_init(&intel_dp->alpm_parameters.lock);
}
/*
@@ -276,6 +280,14 @@ void intel_alpm_lobf_compute_config(struct intel_dp *intel_dp,
int waketime_in_lines, first_sdp_position;
int context_latency, guardband;
if (intel_dp->alpm_parameters.lobf_disable_debug) {
drm_dbg_kms(display->drm, "LOBF is disabled by debug flag\n");
return;
}
if (intel_dp->alpm_parameters.sink_alpm_error)
return;
if (!intel_dp_is_edp(intel_dp))
return;
@@ -288,6 +300,10 @@ void intel_alpm_lobf_compute_config(struct intel_dp *intel_dp,
if (crtc_state->has_psr)
return;
if (crtc_state->vrr.vmin != crtc_state->vrr.vmax ||
crtc_state->vrr.vmin != crtc_state->vrr.flipline)
return;
if (!(intel_alpm_aux_wake_supported(intel_dp) ||
intel_alpm_aux_less_wake_supported(intel_dp)))
return;
@@ -316,15 +332,16 @@ static void lnl_alpm_configure(struct intel_dp *intel_dp,
enum port port = dp_to_dig_port(intel_dp)->base.port;
u32 alpm_ctl;
if (DISPLAY_VER(display) < 20 ||
(!intel_dp->psr.sel_update_enabled && !intel_dp_is_edp(intel_dp)))
if (DISPLAY_VER(display) < 20 || (!intel_psr_needs_alpm(intel_dp, crtc_state) &&
!crtc_state->has_lobf))
return;
mutex_lock(&intel_dp->alpm_parameters.lock);
/*
* Panel Replay on eDP is always using ALPM aux less. I.e. no need to
* check panel support at this point.
*/
if ((intel_dp->psr.panel_replay_enabled && intel_dp_is_edp(intel_dp)) ||
if ((crtc_state->has_panel_replay && intel_dp_is_edp(intel_dp)) ||
(crtc_state->has_lobf && intel_alpm_aux_less_wake_supported(intel_dp))) {
alpm_ctl = ALPM_CTL_ALPM_ENABLE |
ALPM_CTL_ALPM_AUX_LESS_ENABLE |
@@ -353,18 +370,107 @@ static void lnl_alpm_configure(struct intel_dp *intel_dp,
ALPM_CTL_EXTENDED_FAST_WAKE_TIME(intel_dp->alpm_parameters.fast_wake_lines);
}
if (crtc_state->has_lobf)
if (crtc_state->has_lobf) {
alpm_ctl |= ALPM_CTL_LOBF_ENABLE;
drm_dbg_kms(display->drm, "Link off between frames (LOBF) enabled\n");
}
alpm_ctl |= ALPM_CTL_ALPM_ENTRY_CHECK(intel_dp->alpm_parameters.check_entry_lines);
intel_de_write(display, ALPM_CTL(display, cpu_transcoder), alpm_ctl);
mutex_unlock(&intel_dp->alpm_parameters.lock);
}
void intel_alpm_configure(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{
lnl_alpm_configure(intel_dp, crtc_state);
intel_dp->alpm_parameters.transcoder = crtc_state->cpu_transcoder;
}
void intel_alpm_pre_plane_update(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
struct intel_display *display = to_intel_display(state);
const struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
const struct intel_crtc_state *old_crtc_state =
intel_atomic_get_old_crtc_state(state, crtc);
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
struct intel_encoder *encoder;
if (DISPLAY_VER(display) < 20)
return;
if (crtc_state->has_lobf || crtc_state->has_lobf == old_crtc_state->has_lobf)
return;
for_each_intel_encoder_mask(display->drm, encoder,
crtc_state->uapi.encoder_mask) {
struct intel_dp *intel_dp;
if (!intel_encoder_is_dp(encoder))
continue;
intel_dp = enc_to_intel_dp(encoder);
if (!intel_dp_is_edp(intel_dp))
continue;
if (old_crtc_state->has_lobf) {
mutex_lock(&intel_dp->alpm_parameters.lock);
intel_de_write(display, ALPM_CTL(display, cpu_transcoder), 0);
drm_dbg_kms(display->drm, "Link off between frames (LOBF) disabled\n");
mutex_unlock(&intel_dp->alpm_parameters.lock);
}
}
}
static void intel_alpm_enable_sink(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{
u8 val;
if (!intel_psr_needs_alpm(intel_dp, crtc_state) && !crtc_state->has_lobf)
return;
val = DP_ALPM_ENABLE | DP_ALPM_LOCK_ERROR_IRQ_HPD_ENABLE;
if (crtc_state->has_panel_replay || (crtc_state->has_lobf &&
intel_alpm_aux_less_wake_supported(intel_dp)))
val |= DP_ALPM_MODE_AUX_LESS;
drm_dp_dpcd_writeb(&intel_dp->aux, DP_RECEIVER_ALPM_CONFIG, val);
}
void intel_alpm_post_plane_update(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
struct intel_display *display = to_intel_display(state);
const struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
const struct intel_crtc_state *old_crtc_state =
intel_atomic_get_old_crtc_state(state, crtc);
struct intel_encoder *encoder;
if ((!crtc_state->has_lobf ||
crtc_state->has_lobf == old_crtc_state->has_lobf) && !crtc_state->has_psr)
return;
for_each_intel_encoder_mask(display->drm, encoder,
crtc_state->uapi.encoder_mask) {
struct intel_dp *intel_dp;
if (!intel_encoder_is_dp(encoder))
continue;
intel_dp = enc_to_intel_dp(encoder);
if (intel_dp_is_edp(intel_dp)) {
intel_alpm_enable_sink(intel_dp, crtc_state);
intel_alpm_configure(intel_dp, crtc_state);
}
}
}
static int i915_edp_lobf_info_show(struct seq_file *m, void *data)
@@ -403,6 +509,32 @@ out:
DEFINE_SHOW_ATTRIBUTE(i915_edp_lobf_info);
static int
i915_edp_lobf_debug_get(void *data, u64 *val)
{
struct intel_connector *connector = data;
struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
*val = intel_dp->alpm_parameters.lobf_disable_debug;
return 0;
}
static int
i915_edp_lobf_debug_set(void *data, u64 val)
{
struct intel_connector *connector = data;
struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
intel_dp->alpm_parameters.lobf_disable_debug = val;
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(i915_edp_lobf_debug_fops,
i915_edp_lobf_debug_get, i915_edp_lobf_debug_set,
"%llu\n");
void intel_alpm_lobf_debugfs_add(struct intel_connector *connector)
{
struct intel_display *display = to_intel_display(connector);
@@ -412,6 +544,55 @@ void intel_alpm_lobf_debugfs_add(struct intel_connector *connector)
connector->base.connector_type != DRM_MODE_CONNECTOR_eDP)
return;
debugfs_create_file("i915_edp_lobf_debug", 0644, root,
connector, &i915_edp_lobf_debug_fops);
debugfs_create_file("i915_edp_lobf_info", 0444, root,
connector, &i915_edp_lobf_info_fops);
}
void intel_alpm_disable(struct intel_dp *intel_dp)
{
struct intel_display *display = to_intel_display(intel_dp);
enum transcoder cpu_transcoder = intel_dp->alpm_parameters.transcoder;
if (DISPLAY_VER(display) < 20 || !intel_dp->alpm_dpcd)
return;
mutex_lock(&intel_dp->alpm_parameters.lock);
intel_de_rmw(display, ALPM_CTL(display, cpu_transcoder),
ALPM_CTL_ALPM_ENABLE | ALPM_CTL_LOBF_ENABLE |
ALPM_CTL_ALPM_AUX_LESS_ENABLE, 0);
intel_de_rmw(display,
PORT_ALPM_CTL(cpu_transcoder),
PORT_ALPM_CTL_ALPM_AUX_LESS_ENABLE, 0);
drm_dbg_kms(display->drm, "Disabling ALPM\n");
mutex_unlock(&intel_dp->alpm_parameters.lock);
}
bool intel_alpm_get_error(struct intel_dp *intel_dp)
{
struct intel_display *display = to_intel_display(intel_dp);
struct drm_dp_aux *aux = &intel_dp->aux;
u8 val;
int r;
r = drm_dp_dpcd_readb(aux, DP_RECEIVER_ALPM_STATUS, &val);
if (r != 1) {
drm_err(display->drm, "Error reading ALPM status\n");
return true;
}
if (val & DP_ALPM_LOCK_TIMEOUT_ERROR) {
drm_dbg_kms(display->drm, "ALPM lock timeout error\n");
/* Clearing error */
drm_dp_dpcd_writeb(aux, DP_RECEIVER_ALPM_STATUS, val);
return true;
}
return false;
}

View File

@@ -12,8 +12,10 @@ struct intel_dp;
struct intel_crtc_state;
struct drm_connector_state;
struct intel_connector;
struct intel_atomic_state;
struct intel_crtc;
void intel_alpm_init_dpcd(struct intel_dp *intel_dp);
void intel_alpm_init(struct intel_dp *intel_dp);
bool intel_alpm_compute_params(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state);
void intel_alpm_lobf_compute_config(struct intel_dp *intel_dp,
@@ -21,7 +23,13 @@ void intel_alpm_lobf_compute_config(struct intel_dp *intel_dp,
struct drm_connector_state *conn_state);
void intel_alpm_configure(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state);
void intel_alpm_pre_plane_update(struct intel_atomic_state *state,
struct intel_crtc *crtc);
void intel_alpm_post_plane_update(struct intel_atomic_state *state,
struct intel_crtc *crtc);
void intel_alpm_lobf_debugfs_add(struct intel_connector *connector);
bool intel_alpm_aux_wake_supported(struct intel_dp *intel_dp);
bool intel_alpm_aux_less_wake_supported(struct intel_dp *intel_dp);
void intel_alpm_disable(struct intel_dp *intel_dp);
bool intel_alpm_get_error(struct intel_dp *intel_dp);
#endif

View File

@@ -27,9 +27,9 @@
#include <drm/drm_edid.h>
#include <drm/drm_eld.h>
#include <drm/drm_fixed.h>
#include <drm/drm_print.h>
#include <drm/intel/i915_component.h>
#include "i915_drv.h"
#include "intel_atomic.h"
#include "intel_audio.h"
#include "intel_audio_regs.h"
@@ -587,19 +587,17 @@ static void ibx_audio_regs_init(struct intel_display *display,
enum pipe pipe,
struct ibx_audio_regs *regs)
{
struct drm_i915_private *i915 = to_i915(display->drm);
if (display->platform.valleyview || display->platform.cherryview) {
regs->hdmiw_hdmiedid = VLV_HDMIW_HDMIEDID(pipe);
regs->aud_config = VLV_AUD_CFG(pipe);
regs->aud_cntl_st = VLV_AUD_CNTL_ST(pipe);
regs->aud_cntrl_st2 = VLV_AUD_CNTL_ST2;
} else if (HAS_PCH_CPT(i915)) {
} else if (HAS_PCH_CPT(display)) {
regs->hdmiw_hdmiedid = CPT_HDMIW_HDMIEDID(pipe);
regs->aud_config = CPT_AUD_CFG(pipe);
regs->aud_cntl_st = CPT_AUD_CNTL_ST(pipe);
regs->aud_cntrl_st2 = CPT_AUD_CNTRL_ST2;
} else if (HAS_PCH_IBX(i915)) {
} else if (HAS_PCH_IBX(display)) {
regs->hdmiw_hdmiedid = IBX_HDMIW_HDMIEDID(pipe);
regs->aud_config = IBX_AUD_CFG(pipe);
regs->aud_cntl_st = IBX_AUD_CNTL_ST(pipe);
@@ -889,12 +887,10 @@ static const struct intel_audio_funcs hsw_audio_funcs = {
*/
void intel_audio_hooks_init(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
if (display->platform.g4x)
display->funcs.audio = &g4x_audio_funcs;
else if (display->platform.valleyview || display->platform.cherryview ||
HAS_PCH_CPT(i915) || HAS_PCH_IBX(i915))
HAS_PCH_CPT(display) || HAS_PCH_IBX(display))
display->funcs.audio = &ibx_audio_funcs;
else if (display->platform.haswell || DISPLAY_VER(display) >= 8)
display->funcs.audio = &hsw_audio_funcs;

View File

@@ -10,8 +10,11 @@
#include <acpi/video.h>
#include "i915_drv.h"
#include <drm/drm_file.h>
#include <drm/drm_print.h>
#include "i915_reg.h"
#include "i915_utils.h"
#include "intel_backlight.h"
#include "intel_backlight_regs.h"
#include "intel_connector.h"
@@ -473,7 +476,6 @@ static void lpt_enable_backlight(const struct intel_crtc_state *crtc_state,
{
struct intel_connector *connector = to_intel_connector(conn_state->connector);
struct intel_display *display = to_intel_display(connector);
struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct intel_panel *panel = &connector->panel;
u32 pch_ctl1, pch_ctl2;
@@ -486,7 +488,7 @@ static void lpt_enable_backlight(const struct intel_crtc_state *crtc_state,
intel_de_write(display, BLC_PWM_PCH_CTL1, pch_ctl1);
}
if (HAS_PCH_LPT(i915))
if (HAS_PCH_LPT(display))
intel_de_rmw(display, SOUTH_CHICKEN2, LPT_PWM_GRANULARITY,
panel->backlight.alternate_pwm_increment ?
LPT_PWM_GRANULARITY : 0);
@@ -503,7 +505,7 @@ static void lpt_enable_backlight(const struct intel_crtc_state *crtc_state,
pch_ctl1 |= BLM_PCH_POLARITY;
/* After LPT, override is the default. */
if (HAS_PCH_LPT(i915))
if (HAS_PCH_LPT(display))
pch_ctl1 |= BLM_PCH_OVERRIDE_ENABLE;
intel_de_write(display, BLC_PWM_PCH_CTL1, pch_ctl1);
@@ -1064,7 +1066,7 @@ static u32 spt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
*/
static u32 lpt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
{
struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct intel_display *display = to_intel_display(connector);
struct intel_panel *panel = &connector->panel;
u32 mul, clock;
@@ -1073,7 +1075,7 @@ static u32 lpt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
else
mul = 128;
if (HAS_PCH_LPT_H(i915))
if (HAS_PCH_LPT_H(display))
clock = MHz(135); /* LPT:H */
else
clock = MHz(24); /* LPT:LP */
@@ -1230,12 +1232,11 @@ static u32 get_backlight_min_vbt(struct intel_connector *connector)
static int lpt_setup_backlight(struct intel_connector *connector, enum pipe unused)
{
struct intel_display *display = to_intel_display(connector);
struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct intel_panel *panel = &connector->panel;
u32 cpu_ctl2, pch_ctl1, pch_ctl2, val;
bool alt, cpu_mode;
if (HAS_PCH_LPT(i915))
if (HAS_PCH_LPT(display))
alt = intel_de_read(display, SOUTH_CHICKEN2) & LPT_PWM_GRANULARITY;
else
alt = intel_de_read(display, SOUTH_CHICKEN1) & SPT_PWM_GRANULARITY;
@@ -1259,7 +1260,7 @@ static int lpt_setup_backlight(struct intel_connector *connector, enum pipe unus
panel->backlight.pwm_enabled = pch_ctl1 & BLM_PCH_PWM_ENABLE;
cpu_mode = panel->backlight.pwm_enabled && HAS_PCH_LPT(i915) &&
cpu_mode = panel->backlight.pwm_enabled && HAS_PCH_LPT(display) &&
!(pch_ctl1 & BLM_PCH_OVERRIDE_ENABLE) &&
(cpu_ctl2 & BLM_PWM_ENABLE);
@@ -1466,15 +1467,13 @@ bxt_setup_backlight(struct intel_connector *connector, enum pipe unused)
static int cnp_num_backlight_controllers(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
if (INTEL_PCH_TYPE(i915) >= PCH_MTL)
if (INTEL_PCH_TYPE(display) >= PCH_MTL)
return 2;
if (INTEL_PCH_TYPE(i915) >= PCH_DG1)
if (INTEL_PCH_TYPE(display) >= PCH_DG1)
return 1;
if (INTEL_PCH_TYPE(i915) >= PCH_ICP)
if (INTEL_PCH_TYPE(display) >= PCH_ICP)
return 2;
return 1;
@@ -1482,14 +1481,12 @@ static int cnp_num_backlight_controllers(struct intel_display *display)
static bool cnp_backlight_controller_is_valid(struct intel_display *display, int controller)
{
struct drm_i915_private *i915 = to_i915(display->drm);
if (controller < 0 || controller >= cnp_num_backlight_controllers(display))
return false;
if (controller == 1 &&
INTEL_PCH_TYPE(i915) >= PCH_ICP &&
INTEL_PCH_TYPE(i915) <= PCH_ADP)
INTEL_PCH_TYPE(display) >= PCH_ICP &&
INTEL_PCH_TYPE(display) <= PCH_ADP)
return intel_de_read(display, SOUTH_CHICKEN1) & ICP_SECOND_PPS_IO_SELECT;
return true;
@@ -1818,7 +1815,6 @@ void intel_backlight_init_funcs(struct intel_panel *panel)
struct intel_connector *connector =
container_of(panel, struct intel_connector, panel);
struct intel_display *display = to_intel_display(connector);
struct drm_i915_private *i915 = to_i915(connector->base.dev);
if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI &&
intel_dsi_dcs_init_backlight_funcs(connector) == 0)
@@ -1826,14 +1822,14 @@ void intel_backlight_init_funcs(struct intel_panel *panel)
if (display->platform.geminilake || display->platform.broxton) {
panel->backlight.pwm_funcs = &bxt_pwm_funcs;
} else if (INTEL_PCH_TYPE(i915) >= PCH_CNP) {
} else if (INTEL_PCH_TYPE(display) >= PCH_CNP) {
panel->backlight.pwm_funcs = &cnp_pwm_funcs;
} else if (INTEL_PCH_TYPE(i915) >= PCH_LPT_H) {
if (HAS_PCH_LPT(i915))
} else if (INTEL_PCH_TYPE(display) >= PCH_LPT_H) {
if (HAS_PCH_LPT(display))
panel->backlight.pwm_funcs = &lpt_pwm_funcs;
else
panel->backlight.pwm_funcs = &spt_pwm_funcs;
} else if (HAS_PCH_SPLIT(i915)) {
} else if (HAS_PCH_SPLIT(display)) {
panel->backlight.pwm_funcs = &pch_pwm_funcs;
} else if (display->platform.valleyview || display->platform.cherryview) {
if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI) {

View File

@@ -2245,28 +2245,27 @@ static const u8 adlp_ddc_pin_map[] = {
static u8 map_ddc_pin(struct intel_display *display, u8 vbt_pin)
{
struct drm_i915_private *i915 = to_i915(display->drm);
const u8 *ddc_pin_map;
int i, n_entries;
if (INTEL_PCH_TYPE(i915) >= PCH_MTL || display->platform.alderlake_p) {
if (INTEL_PCH_TYPE(display) >= PCH_MTL || display->platform.alderlake_p) {
ddc_pin_map = adlp_ddc_pin_map;
n_entries = ARRAY_SIZE(adlp_ddc_pin_map);
} else if (display->platform.alderlake_s) {
ddc_pin_map = adls_ddc_pin_map;
n_entries = ARRAY_SIZE(adls_ddc_pin_map);
} else if (INTEL_PCH_TYPE(i915) >= PCH_DG1) {
} else if (INTEL_PCH_TYPE(display) >= PCH_DG1) {
return vbt_pin;
} else if (display->platform.rocketlake && INTEL_PCH_TYPE(i915) == PCH_TGP) {
} else if (display->platform.rocketlake && INTEL_PCH_TYPE(display) == PCH_TGP) {
ddc_pin_map = rkl_pch_tgp_ddc_pin_map;
n_entries = ARRAY_SIZE(rkl_pch_tgp_ddc_pin_map);
} else if (HAS_PCH_TGP(i915) && DISPLAY_VER(display) == 9) {
} else if (HAS_PCH_TGP(display) && DISPLAY_VER(display) == 9) {
ddc_pin_map = gen9bc_tgp_ddc_pin_map;
n_entries = ARRAY_SIZE(gen9bc_tgp_ddc_pin_map);
} else if (INTEL_PCH_TYPE(i915) >= PCH_ICP) {
} else if (INTEL_PCH_TYPE(display) >= PCH_ICP) {
ddc_pin_map = icp_ddc_pin_map;
n_entries = ARRAY_SIZE(icp_ddc_pin_map);
} else if (HAS_PCH_CNP(i915)) {
} else if (HAS_PCH_CNP(display)) {
ddc_pin_map = cnp_ddc_pin_map;
n_entries = ARRAY_SIZE(cnp_ddc_pin_map);
} else {
@@ -2865,8 +2864,6 @@ parse_general_definitions(struct intel_display *display)
static void
init_vbt_defaults(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
display->vbt.crt_ddc_pin = GMBUS_PIN_VGADDC;
/* general features */
@@ -2883,7 +2880,7 @@ init_vbt_defaults(struct intel_display *display)
* clock for LVDS.
*/
display->vbt.lvds_ssc_freq = intel_bios_ssc_frequency(display,
!HAS_PCH_SPLIT(i915));
!HAS_PCH_SPLIT(display));
drm_dbg_kms(display->drm, "Set default to SSC at %d kHz\n",
display->vbt.lvds_ssc_freq);
}
@@ -3126,7 +3123,7 @@ static const struct vbt_header *intel_bios_get_vbt(struct intel_display *display
* If the OpRegion does not have VBT, look in SPI flash
* through MMIO or PCI mapping
*/
if (!vbt && IS_DGFX(i915))
if (!vbt && display->platform.dgfx)
with_intel_display_rpm(display)
vbt = oprom_get_vbt(display, intel_rom_spi(i915), sizep, "SPI flash");

View File

@@ -24,7 +24,7 @@
/*
* Please use intel_vbt_defs.h for VBT private data, to hide and abstract away
* the VBT from the rest of the driver. Add the parsed, clean data to struct
* intel_vbt_data within struct drm_i915_private.
* intel_vbt_data within struct intel_display.
*/
#ifndef _INTEL_BIOS_H_

View File

@@ -3494,7 +3494,6 @@ static int dg1_rawclk(struct intel_display *display)
static int cnp_rawclk(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
int divider, fraction;
u32 rawclk;
@@ -3514,7 +3513,7 @@ static int cnp_rawclk(struct intel_display *display)
rawclk |= CNP_RAWCLK_DEN(DIV_ROUND_CLOSEST(numerator * 1000,
fraction) - 1);
if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP)
if (INTEL_PCH_TYPE(display) >= PCH_ICP)
rawclk |= ICP_RAWCLK_NUM(numerator);
}
@@ -3553,21 +3552,20 @@ static int i9xx_hrawclk(struct intel_display *display)
*/
u32 intel_read_rawclk(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
u32 freq;
if (INTEL_PCH_TYPE(dev_priv) >= PCH_MTL)
if (INTEL_PCH_TYPE(display) >= PCH_MTL)
/*
* MTL always uses a 38.4 MHz rawclk. The bspec tells us
* "RAWCLK_FREQ defaults to the values for 38.4 and does
* not need to be programmed."
*/
freq = 38400;
else if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG1)
else if (INTEL_PCH_TYPE(display) >= PCH_DG1)
freq = dg1_rawclk(display);
else if (INTEL_PCH_TYPE(dev_priv) >= PCH_CNP)
else if (INTEL_PCH_TYPE(display) >= PCH_CNP)
freq = cnp_rawclk(display);
else if (HAS_PCH_SPLIT(dev_priv))
else if (HAS_PCH_SPLIT(display))
freq = pch_rawclk(display);
else if (display->platform.valleyview || display->platform.cherryview)
freq = vlv_hrawclk(display);

View File

@@ -9,7 +9,6 @@
#include <drm/drm_device.h>
#include <drm/drm_print.h>
#include "i915_drv.h"
#include "i915_reg.h"
#include "intel_crtc.h"
#include "intel_cmtg.h"

View File

@@ -31,9 +31,9 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
#include "i915_drv.h"
#include "i915_irq.h"
#include "i915_reg.h"
#include "intel_connector.h"
@@ -91,13 +91,12 @@ static struct intel_crt *intel_attached_crt(struct intel_connector *connector)
bool intel_crt_port_enabled(struct intel_display *display,
i915_reg_t adpa_reg, enum pipe *pipe)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
u32 val;
val = intel_de_read(display, adpa_reg);
/* asserts want to know the pipe even if the port is disabled */
if (HAS_PCH_CPT(dev_priv))
if (HAS_PCH_CPT(display))
*pipe = REG_FIELD_GET(ADPA_PIPE_SEL_MASK_CPT, val);
else
*pipe = REG_FIELD_GET(ADPA_PIPE_SEL_MASK, val);
@@ -177,7 +176,6 @@ static void intel_crt_set_dpms(struct intel_encoder *encoder,
int mode)
{
struct intel_display *display = to_intel_display(encoder);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_crt *crt = intel_encoder_to_crt(encoder);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
@@ -194,14 +192,14 @@ static void intel_crt_set_dpms(struct intel_encoder *encoder,
adpa |= ADPA_VSYNC_ACTIVE_HIGH;
/* For CPT allow 3 pipe config, for others just use A or B */
if (HAS_PCH_LPT(dev_priv))
if (HAS_PCH_LPT(display))
; /* Those bits don't exist here */
else if (HAS_PCH_CPT(dev_priv))
else if (HAS_PCH_CPT(display))
adpa |= ADPA_PIPE_SEL_CPT(crtc->pipe);
else
adpa |= ADPA_PIPE_SEL(crtc->pipe);
if (!HAS_PCH_SPLIT(dev_priv))
if (!HAS_PCH_SPLIT(display))
intel_de_write(display, BCLRPAT(display, crtc->pipe), 0);
switch (mode) {
@@ -356,7 +354,6 @@ intel_crt_mode_valid(struct drm_connector *connector,
const struct drm_display_mode *mode)
{
struct intel_display *display = to_intel_display(connector->dev);
struct drm_i915_private *dev_priv = to_i915(connector->dev);
int max_dotclk = display->cdclk.max_dotclk_freq;
enum drm_mode_status status;
int max_clock;
@@ -368,9 +365,9 @@ intel_crt_mode_valid(struct drm_connector *connector,
if (mode->clock < 25000)
return MODE_CLOCK_LOW;
if (HAS_PCH_LPT(dev_priv))
if (HAS_PCH_LPT(display))
max_clock = 180000;
else if (IS_VALLEYVIEW(dev_priv))
else if (display->platform.valleyview)
/*
* 270 MHz due to current DPLL limits,
* DAC limit supposedly 355 MHz.
@@ -387,7 +384,7 @@ intel_crt_mode_valid(struct drm_connector *connector,
return MODE_CLOCK_HIGH;
/* The FDI receiver on LPT only supports 8bpc and only has 2 lanes. */
if (HAS_PCH_LPT(dev_priv) &&
if (HAS_PCH_LPT(display) &&
ilk_get_lanes_required(mode->clock, 270000, 24) > 2)
return MODE_CLOCK_HIGH;
@@ -438,7 +435,6 @@ static int hsw_crt_compute_config(struct intel_encoder *encoder,
struct drm_connector_state *conn_state)
{
struct intel_display *display = to_intel_display(encoder);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct drm_display_mode *adjusted_mode =
&crtc_state->hw.adjusted_mode;
@@ -457,7 +453,7 @@ static int hsw_crt_compute_config(struct intel_encoder *encoder,
crtc_state->output_format = INTEL_OUTPUT_FORMAT_RGB;
/* LPT FDI RX only supports 8bpc. */
if (HAS_PCH_LPT(dev_priv)) {
if (HAS_PCH_LPT(display)) {
/* TODO: Check crtc_state->max_link_bpp_x16 instead of bw_constrained */
if (crtc_state->bw_constrained && crtc_state->pipe_bpp < 24) {
drm_dbg_kms(display->drm,
@@ -482,13 +478,12 @@ static bool ilk_crt_detect_hotplug(struct drm_connector *connector)
{
struct intel_display *display = to_intel_display(connector->dev);
struct intel_crt *crt = intel_attached_crt(to_intel_connector(connector));
struct drm_i915_private *dev_priv = to_i915(connector->dev);
u32 adpa;
bool ret;
/* The first time through, trigger an explicit detection cycle */
if (crt->force_hotplug_required) {
bool turn_off_dac = HAS_PCH_SPLIT(dev_priv);
bool turn_off_dac = HAS_PCH_SPLIT(display);
u32 save_adpa;
crt->force_hotplug_required = false;
@@ -583,15 +578,14 @@ static bool valleyview_crt_detect_hotplug(struct drm_connector *connector)
static bool intel_crt_detect_hotplug(struct drm_connector *connector)
{
struct intel_display *display = to_intel_display(connector->dev);
struct drm_i915_private *dev_priv = to_i915(connector->dev);
u32 stat;
bool ret = false;
int i, tries = 0;
if (HAS_PCH_SPLIT(dev_priv))
if (HAS_PCH_SPLIT(display))
return ilk_crt_detect_hotplug(connector);
if (IS_VALLEYVIEW(dev_priv))
if (display->platform.valleyview)
return valleyview_crt_detect_hotplug(connector);
/*
@@ -599,7 +593,7 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
* to get a reliable result.
*/
if (IS_G45(dev_priv))
if (display->platform.g45)
tries = 2;
else
tries = 1;
@@ -940,7 +934,6 @@ out:
static int intel_crt_get_modes(struct drm_connector *connector)
{
struct intel_display *display = to_intel_display(connector->dev);
struct drm_i915_private *dev_priv = to_i915(connector->dev);
struct intel_crt *crt = intel_attached_crt(to_intel_connector(connector));
struct intel_encoder *encoder = &crt->base;
intel_wakeref_t wakeref;
@@ -953,7 +946,7 @@ static int intel_crt_get_modes(struct drm_connector *connector)
wakeref = intel_display_power_get(display, encoder->power_domain);
ret = intel_crt_ddc_get_modes(connector, connector->ddc);
if (ret || !IS_G4X(dev_priv))
if (ret || !display->platform.g4x)
goto out;
/* Try to probe digital port for output in DVI-I -> VGA mode. */
@@ -1012,16 +1005,15 @@ static const struct drm_encoder_funcs intel_crt_enc_funcs = {
void intel_crt_init(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
struct intel_connector *connector;
struct intel_crt *crt;
i915_reg_t adpa_reg;
u8 ddc_pin;
u32 adpa;
if (HAS_PCH_SPLIT(dev_priv))
if (HAS_PCH_SPLIT(display))
adpa_reg = PCH_ADPA;
else if (IS_VALLEYVIEW(dev_priv))
else if (display->platform.valleyview)
adpa_reg = VLV_ADPA;
else
adpa_reg = ADPA;
@@ -1069,7 +1061,7 @@ void intel_crt_init(struct intel_display *display)
crt->base.type = INTEL_OUTPUT_ANALOG;
crt->base.cloneable = BIT(INTEL_OUTPUT_DVO) | BIT(INTEL_OUTPUT_HDMI);
if (IS_I830(dev_priv))
if (display->platform.i830)
crt->base.pipe_mask = BIT(PIPE_A);
else
crt->base.pipe_mask = ~0;
@@ -1109,7 +1101,7 @@ void intel_crt_init(struct intel_display *display)
intel_ddi_buf_trans_init(&crt->base);
} else {
if (HAS_PCH_SPLIT(dev_priv)) {
if (HAS_PCH_SPLIT(display)) {
crt->base.compute_config = pch_crt_compute_config;
crt->base.disable = pch_disable_crt;
crt->base.post_disable = pch_post_disable_crt;
@@ -1131,7 +1123,7 @@ void intel_crt_init(struct intel_display *display)
* polarity and link reversal bits or not, instead of relying on the
* BIOS.
*/
if (HAS_PCH_LPT(dev_priv)) {
if (HAS_PCH_LPT(display)) {
u32 fdi_config = FDI_RX_POLARITY_REVERSED_LPT |
FDI_RX_LINK_REVERSAL_OVERRIDE;

View File

@@ -124,7 +124,7 @@ void intel_crtc_vblank_on(const struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
crtc->block_dc_for_vblank = intel_psr_needs_block_dc_vblank(crtc_state);
crtc->vblank_psr_notify = intel_psr_needs_vblank_notification(crtc_state);
assert_vblank_disabled(&crtc->base);
drm_crtc_set_max_vblank_count(&crtc->base,
@@ -154,9 +154,9 @@ void intel_crtc_vblank_off(const struct intel_crtc_state *crtc_state)
drm_crtc_vblank_off(&crtc->base);
assert_vblank_disabled(&crtc->base);
crtc->block_dc_for_vblank = false;
crtc->vblank_psr_notify = false;
flush_work(&display->irq.vblank_dc_work);
flush_work(&display->irq.vblank_notify_work);
}
struct intel_crtc_state *intel_crtc_state_alloc(struct intel_crtc *crtc)
@@ -305,7 +305,6 @@ static const struct drm_crtc_funcs i8xx_crtc_funcs = {
int intel_crtc_init(struct intel_display *display, enum pipe pipe)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
struct intel_plane *primary, *cursor;
const struct drm_crtc_funcs *funcs;
struct intel_crtc *crtc;
@@ -333,7 +332,7 @@ int intel_crtc_init(struct intel_display *display, enum pipe pipe)
for_each_sprite(display, pipe, sprite) {
struct intel_plane *plane;
if (DISPLAY_VER(dev_priv) >= 9)
if (DISPLAY_VER(display) >= 9)
plane = skl_universal_plane_create(display, pipe, PLANE_2 + sprite);
else
plane = intel_sprite_plane_create(display, pipe, sprite);

View File

@@ -9,10 +9,11 @@
#include <drm/drm_blend.h>
#include <drm/drm_damage_helper.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_print.h>
#include <drm/drm_vblank.h>
#include "i915_drv.h"
#include "i915_reg.h"
#include "i915_utils.h"
#include "intel_atomic.h"
#include "intel_atomic_plane.h"
#include "intel_cursor.h"

View File

@@ -6,8 +6,10 @@
#include <linux/log2.h>
#include <linux/math64.h>
#include "i915_drv.h"
#include <drm/drm_print.h>
#include "i915_reg.h"
#include "i915_utils.h"
#include "intel_cx0_phy.h"
#include "intel_cx0_phy_regs.h"
#include "intel_ddi.h"

View File

@@ -30,11 +30,13 @@
#include <drm/display/drm_dp_helper.h>
#include <drm/display/drm_scdc_helper.h>
#include <drm/drm_print.h>
#include <drm/drm_privacy_screen_consumer.h>
#include "i915_drv.h"
#include "i915_reg.h"
#include "i915_utils.h"
#include "icl_dsi.h"
#include "intel_alpm.h"
#include "intel_audio.h"
#include "intel_audio_regs.h"
#include "intel_backlight.h"
@@ -3553,6 +3555,7 @@ static void intel_ddi_disable_dp(struct intel_atomic_state *state,
intel_dp->link.active = false;
intel_psr_disable(intel_dp, old_crtc_state);
intel_alpm_disable(intel_dp);
intel_edp_backlight_off(old_conn_state);
/* Disable the decompression in DP Sink */
intel_dp_sink_disable_decompression(state,
@@ -4902,9 +4905,7 @@ static enum hpd_pin tgl_hpd_pin(struct intel_display *display, enum port port)
static enum hpd_pin rkl_hpd_pin(struct intel_display *display, enum port port)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
if (HAS_PCH_TGP(dev_priv))
if (HAS_PCH_TGP(display))
return tgl_hpd_pin(display, port);
if (port >= PORT_TC1)
@@ -4923,12 +4924,10 @@ static enum hpd_pin icl_hpd_pin(struct intel_display *display, enum port port)
static enum hpd_pin ehl_hpd_pin(struct intel_display *display, enum port port)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
if (port == PORT_D)
return HPD_PORT_A;
if (HAS_PCH_TGP(dev_priv))
if (HAS_PCH_TGP(display))
return icl_hpd_pin(display, port);
return HPD_PORT_A + port - PORT_A;
@@ -4936,9 +4935,7 @@ static enum hpd_pin ehl_hpd_pin(struct intel_display *display, enum port port)
static enum hpd_pin skl_hpd_pin(struct intel_display *display, enum port port)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
if (HAS_PCH_TGP(dev_priv))
if (HAS_PCH_TGP(display))
return icl_hpd_pin(display, port);
return HPD_PORT_A + port - PORT_A;

View File

@@ -6,7 +6,6 @@
#ifndef __INTEL_DE_H__
#define __INTEL_DE_H__
#include "intel_display_conversion.h"
#include "intel_display_core.h"
#include "intel_dmc_wl.h"
#include "intel_dsb.h"
@@ -19,7 +18,7 @@ static inline struct intel_uncore *__to_uncore(struct intel_display *display)
}
static inline u32
__intel_de_read(struct intel_display *display, i915_reg_t reg)
intel_de_read(struct intel_display *display, i915_reg_t reg)
{
u32 val;
@@ -31,7 +30,6 @@ __intel_de_read(struct intel_display *display, i915_reg_t reg)
return val;
}
#define intel_de_read(p,...) __intel_de_read(__to_intel_display(p), __VA_ARGS__)
static inline u8
intel_de_read8(struct intel_display *display, i915_reg_t reg)
@@ -66,7 +64,7 @@ intel_de_read64_2x32(struct intel_display *display,
}
static inline void
__intel_de_posting_read(struct intel_display *display, i915_reg_t reg)
intel_de_posting_read(struct intel_display *display, i915_reg_t reg)
{
intel_dmc_wl_get(display, reg);
@@ -74,10 +72,9 @@ __intel_de_posting_read(struct intel_display *display, i915_reg_t reg)
intel_dmc_wl_put(display, reg);
}
#define intel_de_posting_read(p,...) __intel_de_posting_read(__to_intel_display(p), __VA_ARGS__)
static inline void
__intel_de_write(struct intel_display *display, i915_reg_t reg, u32 val)
intel_de_write(struct intel_display *display, i915_reg_t reg, u32 val)
{
intel_dmc_wl_get(display, reg);
@@ -85,7 +82,6 @@ __intel_de_write(struct intel_display *display, i915_reg_t reg, u32 val)
intel_dmc_wl_put(display, reg);
}
#define intel_de_write(p,...) __intel_de_write(__to_intel_display(p), __VA_ARGS__)
static inline u32
__intel_de_rmw_nowl(struct intel_display *display, i915_reg_t reg,
@@ -95,8 +91,7 @@ __intel_de_rmw_nowl(struct intel_display *display, i915_reg_t reg,
}
static inline u32
__intel_de_rmw(struct intel_display *display, i915_reg_t reg, u32 clear,
u32 set)
intel_de_rmw(struct intel_display *display, i915_reg_t reg, u32 clear, u32 set)
{
u32 val;
@@ -108,7 +103,6 @@ __intel_de_rmw(struct intel_display *display, i915_reg_t reg, u32 clear,
return val;
}
#define intel_de_rmw(p,...) __intel_de_rmw(__to_intel_display(p), __VA_ARGS__)
static inline int
__intel_de_wait_for_register_nowl(struct intel_display *display,

View File

@@ -55,6 +55,7 @@
#include "i9xx_plane.h"
#include "i9xx_plane_regs.h"
#include "i9xx_wm.h"
#include "intel_alpm.h"
#include "intel_atomic.h"
#include "intel_atomic_plane.h"
#include "intel_audio.h"
@@ -1043,14 +1044,13 @@ static void intel_post_plane_update(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
struct intel_display *display = to_intel_display(state);
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
const struct intel_crtc_state *old_crtc_state =
intel_atomic_get_old_crtc_state(state, crtc);
const struct intel_crtc_state *new_crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
enum pipe pipe = crtc->pipe;
intel_frontbuffer_flip(dev_priv, new_crtc_state->fb_bits);
intel_frontbuffer_flip(display, new_crtc_state->fb_bits);
if (new_crtc_state->update_wm_post && new_crtc_state->hw.active)
intel_update_watermarks(display);
@@ -1079,6 +1079,8 @@ static void intel_post_plane_update(struct intel_atomic_state *state,
if (audio_enabling(old_crtc_state, new_crtc_state))
intel_encoders_audio_enable(state, crtc);
intel_alpm_post_plane_update(state, crtc);
intel_psr_post_plane_update(state, crtc);
}
@@ -1174,6 +1176,7 @@ static void intel_pre_plane_update(struct intel_atomic_state *state,
intel_atomic_get_new_crtc_state(state, crtc);
enum pipe pipe = crtc->pipe;
intel_alpm_pre_plane_update(state, crtc);
intel_psr_pre_plane_update(state, crtc);
if (intel_crtc_vrr_disabling(state, crtc)) {
@@ -1281,7 +1284,7 @@ static void intel_pre_plane_update(struct intel_atomic_state *state,
static void intel_crtc_disable_planes(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
struct intel_display *display = to_intel_display(state);
const struct intel_crtc_state *new_crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
unsigned int update_mask = new_crtc_state->update_planes;
@@ -1303,7 +1306,7 @@ static void intel_crtc_disable_planes(struct intel_atomic_state *state,
fb_bits |= plane->frontbuffer_bit;
}
intel_frontbuffer_flip(dev_priv, fb_bits);
intel_frontbuffer_flip(display, fb_bits);
}
static void intel_encoders_update_prepare(struct intel_atomic_state *state)
@@ -1510,7 +1513,6 @@ static void ilk_crtc_enable(struct intel_atomic_state *state,
struct intel_display *display = to_intel_display(crtc);
const struct intel_crtc_state *new_crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum pipe pipe = crtc->pipe;
if (drm_WARN_ON(display->drm, crtc->active))
@@ -1562,7 +1564,7 @@ static void ilk_crtc_enable(struct intel_atomic_state *state,
intel_encoders_enable(state, crtc);
if (HAS_PCH_CPT(dev_priv))
if (HAS_PCH_CPT(display))
intel_wait_for_pipe_scanline_moving(crtc);
/*
@@ -2404,14 +2406,6 @@ static int intel_crtc_compute_pipe_mode(struct intel_crtc_state *crtc_state)
return 0;
}
static bool intel_crtc_needs_wa_14015401596(const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
return intel_vrr_possible(crtc_state) && crtc_state->has_psr &&
IS_DISPLAY_VER(display, 13, 14);
}
static int intel_crtc_vblank_delay(const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
@@ -2420,9 +2414,7 @@ static int intel_crtc_vblank_delay(const struct intel_crtc_state *crtc_state)
if (!HAS_DSB(display))
return 0;
/* Wa_14015401596 */
if (intel_crtc_needs_wa_14015401596(crtc_state))
vblank_delay = max(vblank_delay, 1);
vblank_delay = max(vblank_delay, intel_psr_min_vblank_delay(crtc_state));
return vblank_delay;
}
@@ -2534,15 +2526,13 @@ intel_link_compute_m_n(u16 bits_per_pixel_x16, int nlanes,
void intel_panel_sanitize_ssc(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
/*
* There may be no VBT; and if the BIOS enabled SSC we can
* just keep using it to avoid unnecessary flicker. Whereas if the
* BIOS isn't using it, don't assume it will work even if the VBT
* indicates as much.
*/
if (HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv)) {
if (HAS_PCH_IBX(display) || HAS_PCH_CPT(display)) {
bool bios_lvds_use_ssc = intel_de_read(display,
PCH_DREF_CONTROL) &
DREF_SSC1_ENABLE;
@@ -2724,6 +2714,19 @@ static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_sta
intel_de_write(display, TRANS_VTOTAL(display, pipe),
VACTIVE(crtc_vdisplay - 1) |
VTOTAL(crtc_vtotal - 1));
if (DISPLAY_VER(display) >= 30) {
/*
* Address issues for resolutions with high refresh rate that
* have small Hblank, specifically where Hblank is smaller than
* one MTP. Simulations indicate this will address the
* jitter issues that currently causes BS to be immediately
* followed by BE which DPRX devices are unable to handle.
* https://groups.vesa.org/wg/DP/document/20494
*/
intel_de_write(display, DP_MIN_HBLANK_CTL(cpu_transcoder),
crtc_state->min_hblank);
}
}
static void intel_set_transcoder_timings_lrr(const struct intel_crtc_state *crtc_state)
@@ -2867,6 +2870,10 @@ static void intel_get_transcoder_timings(struct intel_crtc *crtc,
adjusted_mode->crtc_vdisplay +
intel_de_read(display,
TRANS_SET_CONTEXT_LATENCY(display, cpu_transcoder));
if (DISPLAY_VER(display) >= 30)
pipe_config->min_hblank = intel_de_read(display,
DP_MIN_HBLANK_CTL(cpu_transcoder));
}
static void intel_joiner_adjust_pipe_src(struct intel_crtc_state *crtc_state)
@@ -5217,6 +5224,8 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
PIPE_CONF_CHECK_I(lane_count);
PIPE_CONF_CHECK_X(lane_lat_optim_mask);
PIPE_CONF_CHECK_I(min_hblank);
if (HAS_DOUBLE_BUFFERED_M_N(display)) {
if (!fastset || !pipe_config->update_m_n)
PIPE_CONF_CHECK_M_N(dp_m_n);
@@ -6547,7 +6556,6 @@ static void intel_pipe_fastset(const struct intel_crtc_state *old_crtc_state,
{
struct intel_display *display = to_intel_display(new_crtc_state);
struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
/*
* Update pipe size and adjust fitter if needed: the reason for this is
@@ -6563,7 +6571,7 @@ static void intel_pipe_fastset(const struct intel_crtc_state *old_crtc_state,
if (DISPLAY_VER(display) >= 9) {
if (new_crtc_state->pch_pfit.enabled)
skl_pfit_enable(new_crtc_state);
} else if (HAS_PCH_SPLIT(dev_priv)) {
} else if (HAS_PCH_SPLIT(display)) {
if (new_crtc_state->pch_pfit.enabled)
ilk_pfit_enable(new_crtc_state);
else if (old_crtc_state->pch_pfit.enabled)
@@ -6664,6 +6672,8 @@ static void intel_enable_crtc(struct intel_atomic_state *state,
intel_crtc_update_active_timings(pipe_crtc_state, false);
}
intel_psr_notify_pipe_change(state, crtc, true);
display->funcs.display->crtc_enable(state, crtc);
/* vblanks work again, re-enable pipe CRC. */
@@ -6783,6 +6793,8 @@ static void intel_old_crtc_state_disables(struct intel_atomic_state *state,
intel_crtc_joined_pipe_mask(old_crtc_state))
intel_crtc_disable_pipe_crc(pipe_crtc);
intel_psr_notify_pipe_change(state, crtc, false);
display->funcs.display->crtc_disable(state, crtc);
for_each_intel_crtc_in_pipe_mask(display->drm, pipe_crtc,
@@ -7639,15 +7651,13 @@ static bool ilk_has_edp_a(struct intel_display *display)
static bool intel_ddi_crt_present(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
if (DISPLAY_VER(display) >= 9)
return false;
if (display->platform.haswell_ult || display->platform.broadwell_ult)
return false;
if (HAS_PCH_LPT_H(dev_priv) &&
if (HAS_PCH_LPT_H(display) &&
intel_de_read(display, SFUSE_STRAP) & SFUSE_STRAP_CRT_DISABLED)
return false;
@@ -7669,7 +7679,6 @@ bool assert_port_valid(struct intel_display *display, enum port port)
void intel_setup_outputs(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
struct intel_encoder *encoder;
bool dpd_is_edp = false;
@@ -7686,7 +7695,7 @@ void intel_setup_outputs(struct intel_display *display)
if (display->platform.geminilake || display->platform.broxton)
vlv_dsi_init(display);
} else if (HAS_PCH_SPLIT(dev_priv)) {
} else if (HAS_PCH_SPLIT(display)) {
int found;
/*
@@ -8054,13 +8063,11 @@ static const struct intel_display_funcs i9xx_display_funcs = {
*/
void intel_init_display_hooks(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
if (DISPLAY_VER(display) >= 9) {
display->funcs.display = &skl_display_funcs;
} else if (HAS_DDI(display)) {
display->funcs.display = &ddi_display_funcs;
} else if (HAS_PCH_SPLIT(dev_priv)) {
} else if (HAS_PCH_SPLIT(display)) {
display->funcs.display = &pch_split_display_funcs;
} else if (display->platform.cherryview ||
display->platform.valleyview) {

View File

@@ -21,17 +21,15 @@
#include "intel_display_limits.h"
#include "intel_display_params.h"
#include "intel_display_power.h"
#include "intel_dmc_wl.h"
#include "intel_dpll_mgr.h"
#include "intel_fbc.h"
#include "intel_global_state.h"
#include "intel_gmbus.h"
#include "intel_opregion.h"
#include "intel_dmc_wl.h"
#include "intel_pch.h"
#include "intel_wm_types.h"
struct task_struct;
struct drm_i915_private;
struct drm_property;
struct drm_property_blob;
struct i915_audio_component;
@@ -52,6 +50,7 @@ struct intel_hotplug_funcs;
struct intel_initial_plane_config;
struct intel_opregion;
struct intel_overlay;
struct task_struct;
/* Amount of SAGV/QGV points, BSpec precisely defines this */
#define I915_NUM_QGV_POINTS 8
@@ -180,7 +179,7 @@ struct intel_hotplug {
/*
* Queuing of hotplug_work, reenable_work and poll_init_work is
* enabled. Protected by drm_i915_private::irq_lock.
* enabled. Protected by intel_display::irq::lock.
*/
bool detection_work_enabled;
@@ -289,6 +288,9 @@ struct intel_display {
/* Platform (and subplatform, if any) identification */
struct intel_display_platforms platform;
/* Intel PCH: where the south display engine lives */
enum intel_pch pch_type;
/* Display functions */
struct {
/* Top level crtc-ish functions */
@@ -426,7 +428,7 @@ struct intel_display {
* reused when sending message to gsc cs.
* this is only populated post Meteorlake
*/
struct intel_hdcp_gsc_message *hdcp_message;
struct intel_hdcp_gsc_context *gsc_context;
/* Mutex to protect the above hdcp related values. */
struct mutex hdcp_mutex;
} hdcp;
@@ -454,6 +456,9 @@ struct intel_display {
} ips;
struct {
/* protects the irq masks */
spinlock_t lock;
/*
* Most platforms treat the display irq block as an always-on
* power domain. vlv/chv can disable it at runtime and need
@@ -466,9 +471,9 @@ struct intel_display {
/* For i915gm/i945gm vblank irq workaround */
u8 vblank_enabled;
int vblank_wa_num_pipes;
int vblank_enable_count;
struct work_struct vblank_dc_work;
struct work_struct vblank_notify_work;
u32 de_irq_mask[I915_MAX_PIPES];
u32 pipestat_irq_mask[I915_MAX_PIPES];
@@ -575,6 +580,8 @@ struct intel_display {
struct intel_vbt_data vbt;
struct intel_dmc_wl wl;
struct intel_wm wm;
struct work_struct psr_dc5_dc6_wa_work;
};
#endif /* __INTEL_DISPLAY_CORE_H__ */

View File

@@ -7,11 +7,12 @@
#include <linux/string_helpers.h>
#include <drm/drm_debugfs.h>
#include <drm/drm_drv.h>
#include <drm/drm_edid.h>
#include <drm/drm_file.h>
#include <drm/drm_fourcc.h>
#include "hsw_ips.h"
#include "i915_drv.h"
#include "i915_irq.h"
#include "i915_reg.h"
#include "i9xx_wm_regs.h"
@@ -53,10 +54,9 @@ static struct intel_display *node_to_intel_display(struct drm_info_node *node)
static int intel_display_caps(struct seq_file *m, void *data)
{
struct intel_display *display = node_to_intel_display(m->private);
struct drm_i915_private *i915 = to_i915(display->drm);
struct drm_printer p = drm_seq_file_printer(m);
drm_printf(&p, "PCH type: %d\n", INTEL_PCH_TYPE(i915));
drm_printf(&p, "PCH type: %d\n", INTEL_PCH_TYPE(display));
intel_display_device_info_print(DISPLAY_INFO(display),
DISPLAY_RUNTIME_INFO(display), &p);
@@ -85,7 +85,6 @@ static int i915_frontbuffer_tracking(struct seq_file *m, void *unused)
static int i915_sr_status(struct seq_file *m, void *unused)
{
struct intel_display *display = node_to_intel_display(m->private);
struct drm_i915_private *dev_priv = to_i915(display->drm);
intel_wakeref_t wakeref;
bool sr_enabled = false;
@@ -93,7 +92,7 @@ static int i915_sr_status(struct seq_file *m, void *unused)
if (DISPLAY_VER(display) >= 9)
/* no global SR status; inspect per-plane WM */;
else if (HAS_PCH_SPLIT(dev_priv))
else if (HAS_PCH_SPLIT(display))
sr_enabled = intel_de_read(display, WM1_LP_ILK) & WM_LP_ENABLE;
else if (display->platform.i965gm || display->platform.g4x ||
display->platform.i945g || display->platform.i945gm)
@@ -558,6 +557,8 @@ static void intel_crtc_info(struct seq_file *m, struct intel_crtc *crtc)
seq_printf(m, "\tpipe src=" DRM_RECT_FMT ", dither=%s, bpp=%d\n",
DRM_RECT_ARG(&crtc_state->pipe_src),
str_yes_no(crtc_state->dither), crtc_state->pipe_bpp);
seq_printf(m, "\tport_clock=%d, lane_count=%d\n",
crtc_state->port_clock, crtc_state->lane_count);
intel_scaler_info(m, crtc);

View File

@@ -3,11 +3,13 @@
* Copyright © 2023 Intel Corporation
*/
#include <drm/intel/pciids.h>
#include <drm/drm_color_mgmt.h>
#include <linux/pci.h>
#include "i915_drv.h"
#include <drm/drm_color_mgmt.h>
#include <drm/drm_drv.h>
#include <drm/drm_print.h>
#include <drm/intel/pciids.h>
#include "i915_reg.h"
#include "intel_cx0_phy_regs.h"
#include "intel_de.h"
@@ -1711,7 +1713,6 @@ void intel_display_device_remove(struct intel_display *display)
static void __intel_display_device_info_runtime_init(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
struct intel_display_runtime_info *display_runtime = DISPLAY_RUNTIME_INFO(display);
enum pipe pipe;
@@ -1775,7 +1776,7 @@ static void __intel_display_device_info_runtime_init(struct intel_display *displ
goto display_fused_off;
}
if (IS_DISPLAY_VER(display, 7, 8) && HAS_PCH_SPLIT(i915)) {
if (IS_DISPLAY_VER(display, 7, 8) && HAS_PCH_SPLIT(display)) {
u32 fuse_strap = intel_de_read(display, FUSE_STRAP);
u32 sfuse_strap = intel_de_read(display, SFUSE_STRAP);
@@ -1790,7 +1791,7 @@ static void __intel_display_device_info_runtime_init(struct intel_display *displ
*/
if (fuse_strap & ILK_INTERNAL_DISPLAY_DISABLE ||
sfuse_strap & SFUSE_STRAP_DISPLAY_DISABLED ||
(HAS_PCH_CPT(i915) &&
(HAS_PCH_CPT(display) &&
!(sfuse_strap & SFUSE_STRAP_FUSE_LOCK))) {
drm_info(display->drm,
"Display fused off, disabling\n");

View File

@@ -54,6 +54,7 @@
#include "intel_plane_initial.h"
#include "intel_pmdemand.h"
#include "intel_pps.h"
#include "intel_psr.h"
#include "intel_quirks.h"
#include "intel_vga.h"
#include "intel_wm.h"
@@ -180,6 +181,9 @@ static void intel_plane_possible_crtcs_init(struct intel_display *display)
void intel_display_driver_early_probe(struct intel_display *display)
{
/* This must be called before any calls to HAS_PCH_* */
intel_pch_detect(display);
if (!HAS_DISPLAY(display))
return;
@@ -223,6 +227,8 @@ int intel_display_driver_probe_noirq(struct intel_display *display)
if (ret)
goto cleanup_bios;
intel_psr_dc5_dc6_wa_init(display);
/* FIXME: completely on the wrong abstraction layer */
ret = intel_power_domains_init(display);
if (ret < 0)
@@ -415,7 +421,6 @@ bool intel_display_driver_check_access(struct intel_display *display)
/* part #2: call after irq install, but before gem init */
int intel_display_driver_probe_nogem(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
enum pipe pipe;
int ret;
@@ -453,8 +458,6 @@ int intel_display_driver_probe_nogem(struct intel_display *display)
intel_hti_init(display);
/* Just disable it once at startup */
intel_vga_disable(display);
intel_setup_outputs(display);
ret = intel_dp_tunnel_mgr_init(display);
@@ -464,7 +467,7 @@ int intel_display_driver_probe_nogem(struct intel_display *display)
intel_display_driver_disable_user_access(display);
drm_modeset_lock_all(display->drm);
intel_modeset_setup_hw_state(i915, display->drm->mode_config.acquire_ctx);
intel_modeset_setup_hw_state(display, display->drm->mode_config.acquire_ctx);
intel_acpi_assign_connector_fwnodes(display);
drm_modeset_unlock_all(display->drm);
@@ -525,7 +528,6 @@ int intel_display_driver_probe(struct intel_display *display)
void intel_display_driver_register(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
struct drm_printer p = drm_dbg_printer(display->drm, DRM_UT_KMS,
"i915 display info:");
@@ -552,7 +554,7 @@ void intel_display_driver_register(struct intel_display *display)
drm_kms_helper_poll_init(display->drm);
intel_hpd_poll_disable(display);
intel_fbdev_setup(i915);
intel_fbdev_setup(display);
intel_display_device_info_print(DISPLAY_INFO(display),
DISPLAY_RUNTIME_INFO(display), &p);
@@ -687,13 +689,11 @@ __intel_display_driver_resume(struct intel_display *display,
struct drm_atomic_state *state,
struct drm_modeset_acquire_ctx *ctx)
{
struct drm_i915_private *i915 = to_i915(display->drm);
struct drm_crtc_state *crtc_state;
struct drm_crtc *crtc;
int ret, i;
intel_modeset_setup_hw_state(i915, ctx);
intel_vga_redisable(display);
intel_modeset_setup_hw_state(display, ctx);
if (!state)
return 0;

View File

@@ -5,7 +5,6 @@
#include <drm/drm_vblank.h>
#include "gt/intel_rps.h"
#include "i915_drv.h"
#include "i915_irq.h"
#include "i915_reg.h"
@@ -15,6 +14,7 @@
#include "intel_de.h"
#include "intel_display_irq.h"
#include "intel_display_rpm.h"
#include "intel_display_rps.h"
#include "intel_display_trace.h"
#include "intel_display_types.h"
#include "intel_dmc_wl.h"
@@ -135,7 +135,7 @@ void ilk_update_display_irq(struct intel_display *display,
struct drm_i915_private *dev_priv = to_i915(display->drm);
u32 new_val;
lockdep_assert_held(&dev_priv->irq_lock);
lockdep_assert_held(&display->irq.lock);
drm_WARN_ON(display->drm, enabled_irq_mask & ~interrupt_mask);
new_val = dev_priv->irq_mask;
@@ -173,7 +173,7 @@ void bdw_update_port_irq(struct intel_display *display,
u32 new_val;
u32 old_val;
lockdep_assert_held(&dev_priv->irq_lock);
lockdep_assert_held(&display->irq.lock);
drm_WARN_ON(display->drm, enabled_irq_mask & ~interrupt_mask);
@@ -206,7 +206,7 @@ static void bdw_update_pipe_irq(struct intel_display *display,
struct drm_i915_private *dev_priv = to_i915(display->drm);
u32 new_val;
lockdep_assert_held(&dev_priv->irq_lock);
lockdep_assert_held(&display->irq.lock);
drm_WARN_ON(display->drm, enabled_irq_mask & ~interrupt_mask);
@@ -254,7 +254,7 @@ void ibx_display_interrupt_update(struct intel_display *display,
drm_WARN_ON(display->drm, enabled_irq_mask & ~interrupt_mask);
lockdep_assert_held(&dev_priv->irq_lock);
lockdep_assert_held(&display->irq.lock);
if (drm_WARN_ON(display->drm, !intel_irqs_enabled(dev_priv)))
return;
@@ -276,11 +276,10 @@ void ibx_disable_display_interrupt(struct intel_display *display, u32 bits)
u32 i915_pipestat_enable_mask(struct intel_display *display,
enum pipe pipe)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
u32 status_mask = display->irq.pipestat_irq_mask[pipe];
u32 enable_mask = status_mask << 16;
lockdep_assert_held(&dev_priv->irq_lock);
lockdep_assert_held(&display->irq.lock);
if (DISPLAY_VER(display) < 5)
goto out;
@@ -329,7 +328,7 @@ void i915_enable_pipestat(struct intel_display *display,
"pipe %c: status_mask=0x%x\n",
pipe_name(pipe), status_mask);
lockdep_assert_held(&dev_priv->irq_lock);
lockdep_assert_held(&display->irq.lock);
drm_WARN_ON(display->drm, !intel_irqs_enabled(dev_priv));
if ((display->irq.pipestat_irq_mask[pipe] & status_mask) == status_mask)
@@ -353,7 +352,7 @@ void i915_disable_pipestat(struct intel_display *display,
"pipe %c: status_mask=0x%x\n",
pipe_name(pipe), status_mask);
lockdep_assert_held(&dev_priv->irq_lock);
lockdep_assert_held(&display->irq.lock);
drm_WARN_ON(display->drm, !intel_irqs_enabled(dev_priv));
if ((display->irq.pipestat_irq_mask[pipe] & status_mask) == 0)
@@ -377,28 +376,23 @@ static bool i915_has_legacy_blc_interrupt(struct intel_display *display)
return IS_DISPLAY_VER(display, 3, 4) && display->platform.mobile;
}
/**
* i915_enable_asle_pipestat - enable ASLE pipestat for OpRegion
* @display: display device
*/
void i915_enable_asle_pipestat(struct intel_display *display)
/* enable ASLE pipestat for OpRegion */
static void i915_enable_asle_pipestat(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
if (!intel_opregion_asle_present(display))
return;
if (!i915_has_legacy_blc_interrupt(display))
return;
spin_lock_irq(&dev_priv->irq_lock);
spin_lock_irq(&display->irq.lock);
i915_enable_pipestat(display, PIPE_B, PIPE_LEGACY_BLC_EVENT_STATUS);
if (DISPLAY_VER(display) >= 4)
i915_enable_pipestat(display, PIPE_A,
PIPE_LEGACY_BLC_EVENT_STATUS);
spin_unlock_irq(&dev_priv->irq_lock);
spin_unlock_irq(&display->irq.lock);
}
#if IS_ENABLED(CONFIG_DEBUG_FS)
@@ -517,14 +511,13 @@ static void i9xx_pipestat_irq_reset(struct intel_display *display)
void i9xx_pipestat_irq_ack(struct intel_display *display,
u32 iir, u32 pipe_stats[I915_MAX_PIPES])
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
enum pipe pipe;
spin_lock(&dev_priv->irq_lock);
spin_lock(&display->irq.lock);
if ((display->platform.valleyview || display->platform.cherryview) &&
!display->irq.vlv_display_irqs_enabled) {
spin_unlock(&dev_priv->irq_lock);
spin_unlock(&display->irq.lock);
return;
}
@@ -579,7 +572,7 @@ void i9xx_pipestat_irq_ack(struct intel_display *display,
intel_de_write(display, reg, enable_mask);
}
}
spin_unlock(&dev_priv->irq_lock);
spin_unlock(&display->irq.lock);
}
void i915_pipestat_irq_handler(struct intel_display *display,
@@ -879,7 +872,6 @@ static void ilk_gtt_fault_irq_handler(struct intel_display *display)
void ilk_display_irq_handler(struct intel_display *display, u32 de_iir)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
enum pipe pipe;
u32 hotplug_trigger = de_iir & DE_DP_A_HOTPLUG;
@@ -916,7 +908,7 @@ void ilk_display_irq_handler(struct intel_display *display, u32 de_iir)
if (de_iir & DE_PCH_EVENT) {
u32 pch_iir = intel_de_read(display, SDEIIR);
if (HAS_PCH_CPT(dev_priv))
if (HAS_PCH_CPT(display))
cpt_irq_handler(display, pch_iir);
else
ibx_irq_handler(display, pch_iir);
@@ -926,12 +918,11 @@ void ilk_display_irq_handler(struct intel_display *display, u32 de_iir)
}
if (DISPLAY_VER(display) == 5 && de_iir & DE_PCU_EVENT)
gen5_rps_irq_handler(&to_gt(dev_priv)->rps);
ilk_display_rps_irq_handler(display);
}
void ivb_display_irq_handler(struct intel_display *display, u32 de_iir)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
enum pipe pipe;
u32 hotplug_trigger = de_iir & DE_DP_A_HOTPLUG_IVB;
@@ -969,7 +960,7 @@ void ivb_display_irq_handler(struct intel_display *display, u32 de_iir)
}
/* check event from PCH */
if (!HAS_PCH_NOP(dev_priv) && (de_iir & DE_PCH_EVENT_IVB)) {
if (!HAS_PCH_NOP(display) && (de_iir & DE_PCH_EVENT_IVB)) {
u32 pch_iir = intel_de_read(display, SDEIIR);
cpt_irq_handler(display, pch_iir);
@@ -1311,7 +1302,6 @@ static u32 gen8_de_pipe_flip_done_mask(struct intel_display *display)
static void gen8_read_and_ack_pch_irqs(struct intel_display *display, u32 *pch_iir, u32 *pica_iir)
{
struct drm_i915_private *i915 = to_i915(display->drm);
u32 pica_ier = 0;
*pica_iir = 0;
@@ -1325,7 +1315,7 @@ static void gen8_read_and_ack_pch_irqs(struct intel_display *display, u32 *pch_i
* their flags both in the PICA and SDE IIR.
*/
if (*pch_iir & SDE_PICAINTERRUPT) {
drm_WARN_ON(display->drm, INTEL_PCH_TYPE(i915) < PCH_MTL);
drm_WARN_ON(display->drm, INTEL_PCH_TYPE(display) < PCH_MTL);
pica_ier = intel_de_rmw(display, PICAINTERRUPT_IER, ~0, 0);
*pica_iir = intel_de_read(display, PICAINTERRUPT_IIR);
@@ -1340,7 +1330,6 @@ static void gen8_read_and_ack_pch_irqs(struct intel_display *display, u32 *pch_i
void gen8_de_irq_handler(struct intel_display *display, u32 master_ctl)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
u32 iir;
enum pipe pipe;
@@ -1465,7 +1454,7 @@ void gen8_de_irq_handler(struct intel_display *display, u32 master_ctl)
pipe, fault_errors);
}
if (HAS_PCH_SPLIT(dev_priv) && !HAS_PCH_NOP(dev_priv) &&
if (HAS_PCH_SPLIT(display) && !HAS_PCH_NOP(display) &&
master_ctl & GEN8_DE_PCH_IRQ) {
u32 pica_iir;
@@ -1479,9 +1468,9 @@ void gen8_de_irq_handler(struct intel_display *display, u32 master_ctl)
if (pica_iir)
xelpdp_pica_irq_handler(display, pica_iir);
if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP)
if (INTEL_PCH_TYPE(display) >= PCH_ICP)
icp_irq_handler(display, iir);
else if (INTEL_PCH_TYPE(dev_priv) >= PCH_SPT)
else if (INTEL_PCH_TYPE(display) >= PCH_SPT)
spt_irq_handler(display, iir);
else
cpt_irq_handler(display, iir);
@@ -1573,13 +1562,12 @@ void i915gm_irq_cstate_wa(struct intel_display *display, bool enable)
int i8xx_enable_vblank(struct drm_crtc *crtc)
{
struct intel_display *display = to_intel_display(crtc->dev);
struct drm_i915_private *dev_priv = to_i915(crtc->dev);
enum pipe pipe = to_intel_crtc(crtc)->pipe;
unsigned long irqflags;
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
spin_lock_irqsave(&display->irq.lock, irqflags);
i915_enable_pipestat(display, pipe, PIPE_VBLANK_INTERRUPT_STATUS);
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
spin_unlock_irqrestore(&display->irq.lock, irqflags);
return 0;
}
@@ -1587,13 +1575,12 @@ int i8xx_enable_vblank(struct drm_crtc *crtc)
void i8xx_disable_vblank(struct drm_crtc *crtc)
{
struct intel_display *display = to_intel_display(crtc->dev);
struct drm_i915_private *dev_priv = to_i915(crtc->dev);
enum pipe pipe = to_intel_crtc(crtc)->pipe;
unsigned long irqflags;
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
spin_lock_irqsave(&display->irq.lock, irqflags);
i915_disable_pipestat(display, pipe, PIPE_VBLANK_INTERRUPT_STATUS);
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
spin_unlock_irqrestore(&display->irq.lock, irqflags);
}
int i915gm_enable_vblank(struct drm_crtc *crtc)
@@ -1617,14 +1604,13 @@ void i915gm_disable_vblank(struct drm_crtc *crtc)
int i965_enable_vblank(struct drm_crtc *crtc)
{
struct intel_display *display = to_intel_display(crtc->dev);
struct drm_i915_private *dev_priv = to_i915(crtc->dev);
enum pipe pipe = to_intel_crtc(crtc)->pipe;
unsigned long irqflags;
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
spin_lock_irqsave(&display->irq.lock, irqflags);
i915_enable_pipestat(display, pipe,
PIPE_START_VBLANK_INTERRUPT_STATUS);
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
spin_unlock_irqrestore(&display->irq.lock, irqflags);
return 0;
}
@@ -1632,28 +1618,26 @@ int i965_enable_vblank(struct drm_crtc *crtc)
void i965_disable_vblank(struct drm_crtc *crtc)
{
struct intel_display *display = to_intel_display(crtc->dev);
struct drm_i915_private *dev_priv = to_i915(crtc->dev);
enum pipe pipe = to_intel_crtc(crtc)->pipe;
unsigned long irqflags;
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
spin_lock_irqsave(&display->irq.lock, irqflags);
i915_disable_pipestat(display, pipe,
PIPE_START_VBLANK_INTERRUPT_STATUS);
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
spin_unlock_irqrestore(&display->irq.lock, irqflags);
}
int ilk_enable_vblank(struct drm_crtc *crtc)
{
struct intel_display *display = to_intel_display(crtc->dev);
struct drm_i915_private *dev_priv = to_i915(crtc->dev);
enum pipe pipe = to_intel_crtc(crtc)->pipe;
unsigned long irqflags;
u32 bit = DISPLAY_VER(display) >= 7 ?
DE_PIPE_VBLANK_IVB(pipe) : DE_PIPE_VBLANK(pipe);
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
spin_lock_irqsave(&display->irq.lock, irqflags);
ilk_enable_display_irq(display, bit);
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
spin_unlock_irqrestore(&display->irq.lock, irqflags);
/* Even though there is no DMC, frame counter can get stuck when
* PSR is active as no frames are generated.
@@ -1667,15 +1651,14 @@ int ilk_enable_vblank(struct drm_crtc *crtc)
void ilk_disable_vblank(struct drm_crtc *crtc)
{
struct intel_display *display = to_intel_display(crtc->dev);
struct drm_i915_private *dev_priv = to_i915(crtc->dev);
enum pipe pipe = to_intel_crtc(crtc)->pipe;
unsigned long irqflags;
u32 bit = DISPLAY_VER(display) >= 7 ?
DE_PIPE_VBLANK_IVB(pipe) : DE_PIPE_VBLANK(pipe);
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
spin_lock_irqsave(&display->irq.lock, irqflags);
ilk_disable_display_irq(display, bit);
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
spin_unlock_irqrestore(&display->irq.lock, irqflags);
}
static bool gen11_dsi_configure_te(struct intel_crtc *intel_crtc,
@@ -1701,39 +1684,31 @@ static bool gen11_dsi_configure_te(struct intel_crtc *intel_crtc,
return true;
}
static void intel_display_vblank_dc_work(struct work_struct *work)
static void intel_display_vblank_notify_work(struct work_struct *work)
{
struct intel_display *display =
container_of(work, typeof(*display), irq.vblank_dc_work);
int vblank_wa_num_pipes = READ_ONCE(display->irq.vblank_wa_num_pipes);
container_of(work, typeof(*display), irq.vblank_notify_work);
int vblank_enable_count = READ_ONCE(display->irq.vblank_enable_count);
/*
* NOTE: intel_display_power_set_target_dc_state is used only by PSR
* code for DC3CO handling. DC3CO target state is currently disabled in
* PSR code. If DC3CO is taken into use we need take that into account
* here as well.
*/
intel_display_power_set_target_dc_state(display, vblank_wa_num_pipes ? DC_STATE_DISABLE :
DC_STATE_EN_UPTO_DC6);
intel_psr_notify_vblank_enable_disable(display, vblank_enable_count);
}
int bdw_enable_vblank(struct drm_crtc *_crtc)
{
struct intel_crtc *crtc = to_intel_crtc(_crtc);
struct intel_display *display = to_intel_display(crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum pipe pipe = crtc->pipe;
unsigned long irqflags;
if (gen11_dsi_configure_te(crtc, true))
return 0;
if (crtc->block_dc_for_vblank && display->irq.vblank_wa_num_pipes++ == 0)
schedule_work(&display->irq.vblank_dc_work);
if (crtc->vblank_psr_notify && display->irq.vblank_enable_count++ == 0)
schedule_work(&display->irq.vblank_notify_work);
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
spin_lock_irqsave(&display->irq.lock, irqflags);
bdw_enable_pipe_irq(display, pipe, GEN8_PIPE_VBLANK);
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
spin_unlock_irqrestore(&display->irq.lock, irqflags);
/* Even if there is no DMC, frame counter can get stuck when
* PSR is active as no frames are generated, so check only for PSR.
@@ -1748,19 +1723,18 @@ void bdw_disable_vblank(struct drm_crtc *_crtc)
{
struct intel_crtc *crtc = to_intel_crtc(_crtc);
struct intel_display *display = to_intel_display(crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum pipe pipe = crtc->pipe;
unsigned long irqflags;
if (gen11_dsi_configure_te(crtc, false))
return;
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
spin_lock_irqsave(&display->irq.lock, irqflags);
bdw_disable_pipe_irq(display, pipe, GEN8_PIPE_VBLANK);
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
spin_unlock_irqrestore(&display->irq.lock, irqflags);
if (crtc->block_dc_for_vblank && --display->irq.vblank_wa_num_pipes == 0)
schedule_work(&display->irq.vblank_dc_work);
if (crtc->vblank_psr_notify && --display->irq.vblank_enable_count == 0)
schedule_work(&display->irq.vblank_notify_work);
}
static u32 vlv_dpinvgtt_pipe_fault_mask(enum pipe pipe)
@@ -1894,8 +1868,10 @@ static void _vlv_display_irq_reset(struct intel_display *display)
void vlv_display_irq_reset(struct intel_display *display)
{
spin_lock_irq(&display->irq.lock);
if (display->irq.vlv_display_irqs_enabled)
_vlv_display_irq_reset(display);
spin_unlock_irq(&display->irq.lock);
}
void i9xx_display_irq_reset(struct intel_display *display)
@@ -1908,22 +1884,48 @@ void i9xx_display_irq_reset(struct intel_display *display)
i9xx_pipestat_irq_reset(display);
}
void i915_display_irq_postinstall(struct intel_display *display)
{
/*
* Interrupt setup is already guaranteed to be single-threaded, this is
* just to make the assert_spin_locked check happy.
*/
spin_lock_irq(&display->irq.lock);
i915_enable_pipestat(display, PIPE_A, PIPE_CRC_DONE_INTERRUPT_STATUS);
i915_enable_pipestat(display, PIPE_B, PIPE_CRC_DONE_INTERRUPT_STATUS);
spin_unlock_irq(&display->irq.lock);
i915_enable_asle_pipestat(display);
}
void i965_display_irq_postinstall(struct intel_display *display)
{
/*
* Interrupt setup is already guaranteed to be single-threaded, this is
* just to make the assert_spin_locked check happy.
*/
spin_lock_irq(&display->irq.lock);
i915_enable_pipestat(display, PIPE_A, PIPE_GMBUS_INTERRUPT_STATUS);
i915_enable_pipestat(display, PIPE_A, PIPE_CRC_DONE_INTERRUPT_STATUS);
i915_enable_pipestat(display, PIPE_B, PIPE_CRC_DONE_INTERRUPT_STATUS);
spin_unlock_irq(&display->irq.lock);
i915_enable_asle_pipestat(display);
}
static u32 vlv_error_mask(void)
{
/* TODO enable other errors too? */
return VLV_ERROR_PAGE_TABLE;
}
void vlv_display_irq_postinstall(struct intel_display *display)
static void _vlv_display_irq_postinstall(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
u32 pipestat_mask;
u32 enable_mask;
enum pipe pipe;
if (!display->irq.vlv_display_irqs_enabled)
return;
if (display->platform.cherryview)
intel_de_write(display, DPINVGTT,
DPINVGTT_STATUS_MASK_CHV |
@@ -1960,8 +1962,30 @@ void vlv_display_irq_postinstall(struct intel_display *display)
intel_display_irq_regs_init(display, VLV_IRQ_REGS, dev_priv->irq_mask, enable_mask);
}
void vlv_display_irq_postinstall(struct intel_display *display)
{
spin_lock_irq(&display->irq.lock);
if (display->irq.vlv_display_irqs_enabled)
_vlv_display_irq_postinstall(display);
spin_unlock_irq(&display->irq.lock);
}
void ibx_display_irq_reset(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
if (HAS_PCH_NOP(i915))
return;
gen2_irq_reset(to_intel_uncore(display->drm), SDE_IRQ_REGS);
if (HAS_PCH_CPT(i915) || HAS_PCH_LPT(i915))
intel_de_write(display, SERR_INT, 0xffffffff);
}
void gen8_display_irq_reset(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
enum pipe pipe;
if (!HAS_DISPLAY(display))
@@ -1977,11 +2001,13 @@ void gen8_display_irq_reset(struct intel_display *display)
intel_display_irq_regs_reset(display, GEN8_DE_PORT_IRQ_REGS);
intel_display_irq_regs_reset(display, GEN8_DE_MISC_IRQ_REGS);
if (HAS_PCH_SPLIT(i915))
ibx_display_irq_reset(display);
}
void gen11_display_irq_reset(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
enum pipe pipe;
u32 trans_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
BIT(TRANSCODER_C) | BIT(TRANSCODER_D);
@@ -2026,7 +2052,7 @@ void gen11_display_irq_reset(struct intel_display *display)
else
intel_display_irq_regs_reset(display, GEN11_DE_HPD_IRQ_REGS);
if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP)
if (INTEL_PCH_TYPE(display) >= PCH_ICP)
intel_display_irq_regs_reset(display, SDE_IRQ_REGS);
}
@@ -2038,10 +2064,10 @@ void gen8_irq_power_well_post_enable(struct intel_display *display,
gen8_de_pipe_flip_done_mask(display);
enum pipe pipe;
spin_lock_irq(&dev_priv->irq_lock);
spin_lock_irq(&display->irq.lock);
if (!intel_irqs_enabled(dev_priv)) {
spin_unlock_irq(&dev_priv->irq_lock);
spin_unlock_irq(&display->irq.lock);
return;
}
@@ -2050,7 +2076,7 @@ void gen8_irq_power_well_post_enable(struct intel_display *display,
display->irq.de_irq_mask[pipe],
~display->irq.de_irq_mask[pipe] | extra_ier);
spin_unlock_irq(&dev_priv->irq_lock);
spin_unlock_irq(&display->irq.lock);
}
void gen8_irq_power_well_pre_disable(struct intel_display *display,
@@ -2059,17 +2085,17 @@ void gen8_irq_power_well_pre_disable(struct intel_display *display,
struct drm_i915_private *dev_priv = to_i915(display->drm);
enum pipe pipe;
spin_lock_irq(&dev_priv->irq_lock);
spin_lock_irq(&display->irq.lock);
if (!intel_irqs_enabled(dev_priv)) {
spin_unlock_irq(&dev_priv->irq_lock);
spin_unlock_irq(&display->irq.lock);
return;
}
for_each_pipe_masked(display, pipe, pipe_mask)
intel_display_irq_regs_reset(display, GEN8_DE_PIPE_IRQ_REGS(pipe));
spin_unlock_irq(&dev_priv->irq_lock);
spin_unlock_irq(&display->irq.lock);
/* make sure we're done processing display irqs */
intel_synchronize_irq(dev_priv);
@@ -2088,15 +2114,14 @@ void gen8_irq_power_well_pre_disable(struct intel_display *display,
*/
static void ibx_irq_postinstall(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
u32 mask;
if (HAS_PCH_NOP(dev_priv))
if (HAS_PCH_NOP(display))
return;
if (HAS_PCH_IBX(dev_priv))
if (HAS_PCH_IBX(display))
mask = SDE_GMBUS | SDE_AUX_MASK | SDE_POISON;
else if (HAS_PCH_CPT(dev_priv) || HAS_PCH_LPT(dev_priv))
else if (HAS_PCH_CPT(display) || HAS_PCH_LPT(display))
mask = SDE_GMBUS_CPT | SDE_AUX_MASK_CPT;
else
mask = SDE_GMBUS_CPT;
@@ -2108,32 +2133,37 @@ void valleyview_enable_display_irqs(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
lockdep_assert_held(&dev_priv->irq_lock);
spin_lock_irq(&display->irq.lock);
if (display->irq.vlv_display_irqs_enabled)
return;
goto out;
display->irq.vlv_display_irqs_enabled = true;
if (intel_irqs_enabled(dev_priv)) {
_vlv_display_irq_reset(display);
vlv_display_irq_postinstall(display);
_vlv_display_irq_postinstall(display);
}
out:
spin_unlock_irq(&display->irq.lock);
}
void valleyview_disable_display_irqs(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
lockdep_assert_held(&dev_priv->irq_lock);
spin_lock_irq(&display->irq.lock);
if (!display->irq.vlv_display_irqs_enabled)
return;
goto out;
display->irq.vlv_display_irqs_enabled = false;
if (intel_irqs_enabled(dev_priv))
_vlv_display_irq_reset(display);
out:
spin_unlock_irq(&display->irq.lock);
}
void ilk_de_irq_postinstall(struct intel_display *display)
@@ -2184,8 +2214,6 @@ static void icp_irq_postinstall(struct intel_display *display);
void gen8_de_irq_postinstall(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
u32 de_pipe_masked = gen8_de_pipe_fault_mask(display) |
GEN8_PIPE_CDCLK_CRC_DONE;
u32 de_pipe_enables;
@@ -2201,9 +2229,9 @@ void gen8_de_irq_postinstall(struct intel_display *display)
if (DISPLAY_VER(display) >= 14)
mtp_irq_postinstall(display);
else if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP)
else if (INTEL_PCH_TYPE(display) >= PCH_ICP)
icp_irq_postinstall(display);
else if (HAS_PCH_SPLIT(dev_priv))
else if (HAS_PCH_SPLIT(display))
ibx_irq_postinstall(display);
if (DISPLAY_VER(display) < 11)
@@ -2323,9 +2351,40 @@ void dg1_de_irq_postinstall(struct intel_display *display)
void intel_display_irq_init(struct intel_display *display)
{
spin_lock_init(&display->irq.lock);
display->drm->vblank_disable_immediate = true;
intel_hotplug_irq_init(display);
INIT_WORK(&display->irq.vblank_dc_work, intel_display_vblank_dc_work);
INIT_WORK(&display->irq.vblank_notify_work,
intel_display_vblank_notify_work);
}
struct intel_display_irq_snapshot {
u32 derrmr;
};
struct intel_display_irq_snapshot *
intel_display_irq_snapshot_capture(struct intel_display *display)
{
struct intel_display_irq_snapshot *snapshot;
snapshot = kzalloc(sizeof(*snapshot), GFP_ATOMIC);
if (!snapshot)
return NULL;
if (DISPLAY_VER(display) >= 6 && DISPLAY_VER(display) < 20 && !HAS_GMCH(display))
snapshot->derrmr = intel_de_read(display, DERRMR);
return snapshot;
}
void intel_display_irq_snapshot_print(const struct intel_display_irq_snapshot *snapshot,
struct drm_printer *p)
{
if (!snapshot)
return;
drm_printf(p, "DERRMR: 0x%08x\n", snapshot->derrmr);
}

View File

@@ -12,7 +12,9 @@
enum pipe;
struct drm_crtc;
struct drm_printer;
struct intel_display;
struct intel_display_irq_snapshot;
void valleyview_enable_display_irqs(struct intel_display *display);
void valleyview_disable_display_irqs(struct intel_display *display);
@@ -54,10 +56,13 @@ u32 gen11_gu_misc_irq_ack(struct intel_display *display, const u32 master_ctl);
void gen11_gu_misc_irq_handler(struct intel_display *display, const u32 iir);
void i9xx_display_irq_reset(struct intel_display *display);
void ibx_display_irq_reset(struct intel_display *display);
void vlv_display_irq_reset(struct intel_display *display);
void gen8_display_irq_reset(struct intel_display *display);
void gen11_display_irq_reset(struct intel_display *display);
void i915_display_irq_postinstall(struct intel_display *display);
void i965_display_irq_postinstall(struct intel_display *display);
void vlv_display_irq_postinstall(struct intel_display *display);
void ilk_de_irq_postinstall(struct intel_display *display);
void gen8_de_irq_postinstall(struct intel_display *display);
@@ -67,7 +72,6 @@ void dg1_de_irq_postinstall(struct intel_display *display);
u32 i915_pipestat_enable_mask(struct intel_display *display, enum pipe pipe);
void i915_enable_pipestat(struct intel_display *display, enum pipe pipe, u32 status_mask);
void i915_disable_pipestat(struct intel_display *display, enum pipe pipe, u32 status_mask);
void i915_enable_asle_pipestat(struct intel_display *display);
void i9xx_pipestat_irq_ack(struct intel_display *display, u32 iir, u32 pipe_stats[I915_MAX_PIPES]);
@@ -82,4 +86,7 @@ void intel_display_irq_init(struct intel_display *display);
void i915gm_irq_cstate_wa(struct intel_display *display, bool enable);
struct intel_display_irq_snapshot *intel_display_irq_snapshot_capture(struct intel_display *display);
void intel_display_irq_snapshot_print(const struct intel_display_irq_snapshot *snapshot, struct drm_printer *p);
#endif /* __INTEL_DISPLAY_IRQ_H__ */

View File

@@ -323,6 +323,35 @@ unlock:
mutex_unlock(&power_domains->lock);
}
/**
* intel_display_power_get_current_dc_state - Set target dc state.
* @display: display device
*
* This function set the "DC off" power well target_dc_state,
* based upon this target_dc_stste, "DC off" power well will
* enable desired DC state.
*/
u32 intel_display_power_get_current_dc_state(struct intel_display *display)
{
struct i915_power_well *power_well;
struct i915_power_domains *power_domains = &display->power.domains;
u32 current_dc_state = DC_STATE_DISABLE;
mutex_lock(&power_domains->lock);
power_well = lookup_power_well(display, SKL_DISP_DC_OFF);
if (drm_WARN_ON(display->drm, !power_well))
goto unlock;
current_dc_state = intel_power_well_is_enabled(display, power_well) ?
DC_STATE_DISABLE : power_domains->target_dc_state;
unlock:
mutex_unlock(&power_domains->lock);
return current_dc_state;
}
static void __async_put_domains_mask(struct i915_power_domains *power_domains,
struct intel_power_domain_mask *mask)
{
@@ -1365,11 +1394,9 @@ static void hsw_restore_lcpll(struct intel_display *display)
*/
static void hsw_enable_pc8(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
drm_dbg_kms(display->drm, "Enabling package C8+\n");
if (HAS_PCH_LPT_LP(dev_priv))
if (HAS_PCH_LPT_LP(display))
intel_de_rmw(display, SOUTH_DSPCLK_GATE_D,
PCH_LP_PARTITION_LEVEL_DISABLE, 0);
@@ -1415,14 +1442,13 @@ static void intel_pch_reset_handshake(struct intel_display *display,
static void skl_display_core_init(struct intel_display *display,
bool resume)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
struct i915_power_domains *power_domains = &display->power.domains;
struct i915_power_well *well;
gen9_set_dc_state(display, DC_STATE_DISABLE);
/* enable PCH reset handshake */
intel_pch_reset_handshake(display, !HAS_PCH_NOP(dev_priv));
intel_pch_reset_handshake(display, !HAS_PCH_NOP(display));
if (!HAS_DISPLAY(display))
return;
@@ -1624,20 +1650,19 @@ static void tgl_bw_buddy_init(struct intel_display *display)
static void icl_display_core_init(struct intel_display *display,
bool resume)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
struct i915_power_domains *power_domains = &display->power.domains;
struct i915_power_well *well;
gen9_set_dc_state(display, DC_STATE_DISABLE);
/* Wa_14011294188:ehl,jsl,tgl,rkl,adl-s */
if (INTEL_PCH_TYPE(dev_priv) >= PCH_TGP &&
INTEL_PCH_TYPE(dev_priv) < PCH_DG1)
if (INTEL_PCH_TYPE(display) >= PCH_TGP &&
INTEL_PCH_TYPE(display) < PCH_DG1)
intel_de_rmw(display, SOUTH_DSPCLK_GATE_D, 0,
PCH_DPMGUNIT_CLOCK_GATE_DISABLE);
/* 1. Enable PCH reset handshake. */
intel_pch_reset_handshake(display, !HAS_PCH_NOP(dev_priv));
intel_pch_reset_handshake(display, !HAS_PCH_NOP(display));
if (!HAS_DISPLAY(display))
return;
@@ -1908,7 +1933,6 @@ static void intel_power_domains_verify_state(struct intel_display *display);
*/
void intel_power_domains_init_hw(struct intel_display *display, bool resume)
{
struct drm_i915_private *i915 = to_i915(display->drm);
struct i915_power_domains *power_domains = &display->power.domains;
power_domains->initializing = true;
@@ -1932,9 +1956,9 @@ void intel_power_domains_init_hw(struct intel_display *display, bool resume)
assert_isp_power_gated(display);
} else if (display->platform.broadwell || display->platform.haswell) {
hsw_assert_cdclk(display);
intel_pch_reset_handshake(display, !HAS_PCH_NOP(i915));
intel_pch_reset_handshake(display, !HAS_PCH_NOP(display));
} else if (display->platform.ivybridge) {
intel_pch_reset_handshake(display, !HAS_PCH_NOP(i915));
intel_pch_reset_handshake(display, !HAS_PCH_NOP(display));
}
/*
@@ -2229,8 +2253,6 @@ static void intel_power_domains_verify_state(struct intel_display *display)
void intel_display_power_suspend_late(struct intel_display *display, bool s2idle)
{
struct drm_i915_private *i915 = to_i915(display->drm);
intel_power_domains_suspend(display, s2idle);
if (DISPLAY_VER(display) >= 11 || display->platform.geminilake ||
@@ -2241,14 +2263,12 @@ void intel_display_power_suspend_late(struct intel_display *display, bool s2idle
}
/* Tweaked Wa_14010685332:cnp,icp,jsp,mcc,tgp,adp */
if (INTEL_PCH_TYPE(i915) >= PCH_CNP && INTEL_PCH_TYPE(i915) < PCH_DG1)
intel_de_rmw(i915, SOUTH_CHICKEN1, SBCLK_RUN_REFCLK_DIS, SBCLK_RUN_REFCLK_DIS);
if (INTEL_PCH_TYPE(display) >= PCH_CNP && INTEL_PCH_TYPE(display) < PCH_DG1)
intel_de_rmw(display, SOUTH_CHICKEN1, SBCLK_RUN_REFCLK_DIS, SBCLK_RUN_REFCLK_DIS);
}
void intel_display_power_resume_early(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
if (DISPLAY_VER(display) >= 11 || display->platform.geminilake ||
display->platform.broxton) {
gen9_sanitize_dc_state(display);
@@ -2258,8 +2278,8 @@ void intel_display_power_resume_early(struct intel_display *display)
}
/* Tweaked Wa_14010685332:cnp,icp,jsp,mcc,tgp,adp */
if (INTEL_PCH_TYPE(i915) >= PCH_CNP && INTEL_PCH_TYPE(i915) < PCH_DG1)
intel_de_rmw(i915, SOUTH_CHICKEN1, SBCLK_RUN_REFCLK_DIS, 0);
if (INTEL_PCH_TYPE(display) >= PCH_CNP && INTEL_PCH_TYPE(display) < PCH_DG1)
intel_de_rmw(display, SOUTH_CHICKEN1, SBCLK_RUN_REFCLK_DIS, 0);
intel_power_domains_resume(display);
}

View File

@@ -183,6 +183,7 @@ void intel_display_power_suspend(struct intel_display *display);
void intel_display_power_resume(struct intel_display *display);
void intel_display_power_set_target_dc_state(struct intel_display *display,
u32 state);
u32 intel_display_power_get_current_dc_state(struct intel_display *display);
bool intel_display_power_is_enabled(struct intel_display *display,
enum intel_display_power_domain domain);

View File

@@ -25,6 +25,7 @@
#include "intel_hotplug.h"
#include "intel_pcode.h"
#include "intel_pps.h"
#include "intel_psr.h"
#include "intel_tc.h"
#include "intel_vga.h"
#include "skl_watermark.h"
@@ -760,6 +761,9 @@ void gen9_set_dc_state(struct intel_display *display, u32 state)
state & ~power_domains->allowed_dc_mask))
state &= power_domains->allowed_dc_mask;
if (!power_domains->initializing)
intel_psr_notify_dc5_dc6(display);
val = intel_de_read(display, DC_STATE_EN);
mask = gen9_dc_mask(display);
drm_dbg_kms(display->drm, "Setting DC state from %02x to %02x\n",
@@ -1208,7 +1212,6 @@ static void vlv_init_display_clock_gating(struct intel_display *display)
static void vlv_display_power_well_init(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
struct intel_encoder *encoder;
enum pipe pipe;
@@ -1232,9 +1235,7 @@ static void vlv_display_power_well_init(struct intel_display *display)
vlv_init_display_clock_gating(display);
spin_lock_irq(&dev_priv->irq_lock);
valleyview_enable_display_irqs(display);
spin_unlock_irq(&dev_priv->irq_lock);
/*
* During driver initialization/resume we can avoid restoring the
@@ -1252,7 +1253,7 @@ static void vlv_display_power_well_init(struct intel_display *display)
intel_crt_reset(&encoder->base);
}
intel_vga_redisable_power_on(display);
intel_vga_disable(display);
intel_pps_unlock_regs_wa(display);
}
@@ -1261,9 +1262,7 @@ static void vlv_display_power_well_deinit(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
spin_lock_irq(&dev_priv->irq_lock);
valleyview_disable_display_irqs(display);
spin_unlock_irq(&dev_priv->irq_lock);
/* make sure we're done processing display irqs */
intel_synchronize_irq(dev_priv);

View File

@@ -8,6 +8,8 @@
#include "gt/intel_rps.h"
#include "i915_drv.h"
#include "i915_reg.h"
#include "intel_display_irq.h"
#include "intel_display_rps.h"
#include "intel_display_types.h"
@@ -81,3 +83,24 @@ void intel_display_rps_mark_interactive(struct intel_display *display,
intel_rps_mark_interactive(&to_gt(i915)->rps, interactive);
state->rps_interactive = interactive;
}
void ilk_display_rps_enable(struct intel_display *display)
{
spin_lock(&display->irq.lock);
ilk_enable_display_irq(display, DE_PCU_EVENT);
spin_unlock(&display->irq.lock);
}
void ilk_display_rps_disable(struct intel_display *display)
{
spin_lock(&display->irq.lock);
ilk_disable_display_irq(display, DE_PCU_EVENT);
spin_unlock(&display->irq.lock);
}
void ilk_display_rps_irq_handler(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
gen5_rps_irq_handler(&to_gt(i915)->rps);
}

View File

@@ -13,10 +13,34 @@ struct drm_crtc;
struct intel_atomic_state;
struct intel_display;
#ifdef I915
void intel_display_rps_boost_after_vblank(struct drm_crtc *crtc,
struct dma_fence *fence);
void intel_display_rps_mark_interactive(struct intel_display *display,
struct intel_atomic_state *state,
bool interactive);
void ilk_display_rps_enable(struct intel_display *display);
void ilk_display_rps_disable(struct intel_display *display);
void ilk_display_rps_irq_handler(struct intel_display *display);
#else
static inline void intel_display_rps_boost_after_vblank(struct drm_crtc *crtc,
struct dma_fence *fence)
{
}
static inline void intel_display_rps_mark_interactive(struct intel_display *display,
struct intel_atomic_state *state,
bool interactive)
{
}
static inline void ilk_display_rps_enable(struct intel_display *display)
{
}
static inline void ilk_display_rps_disable(struct intel_display *display)
{
}
static inline void ilk_display_rps_irq_handler(struct intel_display *display)
{
}
#endif
#endif /* __INTEL_DISPLAY_RPS_H__ */

View File

@@ -7,6 +7,7 @@
#include "intel_display_core.h"
#include "intel_display_device.h"
#include "intel_display_irq.h"
#include "intel_display_params.h"
#include "intel_display_snapshot.h"
#include "intel_dmc.h"
@@ -20,6 +21,7 @@ struct intel_display_snapshot {
struct intel_display_params params;
struct intel_overlay_snapshot *overlay;
struct intel_dmc_snapshot *dmc;
struct intel_display_irq_snapshot *irq;
};
struct intel_display_snapshot *intel_display_snapshot_capture(struct intel_display *display)
@@ -38,6 +40,7 @@ struct intel_display_snapshot *intel_display_snapshot_capture(struct intel_displ
intel_display_params_copy(&snapshot->params);
snapshot->irq = intel_display_irq_snapshot_capture(display);
snapshot->overlay = intel_overlay_snapshot_capture(display);
snapshot->dmc = intel_dmc_snapshot_capture(display);
@@ -57,6 +60,7 @@ void intel_display_snapshot_print(const struct intel_display_snapshot *snapshot,
intel_display_device_info_print(&snapshot->info, &snapshot->runtime_info, p);
intel_display_params_dump(&snapshot->params, display->drm->driver->name, p);
intel_display_irq_snapshot_print(snapshot->irq, p);
intel_overlay_snapshot_print(snapshot->overlay, p);
intel_dmc_snapshot_print(snapshot->dmc, p);
}
@@ -68,6 +72,7 @@ void intel_display_snapshot_free(struct intel_display_snapshot *snapshot)
intel_display_params_free(&snapshot->params);
kfree(snapshot->irq);
kfree(snapshot->overlay);
kfree(snapshot->dmc);
kfree(snapshot);

View File

@@ -1114,6 +1114,7 @@ struct intel_crtc_state {
bool wm_level_disabled;
u32 dc3co_exitline;
u16 su_y_granularity;
u8 active_non_psr_pipes;
/*
* Frequency the dpll for the port should run at. Differs from the
@@ -1387,7 +1388,7 @@ struct intel_crtc {
/* armed event for DSB based updates */
struct drm_pending_vblank_event *dsb_event;
/* Access to these should be protected by dev_priv->irq_lock. */
/* Access to these should be protected by display->irq.lock. */
bool cpu_fifo_underrun_disabled;
bool pch_fifo_underrun_disabled;
@@ -1439,7 +1440,7 @@ struct intel_crtc {
struct intel_pipe_crc pipe_crc;
#endif
bool block_dc_for_vblank;
bool vblank_psr_notify;
};
struct intel_plane_error {
@@ -1650,6 +1651,8 @@ struct intel_psr {
u8 entry_setup_frames;
bool link_ok;
u8 active_non_psr_pipes;
};
struct intel_dp {
@@ -1805,12 +1808,16 @@ struct intel_dp {
struct {
u8 io_wake_lines;
u8 fast_wake_lines;
enum transcoder transcoder;
struct mutex lock;
/* LNL and beyond */
u8 check_entry_lines;
u8 aux_less_wake_lines;
u8 silence_period_sym_clocks;
u8 lfps_half_cycle_num_of_syms;
bool lobf_disable_debug;
bool sink_alpm_error;
} alpm_parameters;
u8 alpm_dpcd;

View File

@@ -173,7 +173,6 @@ MODULE_FIRMWARE(BXT_DMC_PATH);
static const char *dmc_firmware_default(struct intel_display *display, u32 *size)
{
struct drm_i915_private *i915 = to_i915(display->drm);
const char *fw_path = NULL;
u32 max_fw_size = 0;
@@ -189,39 +188,39 @@ static const char *dmc_firmware_default(struct intel_display *display, u32 *size
} else if (DISPLAY_VERx100(display) == 1400) {
fw_path = MTL_DMC_PATH;
max_fw_size = XELPDP_DMC_MAX_FW_SIZE;
} else if (IS_DG2(i915)) {
} else if (display->platform.dg2) {
fw_path = DG2_DMC_PATH;
max_fw_size = DISPLAY_VER13_DMC_MAX_FW_SIZE;
} else if (IS_ALDERLAKE_P(i915)) {
} else if (display->platform.alderlake_p) {
fw_path = ADLP_DMC_PATH;
max_fw_size = DISPLAY_VER13_DMC_MAX_FW_SIZE;
} else if (IS_ALDERLAKE_S(i915)) {
} else if (display->platform.alderlake_s) {
fw_path = ADLS_DMC_PATH;
max_fw_size = DISPLAY_VER12_DMC_MAX_FW_SIZE;
} else if (IS_DG1(i915)) {
} else if (display->platform.dg1) {
fw_path = DG1_DMC_PATH;
max_fw_size = DISPLAY_VER12_DMC_MAX_FW_SIZE;
} else if (IS_ROCKETLAKE(i915)) {
} else if (display->platform.rocketlake) {
fw_path = RKL_DMC_PATH;
max_fw_size = DISPLAY_VER12_DMC_MAX_FW_SIZE;
} else if (IS_TIGERLAKE(i915)) {
} else if (display->platform.tigerlake) {
fw_path = TGL_DMC_PATH;
max_fw_size = DISPLAY_VER12_DMC_MAX_FW_SIZE;
} else if (DISPLAY_VER(display) == 11) {
fw_path = ICL_DMC_PATH;
max_fw_size = ICL_DMC_MAX_FW_SIZE;
} else if (IS_GEMINILAKE(i915)) {
} else if (display->platform.geminilake) {
fw_path = GLK_DMC_PATH;
max_fw_size = GLK_DMC_MAX_FW_SIZE;
} else if (IS_KABYLAKE(i915) ||
IS_COFFEELAKE(i915) ||
IS_COMETLAKE(i915)) {
} else if (display->platform.kabylake ||
display->platform.coffeelake ||
display->platform.cometlake) {
fw_path = KBL_DMC_PATH;
max_fw_size = KBL_DMC_MAX_FW_SIZE;
} else if (IS_SKYLAKE(i915)) {
} else if (display->platform.skylake) {
fw_path = SKL_DMC_PATH;
max_fw_size = SKL_DMC_MAX_FW_SIZE;
} else if (IS_BROXTON(i915)) {
} else if (display->platform.broxton) {
fw_path = BXT_DMC_PATH;
max_fw_size = BXT_DMC_MAX_FW_SIZE;
}
@@ -517,6 +516,54 @@ void intel_dmc_disable_pipe(struct intel_display *display, enum pipe pipe)
intel_de_rmw(display, PIPEDMC_CONTROL(pipe), PIPEDMC_ENABLE, 0);
}
/**
* intel_dmc_block_pkgc() - block PKG C-state
* @display: display instance
* @pipe: pipe which register use to block
* @block: block/unblock
*
* This interface is target for Wa_16025596647 usage. I.e. to set/clear
* PIPEDMC_BLOCK_PKGC_SW_BLOCK_PKGC_ALWAYS bit in PIPEDMC_BLOCK_PKGC_SW register.
*/
void intel_dmc_block_pkgc(struct intel_display *display, enum pipe pipe,
bool block)
{
intel_de_rmw(display, PIPEDMC_BLOCK_PKGC_SW(pipe),
PIPEDMC_BLOCK_PKGC_SW_BLOCK_PKGC_ALWAYS, block ?
PIPEDMC_BLOCK_PKGC_SW_BLOCK_PKGC_ALWAYS : 0);
}
/**
* intel_dmc_start_pkgc_exit_at_start_of_undelayed_vblank() - start of PKG
* C-state exit
* @display: display instance
* @pipe: pipe which register use to block
* @enable: enable/disable
*
* This interface is target for Wa_16025596647 usage. I.e. start the package C
* exit at the start of the undelayed vblank
*/
void intel_dmc_start_pkgc_exit_at_start_of_undelayed_vblank(struct intel_display *display,
enum pipe pipe, bool enable)
{
u32 val;
if (enable)
val = DMC_EVT_CTL_ENABLE | DMC_EVT_CTL_RECURRING |
REG_FIELD_PREP(DMC_EVT_CTL_TYPE_MASK,
DMC_EVT_CTL_TYPE_EDGE_0_1) |
REG_FIELD_PREP(DMC_EVT_CTL_EVENT_ID_MASK,
DMC_EVT_CTL_EVENT_ID_VBLANK_A);
else
val = REG_FIELD_PREP(DMC_EVT_CTL_EVENT_ID_MASK,
DMC_EVT_CTL_EVENT_ID_FALSE) |
REG_FIELD_PREP(DMC_EVT_CTL_TYPE_MASK,
DMC_EVT_CTL_TYPE_EDGE_0_1);
intel_de_write(display, MTL_PIPEDMC_EVT_CTL_4(pipe),
val);
}
static bool is_dmc_evt_ctl_reg(struct intel_display *display,
enum intel_dmc_id dmc_id, i915_reg_t reg)
{
@@ -541,8 +588,6 @@ static bool disable_dmc_evt(struct intel_display *display,
enum intel_dmc_id dmc_id,
i915_reg_t reg, u32 data)
{
struct drm_i915_private *i915 = to_i915(display->drm);
if (!is_dmc_evt_ctl_reg(display, dmc_id, reg))
return false;
@@ -551,12 +596,12 @@ static bool disable_dmc_evt(struct intel_display *display,
return true;
/* also disable the flip queue event on the main DMC on TGL */
if (IS_TIGERLAKE(i915) &&
if (display->platform.tigerlake &&
REG_FIELD_GET(DMC_EVT_CTL_EVENT_ID_MASK, data) == DMC_EVT_CTL_EVENT_ID_CLK_MSEC)
return true;
/* also disable the HRR event on the main DMC on TGL/ADLS */
if ((IS_TIGERLAKE(i915) || IS_ALDERLAKE_S(i915)) &&
if ((display->platform.tigerlake || display->platform.alderlake_s) &&
REG_FIELD_GET(DMC_EVT_CTL_EVENT_ID_MASK, data) == DMC_EVT_CTL_EVENT_ID_VBLANK_A)
return true;
@@ -588,7 +633,6 @@ static u32 dmc_mmiodata(struct intel_display *display,
*/
void intel_dmc_load_program(struct intel_display *display)
{
struct drm_i915_private *i915 __maybe_unused = to_i915(display->drm);
struct i915_power_domains *power_domains = &display->power.domains;
struct intel_dmc *dmc = display_to_dmc(display);
enum intel_dmc_id dmc_id;
@@ -1012,9 +1056,7 @@ static void intel_dmc_runtime_pm_put(struct intel_display *display)
static const char *dmc_fallback_path(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
if (IS_ALDERLAKE_P(i915))
if (display->platform.alderlake_p)
return ADLP_DMC_FALLBACK_PATH;
return NULL;
@@ -1279,7 +1321,6 @@ static bool intel_dmc_get_dc6_allowed_count(struct intel_display *display, u32 *
static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused)
{
struct intel_display *display = m->private;
struct drm_i915_private *i915 = to_i915(display->drm);
struct intel_dmc *dmc = display_to_dmc(display);
struct ref_tracker *wakeref;
i915_reg_t dc5_reg, dc6_reg = INVALID_MMIO_REG;
@@ -1299,7 +1340,7 @@ static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused)
seq_printf(m, "Pipe A fw loaded: %s\n",
str_yes_no(has_dmc_id_fw(display, DMC_FW_PIPEA)));
seq_printf(m, "Pipe B fw needed: %s\n",
str_yes_no(IS_ALDERLAKE_P(i915) ||
str_yes_no(display->platform.alderlake_p ||
DISPLAY_VER(display) >= 14));
seq_printf(m, "Pipe B fw loaded: %s\n",
str_yes_no(has_dmc_id_fw(display, DMC_FW_PIPEB)));
@@ -1313,7 +1354,7 @@ static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused)
if (DISPLAY_VER(display) >= 12) {
i915_reg_t dc3co_reg;
if (IS_DGFX(i915) || DISPLAY_VER(display) >= 14) {
if (display->platform.dgfx || DISPLAY_VER(display) >= 14) {
dc3co_reg = DG1_DMC_DEBUG3;
dc5_reg = DG1_DMC_DEBUG_DC5_COUNT;
} else {
@@ -1325,9 +1366,9 @@ static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused)
seq_printf(m, "DC3CO count: %d\n",
intel_de_read(display, dc3co_reg));
} else {
dc5_reg = IS_BROXTON(i915) ? BXT_DMC_DC3_DC5_COUNT :
dc5_reg = display->platform.broxton ? BXT_DMC_DC3_DC5_COUNT :
SKL_DMC_DC3_DC5_COUNT;
if (!IS_GEMINILAKE(i915) && !IS_BROXTON(i915))
if (!display->platform.geminilake && !display->platform.broxton)
dc6_reg = SKL_DMC_DC5_DC6_COUNT;
}

View File

@@ -18,6 +18,10 @@ void intel_dmc_load_program(struct intel_display *display);
void intel_dmc_disable_program(struct intel_display *display);
void intel_dmc_enable_pipe(struct intel_display *display, enum pipe pipe);
void intel_dmc_disable_pipe(struct intel_display *display, enum pipe pipe);
void intel_dmc_block_pkgc(struct intel_display *display, enum pipe pipe,
bool block);
void intel_dmc_start_pkgc_exit_at_start_of_undelayed_vblank(struct intel_display *display,
enum pipe pipe, bool enable);
void intel_dmc_fini(struct intel_display *display);
void intel_dmc_suspend(struct intel_display *display);
void intel_dmc_resume(struct intel_display *display);

View File

@@ -21,6 +21,20 @@
#define MTL_PIPEDMC_CONTROL _MMIO(0x45250)
#define PIPEDMC_ENABLE_MTL(pipe) REG_BIT(((pipe) - PIPE_A) * 4)
#define _MTL_PIPEDMC_EVT_CTL_4_A 0x5f044
#define _MTL_PIPEDMC_EVT_CTL_4_B 0x5f444
#define MTL_PIPEDMC_EVT_CTL_4(pipe) _MMIO_PIPE(pipe, \
_MTL_PIPEDMC_EVT_CTL_4_A, \
_MTL_PIPEDMC_EVT_CTL_4_B)
#define PIPEDMC_BLOCK_PKGC_SW_A 0x5f1d0
#define PIPEDMC_BLOCK_PKGC_SW_B 0x5F5d0
#define PIPEDMC_BLOCK_PKGC_SW(pipe) _MMIO_PIPE(pipe, \
PIPEDMC_BLOCK_PKGC_SW_A, \
PIPEDMC_BLOCK_PKGC_SW_B)
#define PIPEDMC_BLOCK_PKGC_SW_BLOCK_PKGC_ALWAYS BIT(31)
#define PIPEDMC_BLOCK_PKGC_SW_BLOCK_PKGC_UNTIL_NEXT_FRAMESTART BIT(15)
#define _ADLP_PIPEDMC_REG_MMIO_BASE_A 0x5f000
#define _TGL_PIPEDMC_REG_MMIO_BASE_A 0x92000

View File

@@ -45,12 +45,13 @@
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
#include <drm/drm_fixed.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
#include "g4x_dp.h"
#include "i915_drv.h"
#include "i915_irq.h"
#include "i915_reg.h"
#include "i915_utils.h"
#include "intel_alpm.h"
#include "intel_atomic.h"
#include "intel_audio.h"
@@ -58,6 +59,7 @@
#include "intel_combo_phy_regs.h"
#include "intel_connector.h"
#include "intel_crtc.h"
#include "intel_crtc_state_dump.h"
#include "intel_cx0_phy.h"
#include "intel_ddi.h"
#include "intel_de.h"
@@ -92,7 +94,6 @@
#include "intel_tc.h"
#include "intel_vdsc.h"
#include "intel_vrr.h"
#include "intel_crtc_state_dump.h"
/* DP DSC throughput values used for slice count calculations KPixels/s */
#define DP_DSC_PEAK_PIXEL_RATE 2720000
@@ -3104,6 +3105,76 @@ intel_dp_queue_modeset_retry_for_link(struct intel_atomic_state *state,
}
}
int intel_dp_compute_min_hblank(struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state)
{
struct intel_display *display = to_intel_display(crtc_state);
const struct drm_display_mode *adjusted_mode =
&crtc_state->hw.adjusted_mode;
struct intel_connector *connector = to_intel_connector(conn_state->connector);
int symbol_size = intel_dp_is_uhbr(crtc_state) ? 32 : 8;
/*
* min symbol cycles is 3(BS,VBID, BE) for 128b/132b and
* 5(BS, VBID, MVID, MAUD, BE) for 8b/10b
*/
int min_sym_cycles = intel_dp_is_uhbr(crtc_state) ? 3 : 5;
bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST);
int num_joined_pipes = intel_crtc_num_joined_pipes(crtc_state);
int min_hblank;
int max_lane_count = 4;
int hactive_sym_cycles, htotal_sym_cycles;
int dsc_slices = 0;
int link_bpp_x16;
if (DISPLAY_VER(display) < 30)
return 0;
/* MIN_HBLANK should be set only for 8b/10b MST or for 128b/132b SST/MST */
if (!is_mst && !intel_dp_is_uhbr(crtc_state))
return 0;
if (crtc_state->dsc.compression_enable) {
dsc_slices = intel_dp_dsc_get_slice_count(connector,
adjusted_mode->crtc_clock,
adjusted_mode->crtc_hdisplay,
num_joined_pipes);
if (!dsc_slices) {
drm_dbg(display->drm, "failed to calculate dsc slice count\n");
return -EINVAL;
}
}
if (crtc_state->dsc.compression_enable)
link_bpp_x16 = crtc_state->dsc.compressed_bpp_x16;
else
link_bpp_x16 = fxp_q4_from_int(intel_dp_output_bpp(crtc_state->output_format,
crtc_state->pipe_bpp));
/* Calculate min Hblank Link Layer Symbol Cycle Count for 8b/10b MST & 128b/132b */
hactive_sym_cycles = drm_dp_link_symbol_cycles(max_lane_count,
adjusted_mode->hdisplay,
dsc_slices,
link_bpp_x16,
symbol_size, is_mst);
htotal_sym_cycles = adjusted_mode->htotal * hactive_sym_cycles /
adjusted_mode->hdisplay;
min_hblank = htotal_sym_cycles - hactive_sym_cycles;
/* minimum Hblank calculation: https://groups.vesa.org/wg/DP/document/20494 */
min_hblank = max(min_hblank, min_sym_cycles);
/*
* adjust the BlankingStart/BlankingEnd framing control from
* the calculated value
*/
min_hblank = min_hblank - 2;
min_hblank = min(10, min_hblank);
crtc_state->min_hblank = min_hblank;
return 0;
}
int
intel_dp_compute_config(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config,
@@ -3203,6 +3274,10 @@ intel_dp_compute_config(struct intel_encoder *encoder,
&pipe_config->dp_m_n);
}
ret = intel_dp_compute_min_hblank(pipe_config, conn_state);
if (ret)
return ret;
/* FIXME: abstract this better */
if (pipe_config->splitter.enable)
pipe_config->dp_m_n.data_m *= pipe_config->splitter.link_count;
@@ -5392,6 +5467,11 @@ intel_dp_short_pulse(struct intel_dp *intel_dp)
intel_psr_short_pulse(intel_dp);
if (intel_alpm_get_error(intel_dp)) {
intel_alpm_disable(intel_dp);
intel_dp->alpm_parameters.sink_alpm_error = true;
}
if (intel_dp_test_short_pulse(intel_dp))
reprobe_needed = true;
@@ -5827,20 +5907,21 @@ out_vdd_off:
}
static void
intel_dp_force(struct drm_connector *connector)
intel_dp_force(struct drm_connector *_connector)
{
struct intel_display *display = to_intel_display(connector->dev);
struct intel_dp *intel_dp = intel_attached_dp(to_intel_connector(connector));
struct intel_connector *connector = to_intel_connector(_connector);
struct intel_display *display = to_intel_display(connector);
struct intel_dp *intel_dp = intel_attached_dp(connector);
drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s]\n",
connector->base.id, connector->name);
connector->base.base.id, connector->base.name);
if (!intel_display_driver_check_access(display))
return;
intel_dp_unset_edid(intel_dp);
if (connector->status != connector_status_connected)
if (connector->base.status != connector_status_connected)
return;
intel_dp_set_edid(intel_dp);
@@ -5879,24 +5960,25 @@ static int intel_dp_get_modes(struct drm_connector *_connector)
}
static int
intel_dp_connector_register(struct drm_connector *connector)
intel_dp_connector_register(struct drm_connector *_connector)
{
struct intel_display *display = to_intel_display(connector->dev);
struct intel_dp *intel_dp = intel_attached_dp(to_intel_connector(connector));
struct intel_connector *connector = to_intel_connector(_connector);
struct intel_display *display = to_intel_display(connector);
struct intel_dp *intel_dp = intel_attached_dp(connector);
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
int ret;
ret = intel_connector_register(connector);
ret = intel_connector_register(&connector->base);
if (ret)
return ret;
drm_dbg_kms(display->drm, "registering %s bus for %s\n",
intel_dp->aux.name, connector->kdev->kobj.name);
intel_dp->aux.name, connector->base.kdev->kobj.name);
intel_dp->aux.dev = connector->kdev;
intel_dp->aux.dev = connector->base.kdev;
ret = drm_dp_aux_register(&intel_dp->aux);
if (!ret)
drm_dp_cec_register_connector(&intel_dp->aux, connector);
drm_dp_cec_register_connector(&intel_dp->aux, &connector->base);
if (!intel_bios_encoder_is_lspcon(dig_port->base.devdata))
return ret;
@@ -5907,20 +5989,21 @@ intel_dp_connector_register(struct drm_connector *connector)
*/
if (intel_lspcon_init(dig_port)) {
if (intel_lspcon_detect_hdr_capability(dig_port))
drm_connector_attach_hdr_output_metadata_property(connector);
drm_connector_attach_hdr_output_metadata_property(&connector->base);
}
return ret;
}
static void
intel_dp_connector_unregister(struct drm_connector *connector)
intel_dp_connector_unregister(struct drm_connector *_connector)
{
struct intel_dp *intel_dp = intel_attached_dp(to_intel_connector(connector));
struct intel_connector *connector = to_intel_connector(_connector);
struct intel_dp *intel_dp = intel_attached_dp(connector);
drm_dp_cec_unregister_connector(&intel_dp->aux);
drm_dp_aux_unregister(&intel_dp->aux);
intel_connector_unregister(connector);
intel_connector_unregister(&connector->base);
}
void intel_dp_connector_sync_state(struct intel_connector *connector,
@@ -5981,21 +6064,21 @@ static int intel_modeset_tile_group(struct intel_atomic_state *state,
{
struct intel_display *display = to_intel_display(state);
struct drm_connector_list_iter conn_iter;
struct drm_connector *connector;
struct intel_connector *connector;
int ret = 0;
drm_connector_list_iter_begin(display->drm, &conn_iter);
drm_for_each_connector_iter(connector, &conn_iter) {
for_each_intel_connector_iter(connector, &conn_iter) {
struct drm_connector_state *conn_state;
struct intel_crtc_state *crtc_state;
struct intel_crtc *crtc;
if (!connector->has_tile ||
connector->tile_group->id != tile_group_id)
if (!connector->base.has_tile ||
connector->base.tile_group->id != tile_group_id)
continue;
conn_state = drm_atomic_get_connector_state(&state->base,
connector);
&connector->base);
if (IS_ERR(conn_state)) {
ret = PTR_ERR(conn_state);
break;
@@ -6059,10 +6142,11 @@ static int intel_modeset_affected_transcoders(struct intel_atomic_state *state,
}
static int intel_modeset_synced_crtcs(struct intel_atomic_state *state,
struct drm_connector *connector)
struct drm_connector *_connector)
{
struct intel_connector *connector = to_intel_connector(_connector);
const struct drm_connector_state *old_conn_state =
drm_atomic_get_old_connector_state(&state->base, connector);
drm_atomic_get_old_connector_state(&state->base, &connector->base);
const struct intel_crtc_state *old_crtc_state;
struct intel_crtc *crtc;
u8 transcoders;
@@ -6084,17 +6168,18 @@ static int intel_modeset_synced_crtcs(struct intel_atomic_state *state,
transcoders);
}
static int intel_dp_connector_atomic_check(struct drm_connector *conn,
static int intel_dp_connector_atomic_check(struct drm_connector *_connector,
struct drm_atomic_state *_state)
{
struct intel_display *display = to_intel_display(conn->dev);
struct intel_connector *connector = to_intel_connector(_connector);
struct intel_display *display = to_intel_display(connector);
struct intel_atomic_state *state = to_intel_atomic_state(_state);
struct drm_connector_state *conn_state = drm_atomic_get_new_connector_state(_state, conn);
struct intel_connector *intel_conn = to_intel_connector(conn);
struct intel_dp *intel_dp = enc_to_intel_dp(intel_conn->encoder);
struct drm_connector_state *conn_state =
drm_atomic_get_new_connector_state(_state, &connector->base);
struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
int ret;
ret = intel_digital_connector_atomic_check(conn, &state->base);
ret = intel_digital_connector_atomic_check(&connector->base, &state->base);
if (ret)
return ret;
@@ -6104,12 +6189,12 @@ static int intel_dp_connector_atomic_check(struct drm_connector *conn,
return ret;
}
if (!intel_connector_needs_modeset(state, conn))
if (!intel_connector_needs_modeset(state, &connector->base))
return 0;
ret = intel_dp_tunnel_atomic_check_state(state,
intel_dp,
intel_conn);
connector);
if (ret)
return ret;
@@ -6120,26 +6205,26 @@ static int intel_dp_connector_atomic_check(struct drm_connector *conn,
if (DISPLAY_VER(display) < 9)
return 0;
if (conn->has_tile) {
ret = intel_modeset_tile_group(state, conn->tile_group->id);
if (connector->base.has_tile) {
ret = intel_modeset_tile_group(state, connector->base.tile_group->id);
if (ret)
return ret;
}
return intel_modeset_synced_crtcs(state, conn);
return intel_modeset_synced_crtcs(state, &connector->base);
}
static void intel_dp_oob_hotplug_event(struct drm_connector *connector,
static void intel_dp_oob_hotplug_event(struct drm_connector *_connector,
enum drm_connector_status hpd_state)
{
struct intel_display *display = to_intel_display(connector->dev);
struct intel_encoder *encoder = intel_attached_encoder(to_intel_connector(connector));
struct drm_i915_private *i915 = to_i915(connector->dev);
struct intel_connector *connector = to_intel_connector(_connector);
struct intel_display *display = to_intel_display(connector);
struct intel_encoder *encoder = intel_attached_encoder(connector);
bool hpd_high = hpd_state == connector_status_connected;
unsigned int hpd_pin = encoder->hpd_pin;
bool need_work = false;
spin_lock_irq(&i915->irq_lock);
spin_lock_irq(&display->irq.lock);
if (hpd_high != test_bit(hpd_pin, &display->hotplug.oob_hotplug_last_state)) {
display->hotplug.event_bits |= BIT(hpd_pin);
@@ -6148,7 +6233,7 @@ static void intel_dp_oob_hotplug_event(struct drm_connector *connector,
hpd_high);
need_work = true;
}
spin_unlock_irq(&i915->irq_lock);
spin_unlock_irq(&display->irq.lock);
if (need_work)
intel_hpd_schedule_detection(display);
@@ -6280,36 +6365,37 @@ intel_dp_has_gamut_metadata_dip(struct intel_encoder *encoder)
}
static void
intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connector)
intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *_connector)
{
struct intel_connector *connector = to_intel_connector(_connector);
struct intel_display *display = to_intel_display(intel_dp);
enum port port = dp_to_dig_port(intel_dp)->base.port;
if (!intel_dp_is_edp(intel_dp))
drm_connector_attach_dp_subconnector_property(connector);
drm_connector_attach_dp_subconnector_property(&connector->base);
if (!display->platform.g4x && port != PORT_A)
intel_attach_force_audio_property(connector);
intel_attach_force_audio_property(&connector->base);
intel_attach_broadcast_rgb_property(connector);
intel_attach_broadcast_rgb_property(&connector->base);
if (HAS_GMCH(display))
drm_connector_attach_max_bpc_property(connector, 6, 10);
drm_connector_attach_max_bpc_property(&connector->base, 6, 10);
else if (DISPLAY_VER(display) >= 5)
drm_connector_attach_max_bpc_property(connector, 6, 12);
drm_connector_attach_max_bpc_property(&connector->base, 6, 12);
/* Register HDMI colorspace for case of lspcon */
if (intel_bios_encoder_is_lspcon(dp_to_dig_port(intel_dp)->base.devdata)) {
drm_connector_attach_content_type_property(connector);
intel_attach_hdmi_colorspace_property(connector);
drm_connector_attach_content_type_property(&connector->base);
intel_attach_hdmi_colorspace_property(&connector->base);
} else {
intel_attach_dp_colorspace_property(connector);
intel_attach_dp_colorspace_property(&connector->base);
}
if (intel_dp_has_gamut_metadata_dip(&dp_to_dig_port(intel_dp)->base))
drm_connector_attach_hdr_output_metadata_property(connector);
drm_connector_attach_hdr_output_metadata_property(&connector->base);
if (HAS_VRR(display))
drm_connector_attach_vrr_capable_property(connector);
drm_connector_attach_vrr_capable_property(&connector->base);
}
static void
@@ -6344,7 +6430,6 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
struct intel_connector *connector)
{
struct intel_display *display = to_intel_display(intel_dp);
struct drm_i915_private *dev_priv = to_i915(display->drm);
struct drm_display_mode *fixed_mode;
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
bool has_dpcd;
@@ -6361,7 +6446,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
*/
if (intel_get_lvds_encoder(display)) {
drm_WARN_ON(display->drm,
!(HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv)));
!(HAS_PCH_IBX(display) || HAS_PCH_CPT(display)));
drm_info(display->drm,
"LVDS was detected, not registering eDP\n");
@@ -6392,7 +6477,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
*/
intel_hpd_enable_detection(encoder);
intel_alpm_init_dpcd(intel_dp);
intel_alpm_init(intel_dp);
/* Cache DPCD and EDID for edp. */
has_dpcd = intel_edp_init_dpcd(intel_dp, connector);

View File

@@ -208,5 +208,7 @@ bool intel_dp_has_connector(struct intel_dp *intel_dp,
const struct drm_connector_state *conn_state);
int intel_dp_dsc_max_src_input_bpc(struct intel_display *display);
int intel_dp_dsc_min_src_input_bpc(void);
int intel_dp_compute_min_hblank(struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state);
#endif /* __INTEL_DP_H__ */

View File

@@ -3,8 +3,10 @@
* Copyright © 2020-2021 Intel Corporation
*/
#include "i915_drv.h"
#include <drm/drm_print.h>
#include "i915_reg.h"
#include "i915_utils.h"
#include "intel_de.h"
#include "intel_display_types.h"
#include "intel_dp.h"
@@ -111,10 +113,9 @@ static u32 ilk_get_aux_clock_divider(struct intel_dp *intel_dp, int index)
static u32 hsw_get_aux_clock_divider(struct intel_dp *intel_dp, int index)
{
struct intel_display *display = to_intel_display(intel_dp);
struct drm_i915_private *i915 = to_i915(display->drm);
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
if (dig_port->aux_ch != AUX_CH_A && HAS_PCH_LPT_H(i915)) {
if (dig_port->aux_ch != AUX_CH_A && HAS_PCH_LPT_H(display)) {
/* Workaround for non-ULT HSW */
switch (index) {
case 0: return 63;
@@ -177,12 +178,11 @@ static u32 g4x_get_aux_send_ctl(struct intel_dp *intel_dp,
int send_bytes,
u32 aux_clock_divider)
{
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
struct intel_display *display = to_intel_display(intel_dp);
u32 timeout;
/* Max timeout value on G4x-BDW: 1.6ms */
if (IS_BROADWELL(i915))
if (display->platform.broadwell)
timeout = DP_AUX_CH_CTL_TIME_OUT_600us;
else
timeout = DP_AUX_CH_CTL_TIME_OUT_400us;
@@ -786,7 +786,6 @@ void intel_dp_aux_fini(struct intel_dp *intel_dp)
void intel_dp_aux_init(struct intel_dp *intel_dp)
{
struct intel_display *display = to_intel_display(intel_dp);
struct drm_i915_private *i915 = to_i915(display->drm);
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
struct intel_encoder *encoder = &dig_port->base;
enum aux_ch aux_ch = dig_port->aux_ch;
@@ -801,10 +800,10 @@ void intel_dp_aux_init(struct intel_dp *intel_dp)
} else if (DISPLAY_VER(display) >= 9) {
intel_dp->aux_ch_ctl_reg = skl_aux_ctl_reg;
intel_dp->aux_ch_data_reg = skl_aux_data_reg;
} else if (HAS_PCH_SPLIT(i915)) {
} else if (HAS_PCH_SPLIT(display)) {
intel_dp->aux_ch_ctl_reg = ilk_aux_ctl_reg;
intel_dp->aux_ch_data_reg = ilk_aux_data_reg;
} else if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) {
} else if (display->platform.valleyview || display->platform.cherryview) {
intel_dp->aux_ch_ctl_reg = vlv_aux_ctl_reg;
intel_dp->aux_ch_data_reg = vlv_aux_data_reg;
} else {
@@ -814,9 +813,9 @@ void intel_dp_aux_init(struct intel_dp *intel_dp)
if (DISPLAY_VER(display) >= 9)
intel_dp->get_aux_clock_divider = skl_get_aux_clock_divider;
else if (IS_BROADWELL(i915) || IS_HASWELL(i915))
else if (display->platform.broadwell || display->platform.haswell)
intel_dp->get_aux_clock_divider = hsw_get_aux_clock_divider;
else if (HAS_PCH_SPLIT(i915))
else if (HAS_PCH_SPLIT(display))
intel_dp->get_aux_clock_divider = ilk_get_aux_clock_divider;
else
intel_dp->get_aux_clock_divider = g4x_get_aux_clock_divider;

View File

@@ -36,7 +36,6 @@
#include <drm/drm_print.h>
#include "i915_utils.h"
#include "intel_backlight.h"
#include "intel_display_core.h"
#include "intel_display_types.h"
@@ -149,7 +148,7 @@ intel_dp_aux_supports_hdr_backlight(struct intel_connector *connector)
!(connector->base.hdr_sink_metadata.hdmi_type1.metadata_type &
BIT(HDMI_STATIC_METADATA_TYPE1))) {
drm_info(display->drm,
"[CONNECTOR:%d:%s] Panel is missing HDR static metadata. Possible support for Intel HDR backlight interface is not used. If your backlight controls don't work try booting with i915.enable_dpcd_backlight=%d. needs this, please file a _new_ bug report on drm/i915, see " FDO_BUG_URL " for details.\n",
"[CONNECTOR:%d:%s] Panel is missing HDR static metadata. Possible support for Intel HDR backlight interface is not used. If your backlight controls don't work try booting with i915.enable_dpcd_backlight=%d.\n",
connector->base.base.id, connector->base.name,
INTEL_DP_AUX_BACKLIGHT_FORCE_INTEL);
return false;

View File

@@ -27,10 +27,11 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_edid.h>
#include <drm/drm_fixed.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
#include "i915_drv.h"
#include "i915_reg.h"
#include "i915_utils.h"
#include "intel_atomic.h"
#include "intel_audio.h"
#include "intel_connector.h"
@@ -51,6 +52,7 @@
#include "intel_link_bw.h"
#include "intel_pfit.h"
#include "intel_psr.h"
#include "intel_step.h"
#include "intel_vdsc.h"
#include "intel_vrr.h"
#include "skl_scaler.h"
@@ -239,26 +241,6 @@ static int intel_dp_mst_dsc_get_slice_count(const struct intel_connector *connec
num_joined_pipes);
}
static void intel_dp_mst_compute_min_hblank(struct intel_crtc_state *crtc_state,
int bpp_x16)
{
struct intel_display *display = to_intel_display(crtc_state);
const struct drm_display_mode *adjusted_mode =
&crtc_state->hw.adjusted_mode;
int symbol_size = intel_dp_is_uhbr(crtc_state) ? 32 : 8;
int hblank;
if (DISPLAY_VER(display) < 20)
return;
/* Calculate min Hblank Link Layer Symbol Cycle Count for 8b/10b MST & 128b/132b */
hblank = DIV_ROUND_UP((DIV_ROUND_UP
(adjusted_mode->htotal - adjusted_mode->hdisplay, 4) * bpp_x16),
symbol_size);
crtc_state->min_hblank = hblank;
}
int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp,
struct intel_crtc_state *crtc_state,
struct drm_connector_state *conn_state,
@@ -329,8 +311,6 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp,
local_bw_overhead = intel_dp_mst_bw_overhead(crtc_state,
false, dsc_slice_count, link_bpp_x16);
intel_dp_mst_compute_min_hblank(crtc_state, link_bpp_x16);
intel_dp_mst_compute_m_n(crtc_state,
local_bw_overhead,
link_bpp_x16,
@@ -739,6 +719,10 @@ static int mst_stream_compute_config(struct intel_encoder *encoder,
pipe_config->lane_lat_optim_mask =
bxt_dpio_phy_calc_lane_lat_optim_mask(pipe_config->lane_count);
ret = intel_dp_compute_min_hblank(pipe_config, conn_state);
if (ret)
return ret;
intel_vrr_compute_config(pipe_config, conn_state);
intel_dp_audio_compute_config(encoder, pipe_config, conn_state);
@@ -1021,12 +1005,10 @@ static void mst_stream_disable(struct intel_atomic_state *state,
const struct intel_crtc_state *old_crtc_state,
const struct drm_connector_state *old_conn_state)
{
struct intel_display *display = to_intel_display(state);
struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder);
struct intel_dp *intel_dp = to_primary_dp(encoder);
struct intel_connector *connector =
to_intel_connector(old_conn_state->connector);
enum transcoder trans = old_crtc_state->cpu_transcoder;
if (intel_dp_mst_active_streams(intel_dp) == 1)
intel_dp->link.active = false;
@@ -1034,9 +1016,6 @@ static void mst_stream_disable(struct intel_atomic_state *state,
intel_hdcp_disable(intel_mst->connector);
intel_dp_sink_disable_decompression(state, connector, old_crtc_state);
if (DISPLAY_VER(display) >= 20)
intel_de_write(display, DP_MIN_HBLANK_CTL(trans), 0);
}
static void mst_stream_post_disable(struct intel_atomic_state *state,
@@ -1305,7 +1284,7 @@ static void mst_stream_enable(struct intel_atomic_state *state,
enum transcoder trans = pipe_config->cpu_transcoder;
bool first_mst_stream = intel_dp_mst_active_streams(intel_dp) == 1;
struct intel_crtc *pipe_crtc;
int ret, i, min_hblank;
int ret, i;
drm_WARN_ON(display->drm, pipe_config->has_pch_encoder);
@@ -1320,29 +1299,6 @@ static void mst_stream_enable(struct intel_atomic_state *state,
TRANS_DP2_VFREQ_PIXEL_CLOCK(crtc_clock_hz & 0xffffff));
}
if (DISPLAY_VER(display) >= 20) {
/*
* adjust the BlankingStart/BlankingEnd framing control from
* the calculated value
*/
min_hblank = pipe_config->min_hblank - 2;
/* Maximum value to be programmed is limited to 0x10 */
min_hblank = min(0x10, min_hblank);
/*
* Minimum hblank accepted for 128b/132b would be 5 and for
* 8b/10b would be 3 symbol count
*/
if (intel_dp_is_uhbr(pipe_config))
min_hblank = max(min_hblank, 5);
else
min_hblank = max(min_hblank, 3);
intel_de_write(display, DP_MIN_HBLANK_CTL(trans),
min_hblank);
}
enable_bs_jitter_was(pipe_config);
intel_ddi_enable_transcoder_func(encoder, pipe_config);

View File

@@ -222,9 +222,7 @@ static const struct bxt_dpio_phy_info glk_dpio_phy_info[] = {
static const struct bxt_dpio_phy_info *
bxt_get_phy_list(struct intel_display *display, int *count)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
if (IS_GEMINILAKE(dev_priv)) {
if (display->platform.geminilake) {
*count = ARRAY_SIZE(glk_dpio_phy_info);
return glk_dpio_phy_info;
} else {
@@ -808,9 +806,9 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder,
vlv_dpio_put(dev_priv);
}
void chv_data_lane_soft_reset(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
bool reset)
static void __chv_data_lane_soft_reset(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
bool reset)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
@@ -853,6 +851,17 @@ void chv_data_lane_soft_reset(struct intel_encoder *encoder,
}
}
void chv_data_lane_soft_reset(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
bool reset)
{
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
vlv_dpio_get(i915);
__chv_data_lane_soft_reset(encoder, crtc_state, reset);
vlv_dpio_put(i915);
}
void chv_phy_pre_pll_enable(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state)
{
@@ -880,7 +889,7 @@ void chv_phy_pre_pll_enable(struct intel_encoder *encoder,
vlv_dpio_get(dev_priv);
/* Assert data lane reset */
chv_data_lane_soft_reset(encoder, crtc_state, true);
__chv_data_lane_soft_reset(encoder, crtc_state, true);
/* program left/right clock distribution */
if (pipe != PIPE_B) {
@@ -1008,7 +1017,7 @@ void chv_phy_pre_encoder_enable(struct intel_encoder *encoder,
}
/* Deassert data lane reset */
chv_data_lane_soft_reset(encoder, crtc_state, false);
__chv_data_lane_soft_reset(encoder, crtc_state, false);
vlv_dpio_put(dev_priv);
}

View File

@@ -374,12 +374,11 @@ int chv_calc_dpll_params(int refclk, struct dpll *clock)
static int i9xx_pll_refclk(const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
const struct i9xx_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.i9xx;
if ((hw_state->dpll & PLL_REF_INPUT_MASK) == PLLB_REF_INPUT_SPREADSPECTRUMIN)
return display->vbt.lvds_ssc_freq;
else if (HAS_PCH_SPLIT(i915))
else if (HAS_PCH_SPLIT(display))
return 120000;
else if (DISPLAY_VER(display) != 2)
return 96000;
@@ -1235,12 +1234,10 @@ static int mtl_crtc_compute_clock(struct intel_atomic_state *state,
static int ilk_fb_cb_factor(const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS) &&
((intel_panel_use_ssc(display) && display->vbt.lvds_ssc_freq == 100000) ||
(HAS_PCH_IBX(i915) && intel_is_dual_link_lvds(display))))
(HAS_PCH_IBX(display) && intel_is_dual_link_lvds(display))))
return 25;
if (crtc_state->sdvo_tv_clock)
@@ -1791,15 +1788,13 @@ int intel_dpll_crtc_get_shared_dpll(struct intel_atomic_state *state,
void
intel_dpll_init_clock_hook(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
if (DISPLAY_VER(display) >= 14)
display->funcs.dpll = &mtl_dpll_funcs;
else if (display->platform.dg2)
display->funcs.dpll = &dg2_dpll_funcs;
else if (DISPLAY_VER(display) >= 9 || HAS_DDI(display))
display->funcs.dpll = &hsw_dpll_funcs;
else if (HAS_PCH_SPLIT(dev_priv))
else if (HAS_PCH_SPLIT(display))
display->funcs.dpll = &ilk_dpll_funcs;
else if (display->platform.cherryview)
display->funcs.dpll = &chv_dpll_funcs;

View File

@@ -24,9 +24,11 @@
#include <linux/math.h>
#include <linux/string_helpers.h>
#include <drm/drm_print.h>
#include "bxt_dpio_phy_regs.h"
#include "i915_drv.h"
#include "i915_reg.h"
#include "i915_utils.h"
#include "intel_cx0_phy.h"
#include "intel_de.h"
#include "intel_display_types.h"
@@ -38,6 +40,7 @@
#include "intel_hti.h"
#include "intel_mg_phy_regs.h"
#include "intel_pch_refclk.h"
#include "intel_step.h"
#include "intel_tc.h"
/**
@@ -609,13 +612,12 @@ static int ibx_get_dpll(struct intel_atomic_state *state,
struct intel_encoder *encoder)
{
struct intel_display *display = to_intel_display(state);
struct drm_i915_private *i915 = to_i915(display->drm);
struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
struct intel_shared_dpll *pll;
enum intel_dpll_id id;
if (HAS_PCH_IBX(i915)) {
if (HAS_PCH_IBX(display)) {
/* Ironlake PCH has a fixed PLL->PCH pipe mapping. */
id = (enum intel_dpll_id) crtc->pipe;
pll = intel_get_shared_dpll_by_id(display, id);
@@ -4305,7 +4307,6 @@ static const struct intel_dpll_mgr adlp_pll_mgr = {
*/
void intel_shared_dpll_init(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
const struct intel_dpll_mgr *dpll_mgr = NULL;
const struct dpll_info *dpll_info;
int i;
@@ -4335,7 +4336,7 @@ void intel_shared_dpll_init(struct intel_display *display)
dpll_mgr = &skl_pll_mgr;
else if (HAS_DDI(display))
dpll_mgr = &hsw_pll_mgr;
else if (HAS_PCH_IBX(i915) || HAS_PCH_CPT(i915))
else if (HAS_PCH_IBX(display) || HAS_PCH_CPT(display))
dpll_mgr = &pch_pll_mgr;
if (!dpll_mgr)

View File

@@ -3,7 +3,6 @@
* Copyright © 2023 Intel Corporation
*/
#include "i915_drv.h"
#include "i915_reg.h"
#include "intel_de.h"
#include "intel_display_types.h"
@@ -12,9 +11,9 @@
void intel_dpt_configure(struct intel_crtc *crtc)
{
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
struct intel_display *display = to_intel_display(crtc);
if (DISPLAY_VER(i915) == 14) {
if (DISPLAY_VER(display) == 14) {
enum pipe pipe = crtc->pipe;
enum plane_id plane_id;
@@ -22,15 +21,15 @@ void intel_dpt_configure(struct intel_crtc *crtc)
if (plane_id == PLANE_CURSOR)
continue;
intel_de_rmw(i915, PLANE_CHICKEN(pipe, plane_id),
intel_de_rmw(display, PLANE_CHICKEN(pipe, plane_id),
PLANE_CHICKEN_DISABLE_DPT,
i915->display.params.enable_dpt ? 0 :
display->params.enable_dpt ? 0 :
PLANE_CHICKEN_DISABLE_DPT);
}
} else if (DISPLAY_VER(i915) == 13) {
intel_de_rmw(i915, CHICKEN_MISC_2,
} else if (DISPLAY_VER(display) == 13) {
intel_de_rmw(display, CHICKEN_MISC_2,
CHICKEN_MISC_DISABLE_DPT,
i915->display.params.enable_dpt ? 0 :
display->params.enable_dpt ? 0 :
CHICKEN_MISC_DISABLE_DPT);
}
}

View File

@@ -4,11 +4,12 @@
*
*/
#include <drm/drm_print.h>
#include <drm/drm_vblank.h>
#include "i915_drv.h"
#include "i915_irq.h"
#include "i915_reg.h"
#include "i915_utils.h"
#include "intel_crtc.h"
#include "intel_de.h"
#include "intel_display_rpm.h"

View File

@@ -4,8 +4,9 @@
*/
#include <drm/drm_mipi_dsi.h>
#include <drm/drm_print.h>
#include "i915_drv.h"
#include "intel_display_core.h"
#include "intel_dsi.h"
#include "intel_panel.h"
@@ -116,14 +117,14 @@ struct intel_dsi_host *intel_dsi_host_init(struct intel_dsi *intel_dsi,
enum drm_panel_orientation
intel_dsi_get_panel_orientation(struct intel_connector *connector)
{
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
struct intel_display *display = to_intel_display(connector);
enum drm_panel_orientation orientation;
orientation = connector->panel.vbt.dsi.orientation;
if (orientation != DRM_MODE_PANEL_ORIENTATION_UNKNOWN)
return orientation;
orientation = dev_priv->display.vbt.orientation;
orientation = display->vbt.orientation;
if (orientation != DRM_MODE_PANEL_ORIENTATION_UNKNOWN)
return orientation;

View File

@@ -31,16 +31,16 @@
#include <linux/pinctrl/machine.h>
#include <linux/slab.h>
#include <linux/string_helpers.h>
#include <linux/unaligned.h>
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
#include <drm/drm_print.h>
#include <video/mipi_display.h>
#include "i915_drv.h"
#include "i915_reg.h"
#include "i915_utils.h"
#include "intel_de.h"
#include "intel_display_types.h"
#include "intel_dsi.h"
@@ -321,7 +321,6 @@ enum {
static void icl_native_gpio_set_value(struct intel_display *display,
int gpio, bool value)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
int index;
if (drm_WARN_ON(display->drm, DISPLAY_VER(display) == 11 && gpio >= MIPI_RESET_2))
@@ -341,12 +340,12 @@ static void icl_native_gpio_set_value(struct intel_display *display,
* The locking protects against concurrent SHOTPLUG_CTL_DDI
* modifications in irq setup and handling.
*/
spin_lock_irq(&dev_priv->irq_lock);
spin_lock_irq(&display->irq.lock);
intel_de_rmw(display, SHOTPLUG_CTL_DDI,
SHOTPLUG_CTL_DDI_HPD_ENABLE(index) |
SHOTPLUG_CTL_DDI_HPD_OUTPUT_DATA(index),
value ? SHOTPLUG_CTL_DDI_HPD_OUTPUT_DATA(index) : 0);
spin_unlock_irq(&dev_priv->irq_lock);
spin_unlock_irq(&display->irq.lock);
break;
case MIPI_AVDD_EN_1:
case MIPI_AVDD_EN_2:

View File

@@ -560,11 +560,11 @@ static bool plane_has_modifier(struct intel_display *display,
return false;
if (md->modifier == I915_FORMAT_MOD_4_TILED_BMG_CCS &&
(GRAPHICS_VER(i915) < 20 || !IS_DGFX(i915)))
(GRAPHICS_VER(i915) < 20 || !display->platform.dgfx))
return false;
if (md->modifier == I915_FORMAT_MOD_4_TILED_LNL_CCS &&
(GRAPHICS_VER(i915) < 20 || IS_DGFX(i915)))
(GRAPHICS_VER(i915) < 20 || display->platform.dgfx))
return false;
return true;

View File

@@ -252,9 +252,12 @@ static u16 intel_fbc_override_cfb_stride(const struct intel_plane_state *plane_s
* Gen9 hw miscalculates cfb stride for linear as
* PLANE_STRIDE*512 instead of PLANE_STRIDE*64, so
* we always need to use the override there.
*
* wa_14022269668 For bmg, always program the FBC_STRIDE before fbc enable
*/
if (stride != stride_aligned ||
(DISPLAY_VER(display) == 9 && fb->modifier == DRM_FORMAT_MOD_LINEAR))
(DISPLAY_VER(display) == 9 && fb->modifier == DRM_FORMAT_MOD_LINEAR) ||
display->platform.battlemage)
return stride_aligned * 4 / 64;
return 0;

View File

@@ -47,9 +47,9 @@
#include <drm/drm_managed.h>
#include <drm/drm_print.h>
#include "i915_drv.h"
#include "i915_vma.h"
#include "intel_bo.h"
#include "intel_display_core.h"
#include "intel_display_rpm.h"
#include "intel_display_types.h"
#include "intel_fb.h"
@@ -66,9 +66,9 @@ struct intel_fbdev {
static struct intel_fbdev *to_intel_fbdev(struct drm_fb_helper *fb_helper)
{
struct drm_i915_private *i915 = to_i915(fb_helper->client.dev);
struct intel_display *display = to_intel_display(fb_helper->client.dev);
return i915->display.fbdev.fbdev;
return display->fbdev.fbdev;
}
static struct intel_frontbuffer *to_frontbuffer(struct intel_fbdev *ifbdev)
@@ -210,11 +210,9 @@ static const struct drm_fb_helper_funcs intel_fb_helper_funcs = {
int intel_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper,
struct drm_fb_helper_surface_size *sizes)
{
struct intel_display *display = to_intel_display(helper->dev);
struct intel_fbdev *ifbdev = to_intel_fbdev(helper);
struct intel_framebuffer *fb = ifbdev->fb;
struct drm_device *dev = helper->dev;
struct drm_i915_private *dev_priv = to_i915(dev);
struct intel_display *display = to_intel_display(dev);
struct ref_tracker *wakeref;
struct fb_info *info;
struct i915_vma *vma;
@@ -228,7 +226,7 @@ int intel_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper,
if (fb &&
(sizes->fb_width > fb->base.width ||
sizes->fb_height > fb->base.height)) {
drm_dbg_kms(&dev_priv->drm,
drm_dbg_kms(display->drm,
"BIOS fb too small (%dx%d), we require (%dx%d),"
" releasing it\n",
fb->base.width, fb->base.height,
@@ -236,14 +234,14 @@ int intel_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper,
drm_framebuffer_put(&fb->base);
fb = NULL;
}
if (!fb || drm_WARN_ON(dev, !intel_fb_bo(&fb->base))) {
drm_dbg_kms(&dev_priv->drm,
if (!fb || drm_WARN_ON(display->drm, !intel_fb_bo(&fb->base))) {
drm_dbg_kms(display->drm,
"no BIOS fb, allocating a new one\n");
fb = intel_fbdev_fb_alloc(helper, sizes);
if (IS_ERR(fb))
return PTR_ERR(fb);
} else {
drm_dbg_kms(&dev_priv->drm, "re-using BIOS fb\n");
drm_dbg_kms(display->drm, "re-using BIOS fb\n");
prealloc = true;
sizes->fb_width = fb->base.width;
sizes->fb_height = fb->base.height;
@@ -267,7 +265,7 @@ int intel_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper,
info = drm_fb_helper_alloc_info(helper);
if (IS_ERR(info)) {
drm_err(&dev_priv->drm, "Failed to allocate fb_info (%pe)\n", info);
drm_err(display->drm, "Failed to allocate fb_info (%pe)\n", info);
ret = PTR_ERR(info);
goto out_unpin;
}
@@ -279,11 +277,11 @@ int intel_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper,
obj = intel_fb_bo(&fb->base);
ret = intel_fbdev_fb_fill_info(dev_priv, info, obj, vma);
ret = intel_fbdev_fb_fill_info(display, info, obj, vma);
if (ret)
goto out_unpin;
drm_fb_helper_fill_info(info, dev->fb_helper, sizes);
drm_fb_helper_fill_info(info, display->drm->fb_helper, sizes);
/* If the object is shmemfs backed, it will have given us zeroed pages.
* If the object is stolen however, it will be full of whatever
@@ -294,7 +292,7 @@ int intel_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper,
/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
drm_dbg_kms(&dev_priv->drm, "allocated %dx%d fb: 0x%08x\n",
drm_dbg_kms(display->drm, "allocated %dx%d fb: 0x%08x\n",
fb->base.width, fb->base.height,
i915_ggtt_offset(vma));
ifbdev->fb = fb;
@@ -322,16 +320,15 @@ out_unlock:
* Note we only support a single fb shared across pipes for boot (mostly for
* fbcon), so we just find the biggest and use that.
*/
static bool intel_fbdev_init_bios(struct drm_device *dev,
static bool intel_fbdev_init_bios(struct intel_display *display,
struct intel_fbdev *ifbdev)
{
struct drm_i915_private *i915 = to_i915(dev);
struct intel_framebuffer *fb = NULL;
struct intel_crtc *crtc;
unsigned int max_size = 0;
/* Find the largest fb */
for_each_intel_crtc(dev, crtc) {
for_each_intel_crtc(display->drm, crtc) {
struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
struct intel_plane *plane =
@@ -341,21 +338,21 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
struct drm_gem_object *obj = intel_fb_bo(plane_state->uapi.fb);
if (!crtc_state->uapi.active) {
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"[CRTC:%d:%s] not active, skipping\n",
crtc->base.base.id, crtc->base.name);
continue;
}
if (!obj) {
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"[PLANE:%d:%s] no fb, skipping\n",
plane->base.base.id, plane->base.name);
continue;
}
if (obj->size > max_size) {
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"found possible fb from [PLANE:%d:%s]\n",
plane->base.base.id, plane->base.name);
fb = to_intel_framebuffer(plane_state->uapi.fb);
@@ -364,13 +361,13 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
}
if (!fb) {
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"no active fbs found, not using BIOS config\n");
goto out;
}
/* Now make sure all the pipes will fit into it */
for_each_intel_crtc(dev, crtc) {
for_each_intel_crtc(display->drm, crtc) {
struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
struct intel_plane *plane =
@@ -378,13 +375,13 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
unsigned int cur_size;
if (!crtc_state->uapi.active) {
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"[CRTC:%d:%s] not active, skipping\n",
crtc->base.base.id, crtc->base.name);
continue;
}
drm_dbg_kms(&i915->drm, "checking [PLANE:%d:%s] for BIOS fb\n",
drm_dbg_kms(display->drm, "checking [PLANE:%d:%s] for BIOS fb\n",
plane->base.base.id, plane->base.name);
/*
@@ -395,7 +392,7 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
cur_size = crtc_state->uapi.adjusted_mode.crtc_hdisplay;
cur_size = cur_size * fb->base.format->cpp[0];
if (fb->base.pitches[0] < cur_size) {
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"fb not wide enough for [PLANE:%d:%s] (%d vs %d)\n",
plane->base.base.id, plane->base.name,
cur_size, fb->base.pitches[0]);
@@ -406,7 +403,7 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
cur_size = crtc_state->uapi.adjusted_mode.crtc_vdisplay;
cur_size = intel_fb_align_height(&fb->base, 0, cur_size);
cur_size *= fb->base.pitches[0];
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"[CRTC:%d:%s] area: %dx%d, bpp: %d, size: %d\n",
crtc->base.base.id, crtc->base.name,
crtc_state->uapi.adjusted_mode.crtc_hdisplay,
@@ -415,7 +412,7 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
cur_size);
if (cur_size > max_size) {
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"fb not big enough for [PLANE:%d:%s] (%d vs %d)\n",
plane->base.base.id, plane->base.name,
cur_size, max_size);
@@ -423,14 +420,14 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
break;
}
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"fb big enough [PLANE:%d:%s] (%d >= %d)\n",
plane->base.base.id, plane->base.name,
max_size, cur_size);
}
if (!fb) {
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"BIOS fb not suitable for all pipes, not using\n");
goto out;
}
@@ -440,7 +437,7 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
drm_framebuffer_get(&ifbdev->fb->base);
/* Final pass to check if any active pipes don't have fbs */
for_each_intel_crtc(dev, crtc) {
for_each_intel_crtc(display->drm, crtc) {
struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
struct intel_plane *plane =
@@ -451,13 +448,13 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
if (!crtc_state->uapi.active)
continue;
drm_WARN(dev, !plane_state->uapi.fb,
drm_WARN(display->drm, !plane_state->uapi.fb,
"re-used BIOS config but lost an fb on [PLANE:%d:%s]\n",
plane->base.base.id, plane->base.name);
}
drm_dbg_kms(&i915->drm, "using BIOS fb for initial console\n");
drm_dbg_kms(display->drm, "using BIOS fb for initial console\n");
return true;
out:
@@ -482,26 +479,25 @@ static unsigned int intel_fbdev_color_mode(const struct drm_format_info *info)
}
}
void intel_fbdev_setup(struct drm_i915_private *i915)
void intel_fbdev_setup(struct intel_display *display)
{
struct drm_device *dev = &i915->drm;
struct intel_fbdev *ifbdev;
unsigned int preferred_bpp = 0;
if (!HAS_DISPLAY(i915))
if (!HAS_DISPLAY(display))
return;
ifbdev = drmm_kzalloc(dev, sizeof(*ifbdev), GFP_KERNEL);
ifbdev = drmm_kzalloc(display->drm, sizeof(*ifbdev), GFP_KERNEL);
if (!ifbdev)
return;
i915->display.fbdev.fbdev = ifbdev;
if (intel_fbdev_init_bios(dev, ifbdev))
display->fbdev.fbdev = ifbdev;
if (intel_fbdev_init_bios(display, ifbdev))
preferred_bpp = intel_fbdev_color_mode(ifbdev->fb->base.format);
if (!preferred_bpp)
preferred_bpp = 32;
drm_client_setup_with_color_mode(dev, preferred_bpp);
drm_client_setup_with_color_mode(display->drm, preferred_bpp);
}
struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev)

View File

@@ -10,7 +10,7 @@
struct drm_fb_helper;
struct drm_fb_helper_surface_size;
struct drm_i915_private;
struct intel_display;
struct intel_fbdev;
struct intel_framebuffer;
@@ -19,14 +19,14 @@ int intel_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper,
struct drm_fb_helper_surface_size *sizes);
#define INTEL_FBDEV_DRIVER_OPS \
.fbdev_probe = intel_fbdev_driver_fbdev_probe
void intel_fbdev_setup(struct drm_i915_private *dev_priv);
void intel_fbdev_setup(struct intel_display *display);
struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev);
struct i915_vma *intel_fbdev_vma_pointer(struct intel_fbdev *fbdev);
#else
#define INTEL_FBDEV_DRIVER_OPS \
.fbdev_probe = NULL
static inline void intel_fbdev_setup(struct drm_i915_private *dev_priv)
static inline void intel_fbdev_setup(struct intel_display *display)
{
}
static inline struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev)

View File

@@ -15,9 +15,9 @@
struct intel_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper,
struct drm_fb_helper_surface_size *sizes)
{
struct intel_display *display = to_intel_display(helper->dev);
struct drm_i915_private *dev_priv = to_i915(display->drm);
struct drm_framebuffer *fb;
struct drm_device *dev = helper->dev;
struct drm_i915_private *dev_priv = to_i915(dev);
struct drm_mode_fb_cmd2 mode_cmd = {};
struct drm_i915_gem_object *obj;
int size;
@@ -50,14 +50,14 @@ struct intel_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper,
*
* Also skip stolen on MTL as Wa_22018444074 mitigation.
*/
if (!(IS_METEORLAKE(dev_priv)) && size * 2 < dev_priv->dsm.usable_size)
if (!display->platform.meteorlake && size * 2 < dev_priv->dsm.usable_size)
obj = i915_gem_object_create_stolen(dev_priv, size);
if (IS_ERR(obj))
obj = i915_gem_object_create_shmem(dev_priv, size);
}
if (IS_ERR(obj)) {
drm_err(&dev_priv->drm, "failed to allocate framebuffer (%pe)\n", obj);
drm_err(display->drm, "failed to allocate framebuffer (%pe)\n", obj);
return ERR_PTR(-ENOMEM);
}
@@ -67,9 +67,10 @@ struct intel_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper,
return to_intel_framebuffer(fb);
}
int intel_fbdev_fb_fill_info(struct drm_i915_private *i915, struct fb_info *info,
int intel_fbdev_fb_fill_info(struct intel_display *display, struct fb_info *info,
struct drm_gem_object *_obj, struct i915_vma *vma)
{
struct drm_i915_private *i915 = to_i915(display->drm);
struct drm_i915_gem_object *obj = to_intel_bo(_obj);
struct i915_gem_ww_ctx ww;
void __iomem *vaddr;
@@ -101,7 +102,7 @@ int intel_fbdev_fb_fill_info(struct drm_i915_private *i915, struct fb_info *info
vaddr = i915_vma_pin_iomap(vma);
if (IS_ERR(vaddr)) {
drm_err(&i915->drm,
drm_err(display->drm,
"Failed to remap framebuffer into virtual memory (%pe)\n", vaddr);
ret = PTR_ERR(vaddr);
continue;

View File

@@ -9,13 +9,13 @@
struct drm_fb_helper;
struct drm_fb_helper_surface_size;
struct drm_gem_object;
struct drm_i915_private;
struct fb_info;
struct i915_vma;
struct intel_display;
struct intel_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper,
struct drm_fb_helper_surface_size *sizes);
int intel_fbdev_fb_fill_info(struct drm_i915_private *i915, struct fb_info *info,
int intel_fbdev_fb_fill_info(struct intel_display *display, struct fb_info *info,
struct drm_gem_object *obj, struct i915_vma *vma);
#endif

View File

@@ -6,15 +6,16 @@
#include <linux/string_helpers.h>
#include <drm/drm_fixed.h>
#include <drm/drm_print.h>
#include "i915_drv.h"
#include "i915_reg.h"
#include "i915_utils.h"
#include "intel_atomic.h"
#include "intel_crtc.h"
#include "intel_ddi.h"
#include "intel_de.h"
#include "intel_dp.h"
#include "intel_display_types.h"
#include "intel_dp.h"
#include "intel_fdi.h"
#include "intel_fdi_regs.h"
#include "intel_link_bw.h"
@@ -464,7 +465,6 @@ static void ivb_update_fdi_bc_bifurcation(const struct intel_crtc_state *crtc_st
void intel_fdi_normal_train(struct intel_crtc *crtc)
{
struct intel_display *display = to_intel_display(crtc);
struct drm_i915_private *dev_priv = to_i915(display->drm);
enum pipe pipe = crtc->pipe;
i915_reg_t reg;
u32 temp;
@@ -483,7 +483,7 @@ void intel_fdi_normal_train(struct intel_crtc *crtc)
reg = FDI_RX_CTL(pipe);
temp = intel_de_read(display, reg);
if (HAS_PCH_CPT(dev_priv)) {
if (HAS_PCH_CPT(display)) {
temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
temp |= FDI_LINK_TRAIN_NORMAL_CPT;
} else {
@@ -607,7 +607,6 @@ static void gen6_fdi_link_train(struct intel_crtc *crtc,
const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc);
struct drm_i915_private *dev_priv = to_i915(display->drm);
enum pipe pipe = crtc->pipe;
i915_reg_t reg;
u32 temp, i, retry;
@@ -647,7 +646,7 @@ static void gen6_fdi_link_train(struct intel_crtc *crtc,
reg = FDI_RX_CTL(pipe);
temp = intel_de_read(display, reg);
if (HAS_PCH_CPT(dev_priv)) {
if (HAS_PCH_CPT(display)) {
temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
temp |= FDI_LINK_TRAIN_PATTERN_1_CPT;
} else {
@@ -698,7 +697,7 @@ static void gen6_fdi_link_train(struct intel_crtc *crtc,
reg = FDI_RX_CTL(pipe);
temp = intel_de_read(display, reg);
if (HAS_PCH_CPT(dev_priv)) {
if (HAS_PCH_CPT(display)) {
temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
temp |= FDI_LINK_TRAIN_PATTERN_2_CPT;
} else {
@@ -1077,7 +1076,6 @@ void ilk_fdi_pll_disable(struct intel_crtc *crtc)
void ilk_fdi_disable(struct intel_crtc *crtc)
{
struct intel_display *display = to_intel_display(crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum pipe pipe = crtc->pipe;
i915_reg_t reg;
u32 temp;
@@ -1096,7 +1094,7 @@ void ilk_fdi_disable(struct intel_crtc *crtc)
udelay(100);
/* Ironlake workaround, disable clock pointer after downing FDI */
if (HAS_PCH_IBX(dev_priv))
if (HAS_PCH_IBX(display))
intel_de_write(display, FDI_RX_CHICKEN(pipe),
FDI_RX_PHASE_SYNC_POINTER_OVR);
@@ -1106,7 +1104,7 @@ void ilk_fdi_disable(struct intel_crtc *crtc)
reg = FDI_RX_CTL(pipe);
temp = intel_de_read(display, reg);
if (HAS_PCH_CPT(dev_priv)) {
if (HAS_PCH_CPT(display)) {
temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
temp |= FDI_LINK_TRAIN_PATTERN_1_CPT;
} else {

View File

@@ -25,7 +25,8 @@
*
*/
#include "i915_drv.h"
#include <drm/drm_print.h>
#include "i915_reg.h"
#include "intel_de.h"
#include "intel_display_irq.h"
@@ -57,11 +58,10 @@
static bool ivb_can_enable_err_int(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
struct intel_crtc *crtc;
enum pipe pipe;
lockdep_assert_held(&dev_priv->irq_lock);
lockdep_assert_held(&display->irq.lock);
for_each_pipe(display, pipe) {
crtc = intel_crtc_for_pipe(display, pipe);
@@ -75,11 +75,10 @@ static bool ivb_can_enable_err_int(struct intel_display *display)
static bool cpt_can_enable_serr_int(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
enum pipe pipe;
struct intel_crtc *crtc;
lockdep_assert_held(&dev_priv->irq_lock);
lockdep_assert_held(&display->irq.lock);
for_each_pipe(display, pipe) {
crtc = intel_crtc_for_pipe(display, pipe);
@@ -94,11 +93,10 @@ static bool cpt_can_enable_serr_int(struct intel_display *display)
static void i9xx_check_fifo_underruns(struct intel_crtc *crtc)
{
struct intel_display *display = to_intel_display(crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
i915_reg_t reg = PIPESTAT(display, crtc->pipe);
u32 enable_mask;
lockdep_assert_held(&dev_priv->irq_lock);
lockdep_assert_held(&display->irq.lock);
if ((intel_de_read(display, reg) & PIPE_FIFO_UNDERRUN_STATUS) == 0)
return;
@@ -115,10 +113,9 @@ static void i9xx_set_fifo_underrun_reporting(struct intel_display *display,
enum pipe pipe,
bool enable, bool old)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
i915_reg_t reg = PIPESTAT(display, pipe);
lockdep_assert_held(&dev_priv->irq_lock);
lockdep_assert_held(&display->irq.lock);
if (enable) {
u32 enable_mask = i915_pipestat_enable_mask(display, pipe);
@@ -148,11 +145,10 @@ static void ilk_set_fifo_underrun_reporting(struct intel_display *display,
static void ivb_check_fifo_underruns(struct intel_crtc *crtc)
{
struct intel_display *display = to_intel_display(crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum pipe pipe = crtc->pipe;
u32 err_int = intel_de_read(display, GEN7_ERR_INT);
lockdep_assert_held(&dev_priv->irq_lock);
lockdep_assert_held(&display->irq.lock);
if ((err_int & ERR_INT_FIFO_UNDERRUN(pipe)) == 0)
return;
@@ -213,11 +209,10 @@ static void ibx_set_fifo_underrun_reporting(struct intel_display *display,
static void cpt_check_pch_fifo_underruns(struct intel_crtc *crtc)
{
struct intel_display *display = to_intel_display(crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum pipe pch_transcoder = crtc->pipe;
u32 serr_int = intel_de_read(display, SERR_INT);
lockdep_assert_held(&dev_priv->irq_lock);
lockdep_assert_held(&display->irq.lock);
if ((serr_int & SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder)) == 0)
return;
@@ -258,11 +253,10 @@ static void cpt_set_fifo_underrun_reporting(struct intel_display *display,
static bool __intel_set_cpu_fifo_underrun_reporting(struct intel_display *display,
enum pipe pipe, bool enable)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe);
bool old;
lockdep_assert_held(&dev_priv->irq_lock);
lockdep_assert_held(&display->irq.lock);
old = !crtc->cpu_fifo_underrun_disabled;
crtc->cpu_fifo_underrun_disabled = !enable;
@@ -298,13 +292,12 @@ static bool __intel_set_cpu_fifo_underrun_reporting(struct intel_display *displa
bool intel_set_cpu_fifo_underrun_reporting(struct intel_display *display,
enum pipe pipe, bool enable)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
unsigned long flags;
bool ret;
spin_lock_irqsave(&dev_priv->irq_lock, flags);
spin_lock_irqsave(&display->irq.lock, flags);
ret = __intel_set_cpu_fifo_underrun_reporting(display, pipe, enable);
spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
spin_unlock_irqrestore(&display->irq.lock, flags);
return ret;
}
@@ -327,7 +320,6 @@ bool intel_set_pch_fifo_underrun_reporting(struct intel_display *display,
enum pipe pch_transcoder,
bool enable)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
struct intel_crtc *crtc = intel_crtc_for_pipe(display, pch_transcoder);
unsigned long flags;
bool old;
@@ -341,12 +333,12 @@ bool intel_set_pch_fifo_underrun_reporting(struct intel_display *display,
* crtc on LPT won't cause issues.
*/
spin_lock_irqsave(&dev_priv->irq_lock, flags);
spin_lock_irqsave(&display->irq.lock, flags);
old = !crtc->pch_fifo_underrun_disabled;
crtc->pch_fifo_underrun_disabled = !enable;
if (HAS_PCH_IBX(dev_priv))
if (HAS_PCH_IBX(display))
ibx_set_fifo_underrun_reporting(display,
pch_transcoder,
enable);
@@ -355,7 +347,7 @@ bool intel_set_pch_fifo_underrun_reporting(struct intel_display *display,
pch_transcoder,
enable, old);
spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
spin_unlock_irqrestore(&display->irq.lock, flags);
return old;
}
@@ -422,10 +414,9 @@ void intel_pch_fifo_underrun_irq_handler(struct intel_display *display,
*/
void intel_check_cpu_fifo_underruns(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
struct intel_crtc *crtc;
spin_lock_irq(&dev_priv->irq_lock);
spin_lock_irq(&display->irq.lock);
for_each_intel_crtc(display->drm, crtc) {
if (crtc->cpu_fifo_underrun_disabled)
@@ -437,7 +428,7 @@ void intel_check_cpu_fifo_underruns(struct intel_display *display)
ivb_check_fifo_underruns(crtc);
}
spin_unlock_irq(&dev_priv->irq_lock);
spin_unlock_irq(&display->irq.lock);
}
/**
@@ -450,20 +441,19 @@ void intel_check_cpu_fifo_underruns(struct intel_display *display)
*/
void intel_check_pch_fifo_underruns(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
struct intel_crtc *crtc;
spin_lock_irq(&dev_priv->irq_lock);
spin_lock_irq(&display->irq.lock);
for_each_intel_crtc(display->drm, crtc) {
if (crtc->pch_fifo_underrun_disabled)
continue;
if (HAS_PCH_CPT(dev_priv))
if (HAS_PCH_CPT(display))
cpt_check_pch_fifo_underruns(crtc);
}
spin_unlock_irq(&dev_priv->irq_lock);
spin_unlock_irq(&display->irq.lock);
}
void intel_init_fifo_underrun_reporting(struct intel_display *display,

View File

@@ -58,7 +58,6 @@
#include <drm/drm_gem.h>
#include "i915_active.h"
#include "i915_drv.h"
#include "i915_vma.h"
#include "intel_bo.h"
#include "intel_display_trace.h"
@@ -72,7 +71,7 @@
/**
* frontbuffer_flush - flush frontbuffer
* @i915: i915 device
* @display: display device
* @frontbuffer_bits: frontbuffer plane tracking bits
* @origin: which operation caused the flush
*
@@ -82,16 +81,14 @@
*
* Can be called without any locks held.
*/
static void frontbuffer_flush(struct drm_i915_private *i915,
static void frontbuffer_flush(struct intel_display *display,
unsigned int frontbuffer_bits,
enum fb_op_origin origin)
{
struct intel_display *display = &i915->display;
/* Delay flushing when rings are still busy.*/
spin_lock(&i915->display.fb_tracking.lock);
frontbuffer_bits &= ~i915->display.fb_tracking.busy_bits;
spin_unlock(&i915->display.fb_tracking.lock);
spin_lock(&display->fb_tracking.lock);
frontbuffer_bits &= ~display->fb_tracking.busy_bits;
spin_unlock(&display->fb_tracking.lock);
if (!frontbuffer_bits)
return;
@@ -107,7 +104,7 @@ static void frontbuffer_flush(struct drm_i915_private *i915,
/**
* intel_frontbuffer_flip_prepare - prepare asynchronous frontbuffer flip
* @i915: i915 device
* @display: display device
* @frontbuffer_bits: frontbuffer plane tracking bits
*
* This function gets called after scheduling a flip on @obj. The actual
@@ -117,19 +114,19 @@ static void frontbuffer_flush(struct drm_i915_private *i915,
*
* Can be called without any locks held.
*/
void intel_frontbuffer_flip_prepare(struct drm_i915_private *i915,
void intel_frontbuffer_flip_prepare(struct intel_display *display,
unsigned frontbuffer_bits)
{
spin_lock(&i915->display.fb_tracking.lock);
i915->display.fb_tracking.flip_bits |= frontbuffer_bits;
spin_lock(&display->fb_tracking.lock);
display->fb_tracking.flip_bits |= frontbuffer_bits;
/* Remove stale busy bits due to the old buffer. */
i915->display.fb_tracking.busy_bits &= ~frontbuffer_bits;
spin_unlock(&i915->display.fb_tracking.lock);
display->fb_tracking.busy_bits &= ~frontbuffer_bits;
spin_unlock(&display->fb_tracking.lock);
}
/**
* intel_frontbuffer_flip_complete - complete asynchronous frontbuffer flip
* @i915: i915 device
* @display: display device
* @frontbuffer_bits: frontbuffer plane tracking bits
*
* This function gets called after the flip has been latched and will complete
@@ -137,22 +134,22 @@ void intel_frontbuffer_flip_prepare(struct drm_i915_private *i915,
*
* Can be called without any locks held.
*/
void intel_frontbuffer_flip_complete(struct drm_i915_private *i915,
void intel_frontbuffer_flip_complete(struct intel_display *display,
unsigned frontbuffer_bits)
{
spin_lock(&i915->display.fb_tracking.lock);
spin_lock(&display->fb_tracking.lock);
/* Mask any cancelled flips. */
frontbuffer_bits &= i915->display.fb_tracking.flip_bits;
i915->display.fb_tracking.flip_bits &= ~frontbuffer_bits;
spin_unlock(&i915->display.fb_tracking.lock);
frontbuffer_bits &= display->fb_tracking.flip_bits;
display->fb_tracking.flip_bits &= ~frontbuffer_bits;
spin_unlock(&display->fb_tracking.lock);
if (frontbuffer_bits)
frontbuffer_flush(i915, frontbuffer_bits, ORIGIN_FLIP);
frontbuffer_flush(display, frontbuffer_bits, ORIGIN_FLIP);
}
/**
* intel_frontbuffer_flip - synchronous frontbuffer flip
* @i915: i915 device
* @display: display device
* @frontbuffer_bits: frontbuffer plane tracking bits
*
* This function gets called after scheduling a flip on @obj. This is for
@@ -161,15 +158,15 @@ void intel_frontbuffer_flip_complete(struct drm_i915_private *i915,
*
* Can be called without any locks held.
*/
void intel_frontbuffer_flip(struct drm_i915_private *i915,
void intel_frontbuffer_flip(struct intel_display *display,
unsigned frontbuffer_bits)
{
spin_lock(&i915->display.fb_tracking.lock);
spin_lock(&display->fb_tracking.lock);
/* Remove stale busy bits due to the old buffer. */
i915->display.fb_tracking.busy_bits &= ~frontbuffer_bits;
spin_unlock(&i915->display.fb_tracking.lock);
display->fb_tracking.busy_bits &= ~frontbuffer_bits;
spin_unlock(&display->fb_tracking.lock);
frontbuffer_flush(i915, frontbuffer_bits, ORIGIN_FLIP);
frontbuffer_flush(display, frontbuffer_bits, ORIGIN_FLIP);
}
void __intel_fb_invalidate(struct intel_frontbuffer *front,
@@ -198,7 +195,6 @@ void __intel_fb_flush(struct intel_frontbuffer *front,
unsigned int frontbuffer_bits)
{
struct intel_display *display = to_intel_display(front->obj->dev);
struct drm_i915_private *i915 = to_i915(display->drm);
if (origin == ORIGIN_CS) {
spin_lock(&display->fb_tracking.lock);
@@ -209,7 +205,7 @@ void __intel_fb_flush(struct intel_frontbuffer *front,
}
if (frontbuffer_bits)
frontbuffer_flush(i915, frontbuffer_bits, origin);
frontbuffer_flush(display, frontbuffer_bits, origin);
}
static void intel_frontbuffer_flush_work(struct work_struct *work)
@@ -280,7 +276,7 @@ static void frontbuffer_release(struct kref *ref)
struct intel_frontbuffer *
intel_frontbuffer_get(struct drm_gem_object *obj)
{
struct drm_i915_private *i915 = to_i915(obj->dev);
struct intel_display *display = to_intel_display(obj->dev);
struct intel_frontbuffer *front, *cur;
front = intel_bo_get_frontbuffer(obj);
@@ -300,9 +296,9 @@ intel_frontbuffer_get(struct drm_gem_object *obj)
I915_ACTIVE_RETIRE_SLEEPS);
INIT_WORK(&front->flush_work, intel_frontbuffer_flush_work);
spin_lock(&i915->display.fb_tracking.lock);
spin_lock(&display->fb_tracking.lock);
cur = intel_bo_set_frontbuffer(obj, front);
spin_unlock(&i915->display.fb_tracking.lock);
spin_unlock(&display->fb_tracking.lock);
if (cur != front)
kfree(front);
return cur;

View File

@@ -31,7 +31,7 @@
#include "i915_active_types.h"
struct drm_gem_object;
struct drm_i915_private;
struct intel_display;
enum fb_op_origin {
ORIGIN_CPU = 0,
@@ -68,11 +68,11 @@ struct intel_frontbuffer {
GENMASK(INTEL_FRONTBUFFER_BITS_PER_PIPE * ((pipe) + 1) - 1, \
INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe))
void intel_frontbuffer_flip_prepare(struct drm_i915_private *i915,
void intel_frontbuffer_flip_prepare(struct intel_display *display,
unsigned frontbuffer_bits);
void intel_frontbuffer_flip_complete(struct drm_i915_private *i915,
void intel_frontbuffer_flip_complete(struct intel_display *display,
unsigned frontbuffer_bits);
void intel_frontbuffer_flip(struct drm_i915_private *i915,
void intel_frontbuffer_flip(struct intel_display *display,
unsigned frontbuffer_bits);
void intel_frontbuffer_put(struct intel_frontbuffer *front);

View File

@@ -3,10 +3,13 @@
* Copyright © 2020 Intel Corporation
*/
#include <linux/pci.h>
#include <linux/string.h>
#include "i915_drv.h"
#include <drm/drm_print.h>
#include "intel_atomic.h"
#include "intel_display_core.h"
#include "intel_display_types.h"
#include "intel_global_state.h"

View File

@@ -152,32 +152,31 @@ static const struct gmbus_pin gmbus_pins_mtp[] = {
static const struct gmbus_pin *get_gmbus_pin(struct intel_display *display,
unsigned int pin)
{
struct drm_i915_private *i915 = to_i915(display->drm);
const struct gmbus_pin *pins;
size_t size;
if (INTEL_PCH_TYPE(i915) >= PCH_MTL) {
if (INTEL_PCH_TYPE(display) >= PCH_MTL) {
pins = gmbus_pins_mtp;
size = ARRAY_SIZE(gmbus_pins_mtp);
} else if (INTEL_PCH_TYPE(i915) >= PCH_DG2) {
} else if (INTEL_PCH_TYPE(display) >= PCH_DG2) {
pins = gmbus_pins_dg2;
size = ARRAY_SIZE(gmbus_pins_dg2);
} else if (INTEL_PCH_TYPE(i915) >= PCH_DG1) {
} else if (INTEL_PCH_TYPE(display) >= PCH_DG1) {
pins = gmbus_pins_dg1;
size = ARRAY_SIZE(gmbus_pins_dg1);
} else if (INTEL_PCH_TYPE(i915) >= PCH_ICP) {
} else if (INTEL_PCH_TYPE(display) >= PCH_ICP) {
pins = gmbus_pins_icp;
size = ARRAY_SIZE(gmbus_pins_icp);
} else if (HAS_PCH_CNP(i915)) {
} else if (HAS_PCH_CNP(display)) {
pins = gmbus_pins_cnp;
size = ARRAY_SIZE(gmbus_pins_cnp);
} else if (IS_GEMINILAKE(i915) || IS_BROXTON(i915)) {
} else if (display->platform.geminilake || display->platform.broxton) {
pins = gmbus_pins_bxt;
size = ARRAY_SIZE(gmbus_pins_bxt);
} else if (DISPLAY_VER(display) == 9) {
pins = gmbus_pins_skl;
size = ARRAY_SIZE(gmbus_pins_skl);
} else if (IS_BROADWELL(i915)) {
} else if (display->platform.broadwell) {
pins = gmbus_pins_bdw;
size = ARRAY_SIZE(gmbus_pins_bdw);
} else {
@@ -240,11 +239,10 @@ static void bxt_gmbus_clock_gating(struct intel_display *display,
static u32 get_reserved(struct intel_gmbus *bus)
{
struct intel_display *display = bus->display;
struct drm_i915_private *i915 = to_i915(display->drm);
u32 reserved = 0;
/* On most chips, these bits must be preserved in software. */
if (!IS_I830(i915) && !IS_I845G(i915))
if (!display->platform.i830 && !display->platform.i845g)
reserved = intel_de_read_notrace(display, bus->gpio_reg) &
(GPIO_DATA_PULLUP_DISABLE | GPIO_CLOCK_PULLUP_DISABLE);
@@ -314,11 +312,10 @@ intel_gpio_pre_xfer(struct i2c_adapter *adapter)
{
struct intel_gmbus *bus = to_intel_gmbus(adapter);
struct intel_display *display = bus->display;
struct drm_i915_private *i915 = to_i915(display->drm);
intel_gmbus_reset(display);
if (IS_PINEVIEW(i915))
if (display->platform.pineview)
pnv_gmbus_clock_gating(display, false);
set_data(bus, 1);
@@ -332,12 +329,11 @@ intel_gpio_post_xfer(struct i2c_adapter *adapter)
{
struct intel_gmbus *bus = to_intel_gmbus(adapter);
struct intel_display *display = bus->display;
struct drm_i915_private *i915 = to_i915(display->drm);
set_data(bus, 1);
set_clock(bus, 1);
if (IS_PINEVIEW(i915))
if (display->platform.pineview)
pnv_gmbus_clock_gating(display, true);
}
@@ -630,14 +626,13 @@ do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num,
{
struct intel_gmbus *bus = to_intel_gmbus(adapter);
struct intel_display *display = bus->display;
struct drm_i915_private *i915 = to_i915(display->drm);
int i = 0, inc, try = 0;
int ret = 0;
/* Display WA #0868: skl,bxt,kbl,cfl,glk */
if (IS_GEMINILAKE(i915) || IS_BROXTON(i915))
if (display->platform.geminilake || display->platform.broxton)
bxt_gmbus_clock_gating(display, false);
else if (HAS_PCH_SPT(i915) || HAS_PCH_CNP(i915))
else if (HAS_PCH_SPT(display) || HAS_PCH_CNP(display))
pch_gmbus_clock_gating(display, false);
retry:
@@ -748,9 +743,9 @@ timeout:
out:
/* Display WA #0868: skl,bxt,kbl,cfl,glk */
if (IS_GEMINILAKE(i915) || IS_BROXTON(i915))
if (display->platform.geminilake || display->platform.broxton)
bxt_gmbus_clock_gating(display, true);
else if (HAS_PCH_SPT(i915) || HAS_PCH_CNP(i915))
else if (HAS_PCH_SPT(display) || HAS_PCH_CNP(display))
pch_gmbus_clock_gating(display, true);
return ret;
@@ -873,12 +868,11 @@ static const struct i2c_lock_operations gmbus_lock_ops = {
*/
int intel_gmbus_setup(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
struct pci_dev *pdev = to_pci_dev(display->drm->dev);
unsigned int pin;
int ret;
if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915))
if (display->platform.valleyview || display->platform.cherryview)
display->gmbus.mmio_base = VLV_DISPLAY_BASE;
else if (!HAS_GMCH(display))
/*
@@ -925,7 +919,7 @@ int intel_gmbus_setup(struct intel_display *display)
bus->reg0 = pin | GMBUS_RATE_100KHZ;
/* gmbus seems to be broken on i830 */
if (IS_I830(i915))
if (display->platform.i830)
bus->force_bit = 1;
intel_gpio_setup(bus, GPIO(display, gmbus_pin->gpio));

View File

@@ -27,10 +27,13 @@
#include "intel_dp_mst.h"
#include "intel_hdcp.h"
#include "intel_hdcp_gsc.h"
#include "intel_hdcp_gsc_message.h"
#include "intel_hdcp_regs.h"
#include "intel_hdcp_shim.h"
#include "intel_pcode.h"
#define USE_HDCP_GSC(__display) (DISPLAY_VER(__display) >= 14)
#define KEY_LOAD_TRIES 5
#define HDCP2_LC_RETRY_CNT 3
@@ -250,8 +253,8 @@ static bool intel_hdcp2_prerequisite(struct intel_connector *connector)
return false;
/* If MTL+ make sure gsc is loaded and proxy is setup */
if (intel_hdcp_gsc_cs_required(display)) {
if (!intel_hdcp_gsc_check_status(display))
if (USE_HDCP_GSC(display)) {
if (!intel_hdcp_gsc_check_status(display->drm))
return false;
}
@@ -2339,7 +2342,7 @@ static int initialize_hdcp_port_data(struct intel_connector *connector,
static bool is_hdcp2_supported(struct intel_display *display)
{
if (intel_hdcp_gsc_cs_required(display))
if (USE_HDCP_GSC(display))
return true;
if (!IS_ENABLED(CONFIG_INTEL_MEI_HDCP))
@@ -2363,7 +2366,7 @@ void intel_hdcp_component_init(struct intel_display *display)
display->hdcp.comp_added = true;
mutex_unlock(&display->hdcp.hdcp_mutex);
if (intel_hdcp_gsc_cs_required(display))
if (USE_HDCP_GSC(display))
ret = intel_hdcp_gsc_init(display);
else
ret = component_add_typed(display->drm->dev, &i915_hdcp_ops,
@@ -2638,7 +2641,7 @@ void intel_hdcp_component_fini(struct intel_display *display)
display->hdcp.comp_added = false;
mutex_unlock(&display->hdcp.hdcp_mutex);
if (intel_hdcp_gsc_cs_required(display))
if (USE_HDCP_GSC(display))
intel_hdcp_gsc_fini(display);
else
component_del(display->drm->dev, &i915_hdcp_ops);

View File

@@ -11,27 +11,22 @@
#include "i915_drv.h"
#include "i915_utils.h"
#include "intel_hdcp_gsc.h"
#include "intel_hdcp_gsc_message.h"
struct intel_hdcp_gsc_message {
struct intel_hdcp_gsc_context {
struct drm_i915_private *i915;
struct i915_vma *vma;
void *hdcp_cmd_in;
void *hdcp_cmd_out;
};
bool intel_hdcp_gsc_cs_required(struct intel_display *display)
bool intel_hdcp_gsc_check_status(struct drm_device *drm)
{
return DISPLAY_VER(display) >= 14;
}
bool intel_hdcp_gsc_check_status(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
struct drm_i915_private *i915 = to_i915(drm);
struct intel_gt *gt = i915->media_gt;
struct intel_gsc_uc *gsc = gt ? &gt->uc.gsc : NULL;
if (!gsc || !intel_uc_fw_is_running(&gsc->fw)) {
drm_dbg_kms(display->drm,
drm_dbg_kms(&i915->drm,
"GSC components required for HDCP2.2 are not ready\n");
return false;
}
@@ -41,7 +36,7 @@ bool intel_hdcp_gsc_check_status(struct intel_display *display)
/*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)
struct intel_hdcp_gsc_context *gsc_context)
{
struct intel_gt *gt = i915->media_gt;
struct drm_i915_gem_object *obj = NULL;
@@ -78,9 +73,10 @@ static int intel_hdcp_gsc_initialize_message(struct drm_i915_private *i915,
memset(cmd_in, 0, obj->base.size);
hdcp_message->hdcp_cmd_in = cmd_in;
hdcp_message->hdcp_cmd_out = cmd_out;
hdcp_message->vma = vma;
gsc_context->hdcp_cmd_in = cmd_in;
gsc_context->hdcp_cmd_out = cmd_out;
gsc_context->vma = vma;
gsc_context->i915 = i915;
return 0;
@@ -91,80 +87,37 @@ 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 intel_display *display)
struct intel_hdcp_gsc_context *intel_hdcp_gsc_context_alloc(struct drm_device *drm)
{
struct drm_i915_private *i915 = to_i915(display->drm);
struct intel_hdcp_gsc_message *hdcp_message;
struct drm_i915_private *i915 = to_i915(drm);
struct intel_hdcp_gsc_context *gsc_context;
int ret;
hdcp_message = kzalloc(sizeof(*hdcp_message), GFP_KERNEL);
if (!hdcp_message)
return -ENOMEM;
gsc_context = kzalloc(sizeof(*gsc_context), GFP_KERNEL);
if (!gsc_context)
return ERR_PTR(-ENOMEM);
/*
* NOTE: No need to lock the comp mutex here as it is already
* going to be taken before this function called
*/
display->hdcp.hdcp_message = hdcp_message;
ret = intel_hdcp_gsc_initialize_message(i915, hdcp_message);
ret = intel_hdcp_gsc_initialize_message(i915, gsc_context);
if (ret) {
drm_err(&i915->drm, "Could not initialize gsc_context\n");
kfree(gsc_context);
gsc_context = ERR_PTR(ret);
}
if (ret)
drm_err(display->drm, "Could not initialize hdcp_message\n");
return ret;
return gsc_context;
}
static void intel_hdcp_gsc_free_message(struct intel_display *display)
void intel_hdcp_gsc_context_free(struct intel_hdcp_gsc_context *gsc_context)
{
struct intel_hdcp_gsc_message *hdcp_message =
display->hdcp.hdcp_message;
if (!gsc_context)
return;
hdcp_message->hdcp_cmd_in = NULL;
hdcp_message->hdcp_cmd_out = NULL;
i915_vma_unpin_and_release(&hdcp_message->vma, I915_VMA_RELEASE_MAP);
kfree(hdcp_message);
}
int intel_hdcp_gsc_init(struct intel_display *display)
{
struct i915_hdcp_arbiter *data;
int ret;
data = kzalloc(sizeof(struct i915_hdcp_arbiter), GFP_KERNEL);
if (!data)
return -ENOMEM;
mutex_lock(&display->hdcp.hdcp_mutex);
display->hdcp.arbiter = data;
display->hdcp.arbiter->hdcp_dev = display->drm->dev;
display->hdcp.arbiter->ops = &gsc_hdcp_ops;
ret = intel_hdcp_gsc_hdcp2_init(display);
mutex_unlock(&display->hdcp.hdcp_mutex);
return ret;
}
void intel_hdcp_gsc_fini(struct intel_display *display)
{
intel_hdcp_gsc_free_message(display);
kfree(display->hdcp.arbiter);
i915_vma_unpin_and_release(&gsc_context->vma, I915_VMA_RELEASE_MAP);
kfree(gsc_context);
}
static int intel_gsc_send_sync(struct drm_i915_private *i915,
@@ -211,18 +164,18 @@ static int intel_gsc_send_sync(struct drm_i915_private *i915,
/*
* This function can now be used for sending requests and will also handle
* receipt of reply messages hence no different function of message retrieval
* is required. We will initialize intel_hdcp_gsc_message structure then add
* is required. We will initialize intel_hdcp_gsc_context structure then add
* gsc cs memory header as stated in specs after which the normal HDCP payload
* will follow
*/
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)
ssize_t intel_hdcp_gsc_msg_send(struct intel_hdcp_gsc_context *gsc_context,
void *msg_in, size_t msg_in_len,
void *msg_out, size_t msg_out_len)
{
struct drm_i915_private *i915 = gsc_context->i915;
struct intel_gt *gt = i915->media_gt;
struct intel_gsc_mtl_header *header_in, *header_out;
const size_t max_msg_size = PAGE_SIZE - sizeof(*header_in);
struct intel_hdcp_gsc_message *hdcp_message;
u64 addr_in, addr_out, host_session_id;
u32 reply_size, msg_size_in, msg_size_out;
int ret, tries = 0;
@@ -235,10 +188,9 @@ ssize_t intel_hdcp_gsc_msg_send(struct drm_i915_private *i915, u8 *msg_in,
msg_size_in = msg_in_len + sizeof(*header_in);
msg_size_out = msg_out_len + sizeof(*header_out);
hdcp_message = i915->display.hdcp.hdcp_message;
header_in = hdcp_message->hdcp_cmd_in;
header_out = hdcp_message->hdcp_cmd_out;
addr_in = i915_ggtt_offset(hdcp_message->vma);
header_in = gsc_context->hdcp_cmd_in;
header_out = gsc_context->hdcp_cmd_out;
addr_in = i915_ggtt_offset(gsc_context->vma);
addr_out = addr_in + PAGE_SIZE;
memset(header_in, 0, msg_size_in);
@@ -246,7 +198,7 @@ ssize_t intel_hdcp_gsc_msg_send(struct drm_i915_private *i915, u8 *msg_in,
get_random_bytes(&host_session_id, sizeof(u64));
intel_gsc_uc_heci_cmd_emit_mtl_header(header_in, HECI_MEADDRESS_HDCP,
msg_size_in, host_session_id);
memcpy(hdcp_message->hdcp_cmd_in + sizeof(*header_in), msg_in, msg_in_len);
memcpy(gsc_context->hdcp_cmd_in + sizeof(*header_in), msg_in, msg_in_len);
/*
* Keep sending request in case the pending bit is set no need to add
@@ -280,7 +232,7 @@ ssize_t intel_hdcp_gsc_msg_send(struct drm_i915_private *i915, u8 *msg_in,
reply_size, (u32)msg_out_len);
}
memcpy(msg_out, hdcp_message->hdcp_cmd_out + sizeof(*header_out), msg_out_len);
memcpy(msg_out, gsc_context->hdcp_cmd_out + sizeof(*header_out), msg_out_len);
err:
return ret;

View File

@@ -6,19 +6,17 @@
#ifndef __INTEL_HDCP_GSC_H__
#define __INTEL_HDCP_GSC_H__
#include <linux/err.h>
#include <linux/types.h>
struct drm_i915_private;
struct intel_display;
struct intel_hdcp_gsc_message;
struct drm_device;
struct intel_hdcp_gsc_context;
bool intel_hdcp_gsc_cs_required(struct intel_display *display);
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);
int intel_hdcp_gsc_init(struct intel_display *display);
void intel_hdcp_gsc_fini(struct intel_display *display);
bool intel_hdcp_gsc_check_status(struct intel_display *display);
ssize_t intel_hdcp_gsc_msg_send(struct intel_hdcp_gsc_context *gsc_context,
void *msg_in, size_t msg_in_len,
void *msg_out, size_t msg_out_len);
bool intel_hdcp_gsc_check_status(struct drm_device *drm);
struct intel_hdcp_gsc_context *intel_hdcp_gsc_context_alloc(struct drm_device *drm);
void intel_hdcp_gsc_context_free(struct intel_hdcp_gsc_context *gsc_context);
#endif /* __INTEL_HDCP_GCS_H__ */

View File

@@ -4,20 +4,23 @@
*/
#include <linux/err.h>
#include <drm/drm_print.h>
#include <drm/intel/i915_hdcp_interface.h>
#include "i915_drv.h"
#include "intel_display_core.h"
#include "intel_display_types.h"
#include "intel_hdcp_gsc.h"
#include "intel_hdcp_gsc_message.h"
int
static 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 = {};
struct wired_cmd_initiate_hdcp2_session_out session_init_out = {};
struct intel_hdcp_gsc_context *gsc_context;
struct intel_display *display;
struct drm_i915_private *i915;
ssize_t byte;
if (!dev || !data || !ake_data)
@@ -28,7 +31,7 @@ intel_hdcp_gsc_initiate_session(struct device *dev, struct hdcp_port_data *data,
dev_err(dev, "DRM not initialized, aborting HDCP.\n");
return -ENODEV;
}
i915 = to_i915(display->drm);
gsc_context = display->hdcp.gsc_context;
session_init_in.header.api_version = HDCP_API_VERSION;
session_init_in.header.command_id = WIRED_INITIATE_HDCP2_SESSION;
@@ -41,9 +44,9 @@ intel_hdcp_gsc_initiate_session(struct device *dev, struct hdcp_port_data *data,
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,
byte = intel_hdcp_gsc_msg_send(gsc_context, &session_init_in,
sizeof(session_init_in),
(u8 *)&session_init_out,
&session_init_out,
sizeof(session_init_out));
if (byte < 0) {
drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
@@ -64,7 +67,7 @@ intel_hdcp_gsc_initiate_session(struct device *dev, struct hdcp_port_data *data,
return 0;
}
int
static int
intel_hdcp_gsc_verify_receiver_cert_prepare_km(struct device *dev,
struct hdcp_port_data *data,
struct hdcp2_ake_send_cert *rx_cert,
@@ -75,8 +78,8 @@ intel_hdcp_gsc_verify_receiver_cert_prepare_km(struct device *dev,
{
struct wired_cmd_verify_receiver_cert_in verify_rxcert_in = {};
struct wired_cmd_verify_receiver_cert_out verify_rxcert_out = {};
struct intel_hdcp_gsc_context *gsc_context;
struct intel_display *display;
struct drm_i915_private *i915;
ssize_t byte;
if (!dev || !data || !rx_cert || !km_stored || !ek_pub_km || !msg_sz)
@@ -87,7 +90,7 @@ intel_hdcp_gsc_verify_receiver_cert_prepare_km(struct device *dev,
dev_err(dev, "DRM not initialized, aborting HDCP.\n");
return -ENODEV;
}
i915 = to_i915(display->drm);
gsc_context = display->hdcp.gsc_context;
verify_rxcert_in.header.api_version = HDCP_API_VERSION;
verify_rxcert_in.header.command_id = WIRED_VERIFY_RECEIVER_CERT;
@@ -103,9 +106,9 @@ intel_hdcp_gsc_verify_receiver_cert_prepare_km(struct device *dev,
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,
byte = intel_hdcp_gsc_msg_send(gsc_context, &verify_rxcert_in,
sizeof(verify_rxcert_in),
(u8 *)&verify_rxcert_out,
&verify_rxcert_out,
sizeof(verify_rxcert_out));
if (byte < 0) {
drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed: %zd\n", byte);
@@ -134,14 +137,14 @@ intel_hdcp_gsc_verify_receiver_cert_prepare_km(struct device *dev,
return 0;
}
int
static 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 = {};
struct wired_cmd_ake_send_hprime_out send_hprime_out = {};
struct intel_hdcp_gsc_context *gsc_context;
struct intel_display *display;
struct drm_i915_private *i915;
ssize_t byte;
if (!dev || !data || !rx_hprime)
@@ -152,7 +155,7 @@ intel_hdcp_gsc_verify_hprime(struct device *dev, struct hdcp_port_data *data,
dev_err(dev, "DRM not initialized, aborting HDCP.\n");
return -ENODEV;
}
i915 = to_i915(display->drm);
gsc_context = display->hdcp.gsc_context;
send_hprime_in.header.api_version = HDCP_API_VERSION;
send_hprime_in.header.command_id = WIRED_AKE_SEND_HPRIME;
@@ -166,9 +169,9 @@ intel_hdcp_gsc_verify_hprime(struct device *dev, struct hdcp_port_data *data,
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,
byte = intel_hdcp_gsc_msg_send(gsc_context, &send_hprime_in,
sizeof(send_hprime_in),
(u8 *)&send_hprime_out,
&send_hprime_out,
sizeof(send_hprime_out));
if (byte < 0) {
drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
@@ -184,14 +187,14 @@ intel_hdcp_gsc_verify_hprime(struct device *dev, struct hdcp_port_data *data,
return 0;
}
int
static 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 = {};
struct wired_cmd_ake_send_pairing_info_out pairing_info_out = {};
struct intel_hdcp_gsc_context *gsc_context;
struct intel_display *display;
struct drm_i915_private *i915;
ssize_t byte;
if (!dev || !data || !pairing_info)
@@ -202,7 +205,7 @@ intel_hdcp_gsc_store_pairing_info(struct device *dev, struct hdcp_port_data *dat
dev_err(dev, "DRM not initialized, aborting HDCP.\n");
return -ENODEV;
}
i915 = to_i915(display->drm);
gsc_context = display->hdcp.gsc_context;
pairing_info_in.header.api_version = HDCP_API_VERSION;
pairing_info_in.header.command_id = WIRED_AKE_SEND_PAIRING_INFO;
@@ -217,9 +220,9 @@ intel_hdcp_gsc_store_pairing_info(struct device *dev, struct hdcp_port_data *dat
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,
byte = intel_hdcp_gsc_msg_send(gsc_context, &pairing_info_in,
sizeof(pairing_info_in),
(u8 *)&pairing_info_out,
&pairing_info_out,
sizeof(pairing_info_out));
if (byte < 0) {
drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
@@ -236,15 +239,15 @@ intel_hdcp_gsc_store_pairing_info(struct device *dev, struct hdcp_port_data *dat
return 0;
}
int
static 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 = {};
struct wired_cmd_init_locality_check_out lc_init_out = {};
struct intel_hdcp_gsc_context *gsc_context;
struct intel_display *display;
struct drm_i915_private *i915;
ssize_t byte;
if (!dev || !data || !lc_init_data)
@@ -255,7 +258,7 @@ intel_hdcp_gsc_initiate_locality_check(struct device *dev,
dev_err(dev, "DRM not initialized, aborting HDCP.\n");
return -ENODEV;
}
i915 = to_i915(display->drm);
gsc_context = display->hdcp.gsc_context;
lc_init_in.header.api_version = HDCP_API_VERSION;
lc_init_in.header.command_id = WIRED_INIT_LOCALITY_CHECK;
@@ -266,8 +269,8 @@ intel_hdcp_gsc_initiate_locality_check(struct device *dev,
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));
byte = intel_hdcp_gsc_msg_send(gsc_context, &lc_init_in, sizeof(lc_init_in),
&lc_init_out, sizeof(lc_init_out));
if (byte < 0) {
drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
return byte;
@@ -285,14 +288,14 @@ intel_hdcp_gsc_initiate_locality_check(struct device *dev,
return 0;
}
int
static 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 = {};
struct wired_cmd_validate_locality_out verify_lprime_out = {};
struct intel_hdcp_gsc_context *gsc_context;
struct intel_display *display;
struct drm_i915_private *i915;
ssize_t byte;
if (!dev || !data || !rx_lprime)
@@ -303,7 +306,7 @@ intel_hdcp_gsc_verify_lprime(struct device *dev, struct hdcp_port_data *data,
dev_err(dev, "DRM not initialized, aborting HDCP.\n");
return -ENODEV;
}
i915 = to_i915(display->drm);
gsc_context = display->hdcp.gsc_context;
verify_lprime_in.header.api_version = HDCP_API_VERSION;
verify_lprime_in.header.command_id = WIRED_VALIDATE_LOCALITY;
@@ -318,9 +321,9 @@ intel_hdcp_gsc_verify_lprime(struct device *dev, struct hdcp_port_data *data,
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,
byte = intel_hdcp_gsc_msg_send(gsc_context, &verify_lprime_in,
sizeof(verify_lprime_in),
(u8 *)&verify_lprime_out,
&verify_lprime_out,
sizeof(verify_lprime_out));
if (byte < 0) {
drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
@@ -337,14 +340,15 @@ intel_hdcp_gsc_verify_lprime(struct device *dev, struct hdcp_port_data *data,
return 0;
}
int intel_hdcp_gsc_get_session_key(struct device *dev,
struct hdcp_port_data *data,
struct hdcp2_ske_send_eks *ske_data)
static 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 = {};
struct wired_cmd_get_session_key_out get_skey_out = {};
struct intel_hdcp_gsc_context *gsc_context;
struct intel_display *display;
struct drm_i915_private *i915;
ssize_t byte;
if (!dev || !data || !ske_data)
@@ -355,7 +359,7 @@ int intel_hdcp_gsc_get_session_key(struct device *dev,
dev_err(dev, "DRM not initialized, aborting HDCP.\n");
return -ENODEV;
}
i915 = to_i915(display->drm);
gsc_context = display->hdcp.gsc_context;
get_skey_in.header.api_version = HDCP_API_VERSION;
get_skey_in.header.command_id = WIRED_GET_SESSION_KEY;
@@ -366,8 +370,8 @@ int intel_hdcp_gsc_get_session_key(struct device *dev,
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));
byte = intel_hdcp_gsc_msg_send(gsc_context, &get_skey_in, sizeof(get_skey_in),
&get_skey_out, sizeof(get_skey_out));
if (byte < 0) {
drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
return byte;
@@ -387,7 +391,7 @@ int intel_hdcp_gsc_get_session_key(struct device *dev,
return 0;
}
int
static int
intel_hdcp_gsc_repeater_check_flow_prepare_ack(struct device *dev,
struct hdcp_port_data *data,
struct hdcp2_rep_send_receiverid_list
@@ -397,8 +401,8 @@ intel_hdcp_gsc_repeater_check_flow_prepare_ack(struct device *dev,
{
struct wired_cmd_verify_repeater_in verify_repeater_in = {};
struct wired_cmd_verify_repeater_out verify_repeater_out = {};
struct intel_hdcp_gsc_context *gsc_context;
struct intel_display *display;
struct drm_i915_private *i915;
ssize_t byte;
if (!dev || !rep_topology || !rep_send_ack || !data)
@@ -409,7 +413,7 @@ intel_hdcp_gsc_repeater_check_flow_prepare_ack(struct device *dev,
dev_err(dev, "DRM not initialized, aborting HDCP.\n");
return -ENODEV;
}
i915 = to_i915(display->drm);
gsc_context = display->hdcp.gsc_context;
verify_repeater_in.header.api_version = HDCP_API_VERSION;
verify_repeater_in.header.command_id = WIRED_VERIFY_REPEATER;
@@ -430,9 +434,9 @@ intel_hdcp_gsc_repeater_check_flow_prepare_ack(struct device *dev,
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,
byte = intel_hdcp_gsc_msg_send(gsc_context, &verify_repeater_in,
sizeof(verify_repeater_in),
(u8 *)&verify_repeater_out,
&verify_repeater_out,
sizeof(verify_repeater_out));
if (byte < 0) {
drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
@@ -453,14 +457,15 @@ intel_hdcp_gsc_repeater_check_flow_prepare_ack(struct device *dev,
return 0;
}
int intel_hdcp_gsc_verify_mprime(struct device *dev,
struct hdcp_port_data *data,
struct hdcp2_rep_stream_ready *stream_ready)
static 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 = {};
struct intel_hdcp_gsc_context *gsc_context;
struct intel_display *display;
struct drm_i915_private *i915;
ssize_t byte;
size_t cmd_size;
@@ -472,7 +477,7 @@ int intel_hdcp_gsc_verify_mprime(struct device *dev,
dev_err(dev, "DRM not initialized, aborting HDCP.\n");
return -ENODEV;
}
i915 = to_i915(display->drm);
gsc_context = display->hdcp.gsc_context;
cmd_size = struct_size(verify_mprime_in, streams, data->k);
if (cmd_size == SIZE_MAX)
@@ -499,8 +504,8 @@ int intel_hdcp_gsc_verify_mprime(struct device *dev,
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,
byte = intel_hdcp_gsc_msg_send(gsc_context, verify_mprime_in, cmd_size,
&verify_mprime_out,
sizeof(verify_mprime_out));
kfree(verify_mprime_in);
if (byte < 0) {
@@ -518,13 +523,13 @@ int intel_hdcp_gsc_verify_mprime(struct device *dev,
return 0;
}
int intel_hdcp_gsc_enable_authentication(struct device *dev,
struct hdcp_port_data *data)
static int intel_hdcp_gsc_enable_authentication(struct device *dev,
struct hdcp_port_data *data)
{
struct wired_cmd_enable_auth_in enable_auth_in = {};
struct wired_cmd_enable_auth_out enable_auth_out = {};
struct intel_hdcp_gsc_context *gsc_context;
struct intel_display *display;
struct drm_i915_private *i915;
ssize_t byte;
if (!dev || !data)
@@ -535,7 +540,7 @@ int intel_hdcp_gsc_enable_authentication(struct device *dev,
dev_err(dev, "DRM not initialized, aborting HDCP.\n");
return -ENODEV;
}
i915 = to_i915(display->drm);
gsc_context = display->hdcp.gsc_context;
enable_auth_in.header.api_version = HDCP_API_VERSION;
enable_auth_in.header.command_id = WIRED_ENABLE_AUTH;
@@ -547,9 +552,9 @@ int intel_hdcp_gsc_enable_authentication(struct device *dev,
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,
byte = intel_hdcp_gsc_msg_send(gsc_context, &enable_auth_in,
sizeof(enable_auth_in),
(u8 *)&enable_auth_out,
&enable_auth_out,
sizeof(enable_auth_out));
if (byte < 0) {
drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
@@ -565,13 +570,13 @@ int intel_hdcp_gsc_enable_authentication(struct device *dev,
return 0;
}
int
static int
intel_hdcp_gsc_close_session(struct device *dev, struct hdcp_port_data *data)
{
struct wired_cmd_close_session_in session_close_in = {};
struct wired_cmd_close_session_out session_close_out = {};
struct intel_hdcp_gsc_context *gsc_context;
struct intel_display *display;
struct drm_i915_private *i915;
ssize_t byte;
if (!dev || !data)
@@ -582,7 +587,7 @@ intel_hdcp_gsc_close_session(struct device *dev, struct hdcp_port_data *data)
dev_err(dev, "DRM not initialized, aborting HDCP.\n");
return -ENODEV;
}
i915 = to_i915(display->drm);
gsc_context = display->hdcp.gsc_context;
session_close_in.header.api_version = HDCP_API_VERSION;
session_close_in.header.command_id = WIRED_CLOSE_SESSION;
@@ -594,9 +599,9 @@ intel_hdcp_gsc_close_session(struct device *dev, struct hdcp_port_data *data)
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,
byte = intel_hdcp_gsc_msg_send(gsc_context, &session_close_in,
sizeof(session_close_in),
(u8 *)&session_close_out,
&session_close_out,
sizeof(session_close_out));
if (byte < 0) {
drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte);
@@ -611,3 +616,57 @@ intel_hdcp_gsc_close_session(struct device *dev, struct hdcp_port_data *data)
return 0;
}
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,
};
int intel_hdcp_gsc_init(struct intel_display *display)
{
struct intel_hdcp_gsc_context *gsc_context;
struct i915_hdcp_arbiter *arbiter;
int ret = 0;
arbiter = kzalloc(sizeof(*arbiter), GFP_KERNEL);
if (!arbiter)
return -ENOMEM;
mutex_lock(&display->hdcp.hdcp_mutex);
gsc_context = intel_hdcp_gsc_context_alloc(display->drm);
if (IS_ERR(gsc_context)) {
ret = PTR_ERR(gsc_context);
kfree(arbiter);
goto out;
}
display->hdcp.arbiter = arbiter;
display->hdcp.arbiter->hdcp_dev = display->drm->dev;
display->hdcp.arbiter->ops = &gsc_hdcp_ops;
display->hdcp.gsc_context = gsc_context;
out:
mutex_unlock(&display->hdcp.hdcp_mutex);
return ret;
}
void intel_hdcp_gsc_fini(struct intel_display *display)
{
intel_hdcp_gsc_context_free(display->hdcp.gsc_context);
display->hdcp.gsc_context = NULL;
kfree(display->hdcp.arbiter);
display->hdcp.arbiter = NULL;
}

View File

@@ -6,68 +6,9 @@
#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;
struct intel_display;
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 intel_display *display);
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);
int intel_hdcp_gsc_init(struct intel_display *display);
void intel_hdcp_gsc_fini(struct intel_display *display);
#endif /* __INTEL_HDCP_GSC_MESSAGE_H__ */

View File

@@ -38,14 +38,15 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
#include <drm/intel/intel_lpe_audio.h>
#include <media/cec-notifier.h>
#include "g4x_hdmi.h"
#include "i915_drv.h"
#include "i915_reg.h"
#include "i915_utils.h"
#include "intel_atomic.h"
#include "intel_audio.h"
#include "intel_connector.h"
@@ -715,7 +716,7 @@ intel_hdmi_compute_avi_infoframe(struct intel_encoder *encoder,
struct hdmi_avi_infoframe *frame = &crtc_state->infoframes.avi.avi;
const struct drm_display_mode *adjusted_mode =
&crtc_state->hw.adjusted_mode;
struct drm_connector *connector = conn_state->connector;
struct intel_connector *connector = to_intel_connector(conn_state->connector);
int ret;
if (!crtc_state->has_infoframe)
@@ -724,7 +725,7 @@ intel_hdmi_compute_avi_infoframe(struct intel_encoder *encoder,
crtc_state->infoframes.enable |=
intel_hdmi_infoframe_enable(HDMI_INFOFRAME_TYPE_AVI);
ret = drm_hdmi_avi_infoframe_from_display_mode(frame, connector,
ret = drm_hdmi_avi_infoframe_from_display_mode(frame, &connector->base,
adjusted_mode);
if (ret)
return false;
@@ -743,7 +744,7 @@ intel_hdmi_compute_avi_infoframe(struct intel_encoder *encoder,
crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB);
if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_RGB) {
drm_hdmi_avi_infoframe_quant_range(frame, connector,
drm_hdmi_avi_infoframe_quant_range(frame, &connector->base,
adjusted_mode,
crtc_state->limited_color_range ?
HDMI_QUANTIZATION_RANGE_LIMITED :
@@ -769,7 +770,7 @@ intel_hdmi_compute_spd_infoframe(struct intel_encoder *encoder,
struct intel_crtc_state *crtc_state,
struct drm_connector_state *conn_state)
{
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
struct intel_display *display = to_intel_display(crtc_state);
struct hdmi_spd_infoframe *frame = &crtc_state->infoframes.spd.spd;
int ret;
@@ -779,7 +780,7 @@ intel_hdmi_compute_spd_infoframe(struct intel_encoder *encoder,
crtc_state->infoframes.enable |=
intel_hdmi_infoframe_enable(HDMI_INFOFRAME_TYPE_SPD);
if (IS_DGFX(i915))
if (display->platform.dgfx)
ret = hdmi_spd_infoframe_init(frame, "Intel", "Discrete gfx");
else
ret = hdmi_spd_infoframe_init(frame, "Intel", "Integrated gfx");
@@ -979,7 +980,6 @@ static bool intel_hdmi_set_gcp_infoframe(struct intel_encoder *encoder,
const struct drm_connector_state *conn_state)
{
struct intel_display *display = to_intel_display(encoder);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
i915_reg_t reg;
@@ -989,9 +989,9 @@ static bool intel_hdmi_set_gcp_infoframe(struct intel_encoder *encoder,
if (HAS_DDI(display))
reg = HSW_TVIDEO_DIP_GCP(display, crtc_state->cpu_transcoder);
else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
else if (display->platform.valleyview || display->platform.cherryview)
reg = VLV_TVIDEO_DIP_GCP(crtc->pipe);
else if (HAS_PCH_SPLIT(dev_priv))
else if (HAS_PCH_SPLIT(display))
reg = TVIDEO_DIP_GCP(crtc->pipe);
else
return false;
@@ -1005,7 +1005,6 @@ void intel_hdmi_read_gcp_infoframe(struct intel_encoder *encoder,
struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(encoder);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
i915_reg_t reg;
@@ -1015,9 +1014,9 @@ void intel_hdmi_read_gcp_infoframe(struct intel_encoder *encoder,
if (HAS_DDI(display))
reg = HSW_TVIDEO_DIP_GCP(display, crtc_state->cpu_transcoder);
else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
else if (display->platform.valleyview || display->platform.cherryview)
reg = VLV_TVIDEO_DIP_GCP(crtc->pipe);
else if (HAS_PCH_SPLIT(dev_priv))
else if (HAS_PCH_SPLIT(display))
reg = TVIDEO_DIP_GCP(crtc->pipe);
else
return;
@@ -1029,9 +1028,9 @@ static void intel_hdmi_compute_gcp_infoframe(struct intel_encoder *encoder,
struct intel_crtc_state *crtc_state,
struct drm_connector_state *conn_state)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_display *display = to_intel_display(encoder);
if (IS_G4X(dev_priv) || !crtc_state->has_infoframe)
if (display->platform.g4x || !crtc_state->has_infoframe)
return;
crtc_state->infoframes.enable |=
@@ -1539,7 +1538,6 @@ int intel_hdmi_hdcp_toggle_signalling(struct intel_digital_port *dig_port,
struct intel_display *display = to_intel_display(dig_port);
struct intel_hdmi *hdmi = &dig_port->hdmi;
struct intel_connector *connector = hdmi->attached_connector;
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
int ret;
if (!enable)
@@ -1558,7 +1556,7 @@ int intel_hdmi_hdcp_toggle_signalling(struct intel_digital_port *dig_port,
* WA: To fix incorrect positioning of the window of
* opportunity and enc_en signalling in KABYLAKE.
*/
if (IS_KABYLAKE(dev_priv) && enable)
if (display->platform.kabylake && enable)
return kbl_repositioning_enc_en_signal(connector,
cpu_transcoder);
@@ -1570,7 +1568,6 @@ bool intel_hdmi_hdcp_check_link_once(struct intel_digital_port *dig_port,
struct intel_connector *connector)
{
struct intel_display *display = to_intel_display(dig_port);
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
enum port port = dig_port->base.port;
enum transcoder cpu_transcoder = connector->hdcp.cpu_transcoder;
int ret;
@@ -1583,15 +1580,15 @@ bool intel_hdmi_hdcp_check_link_once(struct intel_digital_port *dig_port,
if (ret)
return false;
intel_de_write(i915, HDCP_RPRIME(i915, cpu_transcoder, port), ri.reg);
intel_de_write(display, HDCP_RPRIME(display, cpu_transcoder, port), ri.reg);
/* Wait for Ri prime match */
if (wait_for((intel_de_read(i915, HDCP_STATUS(i915, cpu_transcoder, port)) &
if (wait_for((intel_de_read(display, HDCP_STATUS(display, cpu_transcoder, port)) &
(HDCP_STATUS_RI_MATCH | HDCP_STATUS_ENC)) ==
(HDCP_STATUS_RI_MATCH | HDCP_STATUS_ENC), 1)) {
drm_dbg_kms(display->drm, "Ri' mismatch detected (%x)\n",
intel_de_read(i915, HDCP_STATUS(i915, cpu_transcoder,
port)));
intel_de_read(display, HDCP_STATUS(display, cpu_transcoder,
port)));
return false;
}
return true;
@@ -1814,14 +1811,13 @@ static const struct intel_hdcp_shim intel_hdmi_hdcp_shim = {
static int intel_hdmi_source_max_tmds_clock(struct intel_encoder *encoder)
{
struct intel_display *display = to_intel_display(encoder);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
int max_tmds_clock, vbt_max_tmds_clock;
if (DISPLAY_VER(display) >= 13 || IS_ALDERLAKE_S(dev_priv))
if (DISPLAY_VER(display) >= 13 || display->platform.alderlake_s)
max_tmds_clock = 600000;
else if (DISPLAY_VER(display) >= 10)
max_tmds_clock = 594000;
else if (DISPLAY_VER(display) >= 8 || IS_HASWELL(dev_priv))
else if (DISPLAY_VER(display) >= 8 || display->platform.haswell)
max_tmds_clock = 300000;
else if (DISPLAY_VER(display) >= 5)
max_tmds_clock = 225000;
@@ -1880,7 +1876,6 @@ hdmi_port_clock_valid(struct intel_hdmi *hdmi,
bool has_hdmi_sink)
{
struct intel_display *display = to_intel_display(hdmi);
struct drm_i915_private *dev_priv = to_i915(display->drm);
struct intel_encoder *encoder = &hdmi_to_dig_port(hdmi)->base;
if (clock < 25000)
@@ -1890,16 +1885,16 @@ hdmi_port_clock_valid(struct intel_hdmi *hdmi,
return MODE_CLOCK_HIGH;
/* GLK DPLL can't generate 446-480 MHz */
if (IS_GEMINILAKE(dev_priv) && clock > 446666 && clock < 480000)
if (display->platform.geminilake && clock > 446666 && clock < 480000)
return MODE_CLOCK_RANGE;
/* BXT/GLK DPLL can't generate 223-240 MHz */
if ((IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) &&
if ((display->platform.geminilake || display->platform.broxton) &&
clock > 223333 && clock < 240000)
return MODE_CLOCK_RANGE;
/* CHV DPLL can't generate 216-240 MHz */
if (IS_CHERRYVIEW(dev_priv) && clock > 216000 && clock < 240000)
if (display->platform.cherryview && clock > 216000 && clock < 240000)
return MODE_CLOCK_RANGE;
/* ICL+ combo PHY PLL can't generate 500-533.2 MHz */
@@ -1943,11 +1938,12 @@ static bool intel_hdmi_source_bpc_possible(struct intel_display *display, int bp
}
}
static bool intel_hdmi_sink_bpc_possible(struct drm_connector *connector,
static bool intel_hdmi_sink_bpc_possible(struct drm_connector *_connector,
int bpc, bool has_hdmi_sink,
enum intel_output_format sink_format)
{
const struct drm_display_info *info = &connector->display_info;
struct intel_connector *connector = to_intel_connector(_connector);
const struct drm_display_info *info = &connector->base.display_info;
const struct drm_hdmi_info *hdmi = &info->hdmi;
switch (bpc) {
@@ -1976,12 +1972,13 @@ static bool intel_hdmi_sink_bpc_possible(struct drm_connector *connector,
}
static enum drm_mode_status
intel_hdmi_mode_clock_valid(struct drm_connector *connector, int clock,
intel_hdmi_mode_clock_valid(struct drm_connector *_connector, int clock,
bool has_hdmi_sink,
enum intel_output_format sink_format)
{
struct intel_display *display = to_intel_display(connector->dev);
struct intel_hdmi *hdmi = intel_attached_hdmi(to_intel_connector(connector));
struct intel_connector *connector = to_intel_connector(_connector);
struct intel_display *display = to_intel_display(connector);
struct intel_hdmi *hdmi = intel_attached_hdmi(connector);
enum drm_mode_status status = MODE_OK;
int bpc;
@@ -1996,7 +1993,8 @@ intel_hdmi_mode_clock_valid(struct drm_connector *connector, int clock,
if (!intel_hdmi_source_bpc_possible(display, bpc))
continue;
if (!intel_hdmi_sink_bpc_possible(connector, bpc, has_hdmi_sink, sink_format))
if (!intel_hdmi_sink_bpc_possible(&connector->base, bpc, has_hdmi_sink,
sink_format))
continue;
status = hdmi_port_clock_valid(hdmi, tmds_clock, true, has_hdmi_sink);
@@ -2011,15 +2009,16 @@ intel_hdmi_mode_clock_valid(struct drm_connector *connector, int clock,
}
static enum drm_mode_status
intel_hdmi_mode_valid(struct drm_connector *connector,
intel_hdmi_mode_valid(struct drm_connector *_connector,
const struct drm_display_mode *mode)
{
struct intel_display *display = to_intel_display(connector->dev);
struct intel_hdmi *hdmi = intel_attached_hdmi(to_intel_connector(connector));
struct intel_connector *connector = to_intel_connector(_connector);
struct intel_display *display = to_intel_display(connector);
struct intel_hdmi *hdmi = intel_attached_hdmi(connector);
enum drm_mode_status status;
int clock = mode->clock;
int max_dotclk = to_i915(connector->dev)->display.cdclk.max_dotclk_freq;
bool has_hdmi_sink = intel_has_hdmi_sink(hdmi, connector->state);
int max_dotclk = display->cdclk.max_dotclk_freq;
bool has_hdmi_sink = intel_has_hdmi_sink(hdmi, connector->base.state);
bool ycbcr_420_only;
enum intel_output_format sink_format;
@@ -2048,22 +2047,23 @@ intel_hdmi_mode_valid(struct drm_connector *connector,
if (clock > 600000)
return MODE_CLOCK_HIGH;
ycbcr_420_only = drm_mode_is_420_only(&connector->display_info, mode);
ycbcr_420_only = drm_mode_is_420_only(&connector->base.display_info, mode);
if (ycbcr_420_only)
sink_format = INTEL_OUTPUT_FORMAT_YCBCR420;
else
sink_format = INTEL_OUTPUT_FORMAT_RGB;
status = intel_hdmi_mode_clock_valid(connector, clock, has_hdmi_sink, sink_format);
status = intel_hdmi_mode_clock_valid(&connector->base, clock, has_hdmi_sink, sink_format);
if (status != MODE_OK) {
if (ycbcr_420_only ||
!connector->ycbcr_420_allowed ||
!drm_mode_is_420_also(&connector->display_info, mode))
!connector->base.ycbcr_420_allowed ||
!drm_mode_is_420_also(&connector->base.display_info, mode))
return status;
sink_format = INTEL_OUTPUT_FORMAT_YCBCR420;
status = intel_hdmi_mode_clock_valid(connector, clock, has_hdmi_sink, sink_format);
status = intel_hdmi_mode_clock_valid(&connector->base, clock, has_hdmi_sink,
sink_format);
if (status != MODE_OK)
return status;
}
@@ -2074,16 +2074,16 @@ intel_hdmi_mode_valid(struct drm_connector *connector,
bool intel_hdmi_bpc_possible(const struct intel_crtc_state *crtc_state,
int bpc, bool has_hdmi_sink)
{
struct drm_atomic_state *state = crtc_state->uapi.state;
struct drm_connector_state *connector_state;
struct drm_connector *connector;
struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->uapi.state);
struct intel_digital_connector_state *connector_state;
struct intel_connector *connector;
int i;
for_each_new_connector_in_state(state, connector, connector_state, i) {
if (connector_state->crtc != crtc_state->uapi.crtc)
for_each_new_intel_connector_in_state(state, connector, connector_state, i) {
if (connector_state->base.crtc != crtc_state->uapi.crtc)
continue;
if (!intel_hdmi_sink_bpc_possible(connector, bpc, has_hdmi_sink,
if (!intel_hdmi_sink_bpc_possible(&connector->base, bpc, has_hdmi_sink,
crtc_state->sink_format))
return false;
}
@@ -2211,7 +2211,7 @@ static bool intel_hdmi_has_audio(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state)
{
struct drm_connector *connector = conn_state->connector;
struct intel_connector *connector = to_intel_connector(conn_state->connector);
const struct intel_digital_connector_state *intel_conn_state =
to_intel_digital_connector_state(conn_state);
@@ -2219,7 +2219,7 @@ static bool intel_hdmi_has_audio(struct intel_encoder *encoder,
return false;
if (intel_conn_state->force_audio == HDMI_AUDIO_AUTO)
return connector->display_info.has_audio;
return connector->base.display_info.has_audio;
else
return intel_conn_state->force_audio == HDMI_AUDIO_ON;
}
@@ -2323,14 +2323,14 @@ int intel_hdmi_compute_config(struct intel_encoder *encoder,
{
struct intel_display *display = to_intel_display(encoder);
struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
struct drm_connector *connector = conn_state->connector;
struct drm_scdc *scdc = &connector->display_info.hdmi.scdc;
struct intel_connector *connector = to_intel_connector(conn_state->connector);
struct drm_scdc *scdc = &connector->base.display_info.hdmi.scdc;
int ret;
if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
return -EINVAL;
if (!connector->interlace_allowed &&
if (!connector->base.interlace_allowed &&
adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
return -EINVAL;
@@ -2425,25 +2425,26 @@ void intel_hdmi_encoder_shutdown(struct intel_encoder *encoder)
}
static void
intel_hdmi_unset_edid(struct drm_connector *connector)
intel_hdmi_unset_edid(struct drm_connector *_connector)
{
struct intel_hdmi *intel_hdmi = intel_attached_hdmi(to_intel_connector(connector));
struct intel_connector *connector = to_intel_connector(_connector);
struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
intel_hdmi->dp_dual_mode.type = DRM_DP_DUAL_MODE_NONE;
intel_hdmi->dp_dual_mode.max_tmds_clock = 0;
drm_edid_free(to_intel_connector(connector)->detect_edid);
to_intel_connector(connector)->detect_edid = NULL;
drm_edid_free(connector->detect_edid);
connector->detect_edid = NULL;
}
static void
intel_hdmi_dp_dual_mode_detect(struct drm_connector *connector)
intel_hdmi_dp_dual_mode_detect(struct drm_connector *_connector)
{
struct intel_display *display = to_intel_display(connector->dev);
struct drm_i915_private *dev_priv = to_i915(connector->dev);
struct intel_hdmi *hdmi = intel_attached_hdmi(to_intel_connector(connector));
struct intel_connector *connector = to_intel_connector(_connector);
struct intel_display *display = to_intel_display(connector);
struct intel_hdmi *hdmi = intel_attached_hdmi(connector);
struct intel_encoder *encoder = &hdmi_to_dig_port(hdmi)->base;
struct i2c_adapter *ddc = connector->ddc;
struct i2c_adapter *ddc = connector->base.ddc;
enum drm_dp_dual_mode_type type;
type = drm_dp_dual_mode_detect(display->drm, ddc);
@@ -2458,7 +2459,7 @@ intel_hdmi_dp_dual_mode_detect(struct drm_connector *connector)
* if the port is a dual mode capable DP port.
*/
if (type == DRM_DP_DUAL_MODE_UNKNOWN) {
if (!connector->force &&
if (!connector->base.force &&
intel_bios_encoder_supports_dp_dual_mode(encoder->devdata)) {
drm_dbg_kms(display->drm,
"Assuming DP dual mode adaptor presence based on VBT\n");
@@ -2481,7 +2482,7 @@ intel_hdmi_dp_dual_mode_detect(struct drm_connector *connector)
hdmi->dp_dual_mode.max_tmds_clock);
/* Older VBTs are often buggy and can't be trusted :( Play it safe. */
if ((DISPLAY_VER(display) >= 8 || IS_HASWELL(dev_priv)) &&
if ((DISPLAY_VER(display) >= 8 || display->platform.haswell) &&
!intel_bios_encoder_supports_dp_dual_mode(encoder->devdata)) {
drm_dbg_kms(display->drm,
"Ignoring DP dual mode adaptor max TMDS clock for native HDMI port\n");
@@ -2490,34 +2491,35 @@ intel_hdmi_dp_dual_mode_detect(struct drm_connector *connector)
}
static bool
intel_hdmi_set_edid(struct drm_connector *connector)
intel_hdmi_set_edid(struct drm_connector *_connector)
{
struct intel_display *display = to_intel_display(connector->dev);
struct intel_hdmi *intel_hdmi = intel_attached_hdmi(to_intel_connector(connector));
struct i2c_adapter *ddc = connector->ddc;
struct intel_connector *connector = to_intel_connector(_connector);
struct intel_display *display = to_intel_display(connector);
struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
struct i2c_adapter *ddc = connector->base.ddc;
intel_wakeref_t wakeref;
const struct drm_edid *drm_edid;
bool connected = false;
wakeref = intel_display_power_get(display, POWER_DOMAIN_GMBUS);
drm_edid = drm_edid_read_ddc(connector, ddc);
drm_edid = drm_edid_read_ddc(&connector->base, ddc);
if (!drm_edid && !intel_gmbus_is_forced_bit(ddc)) {
drm_dbg_kms(display->drm,
"HDMI GMBUS EDID read failed, retry using GPIO bit-banging\n");
intel_gmbus_force_bit(ddc, true);
drm_edid = drm_edid_read_ddc(connector, ddc);
drm_edid = drm_edid_read_ddc(&connector->base, ddc);
intel_gmbus_force_bit(ddc, false);
}
/* Below we depend on display info having been updated */
drm_edid_connector_update(connector, drm_edid);
drm_edid_connector_update(&connector->base, drm_edid);
to_intel_connector(connector)->detect_edid = drm_edid;
connector->detect_edid = drm_edid;
if (drm_edid_is_digital(drm_edid)) {
intel_hdmi_dp_dual_mode_detect(connector);
intel_hdmi_dp_dual_mode_detect(&connector->base);
connected = true;
}
@@ -2525,28 +2527,29 @@ intel_hdmi_set_edid(struct drm_connector *connector)
intel_display_power_put(display, POWER_DOMAIN_GMBUS, wakeref);
cec_notifier_set_phys_addr(intel_hdmi->cec_notifier,
connector->display_info.source_physical_address);
connector->base.display_info.source_physical_address);
return connected;
}
static enum drm_connector_status
intel_hdmi_detect(struct drm_connector *connector, bool force)
intel_hdmi_detect(struct drm_connector *_connector, bool force)
{
struct intel_display *display = to_intel_display(connector->dev);
struct intel_connector *connector = to_intel_connector(_connector);
struct intel_display *display = to_intel_display(connector);
enum drm_connector_status status = connector_status_disconnected;
struct intel_hdmi *intel_hdmi = intel_attached_hdmi(to_intel_connector(connector));
struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
struct intel_encoder *encoder = &hdmi_to_dig_port(intel_hdmi)->base;
intel_wakeref_t wakeref;
drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s]\n",
connector->base.id, connector->name);
connector->base.base.id, connector->base.name);
if (!intel_display_device_enabled(display))
return connector_status_disconnected;
if (!intel_display_driver_check_access(display))
return connector->status;
return connector->base.status;
wakeref = intel_display_power_get(display, POWER_DOMAIN_GMBUS);
@@ -2554,9 +2557,9 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
!intel_digital_port_connected(encoder))
goto out;
intel_hdmi_unset_edid(connector);
intel_hdmi_unset_edid(&connector->base);
if (intel_hdmi_set_edid(connector))
if (intel_hdmi_set_edid(&connector->base))
status = connector_status_connected;
out:
@@ -2569,49 +2572,54 @@ out:
}
static void
intel_hdmi_force(struct drm_connector *connector)
intel_hdmi_force(struct drm_connector *_connector)
{
struct intel_display *display = to_intel_display(connector->dev);
struct intel_connector *connector = to_intel_connector(_connector);
struct intel_display *display = to_intel_display(connector);
drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s]\n",
connector->base.id, connector->name);
connector->base.base.id, connector->base.name);
if (!intel_display_driver_check_access(display))
return;
intel_hdmi_unset_edid(connector);
intel_hdmi_unset_edid(&connector->base);
if (connector->status != connector_status_connected)
if (connector->base.status != connector_status_connected)
return;
intel_hdmi_set_edid(connector);
intel_hdmi_set_edid(&connector->base);
}
static int intel_hdmi_get_modes(struct drm_connector *connector)
static int intel_hdmi_get_modes(struct drm_connector *_connector)
{
struct intel_connector *connector = to_intel_connector(_connector);
/* drm_edid_connector_update() done in ->detect() or ->force() */
return drm_edid_connector_add_modes(connector);
return drm_edid_connector_add_modes(&connector->base);
}
static int
intel_hdmi_connector_register(struct drm_connector *connector)
intel_hdmi_connector_register(struct drm_connector *_connector)
{
struct intel_connector *connector = to_intel_connector(_connector);
int ret;
ret = intel_connector_register(connector);
ret = intel_connector_register(&connector->base);
if (ret)
return ret;
return ret;
}
static void intel_hdmi_connector_unregister(struct drm_connector *connector)
static void intel_hdmi_connector_unregister(struct drm_connector *_connector)
{
struct cec_notifier *n = intel_attached_hdmi(to_intel_connector(connector))->cec_notifier;
struct intel_connector *connector = to_intel_connector(_connector);
struct cec_notifier *n = intel_attached_hdmi(connector)->cec_notifier;
cec_notifier_conn_unregister(n);
intel_connector_unregister(connector);
intel_connector_unregister(&connector->base);
}
static const struct drm_connector_funcs intel_hdmi_connector_funcs = {
@@ -2627,15 +2635,16 @@ static const struct drm_connector_funcs intel_hdmi_connector_funcs = {
.atomic_duplicate_state = intel_digital_connector_duplicate_state,
};
static int intel_hdmi_connector_atomic_check(struct drm_connector *connector,
static int intel_hdmi_connector_atomic_check(struct drm_connector *_connector,
struct drm_atomic_state *state)
{
struct intel_display *display = to_intel_display(connector->dev);
struct intel_connector *connector = to_intel_connector(_connector);
struct intel_display *display = to_intel_display(connector);
if (HAS_DDI(display))
return intel_digital_connector_atomic_check(connector, state);
return intel_digital_connector_atomic_check(&connector->base, state);
else
return g4x_hdmi_connector_atomic_check(connector, state);
return g4x_hdmi_connector_atomic_check(&connector->base, state);
}
static const struct drm_connector_helper_funcs intel_hdmi_connector_helper_funcs = {
@@ -2645,22 +2654,23 @@ static const struct drm_connector_helper_funcs intel_hdmi_connector_helper_funcs
};
static void
intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *connector)
intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *_connector)
{
struct intel_connector *connector = to_intel_connector(_connector);
struct intel_display *display = to_intel_display(intel_hdmi);
intel_attach_force_audio_property(connector);
intel_attach_broadcast_rgb_property(connector);
intel_attach_aspect_ratio_property(connector);
intel_attach_force_audio_property(&connector->base);
intel_attach_broadcast_rgb_property(&connector->base);
intel_attach_aspect_ratio_property(&connector->base);
intel_attach_hdmi_colorspace_property(connector);
drm_connector_attach_content_type_property(connector);
intel_attach_hdmi_colorspace_property(&connector->base);
drm_connector_attach_content_type_property(&connector->base);
if (DISPLAY_VER(display) >= 10)
drm_connector_attach_hdr_output_metadata_property(connector);
drm_connector_attach_hdr_output_metadata_property(&connector->base);
if (!HAS_GMCH(display))
drm_connector_attach_max_bpc_property(connector, 8, 12);
drm_connector_attach_max_bpc_property(&connector->base, 8, 12);
}
/*
@@ -2682,25 +2692,26 @@ intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *c
* True on success, false on failure.
*/
bool intel_hdmi_handle_sink_scrambling(struct intel_encoder *encoder,
struct drm_connector *connector,
struct drm_connector *_connector,
bool high_tmds_clock_ratio,
bool scrambling)
{
struct intel_connector *connector = to_intel_connector(_connector);
struct intel_display *display = to_intel_display(encoder);
struct drm_scrambling *sink_scrambling =
&connector->display_info.hdmi.scdc.scrambling;
&connector->base.display_info.hdmi.scdc.scrambling;
if (!sink_scrambling->supported)
return true;
drm_dbg_kms(display->drm,
"[CONNECTOR:%d:%s] scrambling=%s, TMDS bit clock ratio=1/%d\n",
connector->base.id, connector->name,
connector->base.base.id, connector->base.name,
str_yes_no(scrambling), high_tmds_clock_ratio ? 40 : 10);
/* Set TMDS bit clock ratio to 1/40 or 1/10, and enable/disable scrambling */
return drm_scdc_set_high_tmds_clock_ratio(connector, high_tmds_clock_ratio) &&
drm_scdc_set_scrambling(connector, scrambling);
return drm_scdc_set_high_tmds_clock_ratio(&connector->base, high_tmds_clock_ratio) &&
drm_scdc_set_scrambling(&connector->base, scrambling);
}
static u8 chv_encoder_to_ddc_pin(struct intel_encoder *encoder)
@@ -2811,7 +2822,7 @@ static u8 mcc_encoder_to_ddc_pin(struct intel_encoder *encoder)
static u8 rkl_encoder_to_ddc_pin(struct intel_encoder *encoder)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_display *display = to_intel_display(encoder);
enum phy phy = intel_encoder_to_phy(encoder);
WARN_ON(encoder->port == PORT_C);
@@ -2822,7 +2833,7 @@ static u8 rkl_encoder_to_ddc_pin(struct intel_encoder *encoder)
* combo outputs. With CMP, the traditional DDI A-D pins are used for
* all outputs.
*/
if (INTEL_PCH_TYPE(dev_priv) >= PCH_TGP && phy >= PHY_C)
if (INTEL_PCH_TYPE(display) >= PCH_TGP && phy >= PHY_C)
return GMBUS_PIN_9_TC1_ICP + phy - PHY_C;
return GMBUS_PIN_1_BXT + phy;
@@ -2831,7 +2842,6 @@ static u8 rkl_encoder_to_ddc_pin(struct intel_encoder *encoder)
static u8 gen9bc_tgp_encoder_to_ddc_pin(struct intel_encoder *encoder)
{
struct intel_display *display = to_intel_display(encoder);
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
enum phy phy = intel_encoder_to_phy(encoder);
drm_WARN_ON(display->drm, encoder->port == PORT_A);
@@ -2842,7 +2852,7 @@ static u8 gen9bc_tgp_encoder_to_ddc_pin(struct intel_encoder *encoder)
* combo outputs. With CMP, the traditional DDI A-D pins are used for
* all outputs.
*/
if (INTEL_PCH_TYPE(i915) >= PCH_TGP && phy >= PHY_C)
if (INTEL_PCH_TYPE(display) >= PCH_TGP && phy >= PHY_C)
return GMBUS_PIN_9_TC1_ICP + phy - PHY_C;
return GMBUS_PIN_1_BXT + phy;
@@ -2895,27 +2905,26 @@ static u8 g4x_encoder_to_ddc_pin(struct intel_encoder *encoder)
static u8 intel_hdmi_default_ddc_pin(struct intel_encoder *encoder)
{
struct intel_display *display = to_intel_display(encoder);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
u8 ddc_pin;
if (IS_ALDERLAKE_S(dev_priv))
if (display->platform.alderlake_s)
ddc_pin = adls_encoder_to_ddc_pin(encoder);
else if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG1)
else if (INTEL_PCH_TYPE(display) >= PCH_DG1)
ddc_pin = dg1_encoder_to_ddc_pin(encoder);
else if (IS_ROCKETLAKE(dev_priv))
else if (display->platform.rocketlake)
ddc_pin = rkl_encoder_to_ddc_pin(encoder);
else if (DISPLAY_VER(display) == 9 && HAS_PCH_TGP(dev_priv))
else if (DISPLAY_VER(display) == 9 && HAS_PCH_TGP(display))
ddc_pin = gen9bc_tgp_encoder_to_ddc_pin(encoder);
else if ((IS_JASPERLAKE(dev_priv) || IS_ELKHARTLAKE(dev_priv)) &&
HAS_PCH_TGP(dev_priv))
else if ((display->platform.jasperlake || display->platform.elkhartlake) &&
HAS_PCH_TGP(display))
ddc_pin = mcc_encoder_to_ddc_pin(encoder);
else if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP)
else if (INTEL_PCH_TYPE(display) >= PCH_ICP)
ddc_pin = icl_encoder_to_ddc_pin(encoder);
else if (HAS_PCH_CNP(dev_priv))
else if (HAS_PCH_CNP(display))
ddc_pin = cnp_encoder_to_ddc_pin(encoder);
else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
else if (display->platform.geminilake || display->platform.broxton)
ddc_pin = bxt_encoder_to_ddc_pin(encoder);
else if (IS_CHERRYVIEW(dev_priv))
else if (display->platform.cherryview)
ddc_pin = chv_encoder_to_ddc_pin(encoder);
else
ddc_pin = g4x_encoder_to_ddc_pin(encoder);
@@ -2989,15 +2998,13 @@ static u8 intel_hdmi_ddc_pin(struct intel_encoder *encoder)
void intel_infoframe_init(struct intel_digital_port *dig_port)
{
struct intel_display *display = to_intel_display(dig_port);
struct drm_i915_private *dev_priv =
to_i915(dig_port->base.base.dev);
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
if (display->platform.valleyview || display->platform.cherryview) {
dig_port->write_infoframe = vlv_write_infoframe;
dig_port->read_infoframe = vlv_read_infoframe;
dig_port->set_infoframes = vlv_set_infoframes;
dig_port->infoframes_enabled = vlv_infoframes_enabled;
} else if (IS_G4X(dev_priv)) {
} else if (display->platform.g4x) {
dig_port->write_infoframe = g4x_write_infoframe;
dig_port->read_infoframe = g4x_read_infoframe;
dig_port->set_infoframes = g4x_set_infoframes;
@@ -3014,7 +3021,7 @@ void intel_infoframe_init(struct intel_digital_port *dig_port)
dig_port->set_infoframes = hsw_set_infoframes;
dig_port->infoframes_enabled = hsw_infoframes_enabled;
}
} else if (HAS_PCH_IBX(dev_priv)) {
} else if (HAS_PCH_IBX(display)) {
dig_port->write_infoframe = ibx_write_infoframe;
dig_port->read_infoframe = ibx_read_infoframe;
dig_port->set_infoframes = ibx_set_infoframes;

View File

@@ -183,9 +183,7 @@ static bool intel_hpd_irq_storm_detect(struct intel_display *display,
static bool detection_work_enabled(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
lockdep_assert_held(&i915->irq_lock);
lockdep_assert_held(&display->irq.lock);
return display->hotplug.detection_work_enabled;
}
@@ -195,7 +193,7 @@ mod_delayed_detection_work(struct intel_display *display, struct delayed_work *w
{
struct drm_i915_private *i915 = to_i915(display->drm);
lockdep_assert_held(&i915->irq_lock);
lockdep_assert_held(&display->irq.lock);
if (!detection_work_enabled(display))
return false;
@@ -208,7 +206,7 @@ queue_delayed_detection_work(struct intel_display *display, struct delayed_work
{
struct drm_i915_private *i915 = to_i915(display->drm);
lockdep_assert_held(&i915->irq_lock);
lockdep_assert_held(&display->irq.lock);
if (!detection_work_enabled(display))
return false;
@@ -221,7 +219,7 @@ queue_detection_work(struct intel_display *display, struct work_struct *work)
{
struct drm_i915_private *i915 = to_i915(display->drm);
lockdep_assert_held(&i915->irq_lock);
lockdep_assert_held(&display->irq.lock);
if (!detection_work_enabled(display))
return false;
@@ -232,12 +230,11 @@ queue_detection_work(struct intel_display *display, struct work_struct *work)
static void
intel_hpd_irq_storm_switch_to_polling(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
struct drm_connector_list_iter conn_iter;
struct intel_connector *connector;
bool hpd_disabled = false;
lockdep_assert_held(&dev_priv->irq_lock);
lockdep_assert_held(&display->irq.lock);
drm_connector_list_iter_begin(display->drm, &conn_iter);
for_each_intel_connector_iter(connector, &conn_iter) {
@@ -276,7 +273,6 @@ static void intel_hpd_irq_storm_reenable_work(struct work_struct *work)
{
struct intel_display *display =
container_of(work, typeof(*display), hotplug.reenable_work.work);
struct drm_i915_private *dev_priv = to_i915(display->drm);
struct drm_connector_list_iter conn_iter;
struct intel_connector *connector;
struct ref_tracker *wakeref;
@@ -284,7 +280,7 @@ static void intel_hpd_irq_storm_reenable_work(struct work_struct *work)
wakeref = intel_display_rpm_get(display);
spin_lock_irq(&dev_priv->irq_lock);
spin_lock_irq(&display->irq.lock);
drm_connector_list_iter_begin(display->drm, &conn_iter);
for_each_intel_connector_iter(connector, &conn_iter) {
@@ -308,7 +304,7 @@ static void intel_hpd_irq_storm_reenable_work(struct work_struct *work)
intel_hpd_irq_setup(display);
spin_unlock_irq(&dev_priv->irq_lock);
spin_unlock_irq(&display->irq.lock);
intel_display_rpm_put(display, wakeref);
}
@@ -376,9 +372,7 @@ static bool hpd_pin_has_pulse(struct intel_display *display, enum hpd_pin pin)
static bool hpd_pin_is_blocked(struct intel_display *display, enum hpd_pin pin)
{
struct drm_i915_private *i915 = to_i915(display->drm);
lockdep_assert_held(&i915->irq_lock);
lockdep_assert_held(&display->irq.lock);
return display->hotplug.stats[pin].blocked_count;
}
@@ -400,14 +394,13 @@ static void i915_digport_work_func(struct work_struct *work)
{
struct intel_display *display =
container_of(work, struct intel_display, hotplug.dig_port_work);
struct drm_i915_private *dev_priv = to_i915(display->drm);
struct intel_hotplug *hotplug = &display->hotplug;
u32 long_hpd_pin_mask, short_hpd_pin_mask;
struct intel_encoder *encoder;
u32 blocked_hpd_pin_mask;
u32 old_bits = 0;
spin_lock_irq(&dev_priv->irq_lock);
spin_lock_irq(&display->irq.lock);
blocked_hpd_pin_mask = get_blocked_hpd_pin_mask(display);
long_hpd_pin_mask = hotplug->long_hpd_pin_mask & ~blocked_hpd_pin_mask;
@@ -415,7 +408,7 @@ static void i915_digport_work_func(struct work_struct *work)
short_hpd_pin_mask = hotplug->short_hpd_pin_mask & ~blocked_hpd_pin_mask;
hotplug->short_hpd_pin_mask &= ~short_hpd_pin_mask;
spin_unlock_irq(&dev_priv->irq_lock);
spin_unlock_irq(&display->irq.lock);
for_each_intel_encoder(display->drm, encoder) {
struct intel_digital_port *dig_port;
@@ -442,11 +435,11 @@ static void i915_digport_work_func(struct work_struct *work)
}
if (old_bits) {
spin_lock_irq(&dev_priv->irq_lock);
spin_lock_irq(&display->irq.lock);
display->hotplug.event_bits |= old_bits;
queue_delayed_detection_work(display,
&display->hotplug.hotplug_work, 0);
spin_unlock_irq(&dev_priv->irq_lock);
spin_unlock_irq(&display->irq.lock);
}
}
@@ -460,17 +453,16 @@ static void i915_digport_work_func(struct work_struct *work)
void intel_hpd_trigger_irq(struct intel_digital_port *dig_port)
{
struct intel_display *display = to_intel_display(dig_port);
struct drm_i915_private *i915 = to_i915(display->drm);
struct intel_hotplug *hotplug = &display->hotplug;
struct intel_encoder *encoder = &dig_port->base;
spin_lock_irq(&i915->irq_lock);
spin_lock_irq(&display->irq.lock);
hotplug->short_hpd_pin_mask |= BIT(encoder->hpd_pin);
if (!hpd_pin_is_blocked(display, encoder->hpd_pin))
queue_work(hotplug->dp_wq, &hotplug->dig_port_work);
spin_unlock_irq(&i915->irq_lock);
spin_unlock_irq(&display->irq.lock);
}
/*
@@ -480,7 +472,6 @@ static void i915_hotplug_work_func(struct work_struct *work)
{
struct intel_display *display =
container_of(work, struct intel_display, hotplug.hotplug_work.work);
struct drm_i915_private *dev_priv = to_i915(display->drm);
struct intel_hotplug *hotplug = &display->hotplug;
struct drm_connector_list_iter conn_iter;
struct intel_connector *connector;
@@ -494,7 +485,7 @@ static void i915_hotplug_work_func(struct work_struct *work)
mutex_lock(&display->drm->mode_config.mutex);
drm_dbg_kms(display->drm, "running encoder hotplug functions\n");
spin_lock_irq(&dev_priv->irq_lock);
spin_lock_irq(&display->irq.lock);
blocked_hpd_pin_mask = get_blocked_hpd_pin_mask(display);
hpd_event_bits = hotplug->event_bits & ~blocked_hpd_pin_mask;
@@ -505,7 +496,7 @@ static void i915_hotplug_work_func(struct work_struct *work)
/* Enable polling for connectors which had HPD IRQ storms */
intel_hpd_irq_storm_switch_to_polling(display);
spin_unlock_irq(&dev_priv->irq_lock);
spin_unlock_irq(&display->irq.lock);
/* Skip calling encode hotplug handlers if ignore long HPD set*/
if (display->hotplug.ignore_long_hpd) {
@@ -569,13 +560,13 @@ static void i915_hotplug_work_func(struct work_struct *work)
/* Remove shared HPD pins that have changed */
retry &= ~changed;
if (retry) {
spin_lock_irq(&dev_priv->irq_lock);
spin_lock_irq(&display->irq.lock);
display->hotplug.retry_bits |= retry;
mod_delayed_detection_work(display,
&display->hotplug.hotplug_work,
msecs_to_jiffies(HPD_RETRY_DELAY));
spin_unlock_irq(&dev_priv->irq_lock);
spin_unlock_irq(&display->irq.lock);
}
}
@@ -599,7 +590,6 @@ static void i915_hotplug_work_func(struct work_struct *work)
void intel_hpd_irq_handler(struct intel_display *display,
u32 pin_mask, u32 long_mask)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
struct intel_encoder *encoder;
bool storm_detected = false;
bool queue_dig = false, queue_hp = false;
@@ -610,7 +600,7 @@ void intel_hpd_irq_handler(struct intel_display *display,
if (!pin_mask)
return;
spin_lock(&dev_priv->irq_lock);
spin_lock(&display->irq.lock);
/*
* Determine whether ->hpd_pulse() exists for each pin, and
@@ -711,7 +701,7 @@ void intel_hpd_irq_handler(struct intel_display *display,
queue_delayed_detection_work(display,
&display->hotplug.hotplug_work, 0);
spin_unlock(&dev_priv->irq_lock);
spin_unlock(&display->irq.lock);
}
/**
@@ -730,7 +720,6 @@ void intel_hpd_irq_handler(struct intel_display *display,
*/
void intel_hpd_init(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
int i;
if (!HAS_DISPLAY(display))
@@ -745,9 +734,9 @@ void intel_hpd_init(struct intel_display *display)
* Interrupt setup is already guaranteed to be single-threaded, this is
* just to make the assert_spin_locked checks happy.
*/
spin_lock_irq(&dev_priv->irq_lock);
spin_lock_irq(&display->irq.lock);
intel_hpd_irq_setup(display);
spin_unlock_irq(&dev_priv->irq_lock);
spin_unlock_irq(&display->irq.lock);
}
static void i915_hpd_poll_detect_connectors(struct intel_display *display)
@@ -797,7 +786,6 @@ static void i915_hpd_poll_init_work(struct work_struct *work)
{
struct intel_display *display =
container_of(work, typeof(*display), hotplug.poll_init_work);
struct drm_i915_private *dev_priv = to_i915(display->drm);
struct drm_connector_list_iter conn_iter;
struct intel_connector *connector;
intel_wakeref_t wakeref;
@@ -820,7 +808,7 @@ static void i915_hpd_poll_init_work(struct work_struct *work)
cancel_work(&display->hotplug.poll_init_work);
}
spin_lock_irq(&dev_priv->irq_lock);
spin_lock_irq(&display->irq.lock);
drm_connector_list_iter_begin(display->drm, &conn_iter);
for_each_intel_connector_iter(connector, &conn_iter) {
@@ -841,7 +829,7 @@ static void i915_hpd_poll_init_work(struct work_struct *work)
}
drm_connector_list_iter_end(&conn_iter);
spin_unlock_irq(&dev_priv->irq_lock);
spin_unlock_irq(&display->irq.lock);
if (enabled)
drm_kms_helper_poll_reschedule(display->drm);
@@ -879,8 +867,6 @@ static void i915_hpd_poll_init_work(struct work_struct *work)
*/
void intel_hpd_poll_enable(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
if (!HAS_DISPLAY(display) || !intel_display_device_enabled(display))
return;
@@ -892,10 +878,10 @@ void intel_hpd_poll_enable(struct intel_display *display)
* As well, there's no issue if we race here since we always reschedule
* this worker anyway
*/
spin_lock_irq(&dev_priv->irq_lock);
spin_lock_irq(&display->irq.lock);
queue_detection_work(display,
&display->hotplug.poll_init_work);
spin_unlock_irq(&dev_priv->irq_lock);
spin_unlock_irq(&display->irq.lock);
}
/**
@@ -919,17 +905,15 @@ void intel_hpd_poll_enable(struct intel_display *display)
*/
void intel_hpd_poll_disable(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
if (!HAS_DISPLAY(display))
return;
WRITE_ONCE(display->hotplug.poll_enabled, false);
spin_lock_irq(&dev_priv->irq_lock);
spin_lock_irq(&display->irq.lock);
queue_detection_work(display,
&display->hotplug.poll_init_work);
spin_unlock_irq(&dev_priv->irq_lock);
spin_unlock_irq(&display->irq.lock);
}
void intel_hpd_poll_fini(struct intel_display *display)
@@ -981,12 +965,10 @@ static bool cancel_all_detection_work(struct intel_display *display)
void intel_hpd_cancel_work(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
if (!HAS_DISPLAY(display))
return;
spin_lock_irq(&dev_priv->irq_lock);
spin_lock_irq(&display->irq.lock);
drm_WARN_ON(display->drm, get_blocked_hpd_pin_mask(display));
@@ -995,7 +977,7 @@ void intel_hpd_cancel_work(struct intel_display *display)
display->hotplug.event_bits = 0;
display->hotplug.retry_bits = 0;
spin_unlock_irq(&dev_priv->irq_lock);
spin_unlock_irq(&display->irq.lock);
cancel_work_sync(&display->hotplug.dig_port_work);
@@ -1009,13 +991,12 @@ void intel_hpd_cancel_work(struct intel_display *display)
static void queue_work_for_missed_irqs(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
struct intel_hotplug *hotplug = &display->hotplug;
bool queue_hp_work = false;
u32 blocked_hpd_pin_mask;
enum hpd_pin pin;
lockdep_assert_held(&i915->irq_lock);
lockdep_assert_held(&display->irq.lock);
blocked_hpd_pin_mask = get_blocked_hpd_pin_mask(display);
if ((hotplug->event_bits | hotplug->retry_bits) & ~blocked_hpd_pin_mask)
@@ -1043,10 +1024,9 @@ static void queue_work_for_missed_irqs(struct intel_display *display)
static bool block_hpd_pin(struct intel_display *display, enum hpd_pin pin)
{
struct drm_i915_private *i915 = to_i915(display->drm);
struct intel_hotplug *hotplug = &display->hotplug;
lockdep_assert_held(&i915->irq_lock);
lockdep_assert_held(&display->irq.lock);
hotplug->stats[pin].blocked_count++;
@@ -1055,10 +1035,9 @@ static bool block_hpd_pin(struct intel_display *display, enum hpd_pin pin)
static bool unblock_hpd_pin(struct intel_display *display, enum hpd_pin pin)
{
struct drm_i915_private *i915 = to_i915(display->drm);
struct intel_hotplug *hotplug = &display->hotplug;
lockdep_assert_held(&i915->irq_lock);
lockdep_assert_held(&display->irq.lock);
if (drm_WARN_ON(display->drm, hotplug->stats[pin].blocked_count == 0))
return true;
@@ -1095,19 +1074,18 @@ static bool unblock_hpd_pin(struct intel_display *display, enum hpd_pin pin)
void intel_hpd_block(struct intel_encoder *encoder)
{
struct intel_display *display = to_intel_display(encoder);
struct drm_i915_private *i915 = to_i915(display->drm);
struct intel_hotplug *hotplug = &display->hotplug;
bool do_flush = false;
if (encoder->hpd_pin == HPD_NONE)
return;
spin_lock_irq(&i915->irq_lock);
spin_lock_irq(&display->irq.lock);
if (block_hpd_pin(display, encoder->hpd_pin))
do_flush = true;
spin_unlock_irq(&i915->irq_lock);
spin_unlock_irq(&display->irq.lock);
if (do_flush && hpd_pin_has_pulse(display, encoder->hpd_pin))
flush_work(&hotplug->dig_port_work);
@@ -1125,17 +1103,16 @@ void intel_hpd_block(struct intel_encoder *encoder)
void intel_hpd_unblock(struct intel_encoder *encoder)
{
struct intel_display *display = to_intel_display(encoder);
struct drm_i915_private *i915 = to_i915(display->drm);
if (encoder->hpd_pin == HPD_NONE)
return;
spin_lock_irq(&i915->irq_lock);
spin_lock_irq(&display->irq.lock);
if (unblock_hpd_pin(display, encoder->hpd_pin))
queue_work_for_missed_irqs(display);
spin_unlock_irq(&i915->irq_lock);
spin_unlock_irq(&display->irq.lock);
}
/**
@@ -1149,14 +1126,13 @@ void intel_hpd_unblock(struct intel_encoder *encoder)
void intel_hpd_clear_and_unblock(struct intel_encoder *encoder)
{
struct intel_display *display = to_intel_display(encoder);
struct drm_i915_private *i915 = to_i915(display->drm);
struct intel_hotplug *hotplug = &display->hotplug;
enum hpd_pin pin = encoder->hpd_pin;
if (pin == HPD_NONE)
return;
spin_lock_irq(&i915->irq_lock);
spin_lock_irq(&display->irq.lock);
if (unblock_hpd_pin(display, pin)) {
hotplug->event_bits &= ~BIT(pin);
@@ -1165,39 +1141,34 @@ void intel_hpd_clear_and_unblock(struct intel_encoder *encoder)
hotplug->long_hpd_pin_mask &= ~BIT(pin);
}
spin_unlock_irq(&i915->irq_lock);
spin_unlock_irq(&display->irq.lock);
}
void intel_hpd_enable_detection_work(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
spin_lock_irq(&i915->irq_lock);
spin_lock_irq(&display->irq.lock);
display->hotplug.detection_work_enabled = true;
queue_work_for_missed_irqs(display);
spin_unlock_irq(&i915->irq_lock);
spin_unlock_irq(&display->irq.lock);
}
void intel_hpd_disable_detection_work(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
spin_lock_irq(&i915->irq_lock);
spin_lock_irq(&display->irq.lock);
display->hotplug.detection_work_enabled = false;
spin_unlock_irq(&i915->irq_lock);
spin_unlock_irq(&display->irq.lock);
cancel_all_detection_work(display);
}
bool intel_hpd_schedule_detection(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
unsigned long flags;
bool ret;
spin_lock_irqsave(&i915->irq_lock, flags);
spin_lock_irqsave(&display->irq.lock, flags);
ret = queue_delayed_detection_work(display, &display->hotplug.hotplug_work, 0);
spin_unlock_irqrestore(&i915->irq_lock, flags);
spin_unlock_irqrestore(&display->irq.lock, flags);
return ret;
}
@@ -1228,7 +1199,6 @@ static ssize_t i915_hpd_storm_ctl_write(struct file *file,
{
struct seq_file *m = file->private_data;
struct intel_display *display = m->private;
struct drm_i915_private *dev_priv = to_i915(display->drm);
struct intel_hotplug *hotplug = &display->hotplug;
unsigned int new_threshold;
int i;
@@ -1260,12 +1230,12 @@ static ssize_t i915_hpd_storm_ctl_write(struct file *file,
else
drm_dbg_kms(display->drm, "Disabling HPD storm detection\n");
spin_lock_irq(&dev_priv->irq_lock);
spin_lock_irq(&display->irq.lock);
hotplug->hpd_storm_threshold = new_threshold;
/* Reset the HPD storm stats so we don't accidentally trigger a storm */
for_each_hpd_pin(i)
hotplug->stats[i].count = 0;
spin_unlock_irq(&dev_priv->irq_lock);
spin_unlock_irq(&display->irq.lock);
/* Re-enable hpd immediately if we were in an irq storm */
flush_delayed_work(&display->hotplug.reenable_work);
@@ -1310,7 +1280,6 @@ static ssize_t i915_hpd_short_storm_ctl_write(struct file *file,
{
struct seq_file *m = file->private_data;
struct intel_display *display = m->private;
struct drm_i915_private *dev_priv = to_i915(display->drm);
struct intel_hotplug *hotplug = &display->hotplug;
char *newline;
char tmp[16];
@@ -1339,12 +1308,12 @@ static ssize_t i915_hpd_short_storm_ctl_write(struct file *file,
drm_dbg_kms(display->drm, "%sabling HPD short storm detection\n",
new_state ? "En" : "Dis");
spin_lock_irq(&dev_priv->irq_lock);
spin_lock_irq(&display->irq.lock);
hotplug->hpd_short_storm_enabled = new_state;
/* Reset the HPD storm stats so we don't accidentally trigger a storm */
for_each_hpd_pin(i)
hotplug->stats[i].count = 0;
spin_unlock_irq(&dev_priv->irq_lock);
spin_unlock_irq(&display->irq.lock);
/* Re-enable hpd immediately if we were in an irq storm */
flush_delayed_work(&display->hotplug.reenable_work);

View File

@@ -3,8 +3,10 @@
* Copyright © 2023 Intel Corporation
*/
#include "i915_drv.h"
#include <drm/drm_print.h>
#include "i915_reg.h"
#include "i915_utils.h"
#include "intel_de.h"
#include "intel_display_irq.h"
#include "intel_display_types.h"
@@ -133,7 +135,6 @@ static const u32 hpd_mtp[HPD_NUM_PINS] = {
static void intel_hpd_init_pins(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
struct intel_hotplug *hpd = &display->hotplug;
if (HAS_GMCH(display)) {
@@ -160,33 +161,31 @@ static void intel_hpd_init_pins(struct intel_display *display)
else
hpd->hpd = hpd_ilk;
if ((INTEL_PCH_TYPE(dev_priv) < PCH_DG1) &&
(!HAS_PCH_SPLIT(dev_priv) || HAS_PCH_NOP(dev_priv)))
if ((INTEL_PCH_TYPE(display) < PCH_DG1) &&
(!HAS_PCH_SPLIT(display) || HAS_PCH_NOP(display)))
return;
if (INTEL_PCH_TYPE(dev_priv) >= PCH_MTL)
if (INTEL_PCH_TYPE(display) >= PCH_MTL)
hpd->pch_hpd = hpd_mtp;
else if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG1)
else if (INTEL_PCH_TYPE(display) >= PCH_DG1)
hpd->pch_hpd = hpd_sde_dg1;
else if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP)
else if (INTEL_PCH_TYPE(display) >= PCH_ICP)
hpd->pch_hpd = hpd_icp;
else if (HAS_PCH_CNP(dev_priv) || HAS_PCH_SPT(dev_priv))
else if (HAS_PCH_CNP(display) || HAS_PCH_SPT(display))
hpd->pch_hpd = hpd_spt;
else if (HAS_PCH_LPT(dev_priv) || HAS_PCH_CPT(dev_priv))
else if (HAS_PCH_LPT(display) || HAS_PCH_CPT(display))
hpd->pch_hpd = hpd_cpt;
else if (HAS_PCH_IBX(dev_priv))
else if (HAS_PCH_IBX(display))
hpd->pch_hpd = hpd_ibx;
else
MISSING_CASE(INTEL_PCH_TYPE(dev_priv));
MISSING_CASE(INTEL_PCH_TYPE(display));
}
/* For display hotplug interrupt */
void i915_hotplug_interrupt_update_locked(struct intel_display *display,
u32 mask, u32 bits)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
lockdep_assert_held(&dev_priv->irq_lock);
lockdep_assert_held(&display->irq.lock);
drm_WARN_ON(display->drm, bits & ~mask);
intel_de_rmw(display, PORT_HOTPLUG_EN(display), mask, bits);
@@ -208,11 +207,9 @@ void i915_hotplug_interrupt_update(struct intel_display *display,
u32 mask,
u32 bits)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
spin_lock_irq(&dev_priv->irq_lock);
spin_lock_irq(&display->irq.lock);
i915_hotplug_interrupt_update_locked(display, mask, bits);
spin_unlock_irq(&dev_priv->irq_lock);
spin_unlock_irq(&display->irq.lock);
}
static bool gen11_port_hotplug_long_detect(enum hpd_pin pin, u32 val)
@@ -557,7 +554,6 @@ void xelpdp_pica_irq_handler(struct intel_display *display, u32 iir)
void icp_irq_handler(struct intel_display *display, u32 pch_iir)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
u32 ddi_hotplug_trigger = pch_iir & SDE_DDI_HOTPLUG_MASK_ICP;
u32 tc_hotplug_trigger = pch_iir & SDE_TC_HOTPLUG_MASK_ICP;
u32 pin_mask = 0, long_mask = 0;
@@ -566,9 +562,9 @@ void icp_irq_handler(struct intel_display *display, u32 pch_iir)
u32 dig_hotplug_reg;
/* Locking due to DSI native GPIO sequences */
spin_lock(&dev_priv->irq_lock);
spin_lock(&display->irq.lock);
dig_hotplug_reg = intel_de_rmw(display, SHOTPLUG_CTL_DDI, 0, 0);
spin_unlock(&dev_priv->irq_lock);
spin_unlock(&display->irq.lock);
intel_get_hpd_pins(display, &pin_mask, &long_mask,
ddi_hotplug_trigger, dig_hotplug_reg,
@@ -711,7 +707,7 @@ static u32 ibx_hotplug_mask(enum hpd_pin hpd_pin)
static u32 ibx_hotplug_enables(struct intel_encoder *encoder)
{
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
struct intel_display *display = to_intel_display(encoder);
switch (encoder->hpd_pin) {
case HPD_PORT_A:
@@ -719,7 +715,7 @@ static u32 ibx_hotplug_enables(struct intel_encoder *encoder)
* When CPU and PCH are on the same package, port A
* HPD must be enabled in both north and south.
*/
return HAS_PCH_LPT_LP(i915) ?
return HAS_PCH_LPT_LP(display) ?
PORTA_HOTPLUG_ENABLE : 0;
case HPD_PORT_B:
return PORTB_HOTPLUG_ENABLE |
@@ -940,18 +936,17 @@ static void gen11_tbt_hpd_enable_detection(struct intel_encoder *encoder)
static void gen11_hpd_enable_detection(struct intel_encoder *encoder)
{
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
struct intel_display *display = to_intel_display(encoder);
gen11_tc_hpd_enable_detection(encoder);
gen11_tbt_hpd_enable_detection(encoder);
if (INTEL_PCH_TYPE(i915) >= PCH_ICP)
if (INTEL_PCH_TYPE(display) >= PCH_ICP)
icp_hpd_enable_detection(encoder);
}
static void gen11_hpd_irq_setup(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
u32 hotplug_irqs, enabled_irqs;
enabled_irqs = intel_hpd_enabled_irqs(display, display->hotplug.hpd);
@@ -964,7 +959,7 @@ static void gen11_hpd_irq_setup(struct intel_display *display)
gen11_tc_hpd_detection_setup(display);
gen11_tbt_hpd_detection_setup(display);
if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP)
if (INTEL_PCH_TYPE(display) >= PCH_ICP)
icp_hpd_irq_setup(display);
}
@@ -1138,7 +1133,6 @@ static void xelpdp_hpd_enable_detection(struct intel_encoder *encoder)
static void xelpdp_hpd_irq_setup(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
u32 hotplug_irqs, enabled_irqs;
enabled_irqs = intel_hpd_enabled_irqs(display, display->hotplug.hpd);
@@ -1150,9 +1144,9 @@ static void xelpdp_hpd_irq_setup(struct intel_display *display)
xelpdp_pica_hpd_detection_setup(display);
if (INTEL_PCH_TYPE(i915) >= PCH_LNL)
if (INTEL_PCH_TYPE(display) >= PCH_LNL)
xe2lpd_sde_hpd_irq_setup(display);
else if (INTEL_PCH_TYPE(i915) >= PCH_MTL)
else if (INTEL_PCH_TYPE(display) >= PCH_MTL)
mtp_hpd_irq_setup(display);
}
@@ -1194,10 +1188,8 @@ static u32 spt_hotplug2_enables(struct intel_encoder *encoder)
static void spt_hpd_detection_setup(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
/* Display WA #1179 WaHardHangonHotPlug: cnp */
if (HAS_PCH_CNP(dev_priv)) {
if (HAS_PCH_CNP(display)) {
intel_de_rmw(display, SOUTH_CHICKEN1, CHASSIS_CLK_REQ_DURATION_MASK,
CHASSIS_CLK_REQ_DURATION(0xf));
}
@@ -1215,10 +1207,9 @@ static void spt_hpd_detection_setup(struct intel_display *display)
static void spt_hpd_enable_detection(struct intel_encoder *encoder)
{
struct intel_display *display = to_intel_display(encoder);
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
/* Display WA #1179 WaHardHangonHotPlug: cnp */
if (HAS_PCH_CNP(i915)) {
if (HAS_PCH_CNP(display)) {
intel_de_rmw(display, SOUTH_CHICKEN1,
CHASSIS_CLK_REQ_DURATION_MASK,
CHASSIS_CLK_REQ_DURATION(0xf));
@@ -1235,10 +1226,9 @@ static void spt_hpd_enable_detection(struct intel_encoder *encoder)
static void spt_hpd_irq_setup(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
u32 hotplug_irqs, enabled_irqs;
if (INTEL_PCH_TYPE(dev_priv) >= PCH_CNP)
if (INTEL_PCH_TYPE(display) >= PCH_CNP)
intel_de_write(display, SHPD_FILTER_CNT, SHPD_FILTER_CNT_500_ADJ);
enabled_irqs = intel_hpd_enabled_irqs(display, display->hotplug.pch_hpd);
@@ -1402,10 +1392,9 @@ static void i915_hpd_enable_detection(struct intel_encoder *encoder)
static void i915_hpd_irq_setup(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
u32 hotplug_en;
lockdep_assert_held(&dev_priv->irq_lock);
lockdep_assert_held(&display->irq.lock);
/*
* Note HDMI and DP share hotplug bits. Enable bits are the same for all
@@ -1474,8 +1463,6 @@ void intel_hpd_irq_setup(struct intel_display *display)
void intel_hotplug_irq_init(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
intel_hpd_init_pins(display);
intel_hpd_init_early(display);
@@ -1484,9 +1471,9 @@ void intel_hotplug_irq_init(struct intel_display *display)
if (HAS_HOTPLUG(display))
display->funcs.hotplug = &i915_hpd_funcs;
} else {
if (HAS_PCH_DG2(i915))
if (HAS_PCH_DG2(display))
display->funcs.hotplug = &icp_hpd_funcs;
else if (HAS_PCH_DG1(i915))
else if (HAS_PCH_DG1(display))
display->funcs.hotplug = &dg1_hpd_funcs;
else if (DISPLAY_VER(display) >= 14)
display->funcs.hotplug = &xelpdp_hpd_funcs;
@@ -1494,9 +1481,9 @@ void intel_hotplug_irq_init(struct intel_display *display)
display->funcs.hotplug = &gen11_hpd_funcs;
else if (display->platform.geminilake || display->platform.broxton)
display->funcs.hotplug = &bxt_hpd_funcs;
else if (INTEL_PCH_TYPE(i915) >= PCH_ICP)
else if (INTEL_PCH_TYPE(display) >= PCH_ICP)
display->funcs.hotplug = &icp_hpd_funcs;
else if (INTEL_PCH_TYPE(i915) >= PCH_SPT)
else if (INTEL_PCH_TYPE(display) >= PCH_SPT)
display->funcs.hotplug = &spt_hpd_funcs;
else
display->funcs.hotplug = &ilk_hpd_funcs;

View File

@@ -179,7 +179,7 @@ static int lpe_audio_irq_init(struct intel_display *display)
handle_simple_irq,
"hdmi_lpe_audio_irq_handler");
return irq_set_chip_data(irq, dev_priv);
return 0;
}
static bool lpe_audio_detect(struct intel_display *display)

View File

@@ -37,9 +37,9 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
#include "i915_drv.h"
#include "i915_reg.h"
#include "intel_atomic.h"
#include "intel_backlight.h"
@@ -87,13 +87,12 @@ static struct intel_lvds_encoder *to_lvds_encoder(struct intel_encoder *encoder)
bool intel_lvds_port_enabled(struct intel_display *display,
i915_reg_t lvds_reg, enum pipe *pipe)
{
struct drm_i915_private *i915 = to_i915(display->drm);
u32 val;
val = intel_de_read(display, lvds_reg);
/* asserts want to know the pipe even if the port is disabled */
if (HAS_PCH_CPT(i915))
if (HAS_PCH_CPT(display))
*pipe = REG_FIELD_GET(LVDS_PIPE_SEL_MASK_CPT, val);
else
*pipe = REG_FIELD_GET(LVDS_PIPE_SEL_MASK, val);
@@ -243,13 +242,12 @@ static void intel_pre_enable_lvds(struct intel_atomic_state *state,
{
struct intel_display *display = to_intel_display(state);
struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(encoder);
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
enum pipe pipe = crtc->pipe;
u32 temp;
if (HAS_PCH_SPLIT(i915)) {
if (HAS_PCH_SPLIT(display)) {
assert_fdi_rx_pll_disabled(display, pipe);
assert_shared_dpll_disabled(display, crtc_state->shared_dpll);
} else {
@@ -261,7 +259,7 @@ static void intel_pre_enable_lvds(struct intel_atomic_state *state,
temp = lvds_encoder->init_lvds_val;
temp |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP;
if (HAS_PCH_CPT(i915)) {
if (HAS_PCH_CPT(display)) {
temp &= ~LVDS_PIPE_SEL_MASK_CPT;
temp |= LVDS_PIPE_SEL_CPT(pipe);
} else {
@@ -421,7 +419,6 @@ static int intel_lvds_compute_config(struct intel_encoder *encoder,
struct drm_connector_state *conn_state)
{
struct intel_display *display = to_intel_display(encoder);
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(encoder);
struct intel_connector *connector = lvds_encoder->attached_connector;
struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
@@ -435,7 +432,7 @@ static int intel_lvds_compute_config(struct intel_encoder *encoder,
return -EINVAL;
}
if (HAS_PCH_SPLIT(i915)) {
if (HAS_PCH_SPLIT(display)) {
crtc_state->has_pch_encoder = true;
if (!intel_fdi_compute_pipe_bpp(crtc_state))
return -EINVAL;
@@ -798,7 +795,6 @@ bool intel_is_dual_link_lvds(struct intel_display *display)
static bool compute_is_dual_link_lvds(struct intel_lvds_encoder *lvds_encoder)
{
struct intel_display *display = to_intel_display(&lvds_encoder->base);
struct drm_i915_private *i915 = to_i915(lvds_encoder->base.base.dev);
struct intel_connector *connector = lvds_encoder->attached_connector;
const struct drm_display_mode *fixed_mode =
intel_panel_preferred_fixed_mode(connector);
@@ -822,7 +818,7 @@ static bool compute_is_dual_link_lvds(struct intel_lvds_encoder *lvds_encoder)
* register is uninitialized.
*/
val = intel_de_read(display, lvds_encoder->reg);
if (HAS_PCH_CPT(i915))
if (HAS_PCH_CPT(display))
val &= ~(LVDS_DETECTED | LVDS_PIPE_SEL_MASK_CPT);
else
val &= ~(LVDS_DETECTED | LVDS_PIPE_SEL_MASK);
@@ -846,7 +842,6 @@ static void intel_lvds_add_properties(struct drm_connector *connector)
*/
void intel_lvds_init(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
struct intel_lvds_encoder *lvds_encoder;
struct intel_connector *connector;
const struct drm_edid *drm_edid;
@@ -868,14 +863,14 @@ void intel_lvds_init(struct intel_display *display)
return;
}
if (HAS_PCH_SPLIT(i915))
if (HAS_PCH_SPLIT(display))
lvds_reg = PCH_LVDS;
else
lvds_reg = LVDS;
lvds = intel_de_read(display, lvds_reg);
if (HAS_PCH_SPLIT(i915)) {
if (HAS_PCH_SPLIT(display)) {
if ((lvds & LVDS_DETECTED) == 0)
return;
}
@@ -915,7 +910,7 @@ void intel_lvds_init(struct intel_display *display)
encoder->enable = intel_enable_lvds;
encoder->pre_enable = intel_pre_enable_lvds;
encoder->compute_config = intel_lvds_compute_config;
if (HAS_PCH_SPLIT(i915)) {
if (HAS_PCH_SPLIT(display)) {
encoder->disable = pch_disable_lvds;
encoder->post_disable = pch_post_disable_lvds;
} else {

View File

@@ -6,11 +6,11 @@
* state.
*/
#include <drm/drm_atomic_uapi.h>
#include <drm/drm_atomic_state_helper.h>
#include <drm/drm_atomic_uapi.h>
#include <drm/drm_print.h>
#include <drm/drm_vblank.h>
#include "i915_drv.h"
#include "i915_reg.h"
#include "i9xx_wm.h"
#include "intel_atomic.h"
@@ -31,13 +31,14 @@
#include "intel_pmdemand.h"
#include "intel_tc.h"
#include "intel_vblank.h"
#include "intel_vga.h"
#include "intel_wm.h"
#include "skl_watermark.h"
static void intel_crtc_disable_noatomic_begin(struct intel_crtc *crtc,
struct drm_modeset_acquire_ctx *ctx)
{
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
struct intel_display *display = to_intel_display(crtc);
struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
struct intel_plane *plane;
@@ -48,7 +49,7 @@ static void intel_crtc_disable_noatomic_begin(struct intel_crtc *crtc,
if (!crtc_state->hw.active)
return;
for_each_intel_plane_on_crtc(&i915->drm, crtc, plane) {
for_each_intel_plane_on_crtc(display->drm, crtc, plane) {
const struct intel_plane_state *plane_state =
to_intel_plane_state(plane->base.state);
@@ -56,9 +57,9 @@ static void intel_crtc_disable_noatomic_begin(struct intel_crtc *crtc,
intel_plane_disable_noatomic(crtc, plane);
}
state = drm_atomic_state_alloc(&i915->drm);
state = drm_atomic_state_alloc(display->drm);
if (!state) {
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"failed to disable [CRTC:%d:%s], out of memory",
crtc->base.base.id, crtc->base.name);
return;
@@ -68,7 +69,7 @@ static void intel_crtc_disable_noatomic_begin(struct intel_crtc *crtc,
to_intel_atomic_state(state)->internal = true;
/* Everything's already locked, -EDEADLK can't happen. */
for_each_intel_crtc_in_pipe_mask(&i915->drm, temp_crtc,
for_each_intel_crtc_in_pipe_mask(display->drm, temp_crtc,
BIT(pipe) |
intel_crtc_joiner_secondary_pipes(crtc_state)) {
struct intel_crtc_state *temp_crtc_state =
@@ -77,14 +78,14 @@ static void intel_crtc_disable_noatomic_begin(struct intel_crtc *crtc,
ret = drm_atomic_add_affected_connectors(state, &temp_crtc->base);
drm_WARN_ON(&i915->drm, IS_ERR(temp_crtc_state) || ret);
drm_WARN_ON(display->drm, IS_ERR(temp_crtc_state) || ret);
}
i915->display.funcs.display->crtc_disable(to_intel_atomic_state(state), crtc);
display->funcs.display->crtc_disable(to_intel_atomic_state(state), crtc);
drm_atomic_state_put(state);
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"[CRTC:%d:%s] hw state adjusted, was enabled, now disabled\n",
crtc->base.base.id, crtc->base.name);
@@ -118,13 +119,12 @@ static void set_encoder_for_connector(struct intel_connector *connector,
static void reset_encoder_connector_state(struct intel_encoder *encoder)
{
struct intel_display *display = to_intel_display(encoder);
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
struct intel_pmdemand_state *pmdemand_state =
to_intel_pmdemand_state(i915->display.pmdemand.obj.state);
to_intel_pmdemand_state(display->pmdemand.obj.state);
struct intel_connector *connector;
struct drm_connector_list_iter conn_iter;
drm_connector_list_iter_begin(&i915->drm, &conn_iter);
drm_connector_list_iter_begin(display->drm, &conn_iter);
for_each_intel_connector_iter(connector, &conn_iter) {
if (connector->base.encoder != &encoder->base)
continue;
@@ -143,10 +143,10 @@ static void reset_encoder_connector_state(struct intel_encoder *encoder)
static void reset_crtc_encoder_state(struct intel_crtc *crtc)
{
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
struct intel_display *display = to_intel_display(crtc);
struct intel_encoder *encoder;
for_each_encoder_on_crtc(&i915->drm, &crtc->base, encoder) {
for_each_encoder_on_crtc(display->drm, &crtc->base, encoder) {
reset_encoder_connector_state(encoder);
encoder->base.crtc = NULL;
}
@@ -183,13 +183,13 @@ static void intel_crtc_disable_noatomic_complete(struct intel_crtc *crtc)
* Return all the pipes using a transcoder in @transcoder_mask.
* For joiner configs return only the joiner primary.
*/
static u8 get_transcoder_pipes(struct drm_i915_private *i915,
static u8 get_transcoder_pipes(struct intel_display *display,
u8 transcoder_mask)
{
struct intel_crtc *temp_crtc;
u8 pipes = 0;
for_each_intel_crtc(&i915->drm, temp_crtc) {
for_each_intel_crtc(display->drm, temp_crtc) {
struct intel_crtc_state *temp_crtc_state =
to_intel_crtc_state(temp_crtc->base.state);
@@ -214,7 +214,6 @@ static void get_portsync_pipes(struct intel_crtc *crtc,
u8 *master_pipe_mask, u8 *slave_pipes_mask)
{
struct intel_display *display = to_intel_display(crtc);
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
struct intel_crtc *master_crtc;
@@ -233,20 +232,20 @@ static void get_portsync_pipes(struct intel_crtc *crtc,
else
master_transcoder = crtc_state->master_transcoder;
*master_pipe_mask = get_transcoder_pipes(i915, BIT(master_transcoder));
drm_WARN_ON(&i915->drm, !is_power_of_2(*master_pipe_mask));
*master_pipe_mask = get_transcoder_pipes(display, BIT(master_transcoder));
drm_WARN_ON(display->drm, !is_power_of_2(*master_pipe_mask));
master_crtc = intel_crtc_for_pipe(display, ffs(*master_pipe_mask) - 1);
master_crtc_state = to_intel_crtc_state(master_crtc->base.state);
*slave_pipes_mask = get_transcoder_pipes(i915, master_crtc_state->sync_mode_slaves_mask);
*slave_pipes_mask = get_transcoder_pipes(display, master_crtc_state->sync_mode_slaves_mask);
}
static u8 get_joiner_secondary_pipes(struct drm_i915_private *i915, u8 primary_pipes_mask)
static u8 get_joiner_secondary_pipes(struct intel_display *display, u8 primary_pipes_mask)
{
struct intel_crtc *primary_crtc;
u8 pipes = 0;
for_each_intel_crtc_in_pipe_mask(&i915->drm, primary_crtc, primary_pipes_mask) {
for_each_intel_crtc_in_pipe_mask(display->drm, primary_crtc, primary_pipes_mask) {
struct intel_crtc_state *primary_crtc_state =
to_intel_crtc_state(primary_crtc->base.state);
@@ -259,45 +258,45 @@ static u8 get_joiner_secondary_pipes(struct drm_i915_private *i915, u8 primary_p
static void intel_crtc_disable_noatomic(struct intel_crtc *crtc,
struct drm_modeset_acquire_ctx *ctx)
{
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
struct intel_display *display = to_intel_display(crtc);
struct intel_crtc *temp_crtc;
u8 portsync_master_mask;
u8 portsync_slaves_mask;
u8 joiner_secondaries_mask;
struct intel_crtc *temp_crtc;
/* TODO: Add support for MST */
get_portsync_pipes(crtc, &portsync_master_mask, &portsync_slaves_mask);
joiner_secondaries_mask = get_joiner_secondary_pipes(i915,
joiner_secondaries_mask = get_joiner_secondary_pipes(display,
portsync_master_mask |
portsync_slaves_mask);
drm_WARN_ON(&i915->drm,
drm_WARN_ON(display->drm,
portsync_master_mask & portsync_slaves_mask ||
portsync_master_mask & joiner_secondaries_mask ||
portsync_slaves_mask & joiner_secondaries_mask);
for_each_intel_crtc_in_pipe_mask(&i915->drm, temp_crtc, joiner_secondaries_mask)
for_each_intel_crtc_in_pipe_mask(display->drm, temp_crtc, joiner_secondaries_mask)
intel_crtc_disable_noatomic_begin(temp_crtc, ctx);
for_each_intel_crtc_in_pipe_mask(&i915->drm, temp_crtc, portsync_slaves_mask)
for_each_intel_crtc_in_pipe_mask(display->drm, temp_crtc, portsync_slaves_mask)
intel_crtc_disable_noatomic_begin(temp_crtc, ctx);
for_each_intel_crtc_in_pipe_mask(&i915->drm, temp_crtc, portsync_master_mask)
for_each_intel_crtc_in_pipe_mask(display->drm, temp_crtc, portsync_master_mask)
intel_crtc_disable_noatomic_begin(temp_crtc, ctx);
for_each_intel_crtc_in_pipe_mask(&i915->drm, temp_crtc,
for_each_intel_crtc_in_pipe_mask(display->drm, temp_crtc,
joiner_secondaries_mask |
portsync_slaves_mask |
portsync_master_mask)
intel_crtc_disable_noatomic_complete(temp_crtc);
}
static void intel_modeset_update_connector_atomic_state(struct drm_i915_private *i915)
static void intel_modeset_update_connector_atomic_state(struct intel_display *display)
{
struct intel_connector *connector;
struct drm_connector_list_iter conn_iter;
drm_connector_list_iter_begin(&i915->drm, &conn_iter);
drm_connector_list_iter_begin(display->drm, &conn_iter);
for_each_intel_connector_iter(connector, &conn_iter) {
struct drm_connector_state *conn_state = connector->base.state;
struct intel_encoder *encoder =
@@ -319,7 +318,7 @@ static void intel_modeset_update_connector_atomic_state(struct drm_i915_private
static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state)
{
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
struct intel_display *display = to_intel_display(crtc_state);
if (intel_crtc_is_joiner_secondary(crtc_state))
return;
@@ -332,7 +331,7 @@ static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state
crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
crtc_state->uapi.scaling_filter = crtc_state->hw.scaling_filter;
if (DISPLAY_INFO(i915)->color.degamma_lut_size) {
if (DISPLAY_INFO(display)->color.degamma_lut_size) {
/* assume 1:1 mapping */
drm_property_replace_blob(&crtc_state->hw.degamma_lut,
crtc_state->pre_csc_lut);
@@ -347,7 +346,7 @@ static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state
* to gamma_lut as that is the only valid source of LUTs
* in the uapi.
*/
drm_WARN_ON(&i915->drm, crtc_state->post_csc_lut &&
drm_WARN_ON(display->drm, crtc_state->post_csc_lut &&
crtc_state->pre_csc_lut);
drm_property_replace_blob(&crtc_state->hw.degamma_lut,
@@ -366,15 +365,14 @@ static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state
}
static void
intel_sanitize_plane_mapping(struct drm_i915_private *i915)
intel_sanitize_plane_mapping(struct intel_display *display)
{
struct intel_display *display = &i915->display;
struct intel_crtc *crtc;
if (DISPLAY_VER(i915) >= 4)
if (DISPLAY_VER(display) >= 4)
return;
for_each_intel_crtc(&i915->drm, crtc) {
for_each_intel_crtc(display->drm, crtc) {
struct intel_plane *plane =
to_intel_plane(crtc->base.primary);
struct intel_crtc *plane_crtc;
@@ -386,7 +384,7 @@ intel_sanitize_plane_mapping(struct drm_i915_private *i915)
if (pipe == crtc->pipe)
continue;
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"[PLANE:%d:%s] attached to the wrong pipe, disabling plane\n",
plane->base.base.id, plane->base.name);
@@ -423,12 +421,12 @@ static bool intel_crtc_needs_link_reset(struct intel_crtc *crtc)
static struct intel_connector *intel_encoder_find_connector(struct intel_encoder *encoder)
{
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
struct intel_display *display = to_intel_display(encoder);
struct drm_connector_list_iter conn_iter;
struct intel_connector *connector;
struct intel_connector *found_connector = NULL;
drm_connector_list_iter_begin(&i915->drm, &conn_iter);
drm_connector_list_iter_begin(display->drm, &conn_iter);
for_each_intel_connector_iter(connector, &conn_iter) {
if (&encoder->base == connector->base.encoder) {
found_connector = connector;
@@ -466,7 +464,7 @@ static void intel_sanitize_fifo_underrun_reporting(const struct intel_crtc_state
static bool intel_sanitize_crtc(struct intel_crtc *crtc,
struct drm_modeset_acquire_ctx *ctx)
{
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
struct intel_display *display = to_intel_display(crtc);
struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state);
bool needs_link_reset;
@@ -474,7 +472,7 @@ static bool intel_sanitize_crtc(struct intel_crtc *crtc,
struct intel_plane *plane;
/* Disable everything but the primary plane */
for_each_intel_plane_on_crtc(&i915->drm, crtc, plane) {
for_each_intel_plane_on_crtc(display->drm, crtc, plane) {
const struct intel_plane_state *plane_state =
to_intel_plane_state(plane->base.state);
@@ -515,7 +513,7 @@ static bool intel_sanitize_crtc(struct intel_crtc *crtc,
return true;
}
static void intel_sanitize_all_crtcs(struct drm_i915_private *i915,
static void intel_sanitize_all_crtcs(struct intel_display *display,
struct drm_modeset_acquire_ctx *ctx)
{
struct intel_crtc *crtc;
@@ -530,7 +528,7 @@ static void intel_sanitize_all_crtcs(struct drm_i915_private *i915,
for (;;) {
u32 old_mask = crtcs_forced_off;
for_each_intel_crtc(&i915->drm, crtc) {
for_each_intel_crtc(display->drm, crtc) {
u32 crtc_mask = drm_crtc_mask(&crtc->base);
if (crtcs_forced_off & crtc_mask)
@@ -543,7 +541,7 @@ static void intel_sanitize_all_crtcs(struct drm_i915_private *i915,
break;
}
for_each_intel_crtc(&i915->drm, crtc) {
for_each_intel_crtc(display->drm, crtc) {
struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
@@ -553,7 +551,7 @@ static void intel_sanitize_all_crtcs(struct drm_i915_private *i915,
static bool has_bogus_dpll_config(const struct intel_crtc_state *crtc_state)
{
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
struct intel_display *display = to_intel_display(crtc_state);
/*
* Some SNB BIOSen (eg. ASUS K53SV) are known to misprogram
@@ -565,7 +563,7 @@ static bool has_bogus_dpll_config(const struct intel_crtc_state *crtc_state)
* without several WARNs, but for now let's take the easy
* road.
*/
return IS_SANDYBRIDGE(i915) &&
return display->platform.sandybridge &&
crtc_state->hw.active &&
crtc_state->shared_dpll &&
crtc_state->port_clock == 0;
@@ -574,13 +572,12 @@ static bool has_bogus_dpll_config(const struct intel_crtc_state *crtc_state)
static void intel_sanitize_encoder(struct intel_encoder *encoder)
{
struct intel_display *display = to_intel_display(encoder);
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
struct intel_connector *connector;
struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
struct intel_crtc_state *crtc_state = crtc ?
to_intel_crtc_state(crtc->base.state) : NULL;
struct intel_pmdemand_state *pmdemand_state =
to_intel_pmdemand_state(i915->display.pmdemand.obj.state);
to_intel_pmdemand_state(display->pmdemand.obj.state);
/*
* We need to check both for a crtc link (meaning that the encoder is
@@ -591,7 +588,7 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder)
crtc_state->hw.active;
if (crtc_state && has_bogus_dpll_config(crtc_state)) {
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"BIOS has misprogrammed the hardware. Disabling pipe %c\n",
pipe_name(crtc->pipe));
has_active_crtc = false;
@@ -599,7 +596,7 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder)
connector = intel_encoder_find_connector(encoder);
if (connector && !has_active_crtc) {
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"[ENCODER:%d:%s] has active connectors but no active pipe!\n",
encoder->base.base.id,
encoder->base.name);
@@ -616,7 +613,7 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder)
if (crtc_state) {
struct drm_encoder *best_encoder;
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"[ENCODER:%d:%s] manually disabled\n",
encoder->base.base.id,
encoder->base.name);
@@ -650,18 +647,17 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder)
/* notify opregion of the sanitized encoder state */
intel_opregion_notify_encoder(encoder, connector && has_active_crtc);
if (HAS_DDI(i915))
if (HAS_DDI(display))
intel_ddi_sanitize_encoder_pll_mapping(encoder);
}
/* FIXME read out full plane state for all planes */
static void readout_plane_state(struct drm_i915_private *i915)
static void readout_plane_state(struct intel_display *display)
{
struct intel_display *display = &i915->display;
struct intel_plane *plane;
struct intel_crtc *crtc;
for_each_intel_plane(&i915->drm, plane) {
for_each_intel_plane(display->drm, plane) {
struct intel_plane_state *plane_state =
to_intel_plane_state(plane->base.state);
struct intel_crtc_state *crtc_state;
@@ -675,13 +671,13 @@ static void readout_plane_state(struct drm_i915_private *i915)
intel_set_plane_visible(crtc_state, plane_state, visible);
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"[PLANE:%d:%s] hw state readout: %s, pipe %c\n",
plane->base.base.id, plane->base.name,
str_enabled_disabled(visible), pipe_name(pipe));
}
for_each_intel_crtc(&i915->drm, crtc) {
for_each_intel_crtc(display->drm, crtc) {
struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
@@ -689,18 +685,17 @@ static void readout_plane_state(struct drm_i915_private *i915)
}
}
static void intel_modeset_readout_hw_state(struct drm_i915_private *i915)
static void intel_modeset_readout_hw_state(struct intel_display *display)
{
struct intel_display *display = &i915->display;
struct intel_pmdemand_state *pmdemand_state =
to_intel_pmdemand_state(i915->display.pmdemand.obj.state);
to_intel_pmdemand_state(display->pmdemand.obj.state);
enum pipe pipe;
struct intel_crtc *crtc;
struct intel_encoder *encoder;
struct intel_connector *connector;
struct drm_connector_list_iter conn_iter;
for_each_intel_crtc(&i915->drm, crtc) {
for_each_intel_crtc(display->drm, crtc) {
struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
@@ -715,15 +710,15 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915)
crtc->base.enabled = crtc_state->hw.enable;
crtc->active = crtc_state->hw.active;
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"[CRTC:%d:%s] hw state readout: %s\n",
crtc->base.base.id, crtc->base.name,
str_enabled_disabled(crtc_state->hw.active));
}
readout_plane_state(i915);
readout_plane_state(display);
for_each_intel_encoder(&i915->drm, encoder) {
for_each_intel_encoder(display->drm, encoder) {
struct intel_crtc_state *crtc_state = NULL;
pipe = 0;
@@ -742,7 +737,7 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915)
/* encoder should read be linked to joiner primary */
WARN_ON(intel_crtc_is_joiner_secondary(crtc_state));
for_each_intel_crtc_in_pipe_mask(&i915->drm, secondary_crtc,
for_each_intel_crtc_in_pipe_mask(display->drm, secondary_crtc,
intel_crtc_joiner_secondary_pipes(crtc_state)) {
struct intel_crtc_state *secondary_crtc_state;
@@ -765,7 +760,7 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915)
if (encoder->sync_state)
encoder->sync_state(encoder, crtc_state);
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"[ENCODER:%d:%s] hw state readout: %s, pipe %c\n",
encoder->base.base.id, encoder->base.name,
str_enabled_disabled(encoder->base.crtc),
@@ -774,7 +769,7 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915)
intel_dpll_readout_hw_state(display);
drm_connector_list_iter_begin(&i915->drm, &conn_iter);
drm_connector_list_iter_begin(display->drm, &conn_iter);
for_each_intel_connector_iter(connector, &conn_iter) {
struct intel_crtc_state *crtc_state = NULL;
@@ -808,14 +803,14 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915)
if (connector->sync_state)
connector->sync_state(connector, crtc_state);
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"[CONNECTOR:%d:%s] hw state readout: %s\n",
connector->base.base.id, connector->base.name,
str_enabled_disabled(connector->base.encoder));
}
drm_connector_list_iter_end(&conn_iter);
for_each_intel_crtc(&i915->drm, crtc) {
for_each_intel_crtc(display->drm, crtc) {
struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
struct intel_plane *plane;
@@ -838,7 +833,7 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915)
intel_crtc_copy_hw_to_uapi_state(crtc_state);
}
for_each_intel_plane_on_crtc(&i915->drm, crtc, plane) {
for_each_intel_plane_on_crtc(display->drm, crtc, plane) {
const struct intel_plane_state *plane_state =
to_intel_plane_state(plane->base.state);
@@ -854,14 +849,14 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915)
* use plane->min_cdclk() :(
*/
if (plane_state->uapi.visible && plane->min_cdclk) {
if (crtc_state->double_wide || DISPLAY_VER(i915) >= 10)
if (crtc_state->double_wide || DISPLAY_VER(display) >= 10)
crtc_state->min_cdclk[plane->id] =
DIV_ROUND_UP(crtc_state->pixel_rate, 2);
else
crtc_state->min_cdclk[plane->id] =
crtc_state->pixel_rate;
}
drm_dbg_kms(&i915->drm,
drm_dbg_kms(display->drm,
"[PLANE:%d:%s] min_cdclk %d kHz\n",
plane->base.base.id, plane->base.name,
crtc_state->min_cdclk[plane->id]);
@@ -882,11 +877,11 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915)
}
static void
get_encoder_power_domains(struct drm_i915_private *i915)
get_encoder_power_domains(struct intel_display *display)
{
struct intel_encoder *encoder;
for_each_intel_encoder(&i915->drm, encoder) {
for_each_intel_encoder(display->drm, encoder) {
struct intel_crtc_state *crtc_state;
if (!encoder->get_power_domains)
@@ -904,47 +899,49 @@ get_encoder_power_domains(struct drm_i915_private *i915)
}
}
static void intel_early_display_was(struct drm_i915_private *i915)
static void intel_early_display_was(struct intel_display *display)
{
/*
* Display WA #1185 WaDisableDARBFClkGating:glk,icl,ehl,tgl
* Also known as Wa_14010480278.
*/
if (IS_DISPLAY_VER(i915, 10, 12))
intel_de_rmw(i915, GEN9_CLKGATE_DIS_0, 0, DARBF_GATING_DIS);
if (IS_DISPLAY_VER(display, 10, 12))
intel_de_rmw(display, GEN9_CLKGATE_DIS_0, 0, DARBF_GATING_DIS);
/*
* WaRsPkgCStateDisplayPMReq:hsw
* System hang if this isn't done before disabling all planes!
*/
if (IS_HASWELL(i915))
intel_de_rmw(i915, CHICKEN_PAR1_1, 0, FORCE_ARB_IDLE_PLANES);
if (display->platform.haswell)
intel_de_rmw(display, CHICKEN_PAR1_1, 0, FORCE_ARB_IDLE_PLANES);
if (IS_KABYLAKE(i915) || IS_COFFEELAKE(i915) || IS_COMETLAKE(i915)) {
if (display->platform.kabylake || display->platform.coffeelake ||
display->platform.cometlake) {
/* Display WA #1142:kbl,cfl,cml */
intel_de_rmw(i915, CHICKEN_PAR1_1,
intel_de_rmw(display, CHICKEN_PAR1_1,
KBL_ARB_FILL_SPARE_22, KBL_ARB_FILL_SPARE_22);
intel_de_rmw(i915, CHICKEN_MISC_2,
intel_de_rmw(display, CHICKEN_MISC_2,
KBL_ARB_FILL_SPARE_13 | KBL_ARB_FILL_SPARE_14,
KBL_ARB_FILL_SPARE_14);
}
}
void intel_modeset_setup_hw_state(struct drm_i915_private *i915,
void intel_modeset_setup_hw_state(struct intel_display *display,
struct drm_modeset_acquire_ctx *ctx)
{
struct intel_display *display = &i915->display;
struct intel_encoder *encoder;
struct intel_crtc *crtc;
intel_wakeref_t wakeref;
wakeref = intel_display_power_get(display, POWER_DOMAIN_INIT);
intel_early_display_was(i915);
intel_modeset_readout_hw_state(i915);
intel_early_display_was(display);
intel_vga_disable(display);
intel_modeset_readout_hw_state(display);
/* HW state is read out, now we need to sanitize this mess. */
get_encoder_power_domains(i915);
get_encoder_power_domains(display);
intel_pch_sanitize(display);
@@ -954,7 +951,7 @@ void intel_modeset_setup_hw_state(struct drm_i915_private *i915,
* intel_sanitize_plane_mapping() may need to do vblank
* waits, so we need vblank interrupts restored beforehand.
*/
for_each_intel_crtc(&i915->drm, crtc) {
for_each_intel_crtc(display->drm, crtc) {
struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
@@ -968,20 +965,20 @@ void intel_modeset_setup_hw_state(struct drm_i915_private *i915,
}
}
intel_fbc_sanitize(&i915->display);
intel_fbc_sanitize(display);
intel_sanitize_plane_mapping(i915);
intel_sanitize_plane_mapping(display);
for_each_intel_encoder(&i915->drm, encoder)
for_each_intel_encoder(display->drm, encoder)
intel_sanitize_encoder(encoder);
/*
* Sanitizing CRTCs needs their connector atomic state to be
* up-to-date, so ensure that already here.
*/
intel_modeset_update_connector_atomic_state(i915);
intel_modeset_update_connector_atomic_state(display);
intel_sanitize_all_crtcs(i915, ctx);
intel_sanitize_all_crtcs(display, ctx);
intel_dpll_sanitize_state(display);
@@ -990,13 +987,13 @@ void intel_modeset_setup_hw_state(struct drm_i915_private *i915,
intel_wm_get_hw_state(display);
intel_wm_sanitize(display);
for_each_intel_crtc(&i915->drm, crtc) {
for_each_intel_crtc(display->drm, crtc) {
struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
struct intel_power_domain_mask put_domains;
intel_modeset_get_crtc_power_domains(crtc_state, &put_domains);
if (drm_WARN_ON(&i915->drm, !bitmap_empty(put_domains.bits, POWER_DOMAIN_NUM)))
if (drm_WARN_ON(display->drm, !bitmap_empty(put_domains.bits, POWER_DOMAIN_NUM)))
intel_modeset_put_crtc_power_domains(crtc, &put_domains);
}

View File

@@ -6,10 +6,10 @@
#ifndef __INTEL_MODESET_SETUP_H__
#define __INTEL_MODESET_SETUP_H__
struct drm_i915_private;
struct drm_modeset_acquire_ctx;
struct intel_display;
void intel_modeset_setup_hw_state(struct drm_i915_private *i915,
void intel_modeset_setup_hw_state(struct intel_display *display,
struct drm_modeset_acquire_ctx *ctx);
#endif /* __INTEL_MODESET_SETUP_H__ */

View File

@@ -6,13 +6,14 @@
*/
#include <drm/drm_atomic_state_helper.h>
#include <drm/drm_print.h>
#include "i915_drv.h"
#include "intel_atomic.h"
#include "intel_crtc.h"
#include "intel_crtc_state_dump.h"
#include "intel_cx0_phy.h"
#include "intel_display.h"
#include "intel_display_core.h"
#include "intel_display_types.h"
#include "intel_fdi.h"
#include "intel_modeset_verify.h"
@@ -28,9 +29,8 @@ static void intel_connector_verify_state(const struct intel_crtc_state *crtc_sta
{
struct intel_connector *connector = to_intel_connector(conn_state->connector);
struct intel_display *display = to_intel_display(connector);
struct drm_i915_private *i915 = to_i915(connector->base.dev);
drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s]\n",
drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s]\n",
connector->base.base.id, connector->base.name);
if (connector->get_hw_state(connector)) {
@@ -91,7 +91,6 @@ verify_connector_state(struct intel_atomic_state *state,
static void intel_pipe_config_sanity_check(const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
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(display, crtc_state),
@@ -103,7 +102,7 @@ static void intel_pipe_config_sanity_check(const struct intel_crtc_state *crtc_s
* Yell if the encoder disagrees. Allow for slight
* rounding differences.
*/
drm_WARN(&i915->drm, abs(fdi_dotclock - dotclock) > 1,
drm_WARN(display->drm, abs(fdi_dotclock - dotclock) > 1,
"FDI dotclock and encoder dotclock mismatch, fdi: %i, encoder: %i\n",
fdi_dotclock, dotclock);
}
@@ -113,17 +112,16 @@ static void
verify_encoder_state(struct intel_atomic_state *state)
{
struct intel_display *display = to_intel_display(state);
struct drm_i915_private *i915 = to_i915(state->base.dev);
struct intel_encoder *encoder;
struct drm_connector *connector;
const struct drm_connector_state *old_conn_state, *new_conn_state;
int i;
for_each_intel_encoder(&i915->drm, encoder) {
for_each_intel_encoder(display->drm, encoder) {
bool enabled = false, found = false;
enum pipe pipe;
drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s]\n",
drm_dbg_kms(display->drm, "[ENCODER:%d:%s]\n",
encoder->base.base.id,
encoder->base.name);
@@ -166,7 +164,6 @@ verify_crtc_state(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
struct intel_display *display = to_intel_display(state);
struct drm_i915_private *i915 = to_i915(display->drm);
const struct intel_crtc_state *sw_crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
struct intel_crtc_state *hw_crtc_state;
@@ -185,7 +182,7 @@ verify_crtc_state(struct intel_atomic_state *state,
intel_crtc_get_pipe_config(hw_crtc_state);
/* we keep both pipes enabled on 830 */
if (IS_I830(i915) && hw_crtc_state->hw.active)
if (display->platform.i830 && hw_crtc_state->hw.active)
hw_crtc_state->hw.active = sw_crtc_state->hw.active;
INTEL_DISPLAY_STATE_WARN(display,

View File

@@ -291,7 +291,6 @@ static void intel_overlay_flip_prepare(struct intel_overlay *overlay,
struct i915_vma *vma)
{
struct intel_display *display = overlay->display;
struct drm_i915_private *i915 = to_i915(display->drm);
enum pipe pipe = overlay->crtc->pipe;
struct intel_frontbuffer *frontbuffer = NULL;
@@ -307,7 +306,7 @@ static void intel_overlay_flip_prepare(struct intel_overlay *overlay,
intel_frontbuffer_put(overlay->frontbuffer);
overlay->frontbuffer = frontbuffer;
intel_frontbuffer_flip_prepare(i915, INTEL_FRONTBUFFER_OVERLAY(pipe));
intel_frontbuffer_flip_prepare(display, INTEL_FRONTBUFFER_OVERLAY(pipe));
overlay->old_vma = overlay->vma;
if (vma)
@@ -359,14 +358,13 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
static void intel_overlay_release_old_vma(struct intel_overlay *overlay)
{
struct intel_display *display = overlay->display;
struct drm_i915_private *i915 = to_i915(display->drm);
struct i915_vma *vma;
vma = fetch_and_zero(&overlay->old_vma);
if (drm_WARN_ON(display->drm, !vma))
return;
intel_frontbuffer_flip_complete(i915, INTEL_FRONTBUFFER_OVERLAY(overlay->crtc->pipe));
intel_frontbuffer_flip_complete(display, INTEL_FRONTBUFFER_OVERLAY(overlay->crtc->pipe));
i915_vma_unpin(vma);
i915_vma_put(vma);

View File

@@ -0,0 +1,340 @@
// SPDX-License-Identifier: MIT
/*
* Copyright 2025 Intel Corporation.
*/
#include <drm/drm_print.h>
#include "i915_utils.h"
#include "intel_display_core.h"
#include "intel_pch.h"
#define INTEL_PCH_DEVICE_ID_MASK 0xff80
#define INTEL_PCH_IBX_DEVICE_ID_TYPE 0x3b00
#define INTEL_PCH_CPT_DEVICE_ID_TYPE 0x1c00
#define INTEL_PCH_PPT_DEVICE_ID_TYPE 0x1e00
#define INTEL_PCH_LPT_DEVICE_ID_TYPE 0x8c00
#define INTEL_PCH_LPT_LP_DEVICE_ID_TYPE 0x9c00
#define INTEL_PCH_WPT_DEVICE_ID_TYPE 0x8c80
#define INTEL_PCH_WPT_LP_DEVICE_ID_TYPE 0x9c80
#define INTEL_PCH_SPT_DEVICE_ID_TYPE 0xA100
#define INTEL_PCH_SPT_LP_DEVICE_ID_TYPE 0x9D00
#define INTEL_PCH_KBP_DEVICE_ID_TYPE 0xA280
#define INTEL_PCH_CNP_DEVICE_ID_TYPE 0xA300
#define INTEL_PCH_CNP_LP_DEVICE_ID_TYPE 0x9D80
#define INTEL_PCH_CMP_DEVICE_ID_TYPE 0x0280
#define INTEL_PCH_CMP2_DEVICE_ID_TYPE 0x0680
#define INTEL_PCH_CMP_V_DEVICE_ID_TYPE 0xA380
#define INTEL_PCH_ICP_DEVICE_ID_TYPE 0x3480
#define INTEL_PCH_ICP2_DEVICE_ID_TYPE 0x3880
#define INTEL_PCH_MCC_DEVICE_ID_TYPE 0x4B00
#define INTEL_PCH_TGP_DEVICE_ID_TYPE 0xA080
#define INTEL_PCH_TGP2_DEVICE_ID_TYPE 0x4380
#define INTEL_PCH_JSP_DEVICE_ID_TYPE 0x4D80
#define INTEL_PCH_ADP_DEVICE_ID_TYPE 0x7A80
#define INTEL_PCH_ADP2_DEVICE_ID_TYPE 0x5180
#define INTEL_PCH_ADP3_DEVICE_ID_TYPE 0x7A00
#define INTEL_PCH_ADP4_DEVICE_ID_TYPE 0x5480
#define INTEL_PCH_P2X_DEVICE_ID_TYPE 0x7100
#define INTEL_PCH_P3X_DEVICE_ID_TYPE 0x7000
#define INTEL_PCH_QEMU_DEVICE_ID_TYPE 0x2900 /* qemu q35 has 2918 */
/*
* Check for platforms where the south display is on the same PCI device or SoC
* die as the north display. The PCH (if it even exists) is not involved in
* display. Return a fake PCH type for south display handling on these
* platforms, without actually detecting the PCH, and PCH_NONE otherwise.
*/
static enum intel_pch intel_pch_fake_for_south_display(struct intel_display *display)
{
enum intel_pch pch_type = PCH_NONE;
if (DISPLAY_VER(display) >= 20)
pch_type = PCH_LNL;
else if (display->platform.battlemage || display->platform.meteorlake)
pch_type = PCH_MTL;
else if (display->platform.dg2)
pch_type = PCH_DG2;
else if (display->platform.dg1)
pch_type = PCH_DG1;
return pch_type;
}
/* Map PCH device id to PCH type, or PCH_NONE if unknown. */
static enum intel_pch
intel_pch_type(const struct intel_display *display, unsigned short id)
{
switch (id) {
case INTEL_PCH_IBX_DEVICE_ID_TYPE:
drm_dbg_kms(display->drm, "Found Ibex Peak PCH\n");
drm_WARN_ON(display->drm, DISPLAY_VER(display) != 5);
return PCH_IBX;
case INTEL_PCH_CPT_DEVICE_ID_TYPE:
drm_dbg_kms(display->drm, "Found CougarPoint PCH\n");
drm_WARN_ON(display->drm,
DISPLAY_VER(display) != 6 &&
!display->platform.ivybridge);
return PCH_CPT;
case INTEL_PCH_PPT_DEVICE_ID_TYPE:
drm_dbg_kms(display->drm, "Found PantherPoint PCH\n");
drm_WARN_ON(display->drm,
DISPLAY_VER(display) != 6 &&
!display->platform.ivybridge);
/* PPT is CPT compatible */
return PCH_CPT;
case INTEL_PCH_LPT_DEVICE_ID_TYPE:
drm_dbg_kms(display->drm, "Found LynxPoint PCH\n");
drm_WARN_ON(display->drm,
!display->platform.haswell &&
!display->platform.broadwell);
drm_WARN_ON(display->drm,
display->platform.haswell_ult ||
display->platform.broadwell_ult);
return PCH_LPT_H;
case INTEL_PCH_LPT_LP_DEVICE_ID_TYPE:
drm_dbg_kms(display->drm, "Found LynxPoint LP PCH\n");
drm_WARN_ON(display->drm,
!display->platform.haswell &&
!display->platform.broadwell);
drm_WARN_ON(display->drm,
!display->platform.haswell_ult &&
!display->platform.broadwell_ult);
return PCH_LPT_LP;
case INTEL_PCH_WPT_DEVICE_ID_TYPE:
drm_dbg_kms(display->drm, "Found WildcatPoint PCH\n");
drm_WARN_ON(display->drm,
!display->platform.haswell &&
!display->platform.broadwell);
drm_WARN_ON(display->drm,
display->platform.haswell_ult ||
display->platform.broadwell_ult);
/* WPT is LPT compatible */
return PCH_LPT_H;
case INTEL_PCH_WPT_LP_DEVICE_ID_TYPE:
drm_dbg_kms(display->drm, "Found WildcatPoint LP PCH\n");
drm_WARN_ON(display->drm,
!display->platform.haswell &&
!display->platform.broadwell);
drm_WARN_ON(display->drm,
!display->platform.haswell_ult &&
!display->platform.broadwell_ult);
/* WPT is LPT compatible */
return PCH_LPT_LP;
case INTEL_PCH_SPT_DEVICE_ID_TYPE:
drm_dbg_kms(display->drm, "Found SunrisePoint PCH\n");
drm_WARN_ON(display->drm,
!display->platform.skylake &&
!display->platform.kabylake &&
!display->platform.coffeelake);
return PCH_SPT;
case INTEL_PCH_SPT_LP_DEVICE_ID_TYPE:
drm_dbg_kms(display->drm, "Found SunrisePoint LP PCH\n");
drm_WARN_ON(display->drm,
!display->platform.skylake &&
!display->platform.kabylake &&
!display->platform.coffeelake &&
!display->platform.cometlake);
return PCH_SPT;
case INTEL_PCH_KBP_DEVICE_ID_TYPE:
drm_dbg_kms(display->drm, "Found Kaby Lake PCH (KBP)\n");
drm_WARN_ON(display->drm,
!display->platform.skylake &&
!display->platform.kabylake &&
!display->platform.coffeelake &&
!display->platform.cometlake);
/* KBP is SPT compatible */
return PCH_SPT;
case INTEL_PCH_CNP_DEVICE_ID_TYPE:
drm_dbg_kms(display->drm, "Found Cannon Lake PCH (CNP)\n");
drm_WARN_ON(display->drm,
!display->platform.coffeelake &&
!display->platform.cometlake);
return PCH_CNP;
case INTEL_PCH_CNP_LP_DEVICE_ID_TYPE:
drm_dbg_kms(display->drm,
"Found Cannon Lake LP PCH (CNP-LP)\n");
drm_WARN_ON(display->drm,
!display->platform.coffeelake &&
!display->platform.cometlake);
return PCH_CNP;
case INTEL_PCH_CMP_DEVICE_ID_TYPE:
case INTEL_PCH_CMP2_DEVICE_ID_TYPE:
drm_dbg_kms(display->drm, "Found Comet Lake PCH (CMP)\n");
drm_WARN_ON(display->drm,
!display->platform.coffeelake &&
!display->platform.cometlake &&
!display->platform.rocketlake);
/* CMP is CNP compatible */
return PCH_CNP;
case INTEL_PCH_CMP_V_DEVICE_ID_TYPE:
drm_dbg_kms(display->drm, "Found Comet Lake V PCH (CMP-V)\n");
drm_WARN_ON(display->drm,
!display->platform.coffeelake &&
!display->platform.cometlake);
/* CMP-V is based on KBP, which is SPT compatible */
return PCH_SPT;
case INTEL_PCH_ICP_DEVICE_ID_TYPE:
case INTEL_PCH_ICP2_DEVICE_ID_TYPE:
drm_dbg_kms(display->drm, "Found Ice Lake PCH\n");
drm_WARN_ON(display->drm, !display->platform.icelake);
return PCH_ICP;
case INTEL_PCH_MCC_DEVICE_ID_TYPE:
drm_dbg_kms(display->drm, "Found Mule Creek Canyon PCH\n");
drm_WARN_ON(display->drm, !(display->platform.jasperlake ||
display->platform.elkhartlake));
/* MCC is TGP compatible */
return PCH_TGP;
case INTEL_PCH_TGP_DEVICE_ID_TYPE:
case INTEL_PCH_TGP2_DEVICE_ID_TYPE:
drm_dbg_kms(display->drm, "Found Tiger Lake LP PCH\n");
drm_WARN_ON(display->drm, !display->platform.tigerlake &&
!display->platform.rocketlake &&
!display->platform.skylake &&
!display->platform.kabylake &&
!display->platform.coffeelake &&
!display->platform.cometlake);
return PCH_TGP;
case INTEL_PCH_JSP_DEVICE_ID_TYPE:
drm_dbg_kms(display->drm, "Found Jasper Lake PCH\n");
drm_WARN_ON(display->drm, !(display->platform.jasperlake ||
display->platform.elkhartlake));
/* JSP is ICP compatible */
return PCH_ICP;
case INTEL_PCH_ADP_DEVICE_ID_TYPE:
case INTEL_PCH_ADP2_DEVICE_ID_TYPE:
case INTEL_PCH_ADP3_DEVICE_ID_TYPE:
case INTEL_PCH_ADP4_DEVICE_ID_TYPE:
drm_dbg_kms(display->drm, "Found Alder Lake PCH\n");
drm_WARN_ON(display->drm, !display->platform.alderlake_s &&
!display->platform.alderlake_p);
return PCH_ADP;
default:
return PCH_NONE;
}
}
static bool intel_is_virt_pch(unsigned short id,
unsigned short svendor, unsigned short sdevice)
{
return (id == INTEL_PCH_P2X_DEVICE_ID_TYPE ||
id == INTEL_PCH_P3X_DEVICE_ID_TYPE ||
(id == INTEL_PCH_QEMU_DEVICE_ID_TYPE &&
svendor == PCI_SUBVENDOR_ID_REDHAT_QUMRANET &&
sdevice == PCI_SUBDEVICE_ID_QEMU));
}
static void
intel_virt_detect_pch(const struct intel_display *display,
unsigned short *pch_id, enum intel_pch *pch_type)
{
unsigned short id = 0;
/*
* In a virtualized passthrough environment we can be in a
* setup where the ISA bridge is not able to be passed through.
* In this case, a south bridge can be emulated and we have to
* make an educated guess as to which PCH is really there.
*/
if (display->platform.alderlake_s || display->platform.alderlake_p)
id = INTEL_PCH_ADP_DEVICE_ID_TYPE;
else if (display->platform.tigerlake || display->platform.rocketlake)
id = INTEL_PCH_TGP_DEVICE_ID_TYPE;
else if (display->platform.jasperlake || display->platform.elkhartlake)
id = INTEL_PCH_MCC_DEVICE_ID_TYPE;
else if (display->platform.icelake)
id = INTEL_PCH_ICP_DEVICE_ID_TYPE;
else if (display->platform.coffeelake ||
display->platform.cometlake)
id = INTEL_PCH_CNP_DEVICE_ID_TYPE;
else if (display->platform.kabylake || display->platform.skylake)
id = INTEL_PCH_SPT_DEVICE_ID_TYPE;
else if (display->platform.haswell_ult ||
display->platform.broadwell_ult)
id = INTEL_PCH_LPT_LP_DEVICE_ID_TYPE;
else if (display->platform.haswell || display->platform.broadwell)
id = INTEL_PCH_LPT_DEVICE_ID_TYPE;
else if (DISPLAY_VER(display) == 6 || display->platform.ivybridge)
id = INTEL_PCH_CPT_DEVICE_ID_TYPE;
else if (DISPLAY_VER(display) == 5)
id = INTEL_PCH_IBX_DEVICE_ID_TYPE;
if (id)
drm_dbg_kms(display->drm, "Assuming PCH ID %04x\n", id);
else
drm_dbg_kms(display->drm, "Assuming no PCH\n");
*pch_type = intel_pch_type(display, id);
/* Sanity check virtual PCH id */
if (drm_WARN_ON(display->drm,
id && *pch_type == PCH_NONE))
id = 0;
*pch_id = id;
}
void intel_pch_detect(struct intel_display *display)
{
struct pci_dev *pch = NULL;
unsigned short id;
enum intel_pch pch_type;
pch_type = intel_pch_fake_for_south_display(display);
if (pch_type != PCH_NONE) {
display->pch_type = pch_type;
drm_dbg_kms(display->drm,
"PCH not involved in display, using fake PCH type %d for south display\n",
pch_type);
return;
}
/*
* The reason to probe ISA bridge instead of Dev31:Fun0 is to
* make graphics device passthrough work easy for VMM, that only
* need to expose ISA bridge to let driver know the real hardware
* underneath. This is a requirement from virtualization team.
*
* In some virtualized environments (e.g. XEN), there is irrelevant
* ISA bridge in the system. To work reliably, we should scan through
* all the ISA bridge devices and check for the first match, instead
* of only checking the first one.
*/
while ((pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, pch))) {
if (pch->vendor != PCI_VENDOR_ID_INTEL)
continue;
id = pch->device & INTEL_PCH_DEVICE_ID_MASK;
pch_type = intel_pch_type(display, id);
if (pch_type != PCH_NONE) {
display->pch_type = pch_type;
break;
} else if (intel_is_virt_pch(id, pch->subsystem_vendor,
pch->subsystem_device)) {
intel_virt_detect_pch(display, &id, &pch_type);
display->pch_type = pch_type;
break;
}
}
/*
* Use PCH_NOP (PCH but no South Display) for PCH platforms without
* display.
*/
if (pch && !HAS_DISPLAY(display)) {
drm_dbg_kms(display->drm,
"Display disabled, reverting to NOP PCH\n");
display->pch_type = PCH_NOP;
} else if (!pch) {
if (i915_run_as_guest() && HAS_DISPLAY(display)) {
intel_virt_detect_pch(display, &id, &pch_type);
display->pch_type = pch_type;
} else {
drm_dbg_kms(display->drm, "No PCH found.\n");
}
}
pci_dev_put(pch);
}

View File

@@ -0,0 +1,58 @@
/* SPDX-License-Identifier: MIT */
/*
* Copyright 2025 Intel Corporation.
*/
#ifndef __INTEL_PCH__
#define __INTEL_PCH__
#include "intel_display_conversion.h"
struct intel_display;
/*
* Sorted by south display engine compatibility.
* If the new PCH comes with a south display engine that is not
* inherited from the latest item, please do not add it to the
* end. Instead, add it right after its "parent" PCH.
*/
enum intel_pch {
PCH_NOP = -1, /* PCH without south display */
PCH_NONE = 0, /* No PCH present */
PCH_IBX, /* Ibexpeak PCH */
PCH_CPT, /* Cougarpoint/Pantherpoint PCH */
PCH_LPT_H, /* Lynxpoint/Wildcatpoint H PCH */
PCH_LPT_LP, /* Lynxpoint/Wildcatpoint LP PCH */
PCH_SPT, /* Sunrisepoint/Kaby Lake PCH */
PCH_CNP, /* Cannon/Comet Lake PCH */
PCH_ICP, /* Ice Lake/Jasper Lake PCH */
PCH_TGP, /* Tiger Lake/Mule Creek Canyon PCH */
PCH_ADP, /* Alder Lake PCH */
/* Fake PCHs, functionality handled on the same PCI dev */
PCH_DG1 = 1024,
PCH_DG2,
PCH_MTL,
PCH_LNL,
};
#define INTEL_PCH_TYPE(_display) (__to_intel_display(_display)->pch_type)
#define HAS_PCH_DG2(display) (INTEL_PCH_TYPE(display) == PCH_DG2)
#define HAS_PCH_ADP(display) (INTEL_PCH_TYPE(display) == PCH_ADP)
#define HAS_PCH_DG1(display) (INTEL_PCH_TYPE(display) == PCH_DG1)
#define HAS_PCH_TGP(display) (INTEL_PCH_TYPE(display) == PCH_TGP)
#define HAS_PCH_ICP(display) (INTEL_PCH_TYPE(display) == PCH_ICP)
#define HAS_PCH_CNP(display) (INTEL_PCH_TYPE(display) == PCH_CNP)
#define HAS_PCH_SPT(display) (INTEL_PCH_TYPE(display) == PCH_SPT)
#define HAS_PCH_LPT_H(display) (INTEL_PCH_TYPE(display) == PCH_LPT_H)
#define HAS_PCH_LPT_LP(display) (INTEL_PCH_TYPE(display) == PCH_LPT_LP)
#define HAS_PCH_LPT(display) (INTEL_PCH_TYPE(display) == PCH_LPT_H || \
INTEL_PCH_TYPE(display) == PCH_LPT_LP)
#define HAS_PCH_CPT(display) (INTEL_PCH_TYPE(display) == PCH_CPT)
#define HAS_PCH_IBX(display) (INTEL_PCH_TYPE(display) == PCH_IBX)
#define HAS_PCH_NOP(display) (INTEL_PCH_TYPE(display) == PCH_NOP)
#define HAS_PCH_SPLIT(display) (INTEL_PCH_TYPE(display) != PCH_NONE)
void intel_pch_detect(struct intel_display *display);
#endif /* __INTEL_PCH__ */

View File

@@ -3,8 +3,9 @@
* Copyright © 2021 Intel Corporation
*/
#include <drm/drm_print.h>
#include "g4x_dp.h"
#include "i915_drv.h"
#include "i915_reg.h"
#include "intel_crt.h"
#include "intel_crt_regs.h"
@@ -23,17 +24,15 @@
bool intel_has_pch_trancoder(struct intel_display *display,
enum pipe pch_transcoder)
{
struct drm_i915_private *i915 = to_i915(display->drm);
return HAS_PCH_IBX(i915) || HAS_PCH_CPT(i915) ||
(HAS_PCH_LPT_H(i915) && pch_transcoder == PIPE_A);
return HAS_PCH_IBX(display) || HAS_PCH_CPT(display) ||
(HAS_PCH_LPT_H(display) && pch_transcoder == PIPE_A);
}
enum pipe intel_crtc_pch_transcoder(struct intel_crtc *crtc)
{
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
struct intel_display *display = to_intel_display(crtc);
if (HAS_PCH_LPT(i915))
if (HAS_PCH_LPT(display))
return PIPE_A;
else
return crtc->pipe;
@@ -43,7 +42,6 @@ static void assert_pch_dp_disabled(struct intel_display *display,
enum pipe pipe, enum port port,
i915_reg_t dp_reg)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
enum pipe port_pipe;
bool state;
@@ -54,7 +52,7 @@ static void assert_pch_dp_disabled(struct intel_display *display,
port_name(port), pipe_name(pipe));
INTEL_DISPLAY_STATE_WARN(display,
HAS_PCH_IBX(dev_priv) && !state && port_pipe == PIPE_B,
HAS_PCH_IBX(display) && !state && port_pipe == PIPE_B,
"IBX PCH DP %c still using transcoder B\n",
port_name(port));
}
@@ -63,7 +61,6 @@ static void assert_pch_hdmi_disabled(struct intel_display *display,
enum pipe pipe, enum port port,
i915_reg_t hdmi_reg)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
enum pipe port_pipe;
bool state;
@@ -74,7 +71,7 @@ static void assert_pch_hdmi_disabled(struct intel_display *display,
port_name(port), pipe_name(pipe));
INTEL_DISPLAY_STATE_WARN(display,
HAS_PCH_IBX(dev_priv) && !state && port_pipe == PIPE_B,
HAS_PCH_IBX(display) && !state && port_pipe == PIPE_B,
"IBX PCH HDMI %c still using transcoder B\n",
port_name(port));
}
@@ -249,7 +246,6 @@ static void ilk_enable_pch_transcoder(const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum pipe pipe = crtc->pipe;
i915_reg_t reg;
u32 val, pipeconf_val;
@@ -261,7 +257,7 @@ static void ilk_enable_pch_transcoder(const struct intel_crtc_state *crtc_state)
assert_fdi_tx_enabled(display, pipe);
assert_fdi_rx_enabled(display, pipe);
if (HAS_PCH_CPT(dev_priv)) {
if (HAS_PCH_CPT(display)) {
reg = TRANS_CHICKEN2(pipe);
val = intel_de_read(display, reg);
/*
@@ -279,7 +275,7 @@ static void ilk_enable_pch_transcoder(const struct intel_crtc_state *crtc_state)
val = intel_de_read(display, reg);
pipeconf_val = intel_de_read(display, TRANSCONF(display, pipe));
if (HAS_PCH_IBX(dev_priv)) {
if (HAS_PCH_IBX(display)) {
/* Configure frame start delay to match the CPU */
val &= ~TRANS_FRAME_START_DELAY_MASK;
val |= TRANS_FRAME_START_DELAY(crtc_state->framestart_delay - 1);
@@ -298,7 +294,7 @@ static void ilk_enable_pch_transcoder(const struct intel_crtc_state *crtc_state)
val &= ~TRANS_INTERLACE_MASK;
if ((pipeconf_val & TRANSCONF_INTERLACE_MASK_ILK) == TRANSCONF_INTERLACE_IF_ID_ILK) {
if (HAS_PCH_IBX(dev_priv) &&
if (HAS_PCH_IBX(display) &&
intel_crtc_has_type(crtc_state, INTEL_OUTPUT_SDVO))
val |= TRANS_INTERLACE_LEGACY_VSYNC_IBX;
else
@@ -316,7 +312,6 @@ static void ilk_enable_pch_transcoder(const struct intel_crtc_state *crtc_state)
static void ilk_disable_pch_transcoder(struct intel_crtc *crtc)
{
struct intel_display *display = to_intel_display(crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum pipe pipe = crtc->pipe;
i915_reg_t reg;
@@ -334,7 +329,7 @@ static void ilk_disable_pch_transcoder(struct intel_crtc *crtc)
drm_err(display->drm, "failed to disable transcoder %c\n",
pipe_name(pipe));
if (HAS_PCH_CPT(dev_priv))
if (HAS_PCH_CPT(display))
/* Workaround: Clear the timing override chicken bit again. */
intel_de_rmw(display, TRANS_CHICKEN2(pipe),
TRANS_CHICKEN2_TIMING_OVERRIDE, 0);
@@ -366,7 +361,6 @@ void ilk_pch_enable(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
struct intel_display *display = to_intel_display(crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
const struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
enum pipe pipe = crtc->pipe;
@@ -381,7 +375,7 @@ void ilk_pch_enable(struct intel_atomic_state *state,
* We need to program the right clock selection
* before writing the pixel multiplier into the DPLL.
*/
if (HAS_PCH_CPT(dev_priv)) {
if (HAS_PCH_CPT(display)) {
u32 sel;
temp = intel_de_read(display, PCH_DPLL_SEL);
@@ -417,7 +411,7 @@ void ilk_pch_enable(struct intel_atomic_state *state,
intel_fdi_normal_train(crtc);
/* For PCH DP, enable TRANS_DP_CTL */
if (HAS_PCH_CPT(dev_priv) &&
if (HAS_PCH_CPT(display) &&
intel_crtc_has_dp_encoder(crtc_state)) {
const struct drm_display_mode *adjusted_mode =
&crtc_state->hw.adjusted_mode;
@@ -459,14 +453,13 @@ void ilk_pch_post_disable(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
struct intel_display *display = to_intel_display(crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
const struct intel_crtc_state *old_crtc_state =
intel_atomic_get_old_crtc_state(state, crtc);
enum pipe pipe = crtc->pipe;
ilk_disable_pch_transcoder(crtc);
if (HAS_PCH_CPT(dev_priv)) {
if (HAS_PCH_CPT(display)) {
/* disable TRANS_DP_CTL */
intel_de_rmw(display, TRANS_DP_CTL(pipe),
TRANS_DP_OUTPUT_ENABLE | TRANS_DP_PORT_SEL_MASK,
@@ -503,7 +496,6 @@ void ilk_pch_get_config(struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
struct intel_shared_dpll *pll;
enum pipe pipe = crtc->pipe;
enum intel_dpll_id pll_id;
@@ -522,7 +514,7 @@ void ilk_pch_get_config(struct intel_crtc_state *crtc_state)
intel_cpu_transcoder_get_m1_n1(crtc, crtc_state->cpu_transcoder,
&crtc_state->fdi_m_n);
if (HAS_PCH_IBX(dev_priv)) {
if (HAS_PCH_IBX(display)) {
/*
* The pipe->pch transcoder and pch transcoder->pll
* mapping is fixed.
@@ -646,8 +638,6 @@ void lpt_pch_get_config(struct intel_crtc_state *crtc_state)
void intel_pch_sanitize(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
if (HAS_PCH_IBX(i915))
if (HAS_PCH_IBX(display))
ibx_sanitize_pch_ports(display);
}

View File

@@ -281,7 +281,7 @@ static void lpt_enable_clkout_dp(struct intel_display *display,
if (drm_WARN(display->drm, with_fdi && !with_spread,
"FDI requires downspread\n"))
with_spread = true;
if (drm_WARN(display->drm, HAS_PCH_LPT_LP(dev_priv) &&
if (drm_WARN(display->drm, HAS_PCH_LPT_LP(display) &&
with_fdi, "LP PCH doesn't have FDI\n"))
with_fdi = false;
@@ -303,7 +303,7 @@ static void lpt_enable_clkout_dp(struct intel_display *display,
lpt_fdi_program_mphy(display);
}
reg = HAS_PCH_LPT_LP(dev_priv) ? SBI_GEN0 : SBI_DBUFF0;
reg = HAS_PCH_LPT_LP(display) ? SBI_GEN0 : SBI_DBUFF0;
tmp = intel_sbi_read(dev_priv, reg, SBI_ICLK);
tmp |= SBI_GEN0_CFG_BUFFENABLE_DISABLE;
intel_sbi_write(dev_priv, reg, tmp, SBI_ICLK);
@@ -319,7 +319,7 @@ void lpt_disable_clkout_dp(struct intel_display *display)
intel_sbi_lock(dev_priv);
reg = HAS_PCH_LPT_LP(dev_priv) ? SBI_GEN0 : SBI_DBUFF0;
reg = HAS_PCH_LPT_LP(display) ? SBI_GEN0 : SBI_DBUFF0;
tmp = intel_sbi_read(dev_priv, reg, SBI_ICLK);
tmp &= ~SBI_GEN0_CFG_BUFFENABLE_DISABLE;
intel_sbi_write(dev_priv, reg, tmp, SBI_ICLK);
@@ -498,7 +498,6 @@ static void lpt_init_pch_refclk(struct intel_display *display)
static void ilk_init_pch_refclk(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
struct intel_encoder *encoder;
struct intel_shared_dpll *pll;
int i;
@@ -527,7 +526,7 @@ static void ilk_init_pch_refclk(struct intel_display *display)
}
}
if (HAS_PCH_IBX(dev_priv)) {
if (HAS_PCH_IBX(display)) {
has_ck505 = display->vbt.display_clock_mode;
can_ssc = has_ck505;
} else {
@@ -678,10 +677,8 @@ static void ilk_init_pch_refclk(struct intel_display *display)
*/
void intel_init_pch_refclk(struct intel_display *display)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
if (HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv))
if (HAS_PCH_IBX(display) || HAS_PCH_CPT(display))
ilk_init_pch_refclk(display);
else if (HAS_PCH_LPT(dev_priv))
else if (HAS_PCH_LPT(display))
lpt_init_pch_refclk(display);
}

View File

@@ -53,9 +53,11 @@ intel_reuse_initial_plane_obj(struct intel_crtc *this,
}
static enum intel_memory_type
initial_plane_memory_type(struct drm_i915_private *i915)
initial_plane_memory_type(struct intel_display *display)
{
if (IS_DGFX(i915))
struct drm_i915_private *i915 = to_i915(display->drm);
if (display->platform.dgfx)
return INTEL_MEMORY_LOCAL;
else if (HAS_LMEMBAR_SMEM_STOLEN(i915))
return INTEL_MEMORY_STOLEN_LOCAL;
@@ -75,7 +77,7 @@ initial_plane_phys(struct intel_display *display,
dma_addr_t dma_addr;
u32 base;
mem_type = initial_plane_memory_type(i915);
mem_type = initial_plane_memory_type(display);
mem = intel_memory_region_by_type(i915, mem_type);
if (!mem) {
drm_dbg_kms(display->drm,

View File

@@ -478,13 +478,34 @@ static bool intel_pmdemand_req_complete(struct intel_display *display)
XELPDP_PMDEMAND_REQ_ENABLE);
}
static void intel_pmdemand_poll(struct intel_display *display)
{
const unsigned int timeout_ms = 10;
u32 status;
int ret;
ret = intel_de_wait_custom(display, XELPDP_INITIATE_PMDEMAND_REQUEST(1),
XELPDP_PMDEMAND_REQ_ENABLE, 0,
50, timeout_ms, &status);
if (ret == -ETIMEDOUT)
drm_err(display->drm,
"timed out waiting for Punit PM Demand Response within %ums (status 0x%08x)\n",
timeout_ms, status);
}
static void intel_pmdemand_wait(struct intel_display *display)
{
if (!wait_event_timeout(display->pmdemand.waitqueue,
intel_pmdemand_req_complete(display),
msecs_to_jiffies_timeout(10)))
drm_err(display->drm,
"timed out waiting for Punit PM Demand Response\n");
/* Wa_14024400148 For lnl use polling method */
if (DISPLAY_VER(display) == 20) {
intel_pmdemand_poll(display);
} else {
if (!wait_event_timeout(display->pmdemand.waitqueue,
intel_pmdemand_req_complete(display),
msecs_to_jiffies_timeout(10)))
drm_err(display->drm,
"timed out waiting for Punit PM Demand Response\n");
}
}
/* Required to be programmed during Display Init Sequences. */

View File

@@ -350,21 +350,19 @@ vlv_initial_power_sequencer_setup(struct intel_dp *intel_dp)
static int intel_num_pps(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
if (display->platform.valleyview || display->platform.cherryview)
return 2;
if (display->platform.geminilake || display->platform.broxton)
return 2;
if (INTEL_PCH_TYPE(i915) >= PCH_MTL)
if (INTEL_PCH_TYPE(display) >= PCH_MTL)
return 2;
if (INTEL_PCH_TYPE(i915) >= PCH_DG1)
if (INTEL_PCH_TYPE(display) >= PCH_DG1)
return 1;
if (INTEL_PCH_TYPE(i915) >= PCH_ICP)
if (INTEL_PCH_TYPE(display) >= PCH_ICP)
return 2;
return 1;
@@ -373,11 +371,10 @@ static int intel_num_pps(struct intel_display *display)
static bool intel_pps_is_valid(struct intel_dp *intel_dp)
{
struct intel_display *display = to_intel_display(intel_dp);
struct drm_i915_private *i915 = to_i915(display->drm);
if (intel_dp->pps.pps_idx == 1 &&
INTEL_PCH_TYPE(i915) >= PCH_ICP &&
INTEL_PCH_TYPE(i915) <= PCH_ADP)
INTEL_PCH_TYPE(display) >= PCH_ICP &&
INTEL_PCH_TYPE(display) <= PCH_ADP)
return intel_de_read(display, SOUTH_CHICKEN1) & ICP_SECOND_PPS_IO_SELECT;
return true;
@@ -499,7 +496,6 @@ static void intel_pps_get_registers(struct intel_dp *intel_dp,
struct pps_registers *regs)
{
struct intel_display *display = to_intel_display(intel_dp);
struct drm_i915_private *dev_priv = to_i915(display->drm);
int pps_idx;
memset(regs, 0, sizeof(*regs));
@@ -518,7 +514,7 @@ static void intel_pps_get_registers(struct intel_dp *intel_dp,
/* Cycle delay moved from PP_DIVISOR to PP_CONTROL */
if (display->platform.geminilake || display->platform.broxton ||
INTEL_PCH_TYPE(dev_priv) >= PCH_CNP)
INTEL_PCH_TYPE(display) >= PCH_CNP)
regs->pp_div = INVALID_MMIO_REG;
else
regs->pp_div = PP_DIVISOR(display, pps_idx);
@@ -1591,7 +1587,6 @@ static void pps_init_delays(struct intel_dp *intel_dp)
static void pps_init_registers(struct intel_dp *intel_dp, bool force_disable_vdd)
{
struct intel_display *display = to_intel_display(intel_dp);
struct drm_i915_private *dev_priv = to_i915(display->drm);
u32 pp_on, pp_off, port_sel = 0;
int div = DISPLAY_RUNTIME_INFO(display)->rawclk_freq / 1000;
struct pps_registers regs;
@@ -1638,7 +1633,7 @@ static void pps_init_registers(struct intel_dp *intel_dp, bool force_disable_vdd
* power sequencer any more. */
if (display->platform.valleyview || display->platform.cherryview) {
port_sel = PANEL_PORT_SELECT_VLV(port);
} else if (HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv)) {
} else if (HAS_PCH_IBX(display) || HAS_PCH_CPT(display)) {
switch (port) {
case PORT_A:
port_sel = PANEL_PORT_SELECT_DPA;
@@ -1791,9 +1786,7 @@ void intel_pps_unlock_regs_wa(struct intel_display *display)
void intel_pps_setup(struct intel_display *display)
{
struct drm_i915_private *i915 = to_i915(display->drm);
if (HAS_PCH_SPLIT(i915) || display->platform.geminilake || display->platform.broxton)
if (HAS_PCH_SPLIT(display) || display->platform.geminilake || display->platform.broxton)
display->pps.mmio_base = PCH_PPS_BASE;
else if (display->platform.valleyview || display->platform.cherryview)
display->pps.mmio_base = VLV_PPS_BASE;
@@ -1836,7 +1829,6 @@ void intel_pps_connector_debugfs_add(struct intel_connector *connector)
void assert_pps_unlocked(struct intel_display *display, enum pipe pipe)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
i915_reg_t pp_reg;
u32 val;
enum pipe panel_pipe = INVALID_PIPE;
@@ -1845,7 +1837,7 @@ void assert_pps_unlocked(struct intel_display *display, enum pipe pipe)
if (drm_WARN_ON(display->drm, HAS_DDI(display)))
return;
if (HAS_PCH_SPLIT(dev_priv)) {
if (HAS_PCH_SPLIT(display)) {
u32 port_sel;
pp_reg = PP_CONTROL(display, 0);

View File

@@ -26,6 +26,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_damage_helper.h>
#include <drm/drm_debugfs.h>
#include <drm/drm_vblank.h>
#include "i915_drv.h"
#include "i915_reg.h"
@@ -38,6 +39,7 @@
#include "intel_display_irq.h"
#include "intel_display_rpm.h"
#include "intel_display_types.h"
#include "intel_dmc.h"
#include "intel_dp.h"
#include "intel_dp_aux.h"
#include "intel_frontbuffer.h"
@@ -46,6 +48,7 @@
#include "intel_psr_regs.h"
#include "intel_snps_phy.h"
#include "intel_vblank.h"
#include "intel_vrr.h"
#include "skl_universal_plane.h"
/**
@@ -794,32 +797,9 @@ static void _psr_enable_sink(struct intel_dp *intel_dp,
drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, val);
}
static void intel_psr_enable_sink_alpm(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{
u8 val;
/*
* eDP Panel Replay uses always ALPM
* PSR2 uses ALPM but PSR1 doesn't
*/
if (!intel_dp_is_edp(intel_dp) || (!crtc_state->has_panel_replay &&
!crtc_state->has_sel_update))
return;
val = DP_ALPM_ENABLE | DP_ALPM_LOCK_ERROR_IRQ_HPD_ENABLE;
if (crtc_state->has_panel_replay)
val |= DP_ALPM_MODE_AUX_LESS;
drm_dp_dpcd_writeb(&intel_dp->aux, DP_RECEIVER_ALPM_CONFIG, val);
}
static void intel_psr_enable_sink(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{
intel_psr_enable_sink_alpm(intel_dp, crtc_state);
crtc_state->has_panel_replay ?
_panel_replay_enable_sink(intel_dp, crtc_state) :
_psr_enable_sink(intel_dp, crtc_state);
@@ -905,6 +885,18 @@ static u8 psr_compute_idle_frames(struct intel_dp *intel_dp)
return idle_frames;
}
static bool is_dc5_dc6_blocked(struct intel_dp *intel_dp)
{
struct intel_display *display = to_intel_display(intel_dp);
u32 current_dc_state = intel_display_power_get_current_dc_state(display);
struct drm_vblank_crtc *vblank = &display->drm->vblank[intel_dp->psr.pipe];
return (current_dc_state != DC_STATE_EN_UPTO_DC5 &&
current_dc_state != DC_STATE_EN_UPTO_DC6) ||
intel_dp->psr.active_non_psr_pipes ||
READ_ONCE(vblank->enabled);
}
static void hsw_activate_psr1(struct intel_dp *intel_dp)
{
struct intel_display *display = to_intel_display(intel_dp);
@@ -933,6 +925,14 @@ static void hsw_activate_psr1(struct intel_dp *intel_dp)
intel_de_rmw(display, psr_ctl_reg(display, cpu_transcoder),
~EDP_PSR_RESTORE_PSR_ACTIVE_CTX_MASK, val);
/* Wa_16025596647 */
if ((DISPLAY_VER(display) == 20 ||
IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0)) &&
is_dc5_dc6_blocked(intel_dp))
intel_dmc_start_pkgc_exit_at_start_of_undelayed_vblank(display,
intel_dp->psr.pipe,
true);
}
static u32 intel_psr2_get_tp_time(struct intel_dp *intel_dp)
@@ -1014,8 +1014,16 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
u32 val = EDP_PSR2_ENABLE;
u32 psr_val = 0;
u8 idle_frames;
val |= EDP_PSR2_IDLE_FRAMES(psr_compute_idle_frames(intel_dp));
/* Wa_16025596647 */
if ((DISPLAY_VER(display) == 20 ||
IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0)) &&
is_dc5_dc6_blocked(intel_dp))
idle_frames = 0;
else
idle_frames = psr_compute_idle_frames(intel_dp);
val |= EDP_PSR2_IDLE_FRAMES(idle_frames);
if (DISPLAY_VER(display) < 14 && !display->platform.alderlake_p)
val |= EDP_SU_TRACK_ENABLE;
@@ -1649,6 +1657,9 @@ void intel_psr_compute_config(struct intel_dp *intel_dp,
{
struct intel_display *display = to_intel_display(intel_dp);
const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->uapi.state);
struct intel_crtc *crtc;
u8 active_pipes = 0;
if (!psr_global_enabled(intel_dp)) {
drm_dbg_kms(display->drm, "PSR disabled by flag\n");
@@ -1702,6 +1713,24 @@ void intel_psr_compute_config(struct intel_dp *intel_dp,
drm_dbg_kms(display->drm,
"PSR disabled to workaround PSR FSM hang issue\n");
}
/* Rest is for Wa_16025596647 */
if (DISPLAY_VER(display) != 20 &&
!IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0))
return;
/* Not needed by Panel Replay */
if (crtc_state->has_panel_replay)
return;
/* We ignore possible secondary PSR/Panel Replay capable eDP */
for_each_intel_crtc(display->drm, crtc)
active_pipes |= crtc->active ? BIT(crtc->pipe) : 0;
active_pipes = intel_calc_active_pipes(state, active_pipes);
crtc_state->active_non_psr_pipes = active_pipes &
~BIT(to_intel_crtc(crtc_state->uapi.crtc)->pipe);
}
void intel_psr_get_config(struct intel_encoder *encoder,
@@ -1893,9 +1922,6 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp,
intel_dp->psr.psr2_sel_fetch_enabled ?
IGNORE_PSR2_HW_TRACKING : 0);
if (intel_dp_is_edp(intel_dp))
intel_alpm_configure(intel_dp, crtc_state);
/*
* Wa_16013835468
* Wa_14015648006
@@ -1930,6 +1956,12 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp,
intel_de_rmw(display, CLKGATE_DIS_MISC, 0,
CLKGATE_DIS_MISC_DMASC_GATING_DIS);
}
/* Wa_16025596647 */
if ((DISPLAY_VER(display) == 20 ||
IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0)) &&
!intel_dp->psr.panel_replay_enabled)
intel_dmc_block_pkgc(display, intel_dp->psr.pipe, true);
}
static bool psr_interrupt_error_check(struct intel_dp *intel_dp)
@@ -1985,6 +2017,7 @@ static void intel_psr_enable_locked(struct intel_dp *intel_dp,
intel_dp->psr.psr2_sel_fetch_cff_enabled = false;
intel_dp->psr.req_psr2_sdp_prior_scanline =
crtc_state->req_psr2_sdp_prior_scanline;
intel_dp->psr.active_non_psr_pipes = crtc_state->active_non_psr_pipes;
if (!psr_interrupt_error_check(intel_dp))
return;
@@ -2060,6 +2093,12 @@ static void intel_psr_exit(struct intel_dp *intel_dp)
drm_WARN_ON(display->drm, !(val & EDP_PSR2_ENABLE));
} else {
if (DISPLAY_VER(display) == 20 ||
IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0))
intel_dmc_start_pkgc_exit_at_start_of_undelayed_vblank(display,
intel_dp->psr.pipe,
false);
val = intel_de_rmw(display,
psr_ctl_reg(display, cpu_transcoder),
EDP_PSR_ENABLE, 0);
@@ -2133,17 +2172,6 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp)
if (intel_dp_is_edp(intel_dp))
intel_snps_phy_update_psr_power_state(&dp_to_dig_port(intel_dp)->base, false);
/* Panel Replay on eDP is always using ALPM aux less. */
if (intel_dp->psr.panel_replay_enabled && intel_dp_is_edp(intel_dp)) {
intel_de_rmw(display, ALPM_CTL(display, cpu_transcoder),
ALPM_CTL_ALPM_ENABLE |
ALPM_CTL_ALPM_AUX_LESS_ENABLE, 0);
intel_de_rmw(display,
PORT_ALPM_CTL(cpu_transcoder),
PORT_ALPM_CTL_ALPM_AUX_LESS_ENABLE, 0);
}
/* Disable PSR on Sink */
if (!intel_dp->psr.panel_replay_enabled) {
drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, 0);
@@ -2153,12 +2181,19 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp)
DP_RECEIVER_ALPM_CONFIG, 0);
}
/* Wa_16025596647 */
if ((DISPLAY_VER(display) == 20 ||
IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0)) &&
!intel_dp->psr.panel_replay_enabled)
intel_dmc_block_pkgc(display, intel_dp->psr.pipe, false);
intel_dp->psr.enabled = false;
intel_dp->psr.panel_replay_enabled = false;
intel_dp->psr.sel_update_enabled = false;
intel_dp->psr.psr2_sel_fetch_enabled = false;
intel_dp->psr.su_region_et_enabled = false;
intel_dp->psr.psr2_sel_fetch_cff_enabled = false;
intel_dp->psr.active_non_psr_pipes = 0;
}
/**
@@ -2254,17 +2289,20 @@ out:
}
/**
* intel_psr_needs_block_dc_vblank - Check if block dc entry is needed
* intel_psr_needs_vblank_notification - Check if PSR need vblank enable/disable
* notification.
* @crtc_state: CRTC status
*
* We need to block DC6 entry in case of Panel Replay as enabling VBI doesn't
* prevent it in case of Panel Replay. Panel Replay switches main link off on
* DC entry. This means vblank interrupts are not fired and is a problem if
* user-space is polling for vblank events.
* user-space is polling for vblank events. Also Wa_16025596647 needs
* information when vblank is enabled/disabled.
*/
bool intel_psr_needs_block_dc_vblank(const struct intel_crtc_state *crtc_state)
bool intel_psr_needs_vblank_notification(const struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct intel_display *display = to_intel_display(crtc_state);
struct intel_encoder *encoder;
for_each_encoder_on_crtc(crtc->base.dev, &crtc->base, encoder) {
@@ -2275,8 +2313,15 @@ bool intel_psr_needs_block_dc_vblank(const struct intel_crtc_state *crtc_state)
intel_dp = enc_to_intel_dp(encoder);
if (intel_dp_is_edp(intel_dp) &&
CAN_PANEL_REPLAY(intel_dp))
if (!intel_dp_is_edp(intel_dp))
continue;
if (CAN_PANEL_REPLAY(intel_dp))
return true;
if ((DISPLAY_VER(display) == 20 ||
IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0)) &&
CAN_PSR(intel_dp))
return true;
}
@@ -2304,6 +2349,53 @@ void intel_psr_trigger_frame_change_event(struct intel_dsb *dsb,
CURSURFLIVE(display, crtc->pipe), 0);
}
/**
* intel_psr_min_vblank_delay - Minimum vblank delay needed by PSR
* @crtc_state: the crtc state
*
* Return minimum vblank delay needed by PSR.
*/
int intel_psr_min_vblank_delay(const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
if (!crtc_state->has_psr)
return 0;
/* Wa_14015401596 */
if (intel_vrr_possible(crtc_state) && IS_DISPLAY_VER(display, 13, 14))
return 1;
/* Rest is for SRD_STATUS needed on LunarLake and onwards */
if (DISPLAY_VER(display) < 20)
return 0;
/*
* Comment on SRD_STATUS register in Bspec for LunarLake and onwards:
*
* To deterministically capture the transition of the state machine
* going from SRDOFFACK to IDLE, the delayed V. Blank should be at least
* one line after the non-delayed V. Blank.
*
* Legacy TG: TRANS_SET_CONTEXT_LATENCY > 0
* VRR TG: TRANS_VRR_CTL[ VRR Guardband ] < (TRANS_VRR_VMAX[ VRR Vmax ]
* - TRANS_VTOTAL[ Vertical Active ])
*
* SRD_STATUS is used only by PSR1 on PantherLake.
* SRD_STATUS is used by PSR1 and Panel Replay DP on LunarLake.
*/
if (DISPLAY_VER(display) >= 30 && (crtc_state->has_panel_replay ||
crtc_state->has_sel_update))
return 0;
else if (DISPLAY_VER(display) < 30 && (crtc_state->has_sel_update ||
intel_crtc_has_type(crtc_state,
INTEL_OUTPUT_EDP)))
return 0;
else
return 1;
}
static u32 man_trk_ctl_enable_bit_get(struct intel_display *display)
{
return display->platform.alderlake_p || DISPLAY_VER(display) >= 14 ? 0 :
@@ -3398,29 +3490,15 @@ static int psr_get_status_and_error_status(struct intel_dp *intel_dp,
static void psr_alpm_check(struct intel_dp *intel_dp)
{
struct intel_display *display = to_intel_display(intel_dp);
struct drm_dp_aux *aux = &intel_dp->aux;
struct intel_psr *psr = &intel_dp->psr;
u8 val;
int r;
if (!psr->sel_update_enabled)
return;
r = drm_dp_dpcd_readb(aux, DP_RECEIVER_ALPM_STATUS, &val);
if (r != 1) {
drm_err(display->drm, "Error reading ALPM status\n");
return;
}
if (val & DP_ALPM_LOCK_TIMEOUT_ERROR) {
if (intel_alpm_get_error(intel_dp)) {
intel_psr_disable_locked(intel_dp);
psr->sink_not_reliable = true;
drm_dbg_kms(display->drm,
"ALPM lock timeout error, disabling PSR\n");
/* Clearing error */
drm_dp_dpcd_writeb(aux, DP_RECEIVER_ALPM_STATUS, val);
intel_alpm_disable(intel_dp);
}
}
@@ -3605,6 +3683,168 @@ void intel_psr_unlock(const struct intel_crtc_state *crtc_state)
}
}
/* Wa_16025596647 */
static void intel_psr_apply_underrun_on_idle_wa_locked(struct intel_dp *intel_dp)
{
struct intel_display *display = to_intel_display(intel_dp);
bool dc5_dc6_blocked;
if (!intel_dp->psr.active)
return;
dc5_dc6_blocked = is_dc5_dc6_blocked(intel_dp);
if (intel_dp->psr.sel_update_enabled)
psr2_program_idle_frames(intel_dp, dc5_dc6_blocked ? 0 :
psr_compute_idle_frames(intel_dp));
else
intel_dmc_start_pkgc_exit_at_start_of_undelayed_vblank(display,
intel_dp->psr.pipe,
dc5_dc6_blocked);
}
static void psr_dc5_dc6_wa_work(struct work_struct *work)
{
struct intel_display *display = container_of(work, typeof(*display),
psr_dc5_dc6_wa_work);
struct intel_encoder *encoder;
for_each_intel_encoder_with_psr(display->drm, encoder) {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
mutex_lock(&intel_dp->psr.lock);
if (intel_dp->psr.enabled && !intel_dp->psr.panel_replay_enabled)
intel_psr_apply_underrun_on_idle_wa_locked(intel_dp);
mutex_unlock(&intel_dp->psr.lock);
}
}
/**
* intel_psr_notify_dc5_dc6 - Notify PSR about enable/disable dc5/dc6
* @display: intel atomic state
*
* This is targeted for underrun on idle PSR HW bug (Wa_16025596647) to schedule
* psr_dc5_dc6_wa_work used for applying/removing the workaround.
*/
void intel_psr_notify_dc5_dc6(struct intel_display *display)
{
if (DISPLAY_VER(display) != 20 &&
!IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0))
return;
schedule_work(&display->psr_dc5_dc6_wa_work);
}
/**
* intel_psr_dc5_dc6_wa_init - Init work for underrun on idle PSR HW bug wa
* @display: intel atomic state
*
* This is targeted for underrun on idle PSR HW bug (Wa_16025596647) to init
* psr_dc5_dc6_wa_work used for applying the workaround.
*/
void intel_psr_dc5_dc6_wa_init(struct intel_display *display)
{
if (DISPLAY_VER(display) != 20 &&
!IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0))
return;
INIT_WORK(&display->psr_dc5_dc6_wa_work, psr_dc5_dc6_wa_work);
}
/**
* intel_psr_notify_pipe_change - Notify PSR about enable/disable of a pipe
* @state: intel atomic state
* @crtc: intel crtc
* @enable: enable/disable
*
* This is targeted for underrun on idle PSR HW bug (Wa_16025596647) to apply
* remove the workaround when pipe is getting enabled/disabled
*/
void intel_psr_notify_pipe_change(struct intel_atomic_state *state,
struct intel_crtc *crtc, bool enable)
{
struct intel_display *display = to_intel_display(state);
struct intel_encoder *encoder;
if (DISPLAY_VER(display) != 20 &&
!IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0))
return;
for_each_intel_encoder_with_psr(display->drm, encoder) {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
u8 active_non_psr_pipes;
mutex_lock(&intel_dp->psr.lock);
if (!intel_dp->psr.enabled || intel_dp->psr.panel_replay_enabled)
goto unlock;
active_non_psr_pipes = intel_dp->psr.active_non_psr_pipes;
if (enable)
active_non_psr_pipes |= BIT(crtc->pipe);
else
active_non_psr_pipes &= ~BIT(crtc->pipe);
if (active_non_psr_pipes == intel_dp->psr.active_non_psr_pipes)
goto unlock;
if ((enable && intel_dp->psr.active_non_psr_pipes) ||
(!enable && !intel_dp->psr.active_non_psr_pipes)) {
intel_dp->psr.active_non_psr_pipes = active_non_psr_pipes;
goto unlock;
}
intel_dp->psr.active_non_psr_pipes = active_non_psr_pipes;
intel_psr_apply_underrun_on_idle_wa_locked(intel_dp);
unlock:
mutex_unlock(&intel_dp->psr.lock);
}
}
/**
* intel_psr_notify_vblank_enable_disable - Notify PSR about enable/disable of vblank
* @display: intel display struct
* @enable: enable/disable
*
* This is targeted for underrun on idle PSR HW bug (Wa_16025596647) to apply
* remove the workaround when vblank is getting enabled/disabled
*/
void intel_psr_notify_vblank_enable_disable(struct intel_display *display,
bool enable)
{
struct intel_encoder *encoder;
for_each_intel_encoder_with_psr(display->drm, encoder) {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
mutex_lock(&intel_dp->psr.lock);
if (intel_dp->psr.panel_replay_enabled) {
mutex_unlock(&intel_dp->psr.lock);
break;
}
if (intel_dp->psr.enabled)
intel_psr_apply_underrun_on_idle_wa_locked(intel_dp);
mutex_unlock(&intel_dp->psr.lock);
return;
}
/*
* NOTE: intel_display_power_set_target_dc_state is used
* only by PSR * code for DC3CO handling. DC3CO target
* state is currently disabled in * PSR code. If DC3CO
* is taken into use we need take that into account here
* as well.
*/
intel_display_power_set_target_dc_state(display, enable ? DC_STATE_DISABLE :
DC_STATE_EN_UPTO_DC6);
}
static void
psr_source_status(struct intel_dp *intel_dp, struct seq_file *m)
{
@@ -3977,3 +4217,13 @@ void intel_psr_connector_debugfs_add(struct intel_connector *connector)
debugfs_create_file("i915_psr_status", 0444, root,
connector, &i915_psr_status_fops);
}
bool intel_psr_needs_alpm(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state)
{
/*
* eDP Panel Replay uses always ALPM
* PSR2 uses ALPM but PSR1 doesn't
*/
return intel_dp_is_edp(intel_dp) && (crtc_state->has_sel_update ||
crtc_state->has_panel_replay);
}

View File

@@ -59,7 +59,13 @@ void intel_psr2_program_trans_man_trk_ctl(struct intel_dsb *dsb,
const struct intel_crtc_state *crtc_state);
void intel_psr_pause(struct intel_dp *intel_dp);
void intel_psr_resume(struct intel_dp *intel_dp);
bool intel_psr_needs_block_dc_vblank(const struct intel_crtc_state *crtc_state);
bool intel_psr_needs_vblank_notification(const struct intel_crtc_state *crtc_state);
void intel_psr_notify_pipe_change(struct intel_atomic_state *state,
struct intel_crtc *crtc, bool enable);
void intel_psr_notify_dc5_dc6(struct intel_display *display);
void intel_psr_dc5_dc6_wa_init(struct intel_display *display);
void intel_psr_notify_vblank_enable_disable(struct intel_display *display,
bool enable);
bool intel_psr_link_ok(struct intel_dp *intel_dp);
void intel_psr_lock(const struct intel_crtc_state *crtc_state);
@@ -67,7 +73,9 @@ void intel_psr_unlock(const struct intel_crtc_state *crtc_state);
void intel_psr_trigger_frame_change_event(struct intel_dsb *dsb,
struct intel_atomic_state *state,
struct intel_crtc *crtc);
int intel_psr_min_vblank_delay(const struct intel_crtc_state *crtc_state);
void intel_psr_connector_debugfs_add(struct intel_connector *connector);
void intel_psr_debugfs_register(struct intel_display *display);
bool intel_psr_needs_alpm(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state);
#endif /* __INTEL_PSR_H__ */

View File

@@ -36,9 +36,9 @@
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
#include <drm/drm_eld.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
#include "i915_drv.h"
#include "i915_reg.h"
#include "intel_atomic.h"
#include "intel_audio.h"
@@ -214,18 +214,17 @@ intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo,
static void intel_sdvo_write_sdvox(struct intel_sdvo *intel_sdvo, u32 val)
{
struct intel_display *display = to_intel_display(&intel_sdvo->base);
struct drm_i915_private *dev_priv = to_i915(display->drm);
u32 bval = val, cval = val;
int i;
if (HAS_PCH_SPLIT(dev_priv)) {
if (HAS_PCH_SPLIT(display)) {
intel_de_write(display, intel_sdvo->sdvo_reg, val);
intel_de_posting_read(display, intel_sdvo->sdvo_reg);
/*
* HW workaround, need to write this twice for issue
* that may result in first write getting masked.
*/
if (HAS_PCH_IBX(dev_priv)) {
if (HAS_PCH_IBX(display)) {
intel_de_write(display, intel_sdvo->sdvo_reg, val);
intel_de_posting_read(display, intel_sdvo->sdvo_reg);
}
@@ -1360,14 +1359,13 @@ static int intel_sdvo_compute_config(struct intel_encoder *encoder,
struct drm_connector_state *conn_state)
{
struct intel_display *display = to_intel_display(encoder);
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
struct intel_sdvo *intel_sdvo = to_sdvo(encoder);
struct intel_sdvo_connector *intel_sdvo_connector =
to_intel_sdvo_connector(conn_state->connector);
struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
struct drm_display_mode *mode = &pipe_config->hw.mode;
if (HAS_PCH_SPLIT(i915)) {
if (HAS_PCH_SPLIT(display)) {
pipe_config->has_pch_encoder = true;
if (!intel_fdi_compute_pipe_bpp(pipe_config))
return -EINVAL;
@@ -1527,7 +1525,6 @@ static void intel_sdvo_pre_enable(struct intel_atomic_state *state,
const struct drm_connector_state *conn_state)
{
struct intel_display *display = to_intel_display(intel_encoder);
struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
const struct intel_sdvo_connector_state *sdvo_state =
@@ -1634,7 +1631,7 @@ static void intel_sdvo_pre_enable(struct intel_atomic_state *state,
sdvox |= (9 << 19) | SDVO_BORDER_ENABLE;
}
if (HAS_PCH_CPT(dev_priv))
if (HAS_PCH_CPT(display))
sdvox |= SDVO_PIPE_SEL_CPT(crtc->pipe);
else
sdvox |= SDVO_PIPE_SEL(crtc->pipe);
@@ -1670,13 +1667,12 @@ static bool intel_sdvo_connector_get_hw_state(struct intel_connector *connector)
bool intel_sdvo_port_enabled(struct intel_display *display,
i915_reg_t sdvo_reg, enum pipe *pipe)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
u32 val;
val = intel_de_read(display, sdvo_reg);
/* asserts want to know the pipe even if the port is disabled */
if (HAS_PCH_CPT(dev_priv))
if (HAS_PCH_CPT(display))
*pipe = (val & SDVO_PIPE_SEL_MASK_CPT) >> SDVO_PIPE_SEL_SHIFT_CPT;
else if (display->platform.cherryview)
*pipe = (val & SDVO_PIPE_SEL_MASK_CHV) >> SDVO_PIPE_SEL_SHIFT_CHV;
@@ -1841,7 +1837,6 @@ static void intel_disable_sdvo(struct intel_atomic_state *state,
const struct drm_connector_state *conn_state)
{
struct intel_display *display = to_intel_display(encoder);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_sdvo *intel_sdvo = to_sdvo(encoder);
struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
u32 temp;
@@ -1861,7 +1856,7 @@ static void intel_disable_sdvo(struct intel_atomic_state *state,
* to transcoder A after disabling it to allow the
* matching DP port to be enabled on transcoder A.
*/
if (HAS_PCH_IBX(dev_priv) && crtc->pipe == PIPE_B) {
if (HAS_PCH_IBX(display) && crtc->pipe == PIPE_B) {
/*
* We get CPU/PCH FIFO underruns on the other pipe when
* doing the workaround. Sweep them under the rug.
@@ -3367,9 +3362,7 @@ intel_sdvo_init_ddc_proxy(struct intel_sdvo_ddc *ddc,
static bool is_sdvo_port_valid(struct intel_display *display, enum port port)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
if (HAS_PCH_SPLIT(dev_priv))
if (HAS_PCH_SPLIT(display))
return port == PORT_B;
else
return port == PORT_B || port == PORT_C;
@@ -3384,7 +3377,6 @@ static bool assert_sdvo_port_valid(struct intel_display *display, enum port port
bool intel_sdvo_init(struct intel_display *display,
i915_reg_t sdvo_reg, enum port port)
{
struct drm_i915_private *dev_priv = to_i915(display->drm);
struct intel_encoder *intel_encoder;
struct intel_sdvo *intel_sdvo;
int i;
@@ -3427,7 +3419,7 @@ bool intel_sdvo_init(struct intel_display *display,
}
intel_encoder->compute_config = intel_sdvo_compute_config;
if (HAS_PCH_SPLIT(dev_priv)) {
if (HAS_PCH_SPLIT(display)) {
intel_encoder->disable = pch_disable_sdvo;
intel_encoder->post_disable = pch_post_disable_sdvo;
} else {

View File

@@ -36,9 +36,10 @@
#include <drm/drm_blend.h>
#include <drm/drm_color_mgmt.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_print.h>
#include <drm/drm_rect.h>
#include "i915_drv.h"
#include "i915_utils.h"
#include "i9xx_plane.h"
#include "intel_atomic_plane.h"
#include "intel_de.h"

View File

@@ -3,21 +3,21 @@
* Copyright © 2023 Intel Corporation
*/
#include "i915_drv.h"
#include "intel_crtc.h"
#include "intel_display_core.h"
#include "intel_display_types.h"
#include "intel_sprite_uapi.h"
static bool has_dst_key_in_primary_plane(struct drm_i915_private *dev_priv)
static bool has_dst_key_in_primary_plane(struct intel_display *display)
{
return DISPLAY_VER(dev_priv) >= 9;
return DISPLAY_VER(display) >= 9;
}
static void intel_plane_set_ckey(struct intel_plane_state *plane_state,
const struct drm_intel_sprite_colorkey *set)
{
struct intel_display *display = to_intel_display(plane_state);
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
*key = *set;
@@ -34,7 +34,7 @@ static void intel_plane_set_ckey(struct intel_plane_state *plane_state,
* On SKL+ we want dst key enabled on
* the primary and not on the sprite.
*/
if (DISPLAY_VER(dev_priv) >= 9 && plane->id != PLANE_PRIMARY &&
if (DISPLAY_VER(display) >= 9 && plane->id != PLANE_PRIMARY &&
set->flags & I915_SET_COLORKEY_DESTINATION)
key->flags = 0;
}
@@ -43,7 +43,6 @@ int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct intel_display *display = to_intel_display(dev);
struct drm_i915_private *dev_priv = to_i915(dev);
struct drm_intel_sprite_colorkey *set = data;
struct drm_plane *plane;
struct drm_plane_state *plane_state;
@@ -61,7 +60,7 @@ int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data,
if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
return -EINVAL;
if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
if ((display->platform.valleyview || display->platform.cherryview) &&
set->flags & I915_SET_COLORKEY_DESTINATION)
return -EINVAL;
@@ -74,7 +73,7 @@ int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data,
* Also multiple planes can't do destination keying on the same
* pipe simultaneously.
*/
if (DISPLAY_VER(dev_priv) >= 9 &&
if (DISPLAY_VER(display) >= 9 &&
to_intel_plane(plane)->id >= PLANE_3 &&
set->flags & I915_SET_COLORKEY_DESTINATION)
return -EINVAL;
@@ -99,7 +98,7 @@ int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data,
* On some platforms we have to configure
* the dst colorkey on the primary plane.
*/
if (!ret && has_dst_key_in_primary_plane(dev_priv)) {
if (!ret && has_dst_key_in_primary_plane(display)) {
struct intel_crtc *crtc =
intel_crtc_for_pipe(display,
to_intel_plane(plane)->pipe);

View File

@@ -33,15 +33,15 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
#include "i915_drv.h"
#include "i915_reg.h"
#include "intel_connector.h"
#include "intel_crtc.h"
#include "intel_de.h"
#include "intel_display_irq.h"
#include "intel_display_driver.h"
#include "intel_display_irq.h"
#include "intel_display_types.h"
#include "intel_dpll.h"
#include "intel_hotplug.h"
@@ -1585,19 +1585,17 @@ intel_tv_detect_type(struct intel_tv *intel_tv,
{
struct intel_display *display = to_intel_display(connector->dev);
struct intel_crtc *crtc = to_intel_crtc(connector->state->crtc);
struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = to_i915(dev);
u32 tv_ctl, save_tv_ctl;
u32 tv_dac, save_tv_dac;
int type;
/* Disable TV interrupts around load detect or we'll recurse */
if (connector->polled & DRM_CONNECTOR_POLL_HPD) {
spin_lock_irq(&dev_priv->irq_lock);
spin_lock_irq(&display->irq.lock);
i915_disable_pipestat(display, 0,
PIPE_HOTPLUG_INTERRUPT_STATUS |
PIPE_HOTPLUG_TV_INTERRUPT_STATUS);
spin_unlock_irq(&dev_priv->irq_lock);
spin_unlock_irq(&display->irq.lock);
}
save_tv_dac = tv_dac = intel_de_read(display, TV_DAC);
@@ -1668,11 +1666,11 @@ intel_tv_detect_type(struct intel_tv *intel_tv,
/* Restore interrupt config */
if (connector->polled & DRM_CONNECTOR_POLL_HPD) {
spin_lock_irq(&dev_priv->irq_lock);
spin_lock_irq(&display->irq.lock);
i915_enable_pipestat(display, 0,
PIPE_HOTPLUG_INTERRUPT_STATUS |
PIPE_HOTPLUG_TV_INTERRUPT_STATUS);
spin_unlock_irq(&dev_priv->irq_lock);
spin_unlock_irq(&display->irq.lock);
}
return type;

View File

@@ -4,15 +4,20 @@
*/
#include <linux/delay.h>
#include <linux/pci.h>
#include <linux/vgaarb.h>
#include <drm/drm_device.h>
#include <drm/drm_print.h>
#include <video/vga.h>
#include "soc/intel_gmch.h"
#include "i915_drv.h"
#include "i915_reg.h"
#include "intel_de.h"
#include "intel_display.h"
#include "intel_vga.h"
#include "intel_vga_regs.h"
static i915_reg_t intel_vga_cntrl_reg(struct intel_display *display)
{
@@ -24,16 +29,42 @@ static i915_reg_t intel_vga_cntrl_reg(struct intel_display *display)
return VGACNTRL;
}
static bool has_vga_pipe_sel(struct intel_display *display)
{
if (display->platform.i845g ||
display->platform.i865g)
return false;
if (display->platform.valleyview ||
display->platform.cherryview)
return true;
return DISPLAY_VER(display) < 7;
}
/* Disable the VGA plane that we never use */
void intel_vga_disable(struct intel_display *display)
{
struct pci_dev *pdev = to_pci_dev(display->drm->dev);
i915_reg_t vga_reg = intel_vga_cntrl_reg(display);
enum pipe pipe;
u32 tmp;
u8 sr1;
if (intel_de_read(display, vga_reg) & VGA_DISP_DISABLE)
tmp = intel_de_read(display, vga_reg);
if (tmp & VGA_DISP_DISABLE)
return;
if (display->platform.cherryview)
pipe = REG_FIELD_GET(VGA_PIPE_SEL_MASK_CHV, tmp);
else if (has_vga_pipe_sel(display))
pipe = REG_FIELD_GET(VGA_PIPE_SEL_MASK, tmp);
else
pipe = PIPE_A;
drm_dbg_kms(display->drm, "Disabling VGA plane on pipe %c\n",
pipe_name(pipe));
/* WaEnableVGAAccessThroughIOPort:ctg,elk,ilk,snb,ivb,vlv,hsw */
vga_get_uninterruptible(pdev, VGA_RSRC_LEGACY_IO);
outb(0x01, VGA_SEQ_I);
@@ -46,39 +77,6 @@ void intel_vga_disable(struct intel_display *display)
intel_de_posting_read(display, vga_reg);
}
void intel_vga_redisable_power_on(struct intel_display *display)
{
i915_reg_t vga_reg = intel_vga_cntrl_reg(display);
if (!(intel_de_read(display, vga_reg) & VGA_DISP_DISABLE)) {
drm_dbg_kms(display->drm,
"Something enabled VGA plane, disabling it\n");
intel_vga_disable(display);
}
}
void intel_vga_redisable(struct intel_display *display)
{
intel_wakeref_t wakeref;
/*
* This function can be called both from intel_modeset_setup_hw_state or
* at a very early point in our resume sequence, where the power well
* structures are not yet restored. Since this function is at a very
* paranoid "someone might have enabled VGA while we were not looking"
* level, just check if the power well is enabled instead of trying to
* follow the "don't touch the power well if we don't need it" policy
* the rest of the driver uses.
*/
wakeref = intel_display_power_get_if_enabled(display, POWER_DOMAIN_VGA);
if (!wakeref)
return;
intel_vga_redisable_power_on(display);
intel_display_power_put(display, POWER_DOMAIN_VGA, wakeref);
}
void intel_vga_reset_io_mem(struct intel_display *display)
{
struct pci_dev *pdev = to_pci_dev(display->drm->dev);

View File

@@ -10,8 +10,6 @@ struct intel_display;
void intel_vga_reset_io_mem(struct intel_display *display);
void intel_vga_disable(struct intel_display *display);
void intel_vga_redisable(struct intel_display *display);
void intel_vga_redisable_power_on(struct intel_display *display);
int intel_vga_register(struct intel_display *display);
void intel_vga_unregister(struct intel_display *display);

View File

@@ -0,0 +1,36 @@
/* SPDX-License-Identifier: MIT */
/*
* Copyright © 2025 Intel Corporation
*/
#ifndef __INTEL_VGA_REGS_H__
#define __INTEL_VGA_REGS_H__
#include "intel_display_reg_defs.h"
#define VGACNTRL _MMIO(0x71400)
#define VLV_VGACNTRL _MMIO(VLV_DISPLAY_BASE + 0x71400)
#define CPU_VGACNTRL _MMIO(0x41000)
#define VGA_DISP_DISABLE REG_BIT(31)
#define VGA_2X_MODE REG_BIT(30) /* pre-ilk */
#define VGA_PIPE_SEL_MASK REG_BIT(29) /* pre-ivb */
#define VGA_PIPE_SEL(pipe) REG_FIELD_PREP(VGA_PIPE_SEL_MASK, (pipe))
#define VGA_PIPE_SEL_MASK_CHV REG_GENMASK(29, 28) /* chv */
#define VGA_PIPE_SEL_CHV(pipe) REG_FIELD_PREP(VGA_PIPE_SEL_MASK_CHV, (pipe))
#define VGA_BORDER_ENABLE REG_BIT(26)
#define VGA_PIPE_CSC_ENABLE REG_BIT(24) /* ilk+ */
#define VGA_CENTERING_ENABLE_MASK REG_GENMASK(25, 24) /* pre-ilk */
#define VGA_PALETTE_READ_SEL REG_BIT(23) /* pre-ivb */
#define VGA_PALETTE_A_WRITE_DISABLE REG_BIT(22) /* pre-ivb */
#define VGA_PALETTE_B_WRITE_DISABLE REG_BIT(21) /* pre-ivb */
#define VGA_LEGACY_8BIT_PALETTE_ENABLE REG_BIT(20)
#define VGA_PALETTE_BYPASS REG_BIT(19)
#define VGA_NINE_DOT_DISABLE REG_BIT(18)
#define VGA_PALETTE_READ_SEL_HI_CHV REG_BIT(15) /* chv */
#define VGA_PALETTE_C_WRITE_DISABLE_CHV REG_BIT(14) /* chv */
#define VGA_ACTIVE_THROTTLING_MASK REG_GENMASK(15, 12) /* ilk+ */
#define VGA_BLANK_THROTTLING_MASK REG_GENMASK(11, 8) /* ilk+ */
#define VGA_BLINK_DUTY_CYCLE_MASK REG_GENMASK(7, 6)
#define VGA_VSYNC_BLINK_RATE_MASK REG_GENMASK(5, 0)
#endif /* __INTEL_VGA_REGS_H__ */

View File

@@ -444,7 +444,10 @@ static u32 trans_vrr_ctl(const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
if (DISPLAY_VER(display) >= 13)
if (DISPLAY_VER(display) >= 14)
return VRR_CTL_FLIP_LINE_EN |
XELPD_VRR_CTL_VRR_GUARDBAND(crtc_state->vrr.guardband);
else if (DISPLAY_VER(display) >= 13)
return VRR_CTL_IGN_MAX_SHIFT | VRR_CTL_FLIP_LINE_EN |
XELPD_VRR_CTL_VRR_GUARDBAND(crtc_state->vrr.guardband);
else

View File

@@ -3,8 +3,10 @@
* Copyright © 2020 Intel Corporation
*/
#include "i915_drv.h"
#include <drm/drm_print.h>
#include "i915_reg.h"
#include "i915_utils.h"
#include "intel_de.h"
#include "intel_display_trace.h"
#include "intel_display_types.h"

View File

@@ -2690,24 +2690,22 @@ static void
skl_plane_enable_flip_done(struct intel_plane *plane)
{
struct intel_display *display = to_intel_display(plane);
struct drm_i915_private *i915 = to_i915(plane->base.dev);
enum pipe pipe = plane->pipe;
spin_lock_irq(&i915->irq_lock);
spin_lock_irq(&display->irq.lock);
bdw_enable_pipe_irq(display, pipe, GEN9_PIPE_PLANE_FLIP_DONE(plane->id));
spin_unlock_irq(&i915->irq_lock);
spin_unlock_irq(&display->irq.lock);
}
static void
skl_plane_disable_flip_done(struct intel_plane *plane)
{
struct intel_display *display = to_intel_display(plane);
struct drm_i915_private *i915 = to_i915(plane->base.dev);
enum pipe pipe = plane->pipe;
spin_lock_irq(&i915->irq_lock);
spin_lock_irq(&display->irq.lock);
bdw_disable_pipe_irq(display, pipe, GEN9_PIPE_PLANE_FLIP_DONE(plane->id));
spin_unlock_irq(&i915->irq_lock);
spin_unlock_irq(&display->irq.lock);
}
static bool skl_plane_has_rc_ccs(struct intel_display *display,

View File

@@ -8,7 +8,7 @@
#include <drm/intel/i915_drm.h>
#include "display/intel_display.h"
#include "display/intel_display_irq.h"
#include "display/intel_display_rps.h"
#include "i915_drv.h"
#include "i915_irq.h"
#include "i915_reg.h"
@@ -608,9 +608,7 @@ static bool gen5_rps_enable(struct intel_rps *rps)
rps->ips.last_count2 = intel_uncore_read(uncore, GFXEC);
rps->ips.last_time2 = ktime_get_raw_ns();
spin_lock(&i915->irq_lock);
ilk_enable_display_irq(display, DE_PCU_EVENT);
spin_unlock(&i915->irq_lock);
ilk_display_rps_enable(display);
spin_unlock_irq(&mchdev_lock);
@@ -628,9 +626,7 @@ static void gen5_rps_disable(struct intel_rps *rps)
spin_lock_irq(&mchdev_lock);
spin_lock(&i915->irq_lock);
ilk_disable_display_irq(display, DE_PCU_EVENT);
spin_unlock(&i915->irq_lock);
ilk_display_rps_disable(display);
rgvswctl = intel_uncore_read16(uncore, MEMSWCTL);

View File

@@ -57,7 +57,7 @@ struct intel_rps {
/*
* work, interrupts_enabled and pm_iir are protected by
* i915->irq_lock
* gt->irq_lock
*/
struct timer_list timer;
struct work_struct work;

View File

@@ -56,6 +56,7 @@
#include "display/intel_pps_regs.h"
#include "display/intel_psr_regs.h"
#include "display/intel_sprite_regs.h"
#include "display/intel_vga_regs.h"
#include "display/skl_universal_plane_regs.h"
#include "display/skl_watermark_regs.h"
#include "display/vlv_dsi_pll_regs.h"

View File

@@ -62,7 +62,6 @@
#include "display/intel_pch_refclk.h"
#include "display/intel_pps.h"
#include "display/intel_sprite_uapi.h"
#include "display/intel_vga.h"
#include "display/skl_watermark.h"
#include "gem/i915_gem_context.h"
@@ -235,7 +234,6 @@ static int i915_driver_early_probe(struct drm_i915_private *dev_priv)
intel_uncore_mmio_debug_init_early(dev_priv);
spin_lock_init(&dev_priv->irq_lock);
spin_lock_init(&dev_priv->gpu_error.lock);
intel_sbi_init(dev_priv);
@@ -263,9 +261,6 @@ static int i915_driver_early_probe(struct drm_i915_private *dev_priv)
i915_gem_init_early(dev_priv);
/* This must be called before any calls to HAS_PCH_* */
intel_detect_pch(dev_priv);
intel_irq_init(dev_priv);
intel_display_driver_early_probe(display);
intel_clock_gating_hooks_init(dev_priv);
@@ -1205,8 +1200,6 @@ static int i915_drm_resume(struct drm_device *dev)
i9xx_display_sr_restore(display);
intel_vga_redisable(display);
intel_gmbus_reset(display);
intel_pps_unlock_regs_wa(display);

View File

@@ -15,7 +15,6 @@ struct drm_printer;
#define DRIVER_NAME "i915"
#define DRIVER_DESC "Intel Graphics"
#define DRIVER_TIMESTAMP 1695980603
extern const struct dev_pm_ops i915_pm_ops;

View File

@@ -49,8 +49,6 @@
#include "gt/intel_workarounds.h"
#include "gt/uc/intel_uc.h"
#include "soc/intel_pch.h"
#include "i915_drm_client.h"
#include "i915_gem.h"
#include "i915_gpu_error.h"
@@ -224,8 +222,6 @@ struct drm_i915_private {
};
unsigned int engine_uabi_class_count[I915_LAST_UABI_ENGINE_CLASS + 1];
/* protects the irq masks */
spinlock_t irq_lock;
bool irqs_enabled;
/* LPT/WPT IOSF sideband protection */
@@ -272,9 +268,6 @@ struct drm_i915_private {
/* pm private clock gating functions */
const struct drm_i915_clock_gating_funcs *clock_gating_funcs;
/* PCH chipset type */
enum intel_pch pch_type;
unsigned long gem_quirks;
struct i915_gem_mm mm;

Some files were not shown because too many files have changed in this diff Show More