Core Changes:

- drm: Rename DP_PSR_SELECTIVE_UPDATE to better mach eDP spec (Jose).
 
 Driver Changes:
 
 - Display plane clock rates fixes and improvements (Ville).
 - Uninint DMC FW loader state during shutdown (Imre).
 - Convert snprintf to sysfs_emit (Xuezhi).
 - Fix invalid access to ACPI _DSM objects (Takashi).
 - A big refactor around how i915 addresses the graphics
   and display IP versions. (Matt, Lucas).
 - Backlight fix (Lyude).
 - Display watermark and DBUF fixes (Ville).
 - HDCP fix (Anshuman).
 - Improve cases where display is not available (Jose).
 - Defeature PSR2 for RKL and ALD-S (Jose).
 - VLV DSI panel power fixes and improvements (Hans).
 - display-12 workaround (Jose).
 - Fix modesetting (Imre).
 - Drop redundant address-of op before lttpr_common_caps array (Imre).
 - Fix compiler checks (Jose, Jason).
 - GLK display fixes (Ville).
 - Fix error code returns (Dan).
 - eDP novel: back again to slow and wide link training everywhere (Kai-Heng).
 - Abstract DMC FW path (Rodrigo).
 - Preparation and changes for upcoming
   XeLPD display IP (Jose, Matt, Ville, Juha-Pekka, Animesh).
 - Fix comment typo in DSI code (zuoqilin).
 - Simplify CCS and UV plane alignment handling (Imre).
 - PSR Fixes on TGL (Gwan-gyeong, Jose).
 - Add intel_dp_hdcp.h and rename init (Jani).
 - Move crtc and dpll declarations around (Jani).
 - Fix pre-skl DP AUX precharge length (Ville).
 - Remove stray newlines from random files (Ville).
 - crtc->index and intel_crtc+drm_crtc pointer clean-up (Ville).
 - Add frontbuffer tracking tracepoints (Ville).
 - ADL-S PCI ID updates (Anand).
 - Use unique backlight device names (Jani).
 - A few clean-ups on i915/audio (Jani).
 - Use intel_framebuffer instead of drm one on intel_fb functions (Imre).
 - Add the missing MC CCS/XYUV8888 format support on display >= 12 (Imre).
 - Nuke display error state (Ville).
 - ADL-P initial enablement patches
   starting to land (Clint, Imre, Jose, Umesh, Vandita, Mika).
 - Display clean-up around VBT and the strap bits (Lucas).
 - Try YCbCr420 color when RGB fails (Werner).
 - More PSR fixes and improvements (Jose).
 - Other generic display code clean-up (Jose, Ville).
 - Use correct downstream caps for check Src-Ctl mode for PCON (Ankit).
 - Disable HiZ Raw Stall Optimization on broken gen7 (Simon).
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCAAdFiEEbSBwaO7dZQkcLOKj+mJfZA7rE8oFAmClYcoACgkQ+mJfZA7r
 E8oXBwf/Rfb8o/4WZeoc3vxtFlWenA/9QJA2Xs4ui6U3vJScpaHFLq5Ki6aOSxIO
 WudQvatS1Bw+QzzAjSZFZx+WhCwop4BLhFJJxVK2RD4REeSjJvPZ6oovgndMOGY4
 RvyeXoIJoXoHPQ7uJXMZZGRthYTWR83Aw93hi3uTd4jU+JB8WtHgvvycKTVKIkVB
 T6V3PSuTmXwhHNURfev8d/JyiZMphRDJLD3esamwn2XRYtPDZjfkavwYQVeUlbms
 TstymTGZXjNvPnX9HkzoURdF4F394iNyx3lX1j5nyYm0QgyHJKJI8moy8Dfv4+AB
 JlL5vE7cTKtnKC5OUPCh9NZRH4pNZw==
 =uO7R
 -----END PGP SIGNATURE-----

Merge tag 'drm-intel-next-2021-05-19-1' of git://anongit.freedesktop.org/drm/drm-intel into drm-next

Core Changes:

- drm: Rename DP_PSR_SELECTIVE_UPDATE to better mach eDP spec (Jose).

Driver Changes:

- Display plane clock rates fixes and improvements (Ville).
- Uninint DMC FW loader state during shutdown (Imre).
- Convert snprintf to sysfs_emit (Xuezhi).
- Fix invalid access to ACPI _DSM objects (Takashi).
- A big refactor around how i915 addresses the graphics
  and display IP versions. (Matt, Lucas).
- Backlight fix (Lyude).
- Display watermark and DBUF fixes (Ville).
- HDCP fix (Anshuman).
- Improve cases where display is not available (Jose).
- Defeature PSR2 for RKL and ALD-S (Jose).
- VLV DSI panel power fixes and improvements (Hans).
- display-12 workaround (Jose).
- Fix modesetting (Imre).
- Drop redundant address-of op before lttpr_common_caps array (Imre).
- Fix compiler checks (Jose, Jason).
- GLK display fixes (Ville).
- Fix error code returns (Dan).
- eDP novel: back again to slow and wide link training everywhere (Kai-Heng).
- Abstract DMC FW path (Rodrigo).
- Preparation and changes for upcoming
  XeLPD display IP (Jose, Matt, Ville, Juha-Pekka, Animesh).
- Fix comment typo in DSI code (zuoqilin).
- Simplify CCS and UV plane alignment handling (Imre).
- PSR Fixes on TGL (Gwan-gyeong, Jose).
- Add intel_dp_hdcp.h and rename init (Jani).
- Move crtc and dpll declarations around (Jani).
- Fix pre-skl DP AUX precharge length (Ville).
- Remove stray newlines from random files (Ville).
- crtc->index and intel_crtc+drm_crtc pointer clean-up (Ville).
- Add frontbuffer tracking tracepoints (Ville).
- ADL-S PCI ID updates (Anand).
- Use unique backlight device names (Jani).
- A few clean-ups on i915/audio (Jani).
- Use intel_framebuffer instead of drm one on intel_fb functions (Imre).
- Add the missing MC CCS/XYUV8888 format support on display >= 12 (Imre).
- Nuke display error state (Ville).
- ADL-P initial enablement patches
  starting to land (Clint, Imre, Jose, Umesh, Vandita, Mika).
- Display clean-up around VBT and the strap bits (Lucas).
- Try YCbCr420 color when RGB fails (Werner).
- More PSR fixes and improvements (Jose).
- Other generic display code clean-up (Jose, Ville).
- Use correct downstream caps for check Src-Ctl mode for PCON (Ankit).
- Disable HiZ Raw Stall Optimization on broken gen7 (Simon).

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

From: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/YKVioeu0JkUAlR7y@intel.com
This commit is contained in:
Dave Airlie 2021-05-21 08:53:38 +10:00
commit 2ba0478550
107 changed files with 2811 additions and 1386 deletions

View file

@ -552,6 +552,7 @@ static const struct pci_device_id intel_early_ids[] __initconst = {
INTEL_TGL_12_IDS(&gen11_early_ops), INTEL_TGL_12_IDS(&gen11_early_ops),
INTEL_RKL_IDS(&gen11_early_ops), INTEL_RKL_IDS(&gen11_early_ops),
INTEL_ADLS_IDS(&gen11_early_ops), INTEL_ADLS_IDS(&gen11_early_ops),
INTEL_ADLP_IDS(&gen11_early_ops),
}; };
struct resource intel_graphics_stolen_res __ro_after_init = DEFINE_RES_MEM(0, 0); struct resource intel_graphics_stolen_res __ro_after_init = DEFINE_RES_MEM(0, 0);

View file

@ -8,6 +8,7 @@
#include "g4x_dp.h" #include "g4x_dp.h"
#include "intel_audio.h" #include "intel_audio.h"
#include "intel_connector.h" #include "intel_connector.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_dp.h" #include "intel_dp.h"
#include "intel_dp_link_training.h" #include "intel_dp_link_training.h"

View file

@ -8,6 +8,7 @@
#include "g4x_hdmi.h" #include "g4x_hdmi.h"
#include "intel_audio.h" #include "intel_audio.h"
#include "intel_connector.h" #include "intel_connector.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_dpio_phy.h" #include "intel_dpio_phy.h"
#include "intel_fifo_underrun.h" #include "intel_fifo_underrun.h"

View file

@ -10,6 +10,7 @@
#include "intel_atomic.h" #include "intel_atomic.h"
#include "intel_atomic_plane.h" #include "intel_atomic_plane.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_fb.h" #include "intel_fb.h"
#include "intel_sprite.h" #include "intel_sprite.h"
@ -144,7 +145,7 @@ static bool i9xx_plane_has_windowing(struct intel_plane *plane)
return i9xx_plane == PLANE_B; return i9xx_plane == PLANE_B;
else if (DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv)) else if (DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv))
return false; return false;
else if (IS_DISPLAY_VER(dev_priv, 4)) else if (DISPLAY_VER(dev_priv) == 4)
return i9xx_plane == PLANE_C; return i9xx_plane == PLANE_C;
else else
return i9xx_plane == PLANE_B || return i9xx_plane == PLANE_B ||
@ -1039,4 +1040,3 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
plane_config->fb = intel_fb; plane_config->fb = intel_fb;
} }

View file

@ -31,7 +31,9 @@
#include "intel_atomic.h" #include "intel_atomic.h"
#include "intel_combo_phy.h" #include "intel_combo_phy.h"
#include "intel_connector.h" #include "intel_connector.h"
#include "intel_crtc.h"
#include "intel_ddi.h" #include "intel_ddi.h"
#include "intel_de.h"
#include "intel_dsi.h" #include "intel_dsi.h"
#include "intel_panel.h" #include "intel_panel.h"
#include "intel_vdsc.h" #include "intel_vdsc.h"
@ -592,7 +594,7 @@ gen11_dsi_setup_dphy_timings(struct intel_encoder *encoder,
* a value '0' inside TA_PARAM_REGISTERS otherwise * a value '0' inside TA_PARAM_REGISTERS otherwise
* leave all fields at HW default values. * leave all fields at HW default values.
*/ */
if (IS_DISPLAY_VER(dev_priv, 11)) { if (DISPLAY_VER(dev_priv) == 11) {
if (afe_clk(encoder, crtc_state) <= 800000) { if (afe_clk(encoder, crtc_state) <= 800000) {
for_each_dsi_port(port, intel_dsi->ports) { for_each_dsi_port(port, intel_dsi->ports) {
tmp = intel_de_read(dev_priv, tmp = intel_de_read(dev_priv,
@ -1158,7 +1160,7 @@ gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder,
gen11_dsi_configure_transcoder(encoder, crtc_state); gen11_dsi_configure_transcoder(encoder, crtc_state);
/* Step 4l: Gate DDI clocks */ /* Step 4l: Gate DDI clocks */
if (IS_DISPLAY_VER(dev_priv, 11)) if (DISPLAY_VER(dev_priv) == 11)
gen11_dsi_gate_clocks(encoder); gen11_dsi_gate_clocks(encoder);
} }

View file

@ -321,7 +321,7 @@ static void intel_atomic_setup_scaler(struct intel_crtc_scaler_state *scaler_sta
plane_state->hw.fb->format->is_yuv && plane_state->hw.fb->format->is_yuv &&
plane_state->hw.fb->format->num_planes > 1) { plane_state->hw.fb->format->num_planes > 1) {
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
if (IS_DISPLAY_VER(dev_priv, 9)) { if (DISPLAY_VER(dev_priv) == 9) {
mode = SKL_PS_SCALER_MODE_NV12; mode = SKL_PS_SCALER_MODE_NV12;
} else if (icl_is_hdr_plane(dev_priv, plane->id)) { } else if (icl_is_hdr_plane(dev_priv, plane->id)) {
/* /*

View file

@ -102,7 +102,8 @@ intel_plane_duplicate_state(struct drm_plane *plane)
__drm_atomic_helper_plane_duplicate_state(plane, &intel_state->uapi); __drm_atomic_helper_plane_duplicate_state(plane, &intel_state->uapi);
intel_state->vma = NULL; intel_state->ggtt_vma = NULL;
intel_state->dpt_vma = NULL;
intel_state->flags = 0; intel_state->flags = 0;
/* add reference to fb */ /* add reference to fb */
@ -125,7 +126,9 @@ intel_plane_destroy_state(struct drm_plane *plane,
struct drm_plane_state *state) struct drm_plane_state *state)
{ {
struct intel_plane_state *plane_state = to_intel_plane_state(state); struct intel_plane_state *plane_state = to_intel_plane_state(state);
drm_WARN_ON(plane->dev, plane_state->vma);
drm_WARN_ON(plane->dev, plane_state->ggtt_vma);
drm_WARN_ON(plane->dev, plane_state->dpt_vma);
__drm_atomic_helper_plane_destroy_state(&plane_state->uapi); __drm_atomic_helper_plane_destroy_state(&plane_state->uapi);
if (plane_state->hw.fb) if (plane_state->hw.fb)
@ -133,25 +136,45 @@ intel_plane_destroy_state(struct drm_plane *plane,
kfree(plane_state); kfree(plane_state);
} }
unsigned int intel_plane_pixel_rate(const struct intel_crtc_state *crtc_state, unsigned int intel_adjusted_rate(const struct drm_rect *src,
const struct intel_plane_state *plane_state) const struct drm_rect *dst,
unsigned int rate)
{ {
unsigned int src_w, src_h, dst_w, dst_h; unsigned int src_w, src_h, dst_w, dst_h;
unsigned int pixel_rate = crtc_state->pixel_rate;
src_w = drm_rect_width(&plane_state->uapi.src) >> 16; src_w = drm_rect_width(src) >> 16;
src_h = drm_rect_height(&plane_state->uapi.src) >> 16; src_h = drm_rect_height(src) >> 16;
dst_w = drm_rect_width(&plane_state->uapi.dst); dst_w = drm_rect_width(dst);
dst_h = drm_rect_height(&plane_state->uapi.dst); dst_h = drm_rect_height(dst);
/* Downscaling limits the maximum pixel rate */ /* Downscaling limits the maximum pixel rate */
dst_w = min(src_w, dst_w); dst_w = min(src_w, dst_w);
dst_h = min(src_h, dst_h); dst_h = min(src_h, dst_h);
return DIV_ROUND_UP_ULL(mul_u32_u32(pixel_rate, src_w * src_h), return DIV_ROUND_UP_ULL(mul_u32_u32(rate, src_w * src_h),
dst_w * dst_h); dst_w * dst_h);
} }
unsigned int intel_plane_pixel_rate(const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
{
/*
* Note we don't check for plane visibility here as
* we want to use this when calculating the cursor
* watermarks even if the cursor is fully offscreen.
* That depends on the src/dst rectangles being
* correctly populated whenever the watermark code
* considers the cursor to be visible, whether or not
* it is actually visible.
*
* See: intel_wm_plane_visible() and intel_check_cursor()
*/
return intel_adjusted_rate(&plane_state->uapi.src,
&plane_state->uapi.dst,
crtc_state->pixel_rate);
}
unsigned int intel_plane_data_rate(const struct intel_crtc_state *crtc_state, unsigned int intel_plane_data_rate(const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state) const struct intel_plane_state *plane_state)
{ {

View file

@ -10,6 +10,7 @@
struct drm_plane; struct drm_plane;
struct drm_property; struct drm_property;
struct drm_rect;
struct intel_atomic_state; struct intel_atomic_state;
struct intel_crtc; struct intel_crtc;
struct intel_crtc_state; struct intel_crtc_state;
@ -18,6 +19,9 @@ struct intel_plane_state;
extern const struct drm_plane_helper_funcs intel_plane_helper_funcs; extern const struct drm_plane_helper_funcs intel_plane_helper_funcs;
unsigned int intel_adjusted_rate(const struct drm_rect *src,
const struct drm_rect *dst,
unsigned int rate);
unsigned int intel_plane_pixel_rate(const struct intel_crtc_state *crtc_state, unsigned int intel_plane_pixel_rate(const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state); const struct intel_plane_state *plane_state);

View file

@ -31,6 +31,7 @@
#include "intel_atomic.h" #include "intel_atomic.h"
#include "intel_audio.h" #include "intel_audio.h"
#include "intel_cdclk.h" #include "intel_cdclk.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_lpe_audio.h" #include "intel_lpe_audio.h"
@ -591,40 +592,33 @@ static void enable_audio_dsc_wa(struct intel_encoder *encoder,
val = intel_de_read(i915, AUD_CONFIG_BE); val = intel_de_read(i915, AUD_CONFIG_BE);
if (IS_DISPLAY_VER(i915, 11)) if (DISPLAY_VER(i915) == 11)
val |= HBLANK_EARLY_ENABLE_ICL(pipe); val |= HBLANK_EARLY_ENABLE_ICL(pipe);
else if (DISPLAY_VER(i915) >= 12) else if (DISPLAY_VER(i915) >= 12)
val |= HBLANK_EARLY_ENABLE_TGL(pipe); val |= HBLANK_EARLY_ENABLE_TGL(pipe);
if (crtc_state->dsc.compression_enable && if (crtc_state->dsc.compression_enable &&
(crtc_state->hw.adjusted_mode.hdisplay >= 3840 && crtc_state->hw.adjusted_mode.hdisplay >= 3840 &&
crtc_state->hw.adjusted_mode.vdisplay >= 2160)) { crtc_state->hw.adjusted_mode.vdisplay >= 2160) {
/* Get hblank early enable value required */ /* Get hblank early enable value required */
val &= ~HBLANK_START_COUNT_MASK(pipe);
hblank_early_prog = calc_hblank_early_prog(encoder, crtc_state); hblank_early_prog = calc_hblank_early_prog(encoder, crtc_state);
if (hblank_early_prog < 32) { if (hblank_early_prog < 32)
val &= ~HBLANK_START_COUNT_MASK(pipe);
val |= HBLANK_START_COUNT(pipe, HBLANK_START_COUNT_32); val |= HBLANK_START_COUNT(pipe, HBLANK_START_COUNT_32);
} else if (hblank_early_prog < 64) { else if (hblank_early_prog < 64)
val &= ~HBLANK_START_COUNT_MASK(pipe);
val |= HBLANK_START_COUNT(pipe, HBLANK_START_COUNT_64); val |= HBLANK_START_COUNT(pipe, HBLANK_START_COUNT_64);
} else if (hblank_early_prog < 96) { else if (hblank_early_prog < 96)
val &= ~HBLANK_START_COUNT_MASK(pipe);
val |= HBLANK_START_COUNT(pipe, HBLANK_START_COUNT_96); val |= HBLANK_START_COUNT(pipe, HBLANK_START_COUNT_96);
} else { else
val &= ~HBLANK_START_COUNT_MASK(pipe);
val |= HBLANK_START_COUNT(pipe, HBLANK_START_COUNT_128); val |= HBLANK_START_COUNT(pipe, HBLANK_START_COUNT_128);
}
/* Get samples room value required */ /* Get samples room value required */
val &= ~NUMBER_SAMPLES_PER_LINE_MASK(pipe);
samples_room = calc_samples_room(crtc_state); samples_room = calc_samples_room(crtc_state);
if (samples_room < 3) { if (samples_room < 3)
val &= ~NUMBER_SAMPLES_PER_LINE_MASK(pipe);
val |= NUMBER_SAMPLES_PER_LINE(pipe, samples_room); val |= NUMBER_SAMPLES_PER_LINE(pipe, samples_room);
} else { else /* Program 0 i.e "All Samples available in buffer" */
/* Program 0 i.e "All Samples available in buffer" */
val &= ~NUMBER_SAMPLES_PER_LINE_MASK(pipe);
val |= NUMBER_SAMPLES_PER_LINE(pipe, 0x0); val |= NUMBER_SAMPLES_PER_LINE(pipe, 0x0);
}
} }
intel_de_write(i915, AUD_CONFIG_BE, val); intel_de_write(i915, AUD_CONFIG_BE, val);
@ -1309,7 +1303,7 @@ static void i915_audio_component_init(struct drm_i915_private *dev_priv)
if (DISPLAY_VER(dev_priv) >= 9) { if (DISPLAY_VER(dev_priv) >= 9) {
aud_freq_init = intel_de_read(dev_priv, AUD_FREQ_CNTRL); aud_freq_init = intel_de_read(dev_priv, AUD_FREQ_CNTRL);
if (INTEL_GEN(dev_priv) >= 12) if (DISPLAY_VER(dev_priv) >= 12)
aud_freq = AUD_FREQ_GEN12; aud_freq = AUD_FREQ_GEN12;
else else
aud_freq = aud_freq_init; aud_freq = aud_freq_init;

View file

@ -610,7 +610,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *i915)
* Only parse SDVO mappings on gens that could have SDVO. This isn't * Only parse SDVO mappings on gens that could have SDVO. This isn't
* accurate and doesn't have to be, as long as it's not too strict. * accurate and doesn't have to be, as long as it's not too strict.
*/ */
if (!IS_DISPLAY_RANGE(i915, 3, 7)) { if (!IS_DISPLAY_VER(i915, 3, 7)) {
drm_dbg_kms(&i915->drm, "Skipping SDVO device mapping\n"); drm_dbg_kms(&i915->drm, "Skipping SDVO device mapping\n");
return; return;
} }
@ -917,7 +917,7 @@ parse_psr(struct drm_i915_private *i915, const struct bdb_header *bdb)
* Old decimal value is wake up time in multiples of 100 us. * Old decimal value is wake up time in multiples of 100 us.
*/ */
if (bdb->version >= 205 && if (bdb->version >= 205 &&
(IS_GEN9_BC(i915) || DISPLAY_VER(i915) >= 10)) { (DISPLAY_VER(i915) >= 9 && !IS_BROXTON(i915))) {
switch (psr_table->tp1_wakeup_time) { switch (psr_table->tp1_wakeup_time) {
case 0: case 0:
i915->vbt.psr.tp1_wakeup_time_us = 500; i915->vbt.psr.tp1_wakeup_time_us = 500;
@ -1651,7 +1651,7 @@ static u8 map_ddc_pin(struct drm_i915_private *i915, u8 vbt_pin)
const u8 *ddc_pin_map; const u8 *ddc_pin_map;
int n_entries; int n_entries;
if (HAS_PCH_ADP(i915)) { if (IS_ALDERLAKE_S(i915)) {
ddc_pin_map = adls_ddc_pin_map; ddc_pin_map = adls_ddc_pin_map;
n_entries = ARRAY_SIZE(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(i915) >= PCH_DG1) {
@ -1659,7 +1659,7 @@ static u8 map_ddc_pin(struct drm_i915_private *i915, u8 vbt_pin)
} else if (IS_ROCKETLAKE(i915) && INTEL_PCH_TYPE(i915) == PCH_TGP) { } else if (IS_ROCKETLAKE(i915) && INTEL_PCH_TYPE(i915) == PCH_TGP) {
ddc_pin_map = rkl_pch_tgp_ddc_pin_map; ddc_pin_map = rkl_pch_tgp_ddc_pin_map;
n_entries = ARRAY_SIZE(rkl_pch_tgp_ddc_pin_map); n_entries = ARRAY_SIZE(rkl_pch_tgp_ddc_pin_map);
} else if (HAS_PCH_TGP(i915) && IS_GEN9_BC(i915)) { } else if (HAS_PCH_TGP(i915) && DISPLAY_VER(i915) == 9) {
ddc_pin_map = gen9bc_tgp_ddc_pin_map; ddc_pin_map = gen9bc_tgp_ddc_pin_map;
n_entries = ARRAY_SIZE(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(i915) >= PCH_ICP) {
@ -1743,8 +1743,24 @@ static enum port dvo_port_to_port(struct drm_i915_private *i915,
[PORT_TC3] = { DVO_PORT_HDMID, DVO_PORT_DPD, -1 }, [PORT_TC3] = { DVO_PORT_HDMID, DVO_PORT_DPD, -1 },
[PORT_TC4] = { DVO_PORT_HDMIE, DVO_PORT_DPE, -1 }, [PORT_TC4] = { DVO_PORT_HDMIE, DVO_PORT_DPE, -1 },
}; };
static const int xelpd_port_mapping[][3] = {
[PORT_A] = { DVO_PORT_HDMIA, DVO_PORT_DPA, -1 },
[PORT_B] = { DVO_PORT_HDMIB, DVO_PORT_DPB, -1 },
[PORT_C] = { DVO_PORT_HDMIC, DVO_PORT_DPC, -1 },
[PORT_D_XELPD] = { DVO_PORT_HDMID, DVO_PORT_DPD, -1 },
[PORT_E_XELPD] = { DVO_PORT_HDMIE, DVO_PORT_DPE, -1 },
[PORT_TC1] = { DVO_PORT_HDMIF, DVO_PORT_DPF, -1 },
[PORT_TC2] = { DVO_PORT_HDMIG, DVO_PORT_DPG, -1 },
[PORT_TC3] = { DVO_PORT_HDMIH, DVO_PORT_DPH, -1 },
[PORT_TC4] = { DVO_PORT_HDMII, DVO_PORT_DPI, -1 },
};
if (IS_ALDERLAKE_S(i915)) if (DISPLAY_VER(i915) == 13)
return __dvo_port_to_port(ARRAY_SIZE(xelpd_port_mapping),
ARRAY_SIZE(xelpd_port_mapping[0]),
xelpd_port_mapping,
dvo_port);
else if (IS_ALDERLAKE_S(i915))
return __dvo_port_to_port(ARRAY_SIZE(adls_port_mapping), return __dvo_port_to_port(ARRAY_SIZE(adls_port_mapping),
ARRAY_SIZE(adls_port_mapping[0]), ARRAY_SIZE(adls_port_mapping[0]),
adls_port_mapping, adls_port_mapping,
@ -1852,6 +1868,19 @@ intel_bios_encoder_supports_edp(const struct intel_bios_encoder_data *devdata)
devdata->child.device_type & DEVICE_TYPE_INTERNAL_CONNECTOR; devdata->child.device_type & DEVICE_TYPE_INTERNAL_CONNECTOR;
} }
static bool is_port_valid(struct drm_i915_private *i915, enum port port)
{
/*
* On some ICL/CNL SKUs port F is not present, but broken VBTs mark
* the port as present. Only try to initialize port F for the
* SKUs that may actually have it.
*/
if (port == PORT_F && (IS_ICELAKE(i915) || IS_CANNONLAKE(i915)))
return IS_ICL_WITH_PORT_F(i915) || IS_CNL_WITH_PORT_F(i915);
return true;
}
static void parse_ddi_port(struct drm_i915_private *i915, static void parse_ddi_port(struct drm_i915_private *i915,
struct intel_bios_encoder_data *devdata) struct intel_bios_encoder_data *devdata)
{ {
@ -1865,6 +1894,13 @@ static void parse_ddi_port(struct drm_i915_private *i915,
if (port == PORT_NONE) if (port == PORT_NONE)
return; return;
if (!is_port_valid(i915, port)) {
drm_dbg_kms(&i915->drm,
"VBT reports port %c as supported, but that can't be true: skipping\n",
port_name(port));
return;
}
info = &i915->vbt.ddi_port_info[port]; info = &i915->vbt.ddi_port_info[port];
if (info->devdata) { if (info->devdata) {
@ -2770,7 +2806,8 @@ intel_bios_is_port_hpd_inverted(const struct drm_i915_private *i915,
const struct intel_bios_encoder_data *devdata = const struct intel_bios_encoder_data *devdata =
i915->vbt.ddi_port_info[port].devdata; i915->vbt.ddi_port_info[port].devdata;
if (drm_WARN_ON_ONCE(&i915->drm, !IS_GEN9_LP(i915))) if (drm_WARN_ON_ONCE(&i915->drm,
!IS_GEMINILAKE(i915) && !IS_BROXTON(i915)))
return false; return false;
return devdata && devdata->child.hpd_invert; return devdata && devdata->child.hpd_invert;
@ -2852,7 +2889,9 @@ enum aux_ch intel_bios_port_aux_ch(struct drm_i915_private *i915,
aux_ch = AUX_CH_C; aux_ch = AUX_CH_C;
break; break;
case DP_AUX_D: case DP_AUX_D:
if (IS_ALDERLAKE_S(i915)) if (DISPLAY_VER(i915) == 13)
aux_ch = AUX_CH_D_XELPD;
else if (IS_ALDERLAKE_S(i915))
aux_ch = AUX_CH_USBC3; aux_ch = AUX_CH_USBC3;
else if (IS_DG1(i915) || IS_ROCKETLAKE(i915)) else if (IS_DG1(i915) || IS_ROCKETLAKE(i915))
aux_ch = AUX_CH_USBC2; aux_ch = AUX_CH_USBC2;
@ -2860,22 +2899,36 @@ enum aux_ch intel_bios_port_aux_ch(struct drm_i915_private *i915,
aux_ch = AUX_CH_D; aux_ch = AUX_CH_D;
break; break;
case DP_AUX_E: case DP_AUX_E:
if (IS_ALDERLAKE_S(i915)) if (DISPLAY_VER(i915) == 13)
aux_ch = AUX_CH_E_XELPD;
else if (IS_ALDERLAKE_S(i915))
aux_ch = AUX_CH_USBC4; aux_ch = AUX_CH_USBC4;
else else
aux_ch = AUX_CH_E; aux_ch = AUX_CH_E;
break; break;
case DP_AUX_F: case DP_AUX_F:
aux_ch = AUX_CH_F; if (DISPLAY_VER(i915) == 13)
aux_ch = AUX_CH_USBC1;
else
aux_ch = AUX_CH_F;
break; break;
case DP_AUX_G: case DP_AUX_G:
aux_ch = AUX_CH_G; if (DISPLAY_VER(i915) == 13)
aux_ch = AUX_CH_USBC2;
else
aux_ch = AUX_CH_G;
break; break;
case DP_AUX_H: case DP_AUX_H:
aux_ch = AUX_CH_H; if (DISPLAY_VER(i915) == 13)
aux_ch = AUX_CH_USBC3;
else
aux_ch = AUX_CH_H;
break; break;
case DP_AUX_I: case DP_AUX_I:
aux_ch = AUX_CH_I; if (DISPLAY_VER(i915) == 13)
aux_ch = AUX_CH_USBC4;
else
aux_ch = AUX_CH_I;
break; break;
default: default:
MISSING_CASE(info->alternate_aux_channel); MISSING_CASE(info->alternate_aux_channel);

View file

@ -77,7 +77,7 @@ static int icl_get_qgv_points(struct drm_i915_private *dev_priv,
qi->num_points = dram_info->num_qgv_points; qi->num_points = dram_info->num_qgv_points;
if (IS_DISPLAY_VER(dev_priv, 12)) if (DISPLAY_VER(dev_priv) == 12)
switch (dram_info->type) { switch (dram_info->type) {
case INTEL_DRAM_DDR4: case INTEL_DRAM_DDR4:
qi->t_bl = 4; qi->t_bl = 4;
@ -89,7 +89,7 @@ static int icl_get_qgv_points(struct drm_i915_private *dev_priv,
qi->t_bl = 16; qi->t_bl = 16;
break; break;
} }
else if (IS_DISPLAY_VER(dev_priv, 11)) else if (DISPLAY_VER(dev_priv) == 11)
qi->t_bl = dev_priv->dram_info.type == INTEL_DRAM_DDR4 ? 4 : 8; qi->t_bl = dev_priv->dram_info.type == INTEL_DRAM_DDR4 ? 4 : 8;
if (drm_WARN_ON(&dev_priv->drm, if (drm_WARN_ON(&dev_priv->drm,
@ -271,9 +271,9 @@ void intel_bw_init_hw(struct drm_i915_private *dev_priv)
icl_get_bw_info(dev_priv, &adls_sa_info); icl_get_bw_info(dev_priv, &adls_sa_info);
else if (IS_ROCKETLAKE(dev_priv)) else if (IS_ROCKETLAKE(dev_priv))
icl_get_bw_info(dev_priv, &rkl_sa_info); icl_get_bw_info(dev_priv, &rkl_sa_info);
else if (IS_DISPLAY_VER(dev_priv, 12)) else if (DISPLAY_VER(dev_priv) == 12)
icl_get_bw_info(dev_priv, &tgl_sa_info); icl_get_bw_info(dev_priv, &tgl_sa_info);
else if (IS_DISPLAY_VER(dev_priv, 11)) else if (DISPLAY_VER(dev_priv) == 11)
icl_get_bw_info(dev_priv, &icl_sa_info); icl_get_bw_info(dev_priv, &icl_sa_info);
} }
@ -344,6 +344,9 @@ static unsigned int intel_bw_data_rate(struct drm_i915_private *dev_priv,
for_each_pipe(dev_priv, pipe) for_each_pipe(dev_priv, pipe)
data_rate += bw_state->data_rate[pipe]; data_rate += bw_state->data_rate[pipe];
if (DISPLAY_VER(dev_priv) >= 13 && intel_vtd_active())
data_rate = data_rate * 105 / 100;
return data_rate; return data_rate;
} }
@ -390,7 +393,6 @@ int skl_bw_calc_min_cdclk(struct intel_atomic_state *state)
const struct intel_crtc_state *crtc_state; const struct intel_crtc_state *crtc_state;
struct intel_crtc *crtc; struct intel_crtc *crtc;
int max_bw = 0; int max_bw = 0;
int slice_id;
enum pipe pipe; enum pipe pipe;
int i; int i;
@ -418,6 +420,7 @@ int skl_bw_calc_min_cdclk(struct intel_atomic_state *state)
&crtc_state->wm.skl.plane_ddb_uv[plane_id]; &crtc_state->wm.skl.plane_ddb_uv[plane_id];
unsigned int data_rate = crtc_state->data_rate[plane_id]; unsigned int data_rate = crtc_state->data_rate[plane_id];
unsigned int dbuf_mask = 0; unsigned int dbuf_mask = 0;
enum dbuf_slice slice;
dbuf_mask |= skl_ddb_dbuf_slice_mask(dev_priv, plane_alloc); dbuf_mask |= skl_ddb_dbuf_slice_mask(dev_priv, plane_alloc);
dbuf_mask |= skl_ddb_dbuf_slice_mask(dev_priv, uv_plane_alloc); dbuf_mask |= skl_ddb_dbuf_slice_mask(dev_priv, uv_plane_alloc);
@ -435,8 +438,8 @@ int skl_bw_calc_min_cdclk(struct intel_atomic_state *state)
* pessimistic, which shouldn't pose any significant * pessimistic, which shouldn't pose any significant
* problem anyway. * problem anyway.
*/ */
for_each_dbuf_slice_in_mask(slice_id, dbuf_mask) for_each_dbuf_slice_in_mask(dev_priv, slice, dbuf_mask)
crtc_bw->used_bw[slice_id] += data_rate; crtc_bw->used_bw[slice] += data_rate;
} }
} }
@ -445,10 +448,11 @@ int skl_bw_calc_min_cdclk(struct intel_atomic_state *state)
for_each_pipe(dev_priv, pipe) { for_each_pipe(dev_priv, pipe) {
struct intel_dbuf_bw *crtc_bw; struct intel_dbuf_bw *crtc_bw;
enum dbuf_slice slice;
crtc_bw = &new_bw_state->dbuf_bw[pipe]; crtc_bw = &new_bw_state->dbuf_bw[pipe];
for_each_dbuf_slice(slice_id) { for_each_dbuf_slice(dev_priv, slice) {
/* /*
* Current experimental observations show that contrary * Current experimental observations show that contrary
* to BSpec we get underruns once we exceed 64 * CDCLK * to BSpec we get underruns once we exceed 64 * CDCLK
@ -457,7 +461,7 @@ int skl_bw_calc_min_cdclk(struct intel_atomic_state *state)
* bumped up all the time we calculate CDCLK according * bumped up all the time we calculate CDCLK according
* to this formula for overall bw consumed by slices. * to this formula for overall bw consumed by slices.
*/ */
max_bw += crtc_bw->used_bw[slice_id]; max_bw += crtc_bw->used_bw[slice];
} }
} }

View file

@ -26,6 +26,7 @@
#include "intel_atomic.h" #include "intel_atomic.h"
#include "intel_bw.h" #include "intel_bw.h"
#include "intel_cdclk.h" #include "intel_cdclk.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_sideband.h" #include "intel_sideband.h"
@ -723,12 +724,28 @@ static void bdw_get_cdclk(struct drm_i915_private *dev_priv,
bdw_calc_voltage_level(cdclk_config->cdclk); bdw_calc_voltage_level(cdclk_config->cdclk);
} }
static u32 bdw_cdclk_freq_sel(int cdclk)
{
switch (cdclk) {
default:
MISSING_CASE(cdclk);
fallthrough;
case 337500:
return LCPLL_CLK_FREQ_337_5_BDW;
case 450000:
return LCPLL_CLK_FREQ_450;
case 540000:
return LCPLL_CLK_FREQ_54O_BDW;
case 675000:
return LCPLL_CLK_FREQ_675_BDW;
}
}
static void bdw_set_cdclk(struct drm_i915_private *dev_priv, static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
const struct intel_cdclk_config *cdclk_config, const struct intel_cdclk_config *cdclk_config,
enum pipe pipe) enum pipe pipe)
{ {
int cdclk = cdclk_config->cdclk; int cdclk = cdclk_config->cdclk;
u32 val;
int ret; int ret;
if (drm_WARN(&dev_priv->drm, if (drm_WARN(&dev_priv->drm,
@ -748,9 +765,8 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
return; return;
} }
val = intel_de_read(dev_priv, LCPLL_CTL); intel_de_rmw(dev_priv, LCPLL_CTL,
val |= LCPLL_CD_SOURCE_FCLK; 0, LCPLL_CD_SOURCE_FCLK);
intel_de_write(dev_priv, LCPLL_CTL, val);
/* /*
* According to the spec, it should be enough to poll for this 1 us. * According to the spec, it should be enough to poll for this 1 us.
@ -760,32 +776,11 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
LCPLL_CD_SOURCE_FCLK_DONE, 100)) LCPLL_CD_SOURCE_FCLK_DONE, 100))
drm_err(&dev_priv->drm, "Switching to FCLK failed\n"); drm_err(&dev_priv->drm, "Switching to FCLK failed\n");
val = intel_de_read(dev_priv, LCPLL_CTL); intel_de_rmw(dev_priv, LCPLL_CTL,
val &= ~LCPLL_CLK_FREQ_MASK; LCPLL_CLK_FREQ_MASK, bdw_cdclk_freq_sel(cdclk));
switch (cdclk) { intel_de_rmw(dev_priv, LCPLL_CTL,
default: LCPLL_CD_SOURCE_FCLK, 0);
MISSING_CASE(cdclk);
fallthrough;
case 337500:
val |= LCPLL_CLK_FREQ_337_5_BDW;
break;
case 450000:
val |= LCPLL_CLK_FREQ_450;
break;
case 540000:
val |= LCPLL_CLK_FREQ_54O_BDW;
break;
case 675000:
val |= LCPLL_CLK_FREQ_675_BDW;
break;
}
intel_de_write(dev_priv, LCPLL_CTL, val);
val = intel_de_read(dev_priv, LCPLL_CTL);
val &= ~LCPLL_CD_SOURCE_FCLK;
intel_de_write(dev_priv, LCPLL_CTL, val);
if (wait_for_us((intel_de_read(dev_priv, LCPLL_CTL) & if (wait_for_us((intel_de_read(dev_priv, LCPLL_CTL) &
LCPLL_CD_SOURCE_FCLK_DONE) == 0, 1)) LCPLL_CD_SOURCE_FCLK_DONE) == 0, 1))
@ -954,10 +949,8 @@ static void skl_set_preferred_cdclk_vco(struct drm_i915_private *dev_priv,
intel_update_max_cdclk(dev_priv); intel_update_max_cdclk(dev_priv);
} }
static void skl_dpll0_enable(struct drm_i915_private *dev_priv, int vco) static u32 skl_dpll0_link_rate(struct drm_i915_private *dev_priv, int vco)
{ {
u32 val;
drm_WARN_ON(&dev_priv->drm, vco != 8100000 && vco != 8640000); drm_WARN_ON(&dev_priv->drm, vco != 8100000 && vco != 8640000);
/* /*
@ -969,23 +962,24 @@ static void skl_dpll0_enable(struct drm_i915_private *dev_priv, int vco)
* rate later on, with the constraint of choosing a frequency that * rate later on, with the constraint of choosing a frequency that
* works with vco. * works with vco.
*/ */
val = intel_de_read(dev_priv, DPLL_CTRL1);
val &= ~(DPLL_CTRL1_HDMI_MODE(SKL_DPLL0) | DPLL_CTRL1_SSC(SKL_DPLL0) |
DPLL_CTRL1_LINK_RATE_MASK(SKL_DPLL0));
val |= DPLL_CTRL1_OVERRIDE(SKL_DPLL0);
if (vco == 8640000) if (vco == 8640000)
val |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080, return DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080, SKL_DPLL0);
SKL_DPLL0);
else else
val |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, return DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, SKL_DPLL0);
SKL_DPLL0); }
intel_de_write(dev_priv, DPLL_CTRL1, val); static void skl_dpll0_enable(struct drm_i915_private *dev_priv, int vco)
{
intel_de_rmw(dev_priv, DPLL_CTRL1,
DPLL_CTRL1_HDMI_MODE(SKL_DPLL0) |
DPLL_CTRL1_SSC(SKL_DPLL0) |
DPLL_CTRL1_LINK_RATE_MASK(SKL_DPLL0),
DPLL_CTRL1_OVERRIDE(SKL_DPLL0) |
skl_dpll0_link_rate(dev_priv, vco));
intel_de_posting_read(dev_priv, DPLL_CTRL1); intel_de_posting_read(dev_priv, DPLL_CTRL1);
intel_de_write(dev_priv, LCPLL1_CTL, intel_de_rmw(dev_priv, LCPLL1_CTL,
intel_de_read(dev_priv, LCPLL1_CTL) | LCPLL_PLL_ENABLE); 0, LCPLL_PLL_ENABLE);
if (intel_de_wait_for_set(dev_priv, LCPLL1_CTL, LCPLL_PLL_LOCK, 5)) if (intel_de_wait_for_set(dev_priv, LCPLL1_CTL, LCPLL_PLL_LOCK, 5))
drm_err(&dev_priv->drm, "DPLL0 not locked\n"); drm_err(&dev_priv->drm, "DPLL0 not locked\n");
@ -998,14 +992,38 @@ static void skl_dpll0_enable(struct drm_i915_private *dev_priv, int vco)
static void skl_dpll0_disable(struct drm_i915_private *dev_priv) static void skl_dpll0_disable(struct drm_i915_private *dev_priv)
{ {
intel_de_write(dev_priv, LCPLL1_CTL, intel_de_rmw(dev_priv, LCPLL1_CTL,
intel_de_read(dev_priv, LCPLL1_CTL) & ~LCPLL_PLL_ENABLE); LCPLL_PLL_ENABLE, 0);
if (intel_de_wait_for_clear(dev_priv, LCPLL1_CTL, LCPLL_PLL_LOCK, 1)) if (intel_de_wait_for_clear(dev_priv, LCPLL1_CTL, LCPLL_PLL_LOCK, 1))
drm_err(&dev_priv->drm, "Couldn't disable DPLL0\n"); drm_err(&dev_priv->drm, "Couldn't disable DPLL0\n");
dev_priv->cdclk.hw.vco = 0; dev_priv->cdclk.hw.vco = 0;
} }
static u32 skl_cdclk_freq_sel(struct drm_i915_private *dev_priv,
int cdclk, int vco)
{
switch (cdclk) {
default:
drm_WARN_ON(&dev_priv->drm,
cdclk != dev_priv->cdclk.hw.bypass);
drm_WARN_ON(&dev_priv->drm, vco != 0);
fallthrough;
case 308571:
case 337500:
return CDCLK_FREQ_337_308;
case 450000:
case 432000:
return CDCLK_FREQ_450_432;
case 540000:
return CDCLK_FREQ_540;
case 617143:
case 675000:
return CDCLK_FREQ_675_617;
}
}
static void skl_set_cdclk(struct drm_i915_private *dev_priv, static void skl_set_cdclk(struct drm_i915_private *dev_priv,
const struct intel_cdclk_config *cdclk_config, const struct intel_cdclk_config *cdclk_config,
enum pipe pipe) enum pipe pipe)
@ -1036,29 +1054,7 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,
return; return;
} }
/* Choose frequency for this cdclk */ freq_select = skl_cdclk_freq_sel(dev_priv, cdclk, vco);
switch (cdclk) {
default:
drm_WARN_ON(&dev_priv->drm,
cdclk != dev_priv->cdclk.hw.bypass);
drm_WARN_ON(&dev_priv->drm, vco != 0);
fallthrough;
case 308571:
case 337500:
freq_select = CDCLK_FREQ_337_308;
break;
case 450000:
case 432000:
freq_select = CDCLK_FREQ_450_432;
break;
case 540000:
freq_select = CDCLK_FREQ_540;
break;
case 617143:
case 675000:
freq_select = CDCLK_FREQ_675_617;
break;
}
if (dev_priv->cdclk.hw.vco != 0 && if (dev_priv->cdclk.hw.vco != 0 &&
dev_priv->cdclk.hw.vco != vco) dev_priv->cdclk.hw.vco != vco)
@ -1257,6 +1253,42 @@ static const struct intel_cdclk_vals rkl_cdclk_table[] = {
{} {}
}; };
static const struct intel_cdclk_vals adlp_a_step_cdclk_table[] = {
{ .refclk = 19200, .cdclk = 307200, .divider = 2, .ratio = 32 },
{ .refclk = 19200, .cdclk = 556800, .divider = 2, .ratio = 58 },
{ .refclk = 19200, .cdclk = 652800, .divider = 2, .ratio = 68 },
{ .refclk = 24000, .cdclk = 312000, .divider = 2, .ratio = 26 },
{ .refclk = 24000, .cdclk = 552000, .divider = 2, .ratio = 46 },
{ .refclk = 24400, .cdclk = 648000, .divider = 2, .ratio = 54 },
{ .refclk = 38400, .cdclk = 307200, .divider = 2, .ratio = 16 },
{ .refclk = 38400, .cdclk = 556800, .divider = 2, .ratio = 29 },
{ .refclk = 38400, .cdclk = 652800, .divider = 2, .ratio = 34 },
{}
};
static const struct intel_cdclk_vals adlp_cdclk_table[] = {
{ .refclk = 19200, .cdclk = 172800, .divider = 3, .ratio = 27 },
{ .refclk = 19200, .cdclk = 192000, .divider = 2, .ratio = 20 },
{ .refclk = 19200, .cdclk = 307200, .divider = 2, .ratio = 32 },
{ .refclk = 19200, .cdclk = 556800, .divider = 2, .ratio = 58 },
{ .refclk = 19200, .cdclk = 652800, .divider = 2, .ratio = 68 },
{ .refclk = 24000, .cdclk = 176000, .divider = 3, .ratio = 22 },
{ .refclk = 24000, .cdclk = 192000, .divider = 2, .ratio = 16 },
{ .refclk = 24000, .cdclk = 312000, .divider = 2, .ratio = 26 },
{ .refclk = 24000, .cdclk = 552000, .divider = 2, .ratio = 46 },
{ .refclk = 24400, .cdclk = 648000, .divider = 2, .ratio = 54 },
{ .refclk = 38400, .cdclk = 179200, .divider = 3, .ratio = 14 },
{ .refclk = 38400, .cdclk = 192000, .divider = 2, .ratio = 10 },
{ .refclk = 38400, .cdclk = 307200, .divider = 2, .ratio = 16 },
{ .refclk = 38400, .cdclk = 556800, .divider = 2, .ratio = 29 },
{ .refclk = 38400, .cdclk = 652800, .divider = 2, .ratio = 34 },
{}
};
static int bxt_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk) static int bxt_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk)
{ {
const struct intel_cdclk_vals *table = dev_priv->cdclk.table; const struct intel_cdclk_vals *table = dev_priv->cdclk.table;
@ -1432,18 +1464,12 @@ static void bxt_get_cdclk(struct drm_i915_private *dev_priv,
div = 2; div = 2;
break; break;
case BXT_CDCLK_CD2X_DIV_SEL_1_5: case BXT_CDCLK_CD2X_DIV_SEL_1_5:
drm_WARN(&dev_priv->drm,
DISPLAY_VER(dev_priv) >= 10,
"Unsupported divider\n");
div = 3; div = 3;
break; break;
case BXT_CDCLK_CD2X_DIV_SEL_2: case BXT_CDCLK_CD2X_DIV_SEL_2:
div = 4; div = 4;
break; break;
case BXT_CDCLK_CD2X_DIV_SEL_4: case BXT_CDCLK_CD2X_DIV_SEL_4:
drm_WARN(&dev_priv->drm,
DISPLAY_VER(dev_priv) >= 11 || IS_CANNONLAKE(dev_priv),
"Unsupported divider\n");
div = 8; div = 8;
break; break;
default: default:
@ -1477,12 +1503,9 @@ static void bxt_de_pll_disable(struct drm_i915_private *dev_priv)
static void bxt_de_pll_enable(struct drm_i915_private *dev_priv, int vco) static void bxt_de_pll_enable(struct drm_i915_private *dev_priv, int vco)
{ {
int ratio = DIV_ROUND_CLOSEST(vco, dev_priv->cdclk.hw.ref); int ratio = DIV_ROUND_CLOSEST(vco, dev_priv->cdclk.hw.ref);
u32 val;
val = intel_de_read(dev_priv, BXT_DE_PLL_CTL); intel_de_rmw(dev_priv, BXT_DE_PLL_CTL,
val &= ~BXT_DE_PLL_RATIO_MASK; BXT_DE_PLL_RATIO_MASK, BXT_DE_PLL_RATIO(ratio));
val |= BXT_DE_PLL_RATIO(ratio);
intel_de_write(dev_priv, BXT_DE_PLL_CTL, val);
intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, BXT_DE_PLL_PLL_ENABLE); intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, BXT_DE_PLL_PLL_ENABLE);
@ -1496,16 +1519,12 @@ static void bxt_de_pll_enable(struct drm_i915_private *dev_priv, int vco)
static void cnl_cdclk_pll_disable(struct drm_i915_private *dev_priv) static void cnl_cdclk_pll_disable(struct drm_i915_private *dev_priv)
{ {
u32 val; intel_de_rmw(dev_priv, BXT_DE_PLL_ENABLE,
BXT_DE_PLL_PLL_ENABLE, 0);
val = intel_de_read(dev_priv, BXT_DE_PLL_ENABLE);
val &= ~BXT_DE_PLL_PLL_ENABLE;
intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, val);
/* Timeout 200us */ /* Timeout 200us */
if (wait_for((intel_de_read(dev_priv, BXT_DE_PLL_ENABLE) & BXT_DE_PLL_LOCK) == 0, 1)) if (intel_de_wait_for_clear(dev_priv, BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK, 1))
drm_err(&dev_priv->drm, drm_err(&dev_priv->drm, "timeout waiting for CDCLK PLL unlock\n");
"timeout waiting for CDCLK PLL unlock\n");
dev_priv->cdclk.hw.vco = 0; dev_priv->cdclk.hw.vco = 0;
} }
@ -1522,9 +1541,8 @@ static void cnl_cdclk_pll_enable(struct drm_i915_private *dev_priv, int vco)
intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, val); intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, val);
/* Timeout 200us */ /* Timeout 200us */
if (wait_for((intel_de_read(dev_priv, BXT_DE_PLL_ENABLE) & BXT_DE_PLL_LOCK) != 0, 1)) if (intel_de_wait_for_set(dev_priv, BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK, 1))
drm_err(&dev_priv->drm, drm_err(&dev_priv->drm, "timeout waiting for CDCLK PLL lock\n");
"timeout waiting for CDCLK PLL lock\n");
dev_priv->cdclk.hw.vco = vco; dev_priv->cdclk.hw.vco = vco;
} }
@ -1549,13 +1567,34 @@ static u32 bxt_cdclk_cd2x_pipe(struct drm_i915_private *dev_priv, enum pipe pipe
} }
} }
static u32 bxt_cdclk_cd2x_div_sel(struct drm_i915_private *dev_priv,
int cdclk, int vco)
{
/* cdclk = vco / 2 / div{1,1.5,2,4} */
switch (DIV_ROUND_CLOSEST(vco, cdclk)) {
default:
drm_WARN_ON(&dev_priv->drm,
cdclk != dev_priv->cdclk.hw.bypass);
drm_WARN_ON(&dev_priv->drm, vco != 0);
fallthrough;
case 2:
return BXT_CDCLK_CD2X_DIV_SEL_1;
case 3:
return BXT_CDCLK_CD2X_DIV_SEL_1_5;
case 4:
return BXT_CDCLK_CD2X_DIV_SEL_2;
case 8:
return BXT_CDCLK_CD2X_DIV_SEL_4;
}
}
static void bxt_set_cdclk(struct drm_i915_private *dev_priv, static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
const struct intel_cdclk_config *cdclk_config, const struct intel_cdclk_config *cdclk_config,
enum pipe pipe) enum pipe pipe)
{ {
int cdclk = cdclk_config->cdclk; int cdclk = cdclk_config->cdclk;
int vco = cdclk_config->vco; int vco = cdclk_config->vco;
u32 val, divider; u32 val;
int ret; int ret;
/* Inform power controller of upcoming frequency change. */ /* Inform power controller of upcoming frequency change. */
@ -1580,33 +1619,6 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
return; return;
} }
/* cdclk = vco / 2 / div{1,1.5,2,4} */
switch (DIV_ROUND_CLOSEST(vco, cdclk)) {
default:
drm_WARN_ON(&dev_priv->drm,
cdclk != dev_priv->cdclk.hw.bypass);
drm_WARN_ON(&dev_priv->drm, vco != 0);
fallthrough;
case 2:
divider = BXT_CDCLK_CD2X_DIV_SEL_1;
break;
case 3:
drm_WARN(&dev_priv->drm,
DISPLAY_VER(dev_priv) >= 10,
"Unsupported divider\n");
divider = BXT_CDCLK_CD2X_DIV_SEL_1_5;
break;
case 4:
divider = BXT_CDCLK_CD2X_DIV_SEL_2;
break;
case 8:
drm_WARN(&dev_priv->drm,
DISPLAY_VER(dev_priv) >= 11 || IS_CANNONLAKE(dev_priv),
"Unsupported divider\n");
divider = BXT_CDCLK_CD2X_DIV_SEL_4;
break;
}
if (DISPLAY_VER(dev_priv) >= 11 || IS_CANNONLAKE(dev_priv)) { if (DISPLAY_VER(dev_priv) >= 11 || IS_CANNONLAKE(dev_priv)) {
if (dev_priv->cdclk.hw.vco != 0 && if (dev_priv->cdclk.hw.vco != 0 &&
dev_priv->cdclk.hw.vco != vco) dev_priv->cdclk.hw.vco != vco)
@ -1624,14 +1636,16 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
bxt_de_pll_enable(dev_priv, vco); bxt_de_pll_enable(dev_priv, vco);
} }
val = divider | skl_cdclk_decimal(cdclk) | val = bxt_cdclk_cd2x_div_sel(dev_priv, cdclk, vco) |
bxt_cdclk_cd2x_pipe(dev_priv, pipe); bxt_cdclk_cd2x_pipe(dev_priv, pipe) |
skl_cdclk_decimal(cdclk);
/* /*
* Disable SSA Precharge when CD clock frequency < 500 MHz, * Disable SSA Precharge when CD clock frequency < 500 MHz,
* enable otherwise. * enable otherwise.
*/ */
if (IS_GEN9_LP(dev_priv) && cdclk >= 500000) if ((IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) &&
cdclk >= 500000)
val |= BXT_CDCLK_SSA_PRECHARGE_ENABLE; val |= BXT_CDCLK_SSA_PRECHARGE_ENABLE;
intel_de_write(dev_priv, CDCLK_CTL, val); intel_de_write(dev_priv, CDCLK_CTL, val);
@ -1710,29 +1724,16 @@ static void bxt_sanitize_cdclk(struct drm_i915_private *dev_priv)
expected = skl_cdclk_decimal(cdclk); expected = skl_cdclk_decimal(cdclk);
/* Figure out what CD2X divider we should be using for this cdclk */ /* Figure out what CD2X divider we should be using for this cdclk */
switch (DIV_ROUND_CLOSEST(dev_priv->cdclk.hw.vco, expected |= bxt_cdclk_cd2x_div_sel(dev_priv,
dev_priv->cdclk.hw.cdclk)) { dev_priv->cdclk.hw.cdclk,
case 2: dev_priv->cdclk.hw.vco);
expected |= BXT_CDCLK_CD2X_DIV_SEL_1;
break;
case 3:
expected |= BXT_CDCLK_CD2X_DIV_SEL_1_5;
break;
case 4:
expected |= BXT_CDCLK_CD2X_DIV_SEL_2;
break;
case 8:
expected |= BXT_CDCLK_CD2X_DIV_SEL_4;
break;
default:
goto sanitize;
}
/* /*
* Disable SSA Precharge when CD clock frequency < 500 MHz, * Disable SSA Precharge when CD clock frequency < 500 MHz,
* enable otherwise. * enable otherwise.
*/ */
if (IS_GEN9_LP(dev_priv) && dev_priv->cdclk.hw.cdclk >= 500000) if ((IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) &&
dev_priv->cdclk.hw.cdclk >= 500000)
expected |= BXT_CDCLK_SSA_PRECHARGE_ENABLE; expected |= BXT_CDCLK_SSA_PRECHARGE_ENABLE;
if (cdctl == expected) if (cdctl == expected)
@ -1797,9 +1798,9 @@ static void bxt_cdclk_uninit_hw(struct drm_i915_private *dev_priv)
*/ */
void intel_cdclk_init_hw(struct drm_i915_private *i915) void intel_cdclk_init_hw(struct drm_i915_private *i915)
{ {
if (IS_GEN9_LP(i915) || DISPLAY_VER(i915) >= 10) if (DISPLAY_VER(i915) >= 10 || IS_BROXTON(i915))
bxt_cdclk_init_hw(i915); bxt_cdclk_init_hw(i915);
else if (IS_GEN9_BC(i915)) else if (DISPLAY_VER(i915) == 9)
skl_cdclk_init_hw(i915); skl_cdclk_init_hw(i915);
} }
@ -1812,9 +1813,9 @@ void intel_cdclk_init_hw(struct drm_i915_private *i915)
*/ */
void intel_cdclk_uninit_hw(struct drm_i915_private *i915) void intel_cdclk_uninit_hw(struct drm_i915_private *i915)
{ {
if (DISPLAY_VER(i915) >= 10 || IS_GEN9_LP(i915)) if (DISPLAY_VER(i915) >= 10 || IS_BROXTON(i915))
bxt_cdclk_uninit_hw(i915); bxt_cdclk_uninit_hw(i915);
else if (IS_GEN9_BC(i915)) else if (DISPLAY_VER(i915) == 9)
skl_cdclk_uninit_hw(i915); skl_cdclk_uninit_hw(i915);
} }
@ -1852,7 +1853,7 @@ static bool intel_cdclk_can_cd2x_update(struct drm_i915_private *dev_priv,
const struct intel_cdclk_config *b) const struct intel_cdclk_config *b)
{ {
/* Older hw doesn't have the capability */ /* Older hw doesn't have the capability */
if (DISPLAY_VER(dev_priv) < 10 && !IS_GEN9_LP(dev_priv)) if (DISPLAY_VER(dev_priv) < 10 && !IS_BROXTON(dev_priv))
return false; return false;
return a->cdclk != b->cdclk && return a->cdclk != b->cdclk &&
@ -2002,7 +2003,7 @@ static int intel_pixel_rate_to_cdclk(const struct intel_crtc_state *crtc_state)
if (DISPLAY_VER(dev_priv) >= 10) if (DISPLAY_VER(dev_priv) >= 10)
return DIV_ROUND_UP(pixel_rate, 2); return DIV_ROUND_UP(pixel_rate, 2);
else if (IS_DISPLAY_VER(dev_priv, 9) || else if (DISPLAY_VER(dev_priv) == 9 ||
IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
return pixel_rate; return pixel_rate;
else if (IS_CHERRYVIEW(dev_priv)) else if (IS_CHERRYVIEW(dev_priv))
@ -2050,10 +2051,10 @@ int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state)
crtc_state->has_audio && crtc_state->has_audio &&
crtc_state->port_clock >= 540000 && crtc_state->port_clock >= 540000 &&
crtc_state->lane_count == 4) { crtc_state->lane_count == 4) {
if (IS_DISPLAY_VER(dev_priv, 10)) { if (DISPLAY_VER(dev_priv) == 10) {
/* Display WA #1145: glk,cnl */ /* Display WA #1145: glk,cnl */
min_cdclk = max(316800, min_cdclk); min_cdclk = max(316800, min_cdclk);
} else if (IS_DISPLAY_VER(dev_priv, 9) || IS_BROADWELL(dev_priv)) { } else if (DISPLAY_VER(dev_priv) == 9 || IS_BROADWELL(dev_priv)) {
/* Display WA #1144: skl,bxt */ /* Display WA #1144: skl,bxt */
min_cdclk = max(432000, min_cdclk); min_cdclk = max(432000, min_cdclk);
} }
@ -2389,44 +2390,6 @@ static int bxt_modeset_calc_cdclk(struct intel_cdclk_state *cdclk_state)
return 0; return 0;
} }
static int intel_modeset_all_pipes(struct intel_atomic_state *state)
{
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
struct intel_crtc *crtc;
/*
* Add all pipes to the state, and force
* a modeset on all the active ones.
*/
for_each_intel_crtc(&dev_priv->drm, crtc) {
struct intel_crtc_state *crtc_state;
int ret;
crtc_state = intel_atomic_get_crtc_state(&state->base, crtc);
if (IS_ERR(crtc_state))
return PTR_ERR(crtc_state);
if (!crtc_state->hw.active ||
drm_atomic_crtc_needs_modeset(&crtc_state->uapi))
continue;
crtc_state->uapi.mode_changed = true;
ret = drm_atomic_add_affected_connectors(&state->base,
&crtc->base);
if (ret)
return ret;
ret = intel_atomic_add_affected_planes(state, crtc);
if (ret)
return ret;
crtc_state->update_planes |= crtc_state->active_planes;
}
return 0;
}
static int fixed_modeset_calc_cdclk(struct intel_cdclk_state *cdclk_state) static int fixed_modeset_calc_cdclk(struct intel_cdclk_state *cdclk_state)
{ {
int min_cdclk; int min_cdclk;
@ -2592,7 +2555,7 @@ static int intel_compute_max_dotclk(struct drm_i915_private *dev_priv)
if (DISPLAY_VER(dev_priv) >= 10) if (DISPLAY_VER(dev_priv) >= 10)
return 2 * max_cdclk_freq; return 2 * max_cdclk_freq;
else if (IS_DISPLAY_VER(dev_priv, 9) || else if (DISPLAY_VER(dev_priv) == 9 ||
IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
return max_cdclk_freq; return max_cdclk_freq;
else if (IS_CHERRYVIEW(dev_priv)) else if (IS_CHERRYVIEW(dev_priv))
@ -2625,7 +2588,11 @@ void intel_update_max_cdclk(struct drm_i915_private *dev_priv)
dev_priv->max_cdclk_freq = 652800; dev_priv->max_cdclk_freq = 652800;
} else if (IS_CANNONLAKE(dev_priv)) { } else if (IS_CANNONLAKE(dev_priv)) {
dev_priv->max_cdclk_freq = 528000; dev_priv->max_cdclk_freq = 528000;
} else if (IS_GEN9_BC(dev_priv)) { } else if (IS_GEMINILAKE(dev_priv)) {
dev_priv->max_cdclk_freq = 316800;
} else if (IS_BROXTON(dev_priv)) {
dev_priv->max_cdclk_freq = 624000;
} else if (DISPLAY_VER(dev_priv) == 9) {
u32 limit = intel_de_read(dev_priv, SKL_DFSM) & SKL_DFSM_CDCLK_LIMIT_MASK; u32 limit = intel_de_read(dev_priv, SKL_DFSM) & SKL_DFSM_CDCLK_LIMIT_MASK;
int max_cdclk, vco; int max_cdclk, vco;
@ -2647,10 +2614,6 @@ void intel_update_max_cdclk(struct drm_i915_private *dev_priv)
max_cdclk = 308571; max_cdclk = 308571;
dev_priv->max_cdclk_freq = skl_calc_cdclk(max_cdclk, vco); dev_priv->max_cdclk_freq = skl_calc_cdclk(max_cdclk, vco);
} else if (IS_GEMINILAKE(dev_priv)) {
dev_priv->max_cdclk_freq = 316800;
} else if (IS_BROXTON(dev_priv)) {
dev_priv->max_cdclk_freq = 624000;
} else if (IS_BROADWELL(dev_priv)) { } else if (IS_BROADWELL(dev_priv)) {
/* /*
* FIXME with extra cooling we can allow * FIXME with extra cooling we can allow
@ -2848,7 +2811,17 @@ u32 intel_read_rawclk(struct drm_i915_private *dev_priv)
*/ */
void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv) void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv)
{ {
if (IS_ROCKETLAKE(dev_priv)) { if (IS_ALDERLAKE_P(dev_priv)) {
dev_priv->display.set_cdclk = bxt_set_cdclk;
dev_priv->display.bw_calc_min_cdclk = skl_bw_calc_min_cdclk;
dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk;
dev_priv->display.calc_voltage_level = tgl_calc_voltage_level;
/* Wa_22011320316:adlp[a0] */
if (IS_ADLP_DISPLAY_STEP(dev_priv, STEP_A0, STEP_A0))
dev_priv->cdclk.table = adlp_a_step_cdclk_table;
else
dev_priv->cdclk.table = adlp_cdclk_table;
} else if (IS_ROCKETLAKE(dev_priv)) {
dev_priv->display.set_cdclk = bxt_set_cdclk; dev_priv->display.set_cdclk = bxt_set_cdclk;
dev_priv->display.bw_calc_min_cdclk = skl_bw_calc_min_cdclk; dev_priv->display.bw_calc_min_cdclk = skl_bw_calc_min_cdclk;
dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk; dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk;
@ -2878,7 +2851,7 @@ void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv)
dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk; dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk;
dev_priv->display.calc_voltage_level = cnl_calc_voltage_level; dev_priv->display.calc_voltage_level = cnl_calc_voltage_level;
dev_priv->cdclk.table = cnl_cdclk_table; dev_priv->cdclk.table = cnl_cdclk_table;
} else if (IS_GEN9_LP(dev_priv)) { } else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) {
dev_priv->display.bw_calc_min_cdclk = skl_bw_calc_min_cdclk; dev_priv->display.bw_calc_min_cdclk = skl_bw_calc_min_cdclk;
dev_priv->display.set_cdclk = bxt_set_cdclk; dev_priv->display.set_cdclk = bxt_set_cdclk;
dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk; dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk;
@ -2887,7 +2860,7 @@ void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv)
dev_priv->cdclk.table = glk_cdclk_table; dev_priv->cdclk.table = glk_cdclk_table;
else else
dev_priv->cdclk.table = bxt_cdclk_table; dev_priv->cdclk.table = bxt_cdclk_table;
} else if (IS_GEN9_BC(dev_priv)) { } else if (DISPLAY_VER(dev_priv) == 9) {
dev_priv->display.bw_calc_min_cdclk = skl_bw_calc_min_cdclk; dev_priv->display.bw_calc_min_cdclk = skl_bw_calc_min_cdclk;
dev_priv->display.set_cdclk = skl_set_cdclk; dev_priv->display.set_cdclk = skl_set_cdclk;
dev_priv->display.modeset_calc_cdclk = skl_modeset_calc_cdclk; dev_priv->display.modeset_calc_cdclk = skl_modeset_calc_cdclk;
@ -2908,9 +2881,9 @@ void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv)
dev_priv->display.modeset_calc_cdclk = fixed_modeset_calc_cdclk; dev_priv->display.modeset_calc_cdclk = fixed_modeset_calc_cdclk;
} }
if (DISPLAY_VER(dev_priv) >= 10 || IS_GEN9_LP(dev_priv)) if (DISPLAY_VER(dev_priv) >= 10 || IS_BROXTON(dev_priv))
dev_priv->display.get_cdclk = bxt_get_cdclk; dev_priv->display.get_cdclk = bxt_get_cdclk;
else if (IS_GEN9_BC(dev_priv)) else if (DISPLAY_VER(dev_priv) == 9)
dev_priv->display.get_cdclk = skl_get_cdclk; dev_priv->display.get_cdclk = skl_get_cdclk;
else if (IS_BROADWELL(dev_priv)) else if (IS_BROADWELL(dev_priv))
dev_priv->display.get_cdclk = bdw_get_cdclk; dev_priv->display.get_cdclk = bdw_get_cdclk;

View file

@ -23,6 +23,7 @@
*/ */
#include "intel_color.h" #include "intel_color.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#define CTM_COEFF_SIGN (1ULL << 63) #define CTM_COEFF_SIGN (1ULL << 63)
@ -225,7 +226,7 @@ static bool ilk_csc_limited_range(const struct intel_crtc_state *crtc_state)
*/ */
return crtc_state->limited_color_range && return crtc_state->limited_color_range &&
(IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv) || (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv) ||
IS_DISPLAY_RANGE(dev_priv, 9, 10)); IS_DISPLAY_VER(dev_priv, 9, 10));
} }
static void ilk_csc_convert_ctm(const struct intel_crtc_state *crtc_state, static void ilk_csc_convert_ctm(const struct intel_crtc_state *crtc_state,
@ -1711,7 +1712,7 @@ int intel_color_get_gamma_bit_precision(const struct intel_crtc_state *crtc_stat
} else { } else {
if (DISPLAY_VER(dev_priv) >= 11) if (DISPLAY_VER(dev_priv) >= 11)
return icl_gamma_precision(crtc_state); return icl_gamma_precision(crtc_state);
else if (IS_DISPLAY_VER(dev_priv, 10)) else if (DISPLAY_VER(dev_priv) == 10)
return glk_gamma_precision(crtc_state); return glk_gamma_precision(crtc_state);
else if (IS_IRONLAKE(dev_priv)) else if (IS_IRONLAKE(dev_priv))
return ilk_gamma_precision(crtc_state); return ilk_gamma_precision(crtc_state);
@ -2136,7 +2137,7 @@ void intel_color_init(struct intel_crtc *crtc)
if (DISPLAY_VER(dev_priv) >= 11) { if (DISPLAY_VER(dev_priv) >= 11) {
dev_priv->display.load_luts = icl_load_luts; dev_priv->display.load_luts = icl_load_luts;
dev_priv->display.read_luts = icl_read_luts; dev_priv->display.read_luts = icl_read_luts;
} else if (IS_DISPLAY_VER(dev_priv, 10)) { } else if (DISPLAY_VER(dev_priv) == 10) {
dev_priv->display.load_luts = glk_load_luts; dev_priv->display.load_luts = glk_load_luts;
dev_priv->display.read_luts = glk_read_luts; dev_priv->display.read_luts = glk_read_luts;
} else if (DISPLAY_VER(dev_priv) >= 8) { } else if (DISPLAY_VER(dev_priv) >= 8) {

View file

@ -4,6 +4,7 @@
*/ */
#include "intel_combo_phy.h" #include "intel_combo_phy.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#define for_each_combo_phy(__dev_priv, __phy) \ #define for_each_combo_phy(__dev_priv, __phy) \

View file

@ -36,7 +36,9 @@
#include "i915_drv.h" #include "i915_drv.h"
#include "intel_connector.h" #include "intel_connector.h"
#include "intel_crt.h" #include "intel_crt.h"
#include "intel_crtc.h"
#include "intel_ddi.h" #include "intel_ddi.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_fdi.h" #include "intel_fdi.h"
#include "intel_fifo_underrun.h" #include "intel_fifo_underrun.h"
@ -356,7 +358,7 @@ intel_crt_mode_valid(struct drm_connector *connector,
* DAC limit supposedly 355 MHz. * DAC limit supposedly 355 MHz.
*/ */
max_clock = 270000; max_clock = 270000;
else if (IS_DISPLAY_RANGE(dev_priv, 3, 4)) else if (IS_DISPLAY_VER(dev_priv, 3, 4))
max_clock = 400000; max_clock = 400000;
else else
max_clock = 350000; max_clock = 350000;
@ -711,7 +713,7 @@ intel_crt_load_detect(struct intel_crt *crt, u32 pipe)
/* Set the border color to purple. */ /* Set the border color to purple. */
intel_uncore_write(uncore, bclrpat_reg, 0x500050); intel_uncore_write(uncore, bclrpat_reg, 0x500050);
if (!IS_DISPLAY_VER(dev_priv, 2)) { if (DISPLAY_VER(dev_priv) != 2) {
u32 pipeconf = intel_uncore_read(uncore, pipeconf_reg); u32 pipeconf = intel_uncore_read(uncore, pipeconf_reg);
intel_uncore_write(uncore, intel_uncore_write(uncore,
pipeconf_reg, pipeconf_reg,
@ -1047,7 +1049,7 @@ void intel_crt_init(struct drm_i915_private *dev_priv)
else else
crt->base.pipe_mask = ~0; crt->base.pipe_mask = ~0;
if (IS_DISPLAY_VER(dev_priv, 2)) if (DISPLAY_VER(dev_priv) == 2)
connector->interlace_allowed = 0; connector->interlace_allowed = 0;
else else
connector->interlace_allowed = 1; connector->interlace_allowed = 1;

View file

@ -302,11 +302,11 @@ int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe)
if (IS_CHERRYVIEW(dev_priv) || if (IS_CHERRYVIEW(dev_priv) ||
IS_VALLEYVIEW(dev_priv) || IS_G4X(dev_priv)) IS_VALLEYVIEW(dev_priv) || IS_G4X(dev_priv))
funcs = &g4x_crtc_funcs; funcs = &g4x_crtc_funcs;
else if (IS_DISPLAY_VER(dev_priv, 4)) else if (DISPLAY_VER(dev_priv) == 4)
funcs = &i965_crtc_funcs; funcs = &i965_crtc_funcs;
else if (IS_I945GM(dev_priv) || IS_I915GM(dev_priv)) else if (IS_I945GM(dev_priv) || IS_I915GM(dev_priv))
funcs = &i915gm_crtc_funcs; funcs = &i915gm_crtc_funcs;
else if (IS_DISPLAY_VER(dev_priv, 3)) else if (DISPLAY_VER(dev_priv) == 3)
funcs = &i915_crtc_funcs; funcs = &i915_crtc_funcs;
else else
funcs = &i8xx_crtc_funcs; funcs = &i8xx_crtc_funcs;

View file

@ -18,5 +18,8 @@ int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe);
struct intel_crtc_state *intel_crtc_state_alloc(struct intel_crtc *crtc); struct intel_crtc_state *intel_crtc_state_alloc(struct intel_crtc *crtc);
void intel_crtc_state_reset(struct intel_crtc_state *crtc_state, void intel_crtc_state_reset(struct intel_crtc_state *crtc_state,
struct intel_crtc *crtc); struct intel_crtc *crtc);
u32 intel_crtc_get_vblank_counter(struct intel_crtc *crtc);
void intel_crtc_vblank_on(const struct intel_crtc_state *crtc_state);
void intel_crtc_vblank_off(const struct intel_crtc_state *crtc_state);
#endif #endif

View file

@ -38,50 +38,56 @@
* low-power state and comes back to normal. * low-power state and comes back to normal.
*/ */
#define DMC_PATH(platform, major, minor) \
"i915/" \
__stringify(platform) "_dmc_ver" \
__stringify(major) "_" \
__stringify(minor) ".bin"
#define GEN12_CSR_MAX_FW_SIZE ICL_CSR_MAX_FW_SIZE #define GEN12_CSR_MAX_FW_SIZE ICL_CSR_MAX_FW_SIZE
#define ADLS_CSR_PATH "i915/adls_dmc_ver2_01.bin" #define ADLS_CSR_PATH DMC_PATH(adls, 2, 01)
#define ADLS_CSR_VERSION_REQUIRED CSR_VERSION(2, 1) #define ADLS_CSR_VERSION_REQUIRED CSR_VERSION(2, 1)
MODULE_FIRMWARE(ADLS_CSR_PATH); MODULE_FIRMWARE(ADLS_CSR_PATH);
#define DG1_CSR_PATH "i915/dg1_dmc_ver2_02.bin" #define DG1_CSR_PATH DMC_PATH(dg1, 2, 02)
#define DG1_CSR_VERSION_REQUIRED CSR_VERSION(2, 2) #define DG1_CSR_VERSION_REQUIRED CSR_VERSION(2, 2)
MODULE_FIRMWARE(DG1_CSR_PATH); MODULE_FIRMWARE(DG1_CSR_PATH);
#define RKL_CSR_PATH "i915/rkl_dmc_ver2_02.bin" #define RKL_CSR_PATH DMC_PATH(rkl, 2, 02)
#define RKL_CSR_VERSION_REQUIRED CSR_VERSION(2, 2) #define RKL_CSR_VERSION_REQUIRED CSR_VERSION(2, 2)
MODULE_FIRMWARE(RKL_CSR_PATH); MODULE_FIRMWARE(RKL_CSR_PATH);
#define TGL_CSR_PATH "i915/tgl_dmc_ver2_08.bin" #define TGL_CSR_PATH DMC_PATH(tgl, 2, 08)
#define TGL_CSR_VERSION_REQUIRED CSR_VERSION(2, 8) #define TGL_CSR_VERSION_REQUIRED CSR_VERSION(2, 8)
MODULE_FIRMWARE(TGL_CSR_PATH); MODULE_FIRMWARE(TGL_CSR_PATH);
#define ICL_CSR_PATH "i915/icl_dmc_ver1_09.bin" #define ICL_CSR_PATH DMC_PATH(icl, 1, 09)
#define ICL_CSR_VERSION_REQUIRED CSR_VERSION(1, 9) #define ICL_CSR_VERSION_REQUIRED CSR_VERSION(1, 9)
#define ICL_CSR_MAX_FW_SIZE 0x6000 #define ICL_CSR_MAX_FW_SIZE 0x6000
MODULE_FIRMWARE(ICL_CSR_PATH); MODULE_FIRMWARE(ICL_CSR_PATH);
#define CNL_CSR_PATH "i915/cnl_dmc_ver1_07.bin" #define CNL_CSR_PATH DMC_PATH(cnl, 1, 07)
#define CNL_CSR_VERSION_REQUIRED CSR_VERSION(1, 7) #define CNL_CSR_VERSION_REQUIRED CSR_VERSION(1, 7)
#define CNL_CSR_MAX_FW_SIZE GLK_CSR_MAX_FW_SIZE #define CNL_CSR_MAX_FW_SIZE GLK_CSR_MAX_FW_SIZE
MODULE_FIRMWARE(CNL_CSR_PATH); MODULE_FIRMWARE(CNL_CSR_PATH);
#define GLK_CSR_PATH "i915/glk_dmc_ver1_04.bin" #define GLK_CSR_PATH DMC_PATH(glk, 1, 04)
#define GLK_CSR_VERSION_REQUIRED CSR_VERSION(1, 4) #define GLK_CSR_VERSION_REQUIRED CSR_VERSION(1, 4)
#define GLK_CSR_MAX_FW_SIZE 0x4000 #define GLK_CSR_MAX_FW_SIZE 0x4000
MODULE_FIRMWARE(GLK_CSR_PATH); MODULE_FIRMWARE(GLK_CSR_PATH);
#define KBL_CSR_PATH "i915/kbl_dmc_ver1_04.bin" #define KBL_CSR_PATH DMC_PATH(kbl, 1, 04)
#define KBL_CSR_VERSION_REQUIRED CSR_VERSION(1, 4) #define KBL_CSR_VERSION_REQUIRED CSR_VERSION(1, 4)
#define KBL_CSR_MAX_FW_SIZE BXT_CSR_MAX_FW_SIZE #define KBL_CSR_MAX_FW_SIZE BXT_CSR_MAX_FW_SIZE
MODULE_FIRMWARE(KBL_CSR_PATH); MODULE_FIRMWARE(KBL_CSR_PATH);
#define SKL_CSR_PATH "i915/skl_dmc_ver1_27.bin" #define SKL_CSR_PATH DMC_PATH(skl, 1, 27)
#define SKL_CSR_VERSION_REQUIRED CSR_VERSION(1, 27) #define SKL_CSR_VERSION_REQUIRED CSR_VERSION(1, 27)
#define SKL_CSR_MAX_FW_SIZE BXT_CSR_MAX_FW_SIZE #define SKL_CSR_MAX_FW_SIZE BXT_CSR_MAX_FW_SIZE
MODULE_FIRMWARE(SKL_CSR_PATH); MODULE_FIRMWARE(SKL_CSR_PATH);
#define BXT_CSR_PATH "i915/bxt_dmc_ver1_07.bin" #define BXT_CSR_PATH DMC_PATH(bxt, 1, 07)
#define BXT_CSR_VERSION_REQUIRED CSR_VERSION(1, 7) #define BXT_CSR_VERSION_REQUIRED CSR_VERSION(1, 7)
#define BXT_CSR_MAX_FW_SIZE 0x3000 #define BXT_CSR_MAX_FW_SIZE 0x3000
MODULE_FIRMWARE(BXT_CSR_PATH); MODULE_FIRMWARE(BXT_CSR_PATH);
@ -284,7 +290,7 @@ static void gen9_set_dc_state_debugmask(struct drm_i915_private *dev_priv)
mask = DC_STATE_DEBUG_MASK_MEMORY_UP; mask = DC_STATE_DEBUG_MASK_MEMORY_UP;
if (IS_GEN9_LP(dev_priv)) if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
mask |= DC_STATE_DEBUG_MASK_CORES; mask |= DC_STATE_DEBUG_MASK_CORES;
/* The below bit doesn't need to be cleared ever afterwards */ /* The below bit doesn't need to be cleared ever afterwards */
@ -709,7 +715,7 @@ void intel_csr_ucode_init(struct drm_i915_private *dev_priv)
csr->fw_path = TGL_CSR_PATH; csr->fw_path = TGL_CSR_PATH;
csr->required_version = TGL_CSR_VERSION_REQUIRED; csr->required_version = TGL_CSR_VERSION_REQUIRED;
csr->max_fw_size = GEN12_CSR_MAX_FW_SIZE; csr->max_fw_size = GEN12_CSR_MAX_FW_SIZE;
} else if (IS_DISPLAY_VER(dev_priv, 11)) { } else if (DISPLAY_VER(dev_priv) == 11) {
csr->fw_path = ICL_CSR_PATH; csr->fw_path = ICL_CSR_PATH;
csr->required_version = ICL_CSR_VERSION_REQUIRED; csr->required_version = ICL_CSR_VERSION_REQUIRED;
csr->max_fw_size = ICL_CSR_MAX_FW_SIZE; csr->max_fw_size = ICL_CSR_MAX_FW_SIZE;

View file

@ -13,6 +13,7 @@
#include "intel_atomic.h" #include "intel_atomic.h"
#include "intel_atomic_plane.h" #include "intel_atomic_plane.h"
#include "intel_cursor.h" #include "intel_cursor.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_display.h" #include "intel_display.h"
#include "intel_fb.h" #include "intel_fb.h"

View file

@ -31,8 +31,10 @@
#include "intel_audio.h" #include "intel_audio.h"
#include "intel_combo_phy.h" #include "intel_combo_phy.h"
#include "intel_connector.h" #include "intel_connector.h"
#include "intel_crtc.h"
#include "intel_ddi.h" #include "intel_ddi.h"
#include "intel_ddi_buf_trans.h" #include "intel_ddi_buf_trans.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_dp.h" #include "intel_dp.h"
#include "intel_dp_link_training.h" #include "intel_dp_link_training.h"
@ -113,7 +115,8 @@ void intel_prepare_dp_ddi_buffers(struct intel_encoder *encoder,
&n_entries); &n_entries);
/* If we're boosting the current, set bit 31 of trans1 */ /* If we're boosting the current, set bit 31 of trans1 */
if (IS_GEN9_BC(dev_priv) && intel_bios_encoder_dp_boost_level(encoder->devdata)) if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv) &&
intel_bios_encoder_dp_boost_level(encoder->devdata))
iboost_bit = DDI_BUF_BALANCE_LEG_ENABLE; iboost_bit = DDI_BUF_BALANCE_LEG_ENABLE;
for (i = 0; i < n_entries; i++) { for (i = 0; i < n_entries; i++) {
@ -146,7 +149,8 @@ static void intel_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder,
level = n_entries - 1; level = n_entries - 1;
/* If we're boosting the current, set bit 31 of trans1 */ /* If we're boosting the current, set bit 31 of trans1 */
if (IS_GEN9_BC(dev_priv) && intel_bios_encoder_hdmi_boost_level(encoder->devdata)) if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv) &&
intel_bios_encoder_hdmi_boost_level(encoder->devdata))
iboost_bit = DDI_BUF_BALANCE_LEG_ENABLE; iboost_bit = DDI_BUF_BALANCE_LEG_ENABLE;
/* Entry 9 is for HDMI: */ /* Entry 9 is for HDMI: */
@ -174,7 +178,7 @@ static void intel_wait_ddi_buf_active(struct drm_i915_private *dev_priv,
enum port port) enum port port)
{ {
/* Wait > 518 usecs for DDI_BUF_CTL to be non idle */ /* Wait > 518 usecs for DDI_BUF_CTL to be non idle */
if (DISPLAY_VER(dev_priv) < 10 && !IS_GEMINILAKE(dev_priv)) { if (DISPLAY_VER(dev_priv) < 10) {
usleep_range(518, 1000); usleep_range(518, 1000);
return; return;
} }
@ -471,7 +475,7 @@ intel_ddi_transcoder_func_reg_val_get(struct intel_encoder *encoder,
temp |= DDI_PORT_WIDTH(crtc_state->lane_count); temp |= DDI_PORT_WIDTH(crtc_state->lane_count);
} }
if (IS_DISPLAY_RANGE(dev_priv, 8, 10) && if (IS_DISPLAY_VER(dev_priv, 8, 10) &&
crtc_state->master_transcoder != INVALID_TRANSCODER) { crtc_state->master_transcoder != INVALID_TRANSCODER) {
u8 master_select = u8 master_select =
bdw_trans_port_sync_master_select(crtc_state->master_transcoder); bdw_trans_port_sync_master_select(crtc_state->master_transcoder);
@ -546,7 +550,7 @@ void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state
ctl &= ~TRANS_DDI_FUNC_ENABLE; ctl &= ~TRANS_DDI_FUNC_ENABLE;
if (IS_DISPLAY_RANGE(dev_priv, 8, 10)) if (IS_DISPLAY_VER(dev_priv, 8, 10))
ctl &= ~(TRANS_DDI_PORT_SYNC_ENABLE | ctl &= ~(TRANS_DDI_PORT_SYNC_ENABLE |
TRANS_DDI_PORT_SYNC_MASTER_SELECT_MASK); TRANS_DDI_PORT_SYNC_MASTER_SELECT_MASK);
@ -759,7 +763,7 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder,
*is_dp_mst = mst_pipe_mask; *is_dp_mst = mst_pipe_mask;
out: out:
if (*pipe_mask && IS_GEN9_LP(dev_priv)) { if (*pipe_mask && (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))) {
tmp = intel_de_read(dev_priv, BXT_PHY_CTL(port)); tmp = intel_de_read(dev_priv, BXT_PHY_CTL(port));
if ((tmp & (BXT_PHY_CMNLANE_POWERDOWN_ACK | if ((tmp & (BXT_PHY_CMNLANE_POWERDOWN_ACK |
BXT_PHY_LANE_POWERDOWN_ACK | BXT_PHY_LANE_POWERDOWN_ACK |
@ -850,18 +854,19 @@ void intel_ddi_enable_pipe_clock(struct intel_encoder *encoder,
{ {
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum port port = encoder->port;
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
u32 val;
if (cpu_transcoder != TRANSCODER_EDP) { if (cpu_transcoder != TRANSCODER_EDP) {
if (DISPLAY_VER(dev_priv) >= 12) if (DISPLAY_VER(dev_priv) >= 13)
intel_de_write(dev_priv, val = TGL_TRANS_CLK_SEL_PORT(phy);
TRANS_CLK_SEL(cpu_transcoder), else if (DISPLAY_VER(dev_priv) >= 12)
TGL_TRANS_CLK_SEL_PORT(port)); val = TGL_TRANS_CLK_SEL_PORT(encoder->port);
else else
intel_de_write(dev_priv, val = TRANS_CLK_SEL_PORT(encoder->port);
TRANS_CLK_SEL(cpu_transcoder),
TRANS_CLK_SEL_PORT(port)); intel_de_write(dev_priv, TRANS_CLK_SEL(cpu_transcoder), val);
} }
} }
@ -976,7 +981,7 @@ static u8 intel_ddi_dp_voltage_max(struct intel_dp *intel_dp,
tgl_get_combo_buf_trans(encoder, crtc_state, &n_entries); tgl_get_combo_buf_trans(encoder, crtc_state, &n_entries);
else else
tgl_get_dkl_buf_trans(encoder, crtc_state, &n_entries); tgl_get_dkl_buf_trans(encoder, crtc_state, &n_entries);
} else if (IS_DISPLAY_VER(dev_priv, 11)) { } else if (DISPLAY_VER(dev_priv) == 11) {
if (IS_PLATFORM(dev_priv, INTEL_JASPERLAKE)) if (IS_PLATFORM(dev_priv, INTEL_JASPERLAKE))
jsl_get_combo_buf_trans(encoder, crtc_state, &n_entries); jsl_get_combo_buf_trans(encoder, crtc_state, &n_entries);
else if (IS_PLATFORM(dev_priv, INTEL_ELKHARTLAKE)) else if (IS_PLATFORM(dev_priv, INTEL_ELKHARTLAKE))
@ -987,7 +992,7 @@ static u8 intel_ddi_dp_voltage_max(struct intel_dp *intel_dp,
icl_get_mg_buf_trans(encoder, crtc_state, &n_entries); icl_get_mg_buf_trans(encoder, crtc_state, &n_entries);
} else if (IS_CANNONLAKE(dev_priv)) { } else if (IS_CANNONLAKE(dev_priv)) {
cnl_get_buf_trans(encoder, crtc_state, &n_entries); cnl_get_buf_trans(encoder, crtc_state, &n_entries);
} else if (IS_GEN9_LP(dev_priv)) { } else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) {
bxt_get_buf_trans(encoder, crtc_state, &n_entries); bxt_get_buf_trans(encoder, crtc_state, &n_entries);
} else { } else {
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
@ -1454,6 +1459,14 @@ tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
val = intel_de_read(dev_priv, DKL_TX_DPCNTL2(tc_port)); val = intel_de_read(dev_priv, DKL_TX_DPCNTL2(tc_port));
val &= ~DKL_TX_DP20BITMODE; val &= ~DKL_TX_DP20BITMODE;
intel_de_write(dev_priv, DKL_TX_DPCNTL2(tc_port), val); intel_de_write(dev_priv, DKL_TX_DPCNTL2(tc_port), val);
if ((intel_crtc_has_dp_encoder(crtc_state) &&
crtc_state->port_clock == 162000) ||
(intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) &&
crtc_state->port_clock == 594000))
val |= DKL_TX_LOADGEN_SHARING_PMD_DISABLE;
else
val &= ~DKL_TX_LOADGEN_SHARING_PMD_DISABLE;
} }
} }
@ -1555,7 +1568,7 @@ hsw_set_signal_levels(struct intel_dp *intel_dp,
intel_dp->DP &= ~DDI_BUF_EMP_MASK; intel_dp->DP &= ~DDI_BUF_EMP_MASK;
intel_dp->DP |= signal_levels; intel_dp->DP |= signal_levels;
if (IS_GEN9_BC(dev_priv)) if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv))
skl_ddi_set_iboost(encoder, crtc_state, level); skl_ddi_set_iboost(encoder, crtc_state, level);
intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP); intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP);
@ -2332,8 +2345,8 @@ static void intel_dp_sink_set_msa_timing_par_ignore_state(struct intel_dp *intel
if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_DOWNSPREAD_CTRL, if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_DOWNSPREAD_CTRL,
enable ? DP_MSA_TIMING_PAR_IGNORE_EN : 0) <= 0) enable ? DP_MSA_TIMING_PAR_IGNORE_EN : 0) <= 0)
drm_dbg_kms(&i915->drm, drm_dbg_kms(&i915->drm,
"Failed to set MSA_TIMING_PAR_IGNORE %s in the sink\n", "Failed to %s MSA_TIMING_PAR_IGNORE in the sink\n",
enable ? "enable" : "disable"); enabledisable(enable));
} }
static void intel_dp_sink_set_fec_ready(struct intel_dp *intel_dp, static void intel_dp_sink_set_fec_ready(struct intel_dp *intel_dp,
@ -2648,7 +2661,7 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
icl_ddi_vswing_sequence(encoder, crtc_state, level); icl_ddi_vswing_sequence(encoder, crtc_state, level);
else if (IS_CANNONLAKE(dev_priv)) else if (IS_CANNONLAKE(dev_priv))
cnl_ddi_vswing_sequence(encoder, crtc_state, level); cnl_ddi_vswing_sequence(encoder, crtc_state, level);
else if (IS_GEN9_LP(dev_priv)) else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
bxt_ddi_vswing_sequence(encoder, crtc_state, level); bxt_ddi_vswing_sequence(encoder, crtc_state, level);
else else
intel_prepare_dp_ddi_buffers(encoder, crtc_state); intel_prepare_dp_ddi_buffers(encoder, crtc_state);
@ -3092,20 +3105,20 @@ static void intel_enable_ddi_hdmi(struct intel_atomic_state *state,
if (DISPLAY_VER(dev_priv) >= 12) if (DISPLAY_VER(dev_priv) >= 12)
tgl_ddi_vswing_sequence(encoder, crtc_state, level); tgl_ddi_vswing_sequence(encoder, crtc_state, level);
else if (IS_DISPLAY_VER(dev_priv, 11)) else if (DISPLAY_VER(dev_priv) == 11)
icl_ddi_vswing_sequence(encoder, crtc_state, level); icl_ddi_vswing_sequence(encoder, crtc_state, level);
else if (IS_CANNONLAKE(dev_priv)) else if (IS_CANNONLAKE(dev_priv))
cnl_ddi_vswing_sequence(encoder, crtc_state, level); cnl_ddi_vswing_sequence(encoder, crtc_state, level);
else if (IS_GEN9_LP(dev_priv)) else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
bxt_ddi_vswing_sequence(encoder, crtc_state, level); bxt_ddi_vswing_sequence(encoder, crtc_state, level);
else else
intel_prepare_hdmi_ddi_buffers(encoder, level); intel_prepare_hdmi_ddi_buffers(encoder, level);
if (IS_GEN9_BC(dev_priv)) if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv))
skl_ddi_set_iboost(encoder, crtc_state, level); skl_ddi_set_iboost(encoder, crtc_state, level);
/* Display WA #1143: skl,kbl,cfl */ /* Display WA #1143: skl,kbl,cfl */
if (IS_GEN9_BC(dev_priv)) { if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv)) {
/* /*
* For some reason these chicken bits have been * For some reason these chicken bits have been
* stuffed into a transcoder register, event though * stuffed into a transcoder register, event though
@ -3321,7 +3334,7 @@ intel_ddi_pre_pll_enable(struct intel_atomic_state *state,
* Type-C ports. Skip this step for TBT. * Type-C ports. Skip this step for TBT.
*/ */
intel_tc_port_set_fia_lane_count(dig_port, crtc_state->lane_count); intel_tc_port_set_fia_lane_count(dig_port, crtc_state->lane_count);
else if (IS_GEN9_LP(dev_priv)) else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
bxt_ddi_phy_set_lane_optim_mask(encoder, bxt_ddi_phy_set_lane_optim_mask(encoder,
crtc_state->lane_lat_optim_mask); crtc_state->lane_lat_optim_mask);
} }
@ -3679,7 +3692,7 @@ static void intel_ddi_get_config(struct intel_encoder *encoder,
if (!pipe_config->bigjoiner_slave) if (!pipe_config->bigjoiner_slave)
ddi_dotclock_get(pipe_config); ddi_dotclock_get(pipe_config);
if (IS_GEN9_LP(dev_priv)) if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
pipe_config->lane_lat_optim_mask = pipe_config->lane_lat_optim_mask =
bxt_ddi_phy_get_lane_lat_optim_mask(encoder); bxt_ddi_phy_get_lane_lat_optim_mask(encoder);
@ -3705,6 +3718,8 @@ static void intel_ddi_get_config(struct intel_encoder *encoder,
intel_read_dp_sdp(encoder, pipe_config, HDMI_PACKET_TYPE_GAMUT_METADATA); intel_read_dp_sdp(encoder, pipe_config, HDMI_PACKET_TYPE_GAMUT_METADATA);
intel_read_dp_sdp(encoder, pipe_config, DP_SDP_VSC); intel_read_dp_sdp(encoder, pipe_config, DP_SDP_VSC);
intel_psr_get_config(encoder, pipe_config);
} }
void intel_ddi_get_clock(struct intel_encoder *encoder, void intel_ddi_get_clock(struct intel_encoder *encoder,
@ -3885,7 +3900,7 @@ static int intel_ddi_compute_config(struct intel_encoder *encoder,
pipe_config->pch_pfit.enabled || pipe_config->pch_pfit.enabled ||
pipe_config->crc_enabled; pipe_config->crc_enabled;
if (IS_GEN9_LP(dev_priv)) if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
pipe_config->lane_lat_optim_mask = pipe_config->lane_lat_optim_mask =
bxt_ddi_phy_calc_lane_lat_optim_mask(pipe_config->lane_count); bxt_ddi_phy_calc_lane_lat_optim_mask(pipe_config->lane_count);
@ -4053,7 +4068,7 @@ intel_ddi_init_dp_connector(struct intel_digital_port *dig_port)
dig_port->dp.set_signal_levels = icl_set_signal_levels; dig_port->dp.set_signal_levels = icl_set_signal_levels;
else if (IS_CANNONLAKE(dev_priv)) else if (IS_CANNONLAKE(dev_priv))
dig_port->dp.set_signal_levels = cnl_set_signal_levels; dig_port->dp.set_signal_levels = cnl_set_signal_levels;
else if (IS_GEN9_LP(dev_priv)) else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
dig_port->dp.set_signal_levels = bxt_set_signal_levels; dig_port->dp.set_signal_levels = bxt_set_signal_levels;
else else
dig_port->dp.set_signal_levels = hsw_set_signal_levels; dig_port->dp.set_signal_levels = hsw_set_signal_levels;
@ -4296,7 +4311,7 @@ static bool intel_ddi_a_force_4_lanes(struct intel_digital_port *dig_port)
/* Broxton/Geminilake: Bspec says that DDI_A_4_LANES is the only /* Broxton/Geminilake: Bspec says that DDI_A_4_LANES is the only
* supported configuration * supported configuration
*/ */
if (IS_GEN9_LP(dev_priv)) if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
return true; return true;
/* Cannonlake: Most of SKUs don't support DDI_E, and the only /* Cannonlake: Most of SKUs don't support DDI_E, and the only
@ -4350,6 +4365,17 @@ static bool hti_uses_phy(struct drm_i915_private *i915, enum phy phy)
i915->hti_state & HDPORT_DDI_USED(phy); i915->hti_state & HDPORT_DDI_USED(phy);
} }
static enum hpd_pin xelpd_hpd_pin(struct drm_i915_private *dev_priv,
enum port port)
{
if (port >= PORT_D_XELPD)
return HPD_PORT_D + port - PORT_D_XELPD;
else if (port >= PORT_TC1)
return HPD_PORT_TC1 + port - PORT_TC1;
else
return HPD_PORT_A + port - PORT_A;
}
static enum hpd_pin dg1_hpd_pin(struct drm_i915_private *dev_priv, static enum hpd_pin dg1_hpd_pin(struct drm_i915_private *dev_priv,
enum port port) enum port port)
{ {
@ -4489,7 +4515,13 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
encoder = &dig_port->base; encoder = &dig_port->base;
encoder->devdata = devdata; encoder->devdata = devdata;
if (DISPLAY_VER(dev_priv) >= 12) { if (DISPLAY_VER(dev_priv) >= 13 && port >= PORT_D_XELPD) {
drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs,
DRM_MODE_ENCODER_TMDS,
"DDI %c/PHY %c",
port_name(port - PORT_D_XELPD + PORT_D),
phy_name(phy));
} else if (DISPLAY_VER(dev_priv) >= 12) {
enum tc_port tc_port = intel_port_to_tc(dev_priv, port); enum tc_port tc_port = intel_port_to_tc(dev_priv, port);
drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs, drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs,
@ -4585,10 +4617,10 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
encoder->disable_clock = cnl_ddi_disable_clock; encoder->disable_clock = cnl_ddi_disable_clock;
encoder->is_clock_enabled = cnl_ddi_is_clock_enabled; encoder->is_clock_enabled = cnl_ddi_is_clock_enabled;
encoder->get_config = cnl_ddi_get_config; encoder->get_config = cnl_ddi_get_config;
} else if (IS_GEN9_LP(dev_priv)) { } else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) {
/* BXT/GLK have fixed PLL->port mapping */ /* BXT/GLK have fixed PLL->port mapping */
encoder->get_config = bxt_ddi_get_config; encoder->get_config = bxt_ddi_get_config;
} else if (IS_GEN9_BC(dev_priv)) { } else if (DISPLAY_VER(dev_priv) == 9) {
encoder->enable_clock = skl_ddi_enable_clock; encoder->enable_clock = skl_ddi_enable_clock;
encoder->disable_clock = skl_ddi_disable_clock; encoder->disable_clock = skl_ddi_disable_clock;
encoder->is_clock_enabled = skl_ddi_is_clock_enabled; encoder->is_clock_enabled = skl_ddi_is_clock_enabled;
@ -4600,7 +4632,9 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
encoder->get_config = hsw_ddi_get_config; encoder->get_config = hsw_ddi_get_config;
} }
if (IS_DG1(dev_priv)) if (DISPLAY_VER(dev_priv) >= 13)
encoder->hpd_pin = xelpd_hpd_pin(dev_priv, port);
else if (IS_DG1(dev_priv))
encoder->hpd_pin = dg1_hpd_pin(dev_priv, port); encoder->hpd_pin = dg1_hpd_pin(dev_priv, port);
else if (IS_ROCKETLAKE(dev_priv)) else if (IS_ROCKETLAKE(dev_priv))
encoder->hpd_pin = rkl_hpd_pin(dev_priv, port); encoder->hpd_pin = rkl_hpd_pin(dev_priv, port);
@ -4608,11 +4642,11 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
encoder->hpd_pin = tgl_hpd_pin(dev_priv, port); encoder->hpd_pin = tgl_hpd_pin(dev_priv, port);
else if (IS_JSL_EHL(dev_priv)) else if (IS_JSL_EHL(dev_priv))
encoder->hpd_pin = ehl_hpd_pin(dev_priv, port); encoder->hpd_pin = ehl_hpd_pin(dev_priv, port);
else if (IS_DISPLAY_VER(dev_priv, 11)) else if (DISPLAY_VER(dev_priv) == 11)
encoder->hpd_pin = icl_hpd_pin(dev_priv, port); encoder->hpd_pin = icl_hpd_pin(dev_priv, port);
else if (IS_DISPLAY_VER(dev_priv, 10)) else if (IS_CANNONLAKE(dev_priv))
encoder->hpd_pin = cnl_hpd_pin(dev_priv, port); encoder->hpd_pin = cnl_hpd_pin(dev_priv, port);
else if (IS_DISPLAY_VER(dev_priv, 9)) else if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv))
encoder->hpd_pin = skl_hpd_pin(dev_priv, port); encoder->hpd_pin = skl_hpd_pin(dev_priv, port);
else else
encoder->hpd_pin = intel_hpd_pin_default(dev_priv, port); encoder->hpd_pin = intel_hpd_pin_default(dev_priv, port);
@ -4672,7 +4706,8 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
else else
dig_port->connected = lpt_digital_port_connected; dig_port->connected = lpt_digital_port_connected;
} else if (DISPLAY_VER(dev_priv) >= 8) { } else if (DISPLAY_VER(dev_priv) >= 8) {
if (port == PORT_A || IS_GEN9_LP(dev_priv)) if (port == PORT_A || IS_GEMINILAKE(dev_priv) ||
IS_BROXTON(dev_priv))
dig_port->connected = bdw_digital_port_connected; dig_port->connected = bdw_digital_port_connected;
else else
dig_port->connected = lpt_digital_port_connected; dig_port->connected = lpt_digital_port_connected;

View file

@ -6,6 +6,7 @@
#include "i915_drv.h" #include "i915_drv.h"
#include "intel_ddi.h" #include "intel_ddi.h"
#include "intel_ddi_buf_trans.h" #include "intel_ddi_buf_trans.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
/* HDMI/DVI modes ignore everything but the last 2 items. So we share /* HDMI/DVI modes ignore everything but the last 2 items. So we share
@ -881,7 +882,7 @@ intel_ddi_get_buf_trans_edp(struct intel_encoder *encoder, int *n_entries)
{ {
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
if (IS_GEN9_BC(dev_priv)) { if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv)) {
const struct ddi_buf_trans *ddi_translations = const struct ddi_buf_trans *ddi_translations =
skl_get_buf_trans_edp(encoder, n_entries); skl_get_buf_trans_edp(encoder, n_entries);
*n_entries = skl_buf_trans_num_entries(encoder->port, *n_entries); *n_entries = skl_buf_trans_num_entries(encoder->port, *n_entries);
@ -919,7 +920,7 @@ intel_ddi_get_buf_trans_hdmi(struct intel_encoder *encoder,
{ {
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
if (IS_GEN9_BC(dev_priv)) { if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv)) {
return skl_get_buf_trans_hdmi(dev_priv, n_entries); return skl_get_buf_trans_hdmi(dev_priv, n_entries);
} else if (IS_BROADWELL(dev_priv)) { } else if (IS_BROADWELL(dev_priv)) {
*n_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi); *n_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
@ -1361,7 +1362,7 @@ int intel_ddi_hdmi_num_entries(struct intel_encoder *encoder,
else else
tgl_get_dkl_buf_trans_hdmi(encoder, crtc_state, &n_entries); tgl_get_dkl_buf_trans_hdmi(encoder, crtc_state, &n_entries);
*default_entry = n_entries - 1; *default_entry = n_entries - 1;
} else if (IS_DISPLAY_VER(dev_priv, 11)) { } else if (DISPLAY_VER(dev_priv) == 11) {
if (intel_phy_is_combo(dev_priv, phy)) if (intel_phy_is_combo(dev_priv, phy))
icl_get_combo_buf_trans_hdmi(encoder, crtc_state, &n_entries); icl_get_combo_buf_trans_hdmi(encoder, crtc_state, &n_entries);
else else
@ -1370,10 +1371,10 @@ int intel_ddi_hdmi_num_entries(struct intel_encoder *encoder,
} else if (IS_CANNONLAKE(dev_priv)) { } else if (IS_CANNONLAKE(dev_priv)) {
cnl_get_buf_trans_hdmi(encoder, &n_entries); cnl_get_buf_trans_hdmi(encoder, &n_entries);
*default_entry = n_entries - 1; *default_entry = n_entries - 1;
} else if (IS_GEN9_LP(dev_priv)) { } else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) {
bxt_get_buf_trans_hdmi(encoder, &n_entries); bxt_get_buf_trans_hdmi(encoder, &n_entries);
*default_entry = n_entries - 1; *default_entry = n_entries - 1;
} else if (IS_GEN9_BC(dev_priv)) { } else if (DISPLAY_VER(dev_priv) == 9) {
intel_ddi_get_buf_trans_hdmi(encoder, &n_entries); intel_ddi_get_buf_trans_hdmi(encoder, &n_entries);
*default_entry = 8; *default_entry = 8;
} else if (IS_BROADWELL(dev_priv)) { } else if (IS_BROADWELL(dev_priv)) {

View file

@ -8,6 +8,7 @@
#include "i915_drv.h" #include "i915_drv.h"
#include "i915_reg.h" #include "i915_reg.h"
#include "i915_trace.h"
#include "intel_uncore.h" #include "intel_uncore.h"
static inline u32 static inline u32
@ -22,26 +23,12 @@ intel_de_posting_read(struct drm_i915_private *i915, i915_reg_t reg)
intel_uncore_posting_read(&i915->uncore, reg); intel_uncore_posting_read(&i915->uncore, reg);
} }
/* Note: read the warnings for intel_uncore_*_fw() functions! */
static inline u32
intel_de_read_fw(struct drm_i915_private *i915, i915_reg_t reg)
{
return intel_uncore_read_fw(&i915->uncore, reg);
}
static inline void static inline void
intel_de_write(struct drm_i915_private *i915, i915_reg_t reg, u32 val) intel_de_write(struct drm_i915_private *i915, i915_reg_t reg, u32 val)
{ {
intel_uncore_write(&i915->uncore, reg, val); intel_uncore_write(&i915->uncore, reg, val);
} }
/* Note: read the warnings for intel_uncore_*_fw() functions! */
static inline void
intel_de_write_fw(struct drm_i915_private *i915, i915_reg_t reg, u32 val)
{
intel_uncore_write_fw(&i915->uncore, reg, val);
}
static inline void static inline void
intel_de_rmw(struct drm_i915_private *i915, i915_reg_t reg, u32 clear, u32 set) intel_de_rmw(struct drm_i915_private *i915, i915_reg_t reg, u32 clear, u32 set)
{ {
@ -69,4 +56,30 @@ intel_de_wait_for_clear(struct drm_i915_private *i915, i915_reg_t reg,
return intel_de_wait_for_register(i915, reg, mask, 0, timeout); return intel_de_wait_for_register(i915, reg, mask, 0, timeout);
} }
/*
* Unlocked mmio-accessors, think carefully before using these.
*
* Certain architectures will die if the same cacheline is concurrently accessed
* by different clients (e.g. on Ivybridge). Access to registers should
* therefore generally be serialised, by either the dev_priv->uncore.lock or
* a more localised lock guarding all access to that bank of registers.
*/
static inline u32
intel_de_read_fw(struct drm_i915_private *i915, i915_reg_t reg)
{
u32 val;
val = intel_uncore_read_fw(&i915->uncore, reg);
trace_i915_reg_rw(false, reg, val, sizeof(val), true);
return val;
}
static inline void
intel_de_write_fw(struct drm_i915_private *i915, i915_reg_t reg, u32 val)
{
trace_i915_reg_rw(true, reg, val, sizeof(val), true);
intel_uncore_write_fw(&i915->uncore, reg, val);
}
#endif /* __INTEL_DE_H__ */ #endif /* __INTEL_DE_H__ */

File diff suppressed because it is too large Load diff

View file

@ -37,13 +37,13 @@ struct drm_encoder;
struct drm_file; struct drm_file;
struct drm_format_info; struct drm_format_info;
struct drm_framebuffer; struct drm_framebuffer;
struct drm_i915_error_state_buf;
struct drm_i915_gem_object; struct drm_i915_gem_object;
struct drm_i915_private; struct drm_i915_private;
struct drm_mode_fb_cmd2; struct drm_mode_fb_cmd2;
struct drm_modeset_acquire_ctx; struct drm_modeset_acquire_ctx;
struct drm_plane; struct drm_plane;
struct drm_plane_state; struct drm_plane_state;
struct i915_address_space;
struct i915_ggtt_view; struct i915_ggtt_view;
struct intel_atomic_state; struct intel_atomic_state;
struct intel_crtc; struct intel_crtc;
@ -188,12 +188,13 @@ enum plane_id {
for ((__p) = PLANE_PRIMARY; (__p) < I915_MAX_PLANES; (__p)++) \ for ((__p) = PLANE_PRIMARY; (__p) < I915_MAX_PLANES; (__p)++) \
for_each_if((__crtc)->plane_ids_mask & BIT(__p)) for_each_if((__crtc)->plane_ids_mask & BIT(__p))
#define for_each_dbuf_slice_in_mask(__slice, __mask) \ #define for_each_dbuf_slice(__dev_priv, __slice) \
for ((__slice) = DBUF_S1; (__slice) < I915_MAX_DBUF_SLICES; (__slice)++) \ for ((__slice) = DBUF_S1; (__slice) < I915_MAX_DBUF_SLICES; (__slice)++) \
for_each_if((BIT(__slice)) & (__mask)) for_each_if(INTEL_INFO(__dev_priv)->dbuf.slice_mask & BIT(__slice))
#define for_each_dbuf_slice(__slice) \ #define for_each_dbuf_slice_in_mask(__dev_priv, __slice, __mask) \
for_each_dbuf_slice_in_mask(__slice, BIT(I915_MAX_DBUF_SLICES) - 1) for_each_dbuf_slice((__dev_priv), (__slice)) \
for_each_if((__mask) & BIT(__slice))
enum port { enum port {
PORT_NONE = -1, PORT_NONE = -1,
@ -216,6 +217,10 @@ enum port {
PORT_TC5, PORT_TC5,
PORT_TC6, PORT_TC6,
/* XE_LPD repositions D/E offsets and bitfields */
PORT_D_XELPD = PORT_TC5,
PORT_E_XELPD,
I915_MAX_PORTS I915_MAX_PORTS
}; };
@ -299,6 +304,10 @@ enum aux_ch {
AUX_CH_USBC4, AUX_CH_USBC4,
AUX_CH_USBC5, AUX_CH_USBC5,
AUX_CH_USBC6, AUX_CH_USBC6,
/* XE_LPD repositions D/E offsets and bitfields */
AUX_CH_D_XELPD = AUX_CH_USBC5,
AUX_CH_E_XELPD,
}; };
#define aux_ch_name(a) ((a) + 'A') #define aux_ch_name(a) ((a) + 'A')
@ -556,9 +565,6 @@ enum tc_port intel_port_to_tc(struct drm_i915_private *dev_priv,
enum port port); enum port port);
int intel_get_pipe_from_crtc_id_ioctl(struct drm_device *dev, void *data, int intel_get_pipe_from_crtc_id_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv); struct drm_file *file_priv);
u32 intel_crtc_get_vblank_counter(struct intel_crtc *crtc);
void intel_crtc_vblank_on(const struct intel_crtc_state *crtc_state);
void intel_crtc_vblank_off(const struct intel_crtc_state *crtc_state);
int ilk_get_lanes_required(int target_clock, int link_bw, int bpp); int ilk_get_lanes_required(int target_clock, int link_bw, int bpp);
void vlv_wait_port_ready(struct drm_i915_private *dev_priv, void vlv_wait_port_ready(struct drm_i915_private *dev_priv,
@ -597,9 +603,6 @@ void intel_dp_get_m_n(struct intel_crtc *crtc,
void intel_dp_set_m_n(const struct intel_crtc_state *crtc_state, void intel_dp_set_m_n(const struct intel_crtc_state *crtc_state,
enum link_m_n_set m_n); enum link_m_n_set m_n);
int intel_dotclock_calculate(int link_freq, const struct intel_link_m_n *m_n); int intel_dotclock_calculate(int link_freq, const struct intel_link_m_n *m_n);
bool bxt_find_best_dpll(struct intel_crtc_state *crtc_state,
struct dpll *best_clock);
int chv_calc_dpll_params(int refclk, struct dpll *pll_clock);
bool hsw_crtc_state_ips_capable(const struct intel_crtc_state *crtc_state); bool hsw_crtc_state_ips_capable(const struct intel_crtc_state *crtc_state);
void hsw_enable_ips(const struct intel_crtc_state *crtc_state); void hsw_enable_ips(const struct intel_crtc_state *crtc_state);
@ -616,11 +619,6 @@ void ilk_pfit_disable(const struct intel_crtc_state *old_crtc_state);
int bdw_get_pipemisc_bpp(struct intel_crtc *crtc); int bdw_get_pipemisc_bpp(struct intel_crtc *crtc);
unsigned int intel_plane_fence_y_offset(const struct intel_plane_state *plane_state); unsigned int intel_plane_fence_y_offset(const struct intel_plane_state *plane_state);
struct intel_display_error_state *
intel_display_capture_error_state(struct drm_i915_private *dev_priv);
void intel_display_print_error_state(struct drm_i915_error_state_buf *e,
struct intel_display_error_state *error);
bool bool
intel_format_info_is_yuv_semiplanar(const struct drm_format_info *info, intel_format_info_is_yuv_semiplanar(const struct drm_format_info *info,
u64 modifier); u64 modifier);
@ -648,6 +646,7 @@ void intel_modeset_driver_remove_noirq(struct drm_i915_private *i915);
void intel_modeset_driver_remove_nogem(struct drm_i915_private *i915); void intel_modeset_driver_remove_nogem(struct drm_i915_private *i915);
void intel_display_resume(struct drm_device *dev); void intel_display_resume(struct drm_device *dev);
void intel_init_pch_refclk(struct drm_i915_private *dev_priv); void intel_init_pch_refclk(struct drm_i915_private *dev_priv);
int intel_modeset_all_pipes(struct intel_atomic_state *state);
/* modesetting asserts */ /* modesetting asserts */
void assert_panel_unlocked(struct drm_i915_private *dev_priv, void assert_panel_unlocked(struct drm_i915_private *dev_priv,

View file

@ -10,6 +10,7 @@
#include "intel_csr.h" #include "intel_csr.h"
#include "intel_display_debugfs.h" #include "intel_display_debugfs.h"
#include "intel_display_power.h" #include "intel_display_power.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_dp.h" #include "intel_dp.h"
#include "intel_fbc.h" #include "intel_fbc.h"
@ -569,7 +570,7 @@ static int i915_dmc_info(struct seq_file *m, void *unused)
} else { } else {
dc5_reg = IS_BROXTON(dev_priv) ? BXT_CSR_DC3_DC5_COUNT : dc5_reg = IS_BROXTON(dev_priv) ? BXT_CSR_DC3_DC5_COUNT :
SKL_CSR_DC3_DC5_COUNT; SKL_CSR_DC3_DC5_COUNT;
if (!IS_GEN9_LP(dev_priv)) if (!IS_GEMINILAKE(dev_priv) && !IS_BROXTON(dev_priv))
dc6_reg = SKL_CSR_DC5_DC6_COUNT; dc6_reg = SKL_CSR_DC5_DC6_COUNT;
} }
@ -1339,6 +1340,12 @@ static int i915_lpsp_status(struct seq_file *m, void *unused)
{ {
struct drm_i915_private *i915 = node_to_i915(m->private); struct drm_i915_private *i915 = node_to_i915(m->private);
if (DISPLAY_VER(i915) >= 13) {
LPSP_STATUS(!intel_lpsp_power_well_enabled(i915,
SKL_DISP_PW_2));
return 0;
}
switch (DISPLAY_VER(i915)) { switch (DISPLAY_VER(i915)) {
case 12: case 12:
case 11: case 11:

View file

@ -11,6 +11,7 @@
#include "intel_combo_phy.h" #include "intel_combo_phy.h"
#include "intel_csr.h" #include "intel_csr.h"
#include "intel_display_power.h" #include "intel_display_power.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_dpio_phy.h" #include "intel_dpio_phy.h"
#include "intel_hotplug.h" #include "intel_hotplug.h"
@ -550,7 +551,7 @@ static void icl_tc_port_assert_ref_held(struct drm_i915_private *dev_priv,
if (drm_WARN_ON(&dev_priv->drm, !dig_port)) if (drm_WARN_ON(&dev_priv->drm, !dig_port))
return; return;
if (IS_DISPLAY_VER(dev_priv, 11) && dig_port->tc_legacy_port) if (DISPLAY_VER(dev_priv) == 11 && dig_port->tc_legacy_port)
return; return;
drm_WARN_ON(&dev_priv->drm, !intel_tc_port_ref_held(dig_port)); drm_WARN_ON(&dev_priv->drm, !intel_tc_port_ref_held(dig_port));
@ -619,7 +620,7 @@ icl_tc_phy_aux_power_well_enable(struct drm_i915_private *dev_priv,
* exit sequence. * exit sequence.
*/ */
timeout_expected = is_tbt; timeout_expected = is_tbt;
if (IS_DISPLAY_VER(dev_priv, 11) && dig_port->tc_legacy_port) { if (DISPLAY_VER(dev_priv) == 11 && dig_port->tc_legacy_port) {
icl_tc_cold_exit(dev_priv); icl_tc_cold_exit(dev_priv);
timeout_expected = true; timeout_expected = true;
} }
@ -709,7 +710,7 @@ static bool hsw_power_well_enabled(struct drm_i915_private *dev_priv,
* BIOS's own request bits, which are forced-on for these power wells * BIOS's own request bits, which are forced-on for these power wells
* when exiting DC5/6. * when exiting DC5/6.
*/ */
if (IS_DISPLAY_VER(dev_priv, 9) && !IS_GEN9_LP(dev_priv) && if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv) &&
(id == SKL_DISP_PW_1 || id == SKL_DISP_PW_MISC_IO)) (id == SKL_DISP_PW_1 || id == SKL_DISP_PW_MISC_IO))
val |= intel_de_read(dev_priv, regs->bios); val |= intel_de_read(dev_priv, regs->bios);
@ -807,9 +808,9 @@ static u32 gen9_dc_mask(struct drm_i915_private *dev_priv)
if (DISPLAY_VER(dev_priv) >= 12) if (DISPLAY_VER(dev_priv) >= 12)
mask |= DC_STATE_EN_DC3CO | DC_STATE_EN_UPTO_DC6 mask |= DC_STATE_EN_DC3CO | DC_STATE_EN_UPTO_DC6
| DC_STATE_EN_DC9; | DC_STATE_EN_DC9;
else if (IS_DISPLAY_VER(dev_priv, 11)) else if (DISPLAY_VER(dev_priv) == 11)
mask |= DC_STATE_EN_UPTO_DC6 | DC_STATE_EN_DC9; mask |= DC_STATE_EN_UPTO_DC6 | DC_STATE_EN_DC9;
else if (IS_GEN9_LP(dev_priv)) else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
mask |= DC_STATE_EN_DC9; mask |= DC_STATE_EN_DC9;
else else
mask |= DC_STATE_EN_UPTO_DC6; mask |= DC_STATE_EN_UPTO_DC6;
@ -821,6 +822,9 @@ static void gen9_sanitize_dc_state(struct drm_i915_private *dev_priv)
{ {
u32 val; u32 val;
if (!HAS_DISPLAY(dev_priv))
return;
val = intel_de_read(dev_priv, DC_STATE_EN) & gen9_dc_mask(dev_priv); val = intel_de_read(dev_priv, DC_STATE_EN) & gen9_dc_mask(dev_priv);
drm_dbg_kms(&dev_priv->drm, drm_dbg_kms(&dev_priv->drm,
@ -857,6 +861,9 @@ static void gen9_set_dc_state(struct drm_i915_private *dev_priv, u32 state)
u32 val; u32 val;
u32 mask; u32 mask;
if (!HAS_DISPLAY(dev_priv))
return;
if (drm_WARN_ON_ONCE(&dev_priv->drm, if (drm_WARN_ON_ONCE(&dev_priv->drm,
state & ~dev_priv->csr.allowed_dc_mask)) state & ~dev_priv->csr.allowed_dc_mask))
state &= dev_priv->csr.allowed_dc_mask; state &= dev_priv->csr.allowed_dc_mask;
@ -1035,7 +1042,7 @@ static void assert_can_enable_dc5(struct drm_i915_private *dev_priv)
enum i915_power_well_id high_pg; enum i915_power_well_id high_pg;
/* Power wells at this level and above must be disabled for DC5 entry */ /* Power wells at this level and above must be disabled for DC5 entry */
if (DISPLAY_VER(dev_priv) >= 12) if (DISPLAY_VER(dev_priv) == 12)
high_pg = ICL_DISP_PW_3; high_pg = ICL_DISP_PW_3;
else else
high_pg = SKL_DISP_PW_2; high_pg = SKL_DISP_PW_2;
@ -1060,7 +1067,7 @@ static void gen9_enable_dc5(struct drm_i915_private *dev_priv)
drm_dbg_kms(&dev_priv->drm, "Enabling DC5\n"); drm_dbg_kms(&dev_priv->drm, "Enabling DC5\n");
/* Wa Display #1183: skl,kbl,cfl */ /* Wa Display #1183: skl,kbl,cfl */
if (IS_GEN9_BC(dev_priv)) if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv))
intel_de_write(dev_priv, GEN8_CHICKEN_DCPR_1, intel_de_write(dev_priv, GEN8_CHICKEN_DCPR_1,
intel_de_read(dev_priv, GEN8_CHICKEN_DCPR_1) | SKL_SELECT_ALTERNATE_DC_EXIT); intel_de_read(dev_priv, GEN8_CHICKEN_DCPR_1) | SKL_SELECT_ALTERNATE_DC_EXIT);
@ -1087,7 +1094,7 @@ static void skl_enable_dc6(struct drm_i915_private *dev_priv)
drm_dbg_kms(&dev_priv->drm, "Enabling DC6\n"); drm_dbg_kms(&dev_priv->drm, "Enabling DC6\n");
/* Wa Display #1183: skl,kbl,cfl */ /* Wa Display #1183: skl,kbl,cfl */
if (IS_GEN9_BC(dev_priv)) if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv))
intel_de_write(dev_priv, GEN8_CHICKEN_DCPR_1, intel_de_write(dev_priv, GEN8_CHICKEN_DCPR_1,
intel_de_read(dev_priv, GEN8_CHICKEN_DCPR_1) | SKL_SELECT_ALTERNATE_DC_EXIT); intel_de_read(dev_priv, GEN8_CHICKEN_DCPR_1) | SKL_SELECT_ALTERNATE_DC_EXIT);
@ -1181,6 +1188,9 @@ static void gen9_disable_dc_states(struct drm_i915_private *dev_priv)
gen9_set_dc_state(dev_priv, DC_STATE_DISABLE); gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
if (!HAS_DISPLAY(dev_priv))
return;
dev_priv->display.get_cdclk(dev_priv, &cdclk_config); dev_priv->display.get_cdclk(dev_priv, &cdclk_config);
/* Can't read out voltage_level so can't use intel_cdclk_changed() */ /* Can't read out voltage_level so can't use intel_cdclk_changed() */
drm_WARN_ON(&dev_priv->drm, drm_WARN_ON(&dev_priv->drm,
@ -1189,7 +1199,7 @@ static void gen9_disable_dc_states(struct drm_i915_private *dev_priv)
gen9_assert_dbuf_enabled(dev_priv); gen9_assert_dbuf_enabled(dev_priv);
if (IS_GEN9_LP(dev_priv)) if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
bxt_verify_ddi_phy_power_wells(dev_priv); bxt_verify_ddi_phy_power_wells(dev_priv);
if (DISPLAY_VER(dev_priv) >= 11) if (DISPLAY_VER(dev_priv) >= 11)
@ -3012,6 +3022,113 @@ intel_display_power_put_mask_in_set(struct drm_i915_private *i915,
BIT_ULL(POWER_DOMAIN_AUX_B) | \ BIT_ULL(POWER_DOMAIN_AUX_B) | \
BIT_ULL(POWER_DOMAIN_INIT)) BIT_ULL(POWER_DOMAIN_INIT))
/*
* XE_LPD Power Domains
*
* Previous platforms required that PG(n-1) be enabled before PG(n). That
* dependency chain turns into a dependency tree on XE_LPD:
*
* PG0
* |
* --PG1--
* / \
* PGA --PG2--
* / | \
* PGB PGC PGD
*
* Power wells must be enabled from top to bottom and disabled from bottom
* to top. This allows pipes to be power gated independently.
*/
#define XELPD_PW_D_POWER_DOMAINS ( \
BIT_ULL(POWER_DOMAIN_PIPE_D) | \
BIT_ULL(POWER_DOMAIN_PIPE_D_PANEL_FITTER) | \
BIT_ULL(POWER_DOMAIN_TRANSCODER_D) | \
BIT_ULL(POWER_DOMAIN_INIT))
#define XELPD_PW_C_POWER_DOMAINS ( \
BIT_ULL(POWER_DOMAIN_PIPE_C) | \
BIT_ULL(POWER_DOMAIN_PIPE_C_PANEL_FITTER) | \
BIT_ULL(POWER_DOMAIN_TRANSCODER_C) | \
BIT_ULL(POWER_DOMAIN_INIT))
#define XELPD_PW_B_POWER_DOMAINS ( \
BIT_ULL(POWER_DOMAIN_PIPE_B) | \
BIT_ULL(POWER_DOMAIN_PIPE_B_PANEL_FITTER) | \
BIT_ULL(POWER_DOMAIN_TRANSCODER_B) | \
BIT_ULL(POWER_DOMAIN_INIT))
#define XELPD_PW_A_POWER_DOMAINS ( \
BIT_ULL(POWER_DOMAIN_PIPE_A) | \
BIT_ULL(POWER_DOMAIN_PIPE_A_PANEL_FITTER) | \
BIT_ULL(POWER_DOMAIN_INIT))
#define XELPD_PW_2_POWER_DOMAINS ( \
XELPD_PW_B_POWER_DOMAINS | \
XELPD_PW_C_POWER_DOMAINS | \
XELPD_PW_D_POWER_DOMAINS | \
BIT_ULL(POWER_DOMAIN_AUDIO) | \
BIT_ULL(POWER_DOMAIN_VGA) | \
BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \
BIT_ULL(POWER_DOMAIN_PORT_DDI_LANES_D_XELPD) | \
BIT_ULL(POWER_DOMAIN_PORT_DDI_LANES_E_XELPD) | \
BIT_ULL(POWER_DOMAIN_AUX_C) | \
BIT_ULL(POWER_DOMAIN_PORT_DDI_LANES_TC1) | \
BIT_ULL(POWER_DOMAIN_PORT_DDI_LANES_TC2) | \
BIT_ULL(POWER_DOMAIN_PORT_DDI_LANES_TC3) | \
BIT_ULL(POWER_DOMAIN_PORT_DDI_LANES_TC4) | \
BIT_ULL(POWER_DOMAIN_AUX_C) | \
BIT_ULL(POWER_DOMAIN_AUX_D_XELPD) | \
BIT_ULL(POWER_DOMAIN_AUX_E_XELPD) | \
BIT_ULL(POWER_DOMAIN_AUX_USBC1) | \
BIT_ULL(POWER_DOMAIN_AUX_USBC2) | \
BIT_ULL(POWER_DOMAIN_AUX_USBC3) | \
BIT_ULL(POWER_DOMAIN_AUX_USBC4) | \
BIT_ULL(POWER_DOMAIN_INIT))
/*
* XELPD PW_1/PG_1 domains (under HW/DMC control):
* - DBUF function (registers are in PW0)
* - Transcoder A
* - DDI_A and DDI_B
*
* XELPD PW_0/PW_1 domains (under HW/DMC control):
* - PCI
* - Clocks except port PLL
* - Shared functions:
* * interrupts except pipe interrupts
* * MBus except PIPE_MBUS_DBOX_CTL
* * DBUF registers
* - Central power except FBC
* - Top-level GTC (DDI-level GTC is in the well associated with the DDI)
*/
#define XELPD_DISPLAY_DC_OFF_POWER_DOMAINS ( \
XELPD_PW_2_POWER_DOMAINS | \
BIT_ULL(POWER_DOMAIN_MODESET) | \
BIT_ULL(POWER_DOMAIN_AUX_A) | \
BIT_ULL(POWER_DOMAIN_AUX_B) | \
BIT_ULL(POWER_DOMAIN_INIT))
#define XELPD_AUX_IO_D_XELPD_POWER_DOMAINS BIT_ULL(POWER_DOMAIN_AUX_D_XELPD)
#define XELPD_AUX_IO_E_XELPD_POWER_DOMAINS BIT_ULL(POWER_DOMAIN_AUX_E_XELPD)
#define XELPD_AUX_IO_USBC1_POWER_DOMAINS BIT_ULL(POWER_DOMAIN_AUX_USBC1)
#define XELPD_AUX_IO_USBC2_POWER_DOMAINS BIT_ULL(POWER_DOMAIN_AUX_USBC2)
#define XELPD_AUX_IO_USBC3_POWER_DOMAINS BIT_ULL(POWER_DOMAIN_AUX_USBC3)
#define XELPD_AUX_IO_USBC4_POWER_DOMAINS BIT_ULL(POWER_DOMAIN_AUX_USBC4)
#define XELPD_AUX_IO_TBT1_POWER_DOMAINS BIT_ULL(POWER_DOMAIN_AUX_TBT1)
#define XELPD_AUX_IO_TBT2_POWER_DOMAINS BIT_ULL(POWER_DOMAIN_AUX_TBT2)
#define XELPD_AUX_IO_TBT3_POWER_DOMAINS BIT_ULL(POWER_DOMAIN_AUX_TBT3)
#define XELPD_AUX_IO_TBT4_POWER_DOMAINS BIT_ULL(POWER_DOMAIN_AUX_TBT4)
#define XELPD_DDI_IO_D_XELPD_POWER_DOMAINS BIT_ULL(POWER_DOMAIN_PORT_DDI_IO_D_XELPD)
#define XELPD_DDI_IO_E_XELPD_POWER_DOMAINS BIT_ULL(POWER_DOMAIN_PORT_DDI_IO_E_XELPD)
#define XELPD_DDI_IO_TC1_POWER_DOMAINS BIT_ULL(POWER_DOMAIN_PORT_DDI_IO_TC1)
#define XELPD_DDI_IO_TC2_POWER_DOMAINS BIT_ULL(POWER_DOMAIN_PORT_DDI_IO_TC2)
#define XELPD_DDI_IO_TC3_POWER_DOMAINS BIT_ULL(POWER_DOMAIN_PORT_DDI_IO_TC3)
#define XELPD_DDI_IO_TC4_POWER_DOMAINS BIT_ULL(POWER_DOMAIN_PORT_DDI_IO_TC4)
static const struct i915_power_well_ops i9xx_always_on_power_well_ops = { static const struct i915_power_well_ops i9xx_always_on_power_well_ops = {
.sync_hw = i9xx_power_well_sync_hw_noop, .sync_hw = i9xx_power_well_sync_hw_noop,
.enable = i9xx_always_on_power_well_noop, .enable = i9xx_always_on_power_well_noop,
@ -4516,6 +4633,319 @@ static const struct i915_power_well_desc rkl_power_wells[] = {
}, },
}; };
static const struct i915_power_well_desc xelpd_power_wells[] = {
{
.name = "always-on",
.always_on = true,
.domains = POWER_DOMAIN_MASK,
.ops = &i9xx_always_on_power_well_ops,
.id = DISP_PW_ID_NONE,
},
{
.name = "power well 1",
/* Handled by the DMC firmware */
.always_on = true,
.domains = 0,
.ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_1,
{
.hsw.regs = &hsw_power_well_regs,
.hsw.idx = ICL_PW_CTL_IDX_PW_1,
.hsw.has_fuses = true,
},
},
{
.name = "DC off",
.domains = XELPD_DISPLAY_DC_OFF_POWER_DOMAINS,
.ops = &gen9_dc_off_power_well_ops,
.id = SKL_DISP_DC_OFF,
},
{
.name = "power well 2",
.domains = XELPD_PW_2_POWER_DOMAINS,
.ops = &hsw_power_well_ops,
.id = SKL_DISP_PW_2,
{
.hsw.regs = &hsw_power_well_regs,
.hsw.idx = ICL_PW_CTL_IDX_PW_2,
.hsw.has_vga = true,
.hsw.has_fuses = true,
},
},
{
.name = "power well A",
.domains = XELPD_PW_A_POWER_DOMAINS,
.ops = &hsw_power_well_ops,
.id = DISP_PW_ID_NONE,
{
.hsw.regs = &hsw_power_well_regs,
.hsw.idx = XELPD_PW_CTL_IDX_PW_A,
.hsw.irq_pipe_mask = BIT(PIPE_A),
.hsw.has_fuses = true,
},
},
{
.name = "power well B",
.domains = XELPD_PW_B_POWER_DOMAINS,
.ops = &hsw_power_well_ops,
.id = DISP_PW_ID_NONE,
{
.hsw.regs = &hsw_power_well_regs,
.hsw.idx = XELPD_PW_CTL_IDX_PW_B,
.hsw.irq_pipe_mask = BIT(PIPE_B),
.hsw.has_fuses = true,
},
},
{
.name = "power well C",
.domains = XELPD_PW_C_POWER_DOMAINS,
.ops = &hsw_power_well_ops,
.id = DISP_PW_ID_NONE,
{
.hsw.regs = &hsw_power_well_regs,
.hsw.idx = XELPD_PW_CTL_IDX_PW_C,
.hsw.irq_pipe_mask = BIT(PIPE_C),
.hsw.has_fuses = true,
},
},
{
.name = "power well D",
.domains = XELPD_PW_D_POWER_DOMAINS,
.ops = &hsw_power_well_ops,
.id = DISP_PW_ID_NONE,
{
.hsw.regs = &hsw_power_well_regs,
.hsw.idx = XELPD_PW_CTL_IDX_PW_D,
.hsw.irq_pipe_mask = BIT(PIPE_D),
.hsw.has_fuses = true,
},
},
{
.name = "DDI A IO",
.domains = ICL_DDI_IO_A_POWER_DOMAINS,
.ops = &hsw_power_well_ops,
.id = DISP_PW_ID_NONE,
{
.hsw.regs = &icl_ddi_power_well_regs,
.hsw.idx = ICL_PW_CTL_IDX_DDI_A,
}
},
{
.name = "DDI B IO",
.domains = ICL_DDI_IO_B_POWER_DOMAINS,
.ops = &hsw_power_well_ops,
.id = DISP_PW_ID_NONE,
{
.hsw.regs = &icl_ddi_power_well_regs,
.hsw.idx = ICL_PW_CTL_IDX_DDI_B,
}
},
{
.name = "DDI C IO",
.domains = ICL_DDI_IO_C_POWER_DOMAINS,
.ops = &hsw_power_well_ops,
.id = DISP_PW_ID_NONE,
{
.hsw.regs = &icl_ddi_power_well_regs,
.hsw.idx = ICL_PW_CTL_IDX_DDI_C,
}
},
{
.name = "DDI IO D_XELPD",
.domains = XELPD_DDI_IO_D_XELPD_POWER_DOMAINS,
.ops = &hsw_power_well_ops,
.id = DISP_PW_ID_NONE,
{
.hsw.regs = &icl_ddi_power_well_regs,
.hsw.idx = XELPD_PW_CTL_IDX_DDI_D,
}
},
{
.name = "DDI IO E_XELPD",
.domains = XELPD_DDI_IO_E_XELPD_POWER_DOMAINS,
.ops = &hsw_power_well_ops,
.id = DISP_PW_ID_NONE,
{
.hsw.regs = &icl_ddi_power_well_regs,
.hsw.idx = XELPD_PW_CTL_IDX_DDI_E,
}
},
{
.name = "DDI IO TC1",
.domains = XELPD_DDI_IO_TC1_POWER_DOMAINS,
.ops = &hsw_power_well_ops,
.id = DISP_PW_ID_NONE,
{
.hsw.regs = &icl_ddi_power_well_regs,
.hsw.idx = TGL_PW_CTL_IDX_DDI_TC1,
}
},
{
.name = "DDI IO TC2",
.domains = XELPD_DDI_IO_TC2_POWER_DOMAINS,
.ops = &hsw_power_well_ops,
.id = DISP_PW_ID_NONE,
{
.hsw.regs = &icl_ddi_power_well_regs,
.hsw.idx = TGL_PW_CTL_IDX_DDI_TC2,
}
},
{
.name = "DDI IO TC3",
.domains = XELPD_DDI_IO_TC3_POWER_DOMAINS,
.ops = &hsw_power_well_ops,
.id = DISP_PW_ID_NONE,
{
.hsw.regs = &icl_ddi_power_well_regs,
.hsw.idx = TGL_PW_CTL_IDX_DDI_TC3,
}
},
{
.name = "DDI IO TC4",
.domains = XELPD_DDI_IO_TC4_POWER_DOMAINS,
.ops = &hsw_power_well_ops,
.id = DISP_PW_ID_NONE,
{
.hsw.regs = &icl_ddi_power_well_regs,
.hsw.idx = TGL_PW_CTL_IDX_DDI_TC4,
}
},
{
.name = "AUX A",
.domains = ICL_AUX_A_IO_POWER_DOMAINS,
.ops = &icl_aux_power_well_ops,
.id = DISP_PW_ID_NONE,
{
.hsw.regs = &icl_aux_power_well_regs,
.hsw.idx = ICL_PW_CTL_IDX_AUX_A,
},
},
{
.name = "AUX B",
.domains = ICL_AUX_B_IO_POWER_DOMAINS,
.ops = &icl_aux_power_well_ops,
.id = DISP_PW_ID_NONE,
{
.hsw.regs = &icl_aux_power_well_regs,
.hsw.idx = ICL_PW_CTL_IDX_AUX_B,
},
},
{
.name = "AUX C",
.domains = TGL_AUX_C_IO_POWER_DOMAINS,
.ops = &icl_aux_power_well_ops,
.id = DISP_PW_ID_NONE,
{
.hsw.regs = &icl_aux_power_well_regs,
.hsw.idx = ICL_PW_CTL_IDX_AUX_C,
},
},
{
.name = "AUX D_XELPD",
.domains = XELPD_AUX_IO_D_XELPD_POWER_DOMAINS,
.ops = &icl_aux_power_well_ops,
.id = DISP_PW_ID_NONE,
{
.hsw.regs = &icl_aux_power_well_regs,
.hsw.idx = XELPD_PW_CTL_IDX_AUX_D,
},
},
{
.name = "AUX E_XELPD",
.domains = XELPD_AUX_IO_E_XELPD_POWER_DOMAINS,
.ops = &icl_aux_power_well_ops,
.id = DISP_PW_ID_NONE,
{
.hsw.regs = &icl_aux_power_well_regs,
.hsw.idx = XELPD_PW_CTL_IDX_AUX_E,
},
},
{
.name = "AUX USBC1",
.domains = XELPD_AUX_IO_USBC1_POWER_DOMAINS,
.ops = &icl_aux_power_well_ops,
.id = DISP_PW_ID_NONE,
{
.hsw.regs = &icl_aux_power_well_regs,
.hsw.idx = TGL_PW_CTL_IDX_AUX_TC1,
},
},
{
.name = "AUX USBC2",
.domains = XELPD_AUX_IO_USBC2_POWER_DOMAINS,
.ops = &icl_aux_power_well_ops,
.id = DISP_PW_ID_NONE,
{
.hsw.regs = &icl_aux_power_well_regs,
.hsw.idx = TGL_PW_CTL_IDX_AUX_TC2,
},
},
{
.name = "AUX USBC3",
.domains = XELPD_AUX_IO_USBC3_POWER_DOMAINS,
.ops = &icl_aux_power_well_ops,
.id = DISP_PW_ID_NONE,
{
.hsw.regs = &icl_aux_power_well_regs,
.hsw.idx = TGL_PW_CTL_IDX_AUX_TC3,
},
},
{
.name = "AUX USBC4",
.domains = XELPD_AUX_IO_USBC4_POWER_DOMAINS,
.ops = &icl_aux_power_well_ops,
.id = DISP_PW_ID_NONE,
{
.hsw.regs = &icl_aux_power_well_regs,
.hsw.idx = TGL_PW_CTL_IDX_AUX_TC4,
},
},
{
.name = "AUX TBT1",
.domains = XELPD_AUX_IO_TBT1_POWER_DOMAINS,
.ops = &icl_aux_power_well_ops,
.id = DISP_PW_ID_NONE,
{
.hsw.regs = &icl_aux_power_well_regs,
.hsw.idx = TGL_PW_CTL_IDX_AUX_TBT1,
.hsw.is_tc_tbt = true,
},
},
{
.name = "AUX TBT2",
.domains = XELPD_AUX_IO_TBT2_POWER_DOMAINS,
.ops = &icl_aux_power_well_ops,
.id = DISP_PW_ID_NONE,
{
.hsw.regs = &icl_aux_power_well_regs,
.hsw.idx = TGL_PW_CTL_IDX_AUX_TBT2,
.hsw.is_tc_tbt = true,
},
},
{
.name = "AUX TBT3",
.domains = XELPD_AUX_IO_TBT3_POWER_DOMAINS,
.ops = &icl_aux_power_well_ops,
.id = DISP_PW_ID_NONE,
{
.hsw.regs = &icl_aux_power_well_regs,
.hsw.idx = TGL_PW_CTL_IDX_AUX_TBT3,
.hsw.is_tc_tbt = true,
},
},
{
.name = "AUX TBT4",
.domains = XELPD_AUX_IO_TBT4_POWER_DOMAINS,
.ops = &icl_aux_power_well_ops,
.id = DISP_PW_ID_NONE,
{
.hsw.regs = &icl_aux_power_well_regs,
.hsw.idx = TGL_PW_CTL_IDX_AUX_TBT4,
.hsw.is_tc_tbt = true,
},
},
};
static int static int
sanitize_disable_power_well_option(const struct drm_i915_private *dev_priv, sanitize_disable_power_well_option(const struct drm_i915_private *dev_priv,
int disable_power_well) int disable_power_well)
@ -4533,14 +4963,17 @@ static u32 get_allowed_dc_mask(const struct drm_i915_private *dev_priv,
int requested_dc; int requested_dc;
int max_dc; int max_dc;
if (!HAS_DISPLAY(dev_priv))
return 0;
if (IS_DG1(dev_priv)) if (IS_DG1(dev_priv))
max_dc = 3; max_dc = 3;
else if (DISPLAY_VER(dev_priv) >= 12) else if (DISPLAY_VER(dev_priv) >= 12)
max_dc = 4; max_dc = 4;
else if (DISPLAY_VER(dev_priv) >= 11 || IS_CANNONLAKE(dev_priv) || IS_GEN9_BC(dev_priv)) else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
max_dc = 2;
else if (IS_GEN9_LP(dev_priv))
max_dc = 1; max_dc = 1;
else if (DISPLAY_VER(dev_priv) >= 9)
max_dc = 2;
else else
max_dc = 0; max_dc = 0;
@ -4549,7 +4982,8 @@ static u32 get_allowed_dc_mask(const struct drm_i915_private *dev_priv,
* not depending on the DMC firmware. It's needed by system * not depending on the DMC firmware. It's needed by system
* suspend/resume, so allow it unconditionally. * suspend/resume, so allow it unconditionally.
*/ */
mask = IS_GEN9_LP(dev_priv) || DISPLAY_VER(dev_priv) >= 11 ? mask = IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv) ||
DISPLAY_VER(dev_priv) >= 11 ?
DC_STATE_EN_DC9 : 0; DC_STATE_EN_DC9 : 0;
if (!dev_priv->params.disable_power_well) if (!dev_priv->params.disable_power_well)
@ -4673,14 +5107,19 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv)
* The enabling order will be from lower to higher indexed wells, * The enabling order will be from lower to higher indexed wells,
* the disabling order is reversed. * the disabling order is reversed.
*/ */
if (IS_ALDERLAKE_S(dev_priv) || IS_DG1(dev_priv)) { if (!HAS_DISPLAY(dev_priv)) {
power_domains->power_well_count = 0;
err = 0;
} else if (DISPLAY_VER(dev_priv) >= 13) {
err = set_power_wells(power_domains, xelpd_power_wells);
} else if (IS_ALDERLAKE_S(dev_priv) || IS_DG1(dev_priv)) {
err = set_power_wells_mask(power_domains, tgl_power_wells, err = set_power_wells_mask(power_domains, tgl_power_wells,
BIT_ULL(TGL_DISP_PW_TC_COLD_OFF)); BIT_ULL(TGL_DISP_PW_TC_COLD_OFF));
} else if (IS_ROCKETLAKE(dev_priv)) { } else if (IS_ROCKETLAKE(dev_priv)) {
err = set_power_wells(power_domains, rkl_power_wells); err = set_power_wells(power_domains, rkl_power_wells);
} else if (IS_DISPLAY_VER(dev_priv, 12)) { } else if (DISPLAY_VER(dev_priv) == 12) {
err = set_power_wells(power_domains, tgl_power_wells); err = set_power_wells(power_domains, tgl_power_wells);
} else if (IS_DISPLAY_VER(dev_priv, 11)) { } else if (DISPLAY_VER(dev_priv) == 11) {
err = set_power_wells(power_domains, icl_power_wells); err = set_power_wells(power_domains, icl_power_wells);
} else if (IS_CNL_WITH_PORT_F(dev_priv)) { } else if (IS_CNL_WITH_PORT_F(dev_priv)) {
err = set_power_wells(power_domains, cnl_power_wells); err = set_power_wells(power_domains, cnl_power_wells);
@ -4692,7 +5131,7 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv)
err = set_power_wells(power_domains, glk_power_wells); err = set_power_wells(power_domains, glk_power_wells);
} else if (IS_BROXTON(dev_priv)) { } else if (IS_BROXTON(dev_priv)) {
err = set_power_wells(power_domains, bxt_power_wells); err = set_power_wells(power_domains, bxt_power_wells);
} else if (IS_GEN9_BC(dev_priv)) { } else if (DISPLAY_VER(dev_priv) == 9) {
err = set_power_wells(power_domains, skl_power_wells); err = set_power_wells(power_domains, skl_power_wells);
} else if (IS_CHERRYVIEW(dev_priv)) { } else if (IS_CHERRYVIEW(dev_priv)) {
err = set_power_wells(power_domains, chv_power_wells); err = set_power_wells(power_domains, chv_power_wells);
@ -4741,33 +5180,28 @@ static void gen9_dbuf_slice_set(struct drm_i915_private *dev_priv,
{ {
i915_reg_t reg = DBUF_CTL_S(slice); i915_reg_t reg = DBUF_CTL_S(slice);
bool state; bool state;
u32 val;
val = intel_de_read(dev_priv, reg); intel_de_rmw(dev_priv, reg, DBUF_POWER_REQUEST,
if (enable) enable ? DBUF_POWER_REQUEST : 0);
val |= DBUF_POWER_REQUEST;
else
val &= ~DBUF_POWER_REQUEST;
intel_de_write(dev_priv, reg, val);
intel_de_posting_read(dev_priv, reg); intel_de_posting_read(dev_priv, reg);
udelay(10); udelay(10);
state = intel_de_read(dev_priv, reg) & DBUF_POWER_STATE; state = intel_de_read(dev_priv, reg) & DBUF_POWER_STATE;
drm_WARN(&dev_priv->drm, enable != state, drm_WARN(&dev_priv->drm, enable != state,
"DBuf slice %d power %s timeout!\n", "DBuf slice %d power %s timeout!\n",
slice, enable ? "enable" : "disable"); slice, enabledisable(enable));
} }
void gen9_dbuf_slices_update(struct drm_i915_private *dev_priv, void gen9_dbuf_slices_update(struct drm_i915_private *dev_priv,
u8 req_slices) u8 req_slices)
{ {
int num_slices = INTEL_INFO(dev_priv)->num_supported_dbuf_slices;
struct i915_power_domains *power_domains = &dev_priv->power_domains; struct i915_power_domains *power_domains = &dev_priv->power_domains;
u8 slice_mask = INTEL_INFO(dev_priv)->dbuf.slice_mask;
enum dbuf_slice slice; enum dbuf_slice slice;
drm_WARN(&dev_priv->drm, req_slices & ~(BIT(num_slices) - 1), drm_WARN(&dev_priv->drm, req_slices & ~slice_mask,
"Invalid set of dbuf slices (0x%x) requested (num dbuf slices %d)\n", "Invalid set of dbuf slices (0x%x) requested (total dbuf slices 0x%x)\n",
req_slices, num_slices); req_slices, slice_mask);
drm_dbg_kms(&dev_priv->drm, "Updating dbuf slices to 0x%x\n", drm_dbg_kms(&dev_priv->drm, "Updating dbuf slices to 0x%x\n",
req_slices); req_slices);
@ -4781,7 +5215,7 @@ void gen9_dbuf_slices_update(struct drm_i915_private *dev_priv,
*/ */
mutex_lock(&power_domains->lock); mutex_lock(&power_domains->lock);
for (slice = DBUF_S1; slice < num_slices; slice++) for_each_dbuf_slice(dev_priv, slice)
gen9_dbuf_slice_set(dev_priv, slice, req_slices & BIT(slice)); gen9_dbuf_slice_set(dev_priv, slice, req_slices & BIT(slice));
dev_priv->dbuf.enabled_slices = req_slices; dev_priv->dbuf.enabled_slices = req_slices;
@ -4809,10 +5243,9 @@ static void gen9_dbuf_disable(struct drm_i915_private *dev_priv)
static void gen12_dbuf_slices_config(struct drm_i915_private *dev_priv) static void gen12_dbuf_slices_config(struct drm_i915_private *dev_priv)
{ {
const int num_slices = INTEL_INFO(dev_priv)->num_supported_dbuf_slices;
enum dbuf_slice slice; enum dbuf_slice slice;
for (slice = DBUF_S1; slice < (DBUF_S1 + num_slices); slice++) for_each_dbuf_slice(dev_priv, slice)
intel_de_rmw(dev_priv, DBUF_CTL_S(slice), intel_de_rmw(dev_priv, DBUF_CTL_S(slice),
DBUF_TRACKER_STATE_SERVICE_MASK, DBUF_TRACKER_STATE_SERVICE_MASK,
DBUF_TRACKER_STATE_SERVICE(8)); DBUF_TRACKER_STATE_SERVICE(8));
@ -4837,7 +5270,7 @@ static void icl_mbus_init(struct drm_i915_private *dev_priv)
* expect us to program the abox_ctl0 register as well, even though * expect us to program the abox_ctl0 register as well, even though
* we don't have to program other instance-0 registers like BW_BUDDY. * we don't have to program other instance-0 registers like BW_BUDDY.
*/ */
if (IS_DISPLAY_VER(dev_priv, 12)) if (DISPLAY_VER(dev_priv) == 12)
abox_regs |= BIT(0); abox_regs |= BIT(0);
for_each_set_bit(i, &abox_regs, sizeof(abox_regs)) for_each_set_bit(i, &abox_regs, sizeof(abox_regs))
@ -5122,6 +5555,9 @@ static void skl_display_core_init(struct drm_i915_private *dev_priv,
/* enable PCH reset handshake */ /* enable PCH reset handshake */
intel_pch_reset_handshake(dev_priv, !HAS_PCH_NOP(dev_priv)); intel_pch_reset_handshake(dev_priv, !HAS_PCH_NOP(dev_priv));
if (!HAS_DISPLAY(dev_priv))
return;
/* enable PG1 and Misc I/O */ /* enable PG1 and Misc I/O */
mutex_lock(&power_domains->lock); mutex_lock(&power_domains->lock);
@ -5146,6 +5582,9 @@ static void skl_display_core_uninit(struct drm_i915_private *dev_priv)
struct i915_power_domains *power_domains = &dev_priv->power_domains; struct i915_power_domains *power_domains = &dev_priv->power_domains;
struct i915_power_well *well; struct i915_power_well *well;
if (!HAS_DISPLAY(dev_priv))
return;
gen9_disable_dc_states(dev_priv); gen9_disable_dc_states(dev_priv);
gen9_dbuf_disable(dev_priv); gen9_dbuf_disable(dev_priv);
@ -5186,6 +5625,9 @@ static void bxt_display_core_init(struct drm_i915_private *dev_priv, bool resume
*/ */
intel_pch_reset_handshake(dev_priv, false); intel_pch_reset_handshake(dev_priv, false);
if (!HAS_DISPLAY(dev_priv))
return;
/* Enable PG1 */ /* Enable PG1 */
mutex_lock(&power_domains->lock); mutex_lock(&power_domains->lock);
@ -5207,6 +5649,9 @@ static void bxt_display_core_uninit(struct drm_i915_private *dev_priv)
struct i915_power_domains *power_domains = &dev_priv->power_domains; struct i915_power_domains *power_domains = &dev_priv->power_domains;
struct i915_power_well *well; struct i915_power_well *well;
if (!HAS_DISPLAY(dev_priv))
return;
gen9_disable_dc_states(dev_priv); gen9_disable_dc_states(dev_priv);
gen9_dbuf_disable(dev_priv); gen9_dbuf_disable(dev_priv);
@ -5240,6 +5685,9 @@ static void cnl_display_core_init(struct drm_i915_private *dev_priv, bool resume
/* 1. Enable PCH Reset Handshake */ /* 1. Enable PCH Reset Handshake */
intel_pch_reset_handshake(dev_priv, !HAS_PCH_NOP(dev_priv)); intel_pch_reset_handshake(dev_priv, !HAS_PCH_NOP(dev_priv));
if (!HAS_DISPLAY(dev_priv))
return;
/* 2-3. */ /* 2-3. */
intel_combo_phy_init(dev_priv); intel_combo_phy_init(dev_priv);
@ -5267,6 +5715,9 @@ static void cnl_display_core_uninit(struct drm_i915_private *dev_priv)
struct i915_power_domains *power_domains = &dev_priv->power_domains; struct i915_power_domains *power_domains = &dev_priv->power_domains;
struct i915_power_well *well; struct i915_power_well *well;
if (!HAS_DISPLAY(dev_priv))
return;
gen9_disable_dc_states(dev_priv); gen9_disable_dc_states(dev_priv);
/* 1. Disable all display engine functions -> aready done */ /* 1. Disable all display engine functions -> aready done */
@ -5381,6 +5832,9 @@ static void icl_display_core_init(struct drm_i915_private *dev_priv,
/* 1. Enable PCH reset handshake. */ /* 1. Enable PCH reset handshake. */
intel_pch_reset_handshake(dev_priv, !HAS_PCH_NOP(dev_priv)); intel_pch_reset_handshake(dev_priv, !HAS_PCH_NOP(dev_priv));
if (!HAS_DISPLAY(dev_priv))
return;
/* 2. Initialize all combo phys */ /* 2. Initialize all combo phys */
intel_combo_phy_init(dev_priv); intel_combo_phy_init(dev_priv);
@ -5413,11 +5867,15 @@ static void icl_display_core_init(struct drm_i915_private *dev_priv,
intel_csr_load_program(dev_priv); intel_csr_load_program(dev_priv);
/* Wa_14011508470 */ /* Wa_14011508470 */
if (IS_DISPLAY_VER(dev_priv, 12)) { if (DISPLAY_VER(dev_priv) == 12) {
val = DCPR_CLEAR_MEMSTAT_DIS | DCPR_SEND_RESP_IMM | val = DCPR_CLEAR_MEMSTAT_DIS | DCPR_SEND_RESP_IMM |
DCPR_MASK_LPMODE | DCPR_MASK_MAXLATENCY_MEMUP_CLR; DCPR_MASK_LPMODE | DCPR_MASK_MAXLATENCY_MEMUP_CLR;
intel_uncore_rmw(&dev_priv->uncore, GEN11_CHICKEN_DCPR_2, 0, val); intel_uncore_rmw(&dev_priv->uncore, GEN11_CHICKEN_DCPR_2, 0, val);
} }
/* Wa_14011503030:xelpd */
if (DISPLAY_VER(dev_priv) >= 13)
intel_de_write(dev_priv, XELPD_DISPLAY_ERR_FATAL_MASK, ~0);
} }
static void icl_display_core_uninit(struct drm_i915_private *dev_priv) static void icl_display_core_uninit(struct drm_i915_private *dev_priv)
@ -5425,6 +5883,9 @@ static void icl_display_core_uninit(struct drm_i915_private *dev_priv)
struct i915_power_domains *power_domains = &dev_priv->power_domains; struct i915_power_domains *power_domains = &dev_priv->power_domains;
struct i915_power_well *well; struct i915_power_well *well;
if (!HAS_DISPLAY(dev_priv))
return;
gen9_disable_dc_states(dev_priv); gen9_disable_dc_states(dev_priv);
/* 1. Disable all display engine functions -> aready done */ /* 1. Disable all display engine functions -> aready done */
@ -5623,10 +6084,10 @@ void intel_power_domains_init_hw(struct drm_i915_private *i915, bool resume)
icl_display_core_init(i915, resume); icl_display_core_init(i915, resume);
} else if (IS_CANNONLAKE(i915)) { } else if (IS_CANNONLAKE(i915)) {
cnl_display_core_init(i915, resume); cnl_display_core_init(i915, resume);
} else if (IS_GEN9_BC(i915)) { } else if (IS_GEMINILAKE(i915) || IS_BROXTON(i915)) {
skl_display_core_init(i915, resume);
} else if (IS_GEN9_LP(i915)) {
bxt_display_core_init(i915, resume); bxt_display_core_init(i915, resume);
} else if (DISPLAY_VER(i915) == 9) {
skl_display_core_init(i915, resume);
} else if (IS_CHERRYVIEW(i915)) { } else if (IS_CHERRYVIEW(i915)) {
mutex_lock(&power_domains->lock); mutex_lock(&power_domains->lock);
chv_phy_control_init(i915); chv_phy_control_init(i915);
@ -5784,10 +6245,10 @@ void intel_power_domains_suspend(struct drm_i915_private *i915,
icl_display_core_uninit(i915); icl_display_core_uninit(i915);
else if (IS_CANNONLAKE(i915)) else if (IS_CANNONLAKE(i915))
cnl_display_core_uninit(i915); cnl_display_core_uninit(i915);
else if (IS_GEN9_BC(i915)) else if (IS_GEMINILAKE(i915) || IS_BROXTON(i915))
skl_display_core_uninit(i915);
else if (IS_GEN9_LP(i915))
bxt_display_core_uninit(i915); bxt_display_core_uninit(i915);
else if (DISPLAY_VER(i915) == 9)
skl_display_core_uninit(i915);
power_domains->display_core_suspended = true; power_domains->display_core_suspended = true;
} }
@ -5908,7 +6369,8 @@ static void intel_power_domains_verify_state(struct drm_i915_private *i915)
void intel_display_power_suspend_late(struct drm_i915_private *i915) void intel_display_power_suspend_late(struct drm_i915_private *i915)
{ {
if (DISPLAY_VER(i915) >= 11 || IS_GEN9_LP(i915)) { if (DISPLAY_VER(i915) >= 11 || IS_GEMINILAKE(i915) ||
IS_BROXTON(i915)) {
bxt_enable_dc9(i915); bxt_enable_dc9(i915);
/* Tweaked Wa_14010685332:icp,jsp,mcc */ /* Tweaked Wa_14010685332:icp,jsp,mcc */
if (INTEL_PCH_TYPE(i915) >= PCH_ICP && INTEL_PCH_TYPE(i915) <= PCH_MCC) if (INTEL_PCH_TYPE(i915) >= PCH_ICP && INTEL_PCH_TYPE(i915) <= PCH_MCC)
@ -5921,7 +6383,8 @@ void intel_display_power_suspend_late(struct drm_i915_private *i915)
void intel_display_power_resume_early(struct drm_i915_private *i915) void intel_display_power_resume_early(struct drm_i915_private *i915)
{ {
if (DISPLAY_VER(i915) >= 11 || IS_GEN9_LP(i915)) { if (DISPLAY_VER(i915) >= 11 || IS_GEMINILAKE(i915) ||
IS_BROXTON(i915)) {
gen9_sanitize_dc_state(i915); gen9_sanitize_dc_state(i915);
bxt_disable_dc9(i915); bxt_disable_dc9(i915);
/* Tweaked Wa_14010685332:icp,jsp,mcc */ /* Tweaked Wa_14010685332:icp,jsp,mcc */
@ -5938,7 +6401,7 @@ void intel_display_power_suspend(struct drm_i915_private *i915)
if (DISPLAY_VER(i915) >= 11) { if (DISPLAY_VER(i915) >= 11) {
icl_display_core_uninit(i915); icl_display_core_uninit(i915);
bxt_enable_dc9(i915); bxt_enable_dc9(i915);
} else if (IS_GEN9_LP(i915)) { } else if (IS_GEMINILAKE(i915) || IS_BROXTON(i915)) {
bxt_display_core_uninit(i915); bxt_display_core_uninit(i915);
bxt_enable_dc9(i915); bxt_enable_dc9(i915);
} else if (IS_HASWELL(i915) || IS_BROADWELL(i915)) { } else if (IS_HASWELL(i915) || IS_BROADWELL(i915)) {
@ -5959,7 +6422,7 @@ void intel_display_power_resume(struct drm_i915_private *i915)
DC_STATE_EN_UPTO_DC5) DC_STATE_EN_UPTO_DC5)
gen9_enable_dc5(i915); gen9_enable_dc5(i915);
} }
} else if (IS_GEN9_LP(i915)) { } else if (IS_GEMINILAKE(i915) || IS_BROXTON(i915)) {
bxt_disable_dc9(i915); bxt_disable_dc9(i915);
bxt_display_core_init(i915, true); bxt_display_core_init(i915, true);
if (i915->csr.dmc_payload && if (i915->csr.dmc_payload &&

View file

@ -49,6 +49,9 @@ enum intel_display_power_domain {
POWER_DOMAIN_PORT_DDI_LANES_TC5, POWER_DOMAIN_PORT_DDI_LANES_TC5,
POWER_DOMAIN_PORT_DDI_LANES_TC6, POWER_DOMAIN_PORT_DDI_LANES_TC6,
POWER_DOMAIN_PORT_DDI_LANES_D_XELPD = POWER_DOMAIN_PORT_DDI_LANES_TC5, /* XELPD */
POWER_DOMAIN_PORT_DDI_LANES_E_XELPD,
POWER_DOMAIN_PORT_DDI_A_IO, POWER_DOMAIN_PORT_DDI_A_IO,
POWER_DOMAIN_PORT_DDI_B_IO, POWER_DOMAIN_PORT_DDI_B_IO,
POWER_DOMAIN_PORT_DDI_C_IO, POWER_DOMAIN_PORT_DDI_C_IO,
@ -66,6 +69,9 @@ enum intel_display_power_domain {
POWER_DOMAIN_PORT_DDI_IO_TC5, POWER_DOMAIN_PORT_DDI_IO_TC5,
POWER_DOMAIN_PORT_DDI_IO_TC6, POWER_DOMAIN_PORT_DDI_IO_TC6,
POWER_DOMAIN_PORT_DDI_IO_D_XELPD = POWER_DOMAIN_PORT_DDI_IO_TC5, /* XELPD */
POWER_DOMAIN_PORT_DDI_IO_E_XELPD,
POWER_DOMAIN_PORT_DSI, POWER_DOMAIN_PORT_DSI,
POWER_DOMAIN_PORT_CRT, POWER_DOMAIN_PORT_CRT,
POWER_DOMAIN_PORT_OTHER, POWER_DOMAIN_PORT_OTHER,
@ -88,6 +94,9 @@ enum intel_display_power_domain {
POWER_DOMAIN_AUX_USBC5, POWER_DOMAIN_AUX_USBC5,
POWER_DOMAIN_AUX_USBC6, POWER_DOMAIN_AUX_USBC6,
POWER_DOMAIN_AUX_D_XELPD = POWER_DOMAIN_AUX_USBC5, /* XELPD */
POWER_DOMAIN_AUX_E_XELPD,
POWER_DOMAIN_AUX_IO_A, POWER_DOMAIN_AUX_IO_A,
POWER_DOMAIN_AUX_C_TBT, POWER_DOMAIN_AUX_C_TBT,
POWER_DOMAIN_AUX_D_TBT, POWER_DOMAIN_AUX_D_TBT,
@ -380,6 +389,8 @@ intel_display_power_put_all_in_set(struct drm_i915_private *i915,
enum dbuf_slice { enum dbuf_slice {
DBUF_S1, DBUF_S1,
DBUF_S2, DBUF_S2,
DBUF_S3,
DBUF_S4,
I915_MAX_DBUF_SLICES I915_MAX_DBUF_SLICES
}; };

View file

@ -45,7 +45,6 @@
#include <media/cec-notifier.h> #include <media/cec-notifier.h>
#include "i915_drv.h" #include "i915_drv.h"
#include "intel_de.h"
struct drm_printer; struct drm_printer;
struct __intel_global_objs_state; struct __intel_global_objs_state;
@ -127,8 +126,12 @@ struct intel_framebuffer {
/* Params to remap the FB pages and program the plane registers in each view. */ /* Params to remap the FB pages and program the plane registers in each view. */
struct intel_fb_view normal_view; struct intel_fb_view normal_view;
struct intel_fb_view rotated_view; union {
struct intel_fb_view remapped_view; struct intel_fb_view rotated_view;
struct intel_fb_view remapped_view;
};
struct i915_address_space *dpt_vm;
}; };
struct intel_fbdev { struct intel_fbdev {
@ -611,7 +614,8 @@ struct intel_plane_state {
enum drm_scaling_filter scaling_filter; enum drm_scaling_filter scaling_filter;
} hw; } hw;
struct i915_vma *vma; struct i915_vma *ggtt_vma;
struct i915_vma *dpt_vma;
unsigned long flags; unsigned long flags;
#define PLANE_HAS_FENCE BIT(0) #define PLANE_HAS_FENCE BIT(0)
@ -1973,9 +1977,19 @@ intel_wait_for_vblank_if_active(struct drm_i915_private *dev_priv, enum pipe pip
intel_wait_for_vblank(dev_priv, pipe); intel_wait_for_vblank(dev_priv, pipe);
} }
static inline u32 intel_plane_ggtt_offset(const struct intel_plane_state *state) static inline bool intel_modifier_uses_dpt(struct drm_i915_private *i915, u64 modifier)
{ {
return i915_ggtt_offset(state->vma); return DISPLAY_VER(i915) >= 13 && modifier != DRM_FORMAT_MOD_LINEAR;
}
static inline bool intel_fb_uses_dpt(const struct drm_framebuffer *fb)
{
return fb && intel_modifier_uses_dpt(to_i915(fb->dev), fb->modifier);
}
static inline u32 intel_plane_ggtt_offset(const struct intel_plane_state *plane_state)
{
return i915_ggtt_offset(plane_state->ggtt_vma);
} }
static inline struct intel_frontbuffer * static inline struct intel_frontbuffer *

View file

@ -46,13 +46,15 @@
#include "intel_audio.h" #include "intel_audio.h"
#include "intel_connector.h" #include "intel_connector.h"
#include "intel_ddi.h" #include "intel_ddi.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_dp.h" #include "intel_dp.h"
#include "intel_dp_aux.h" #include "intel_dp_aux.h"
#include "intel_dp_hdcp.h"
#include "intel_dp_link_training.h" #include "intel_dp_link_training.h"
#include "intel_dp_mst.h" #include "intel_dp_mst.h"
#include "intel_dpll.h"
#include "intel_dpio_phy.h" #include "intel_dpio_phy.h"
#include "intel_dpll.h"
#include "intel_fifo_underrun.h" #include "intel_fifo_underrun.h"
#include "intel_hdcp.h" #include "intel_hdcp.h"
#include "intel_hdmi.h" #include "intel_hdmi.h"
@ -107,6 +109,7 @@ bool intel_dp_is_edp(struct intel_dp *intel_dp)
} }
static void intel_dp_unset_edid(struct intel_dp *intel_dp); static void intel_dp_unset_edid(struct intel_dp *intel_dp);
static int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc);
/* update sink rates from dpcd */ /* update sink rates from dpcd */
static void intel_dp_set_sink_rates(struct intel_dp *intel_dp) static void intel_dp_set_sink_rates(struct intel_dp *intel_dp)
@ -215,7 +218,7 @@ bool intel_dp_can_bigjoiner(struct intel_dp *intel_dp)
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
return DISPLAY_VER(dev_priv) >= 12 || return DISPLAY_VER(dev_priv) >= 12 ||
(IS_DISPLAY_VER(dev_priv, 11) && (DISPLAY_VER(dev_priv) == 11 &&
encoder->port != PORT_A); encoder->port != PORT_A);
} }
@ -295,16 +298,16 @@ intel_dp_set_source_rates(struct intel_dp *intel_dp)
if (DISPLAY_VER(dev_priv) >= 11 || IS_CANNONLAKE(dev_priv)) { if (DISPLAY_VER(dev_priv) >= 11 || IS_CANNONLAKE(dev_priv)) {
source_rates = cnl_rates; source_rates = cnl_rates;
size = ARRAY_SIZE(cnl_rates); size = ARRAY_SIZE(cnl_rates);
if (IS_DISPLAY_VER(dev_priv, 10)) if (DISPLAY_VER(dev_priv) == 10)
max_rate = cnl_max_source_rate(intel_dp); max_rate = cnl_max_source_rate(intel_dp);
else if (IS_JSL_EHL(dev_priv)) else if (IS_JSL_EHL(dev_priv))
max_rate = ehl_max_source_rate(intel_dp); max_rate = ehl_max_source_rate(intel_dp);
else else
max_rate = icl_max_source_rate(intel_dp); max_rate = icl_max_source_rate(intel_dp);
} else if (IS_GEN9_LP(dev_priv)) { } else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) {
source_rates = bxt_rates; source_rates = bxt_rates;
size = ARRAY_SIZE(bxt_rates); size = ARRAY_SIZE(bxt_rates);
} else if (IS_GEN9_BC(dev_priv)) { } else if (DISPLAY_VER(dev_priv) == 9) {
source_rates = skl_rates; source_rates = skl_rates;
size = ARRAY_SIZE(skl_rates); size = ARRAY_SIZE(skl_rates);
} else if ((IS_HASWELL(dev_priv) && !IS_HSW_ULX(dev_priv)) || } else if ((IS_HASWELL(dev_priv) && !IS_HSW_ULX(dev_priv)) ||
@ -492,7 +495,8 @@ small_joiner_ram_size_bits(struct drm_i915_private *i915)
static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915, static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,
u32 link_clock, u32 lane_count, u32 link_clock, u32 lane_count,
u32 mode_clock, u32 mode_hdisplay, u32 mode_clock, u32 mode_hdisplay,
bool bigjoiner) bool bigjoiner,
u32 pipe_bpp)
{ {
u32 bits_per_pixel, max_bpp_small_joiner_ram; u32 bits_per_pixel, max_bpp_small_joiner_ram;
int i; int i;
@ -539,12 +543,17 @@ static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,
return 0; return 0;
} }
/* Find the nearest match in the array of known BPPs from VESA */ /* From XE_LPD onwards we support from bpc upto uncompressed bpp-1 BPPs */
for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) { if (DISPLAY_VER(i915) >= 13) {
if (bits_per_pixel < valid_dsc_bpp[i + 1]) bits_per_pixel = min(bits_per_pixel, pipe_bpp - 1);
break; } else {
/* Find the nearest match in the array of known BPPs from VESA */
for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) {
if (bits_per_pixel < valid_dsc_bpp[i + 1])
break;
}
bits_per_pixel = valid_dsc_bpp[i];
} }
bits_per_pixel = valid_dsc_bpp[i];
/* /*
* Compressed BPP in U6.4 format so multiply by 16, for Gen 11, * Compressed BPP in U6.4 format so multiply by 16, for Gen 11,
@ -778,6 +787,12 @@ intel_dp_mode_valid(struct drm_connector *connector,
*/ */
if (DISPLAY_VER(dev_priv) >= 10 && if (DISPLAY_VER(dev_priv) >= 10 &&
drm_dp_sink_supports_dsc(intel_dp->dsc_dpcd)) { drm_dp_sink_supports_dsc(intel_dp->dsc_dpcd)) {
/*
* TBD pass the connector BPC,
* for now U8_MAX so that max BPC on that platform would be picked
*/
int pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, U8_MAX);
if (intel_dp_is_edp(intel_dp)) { if (intel_dp_is_edp(intel_dp)) {
dsc_max_output_bpp = dsc_max_output_bpp =
drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd) >> 4; drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd) >> 4;
@ -791,7 +806,8 @@ intel_dp_mode_valid(struct drm_connector *connector,
max_lanes, max_lanes,
target_clock, target_clock,
mode->hdisplay, mode->hdisplay,
bigjoiner) >> 4; bigjoiner,
pipe_bpp) >> 4;
dsc_slice_count = dsc_slice_count =
intel_dp_dsc_get_slice_count(intel_dp, intel_dp_dsc_get_slice_count(intel_dp,
target_clock, target_clock,
@ -802,8 +818,11 @@ intel_dp_mode_valid(struct drm_connector *connector,
dsc = dsc_max_output_bpp && dsc_slice_count; dsc = dsc_max_output_bpp && dsc_slice_count;
} }
/* big joiner configuration needs DSC */ /*
if (bigjoiner && !dsc) * Big joiner configuration needs DSC for TGL which is not true for
* XE_LPD where uncompressed joiner is supported.
*/
if (DISPLAY_VER(dev_priv) < 13 && bigjoiner && !dsc)
return MODE_CLOCK_HIGH; return MODE_CLOCK_HIGH;
if (mode_rate > max_rate && !dsc) if (mode_rate > max_rate && !dsc)
@ -916,7 +935,7 @@ static bool intel_dp_source_supports_fec(struct intel_dp *intel_dp,
if (DISPLAY_VER(dev_priv) >= 12) if (DISPLAY_VER(dev_priv) >= 12)
return true; return true;
if (IS_DISPLAY_VER(dev_priv, 11) && pipe_config->cpu_transcoder != TRANSCODER_A) if (DISPLAY_VER(dev_priv) == 11 && pipe_config->cpu_transcoder != TRANSCODER_A)
return true; return true;
return false; return false;
@ -1095,10 +1114,18 @@ intel_dp_compute_link_config_wide(struct intel_dp *intel_dp,
return -EINVAL; return -EINVAL;
} }
static int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc) static int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 max_req_bpc)
{ {
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
int i, num_bpc; int i, num_bpc;
u8 dsc_bpc[3] = {0}; u8 dsc_bpc[3] = {0};
u8 dsc_max_bpc;
/* Max DSC Input BPC for ICL is 10 and for TGL+ is 12 */
if (DISPLAY_VER(i915) >= 12)
dsc_max_bpc = min_t(u8, 12, max_req_bpc);
else
dsc_max_bpc = min_t(u8, 10, max_req_bpc);
num_bpc = drm_dp_dsc_sink_supported_input_bpcs(intel_dp->dsc_dpcd, num_bpc = drm_dp_dsc_sink_supported_input_bpcs(intel_dp->dsc_dpcd,
dsc_bpc); dsc_bpc);
@ -1129,10 +1156,6 @@ static int intel_dp_dsc_compute_params(struct intel_encoder *encoder,
*/ */
vdsc_cfg->rc_model_size = DSC_RC_MODEL_SIZE_CONST; vdsc_cfg->rc_model_size = DSC_RC_MODEL_SIZE_CONST;
ret = intel_dsc_compute_params(encoder, crtc_state);
if (ret)
return ret;
/* /*
* Slice Height of 8 works for all currently available panels. So start * Slice Height of 8 works for all currently available panels. So start
* with that if pic_height is an integral multiple of 8. Eventually add * with that if pic_height is an integral multiple of 8. Eventually add
@ -1145,6 +1168,10 @@ static int intel_dp_dsc_compute_params(struct intel_encoder *encoder,
else else
vdsc_cfg->slice_height = 2; vdsc_cfg->slice_height = 2;
ret = intel_dsc_compute_params(encoder, crtc_state);
if (ret)
return ret;
vdsc_cfg->dsc_version_major = vdsc_cfg->dsc_version_major =
(intel_dp->dsc_dpcd[DP_DSC_REV - DP_DSC_SUPPORT] & (intel_dp->dsc_dpcd[DP_DSC_REV - DP_DSC_SUPPORT] &
DP_DSC_MAJOR_MASK) >> DP_DSC_MAJOR_SHIFT; DP_DSC_MAJOR_MASK) >> DP_DSC_MAJOR_SHIFT;
@ -1186,7 +1213,6 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
const struct drm_display_mode *adjusted_mode = const struct drm_display_mode *adjusted_mode =
&pipe_config->hw.adjusted_mode; &pipe_config->hw.adjusted_mode;
u8 dsc_max_bpc;
int pipe_bpp; int pipe_bpp;
int ret; int ret;
@ -1196,14 +1222,7 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
if (!intel_dp_supports_dsc(intel_dp, pipe_config)) if (!intel_dp_supports_dsc(intel_dp, pipe_config))
return -EINVAL; return -EINVAL;
/* Max DSC Input BPC for ICL is 10 and for TGL+ is 12 */ pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, conn_state->max_requested_bpc);
if (DISPLAY_VER(dev_priv) >= 12)
dsc_max_bpc = min_t(u8, 12, conn_state->max_requested_bpc);
else
dsc_max_bpc = min_t(u8, 10,
conn_state->max_requested_bpc);
pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, dsc_max_bpc);
/* Min Input BPC for ICL+ is 8 */ /* Min Input BPC for ICL+ is 8 */
if (pipe_bpp < 8 * 3) { if (pipe_bpp < 8 * 3) {
@ -1238,7 +1257,8 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
pipe_config->lane_count, pipe_config->lane_count,
adjusted_mode->crtc_clock, adjusted_mode->crtc_clock,
adjusted_mode->crtc_hdisplay, adjusted_mode->crtc_hdisplay,
pipe_config->bigjoiner); pipe_config->bigjoiner,
pipe_bpp);
dsc_dp_slice_count = dsc_dp_slice_count =
intel_dp_dsc_get_slice_count(intel_dp, intel_dp_dsc_get_slice_count(intel_dp,
adjusted_mode->crtc_clock, adjusted_mode->crtc_clock,
@ -1350,9 +1370,13 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
*/ */
ret = intel_dp_compute_link_config_wide(intel_dp, pipe_config, &limits); ret = intel_dp_compute_link_config_wide(intel_dp, pipe_config, &limits);
/* enable compression if the mode doesn't fit available BW */ /*
* Pipe joiner needs compression upto display12 due to BW limitation. DG2
* onwards pipe joiner can be enabled without compression.
*/
drm_dbg_kms(&i915->drm, "Force DSC en = %d\n", intel_dp->force_dsc_en); drm_dbg_kms(&i915->drm, "Force DSC en = %d\n", intel_dp->force_dsc_en);
if (ret || intel_dp->force_dsc_en || pipe_config->bigjoiner) { if (ret || intel_dp->force_dsc_en || (DISPLAY_VER(i915) < 13 &&
pipe_config->bigjoiner)) {
ret = intel_dp_dsc_compute_config(intel_dp, pipe_config, ret = intel_dp_dsc_compute_config(intel_dp, pipe_config,
conn_state, &limits); conn_state, &limits);
if (ret < 0) if (ret < 0)
@ -1812,7 +1836,7 @@ void intel_dp_sink_set_decompression_state(struct intel_dp *intel_dp,
if (ret < 0) if (ret < 0)
drm_dbg_kms(&i915->drm, drm_dbg_kms(&i915->drm,
"Failed to %s sink decompression state\n", "Failed to %s sink decompression state\n",
enable ? "enable" : "disable"); enabledisable(enable));
} }
static void static void
@ -2244,8 +2268,8 @@ void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp,
if (drm_dp_dpcd_writeb(&intel_dp->aux, if (drm_dp_dpcd_writeb(&intel_dp->aux,
DP_PROTOCOL_CONVERTER_CONTROL_0, tmp) != 1) DP_PROTOCOL_CONVERTER_CONTROL_0, tmp) != 1)
drm_dbg_kms(&i915->drm, "Failed to set protocol converter HDMI mode to %s\n", drm_dbg_kms(&i915->drm, "Failed to %s protocol converter HDMI mode\n",
enableddisabled(intel_dp->has_hdmi_sink)); enabledisable(intel_dp->has_hdmi_sink));
tmp = crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR444 && tmp = crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR444 &&
intel_dp->dfp.ycbcr_444_to_420 ? DP_CONVERSION_TO_YCBCR420_ENABLE : 0; intel_dp->dfp.ycbcr_444_to_420 ? DP_CONVERSION_TO_YCBCR420_ENABLE : 0;
@ -2253,8 +2277,8 @@ void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp,
if (drm_dp_dpcd_writeb(&intel_dp->aux, if (drm_dp_dpcd_writeb(&intel_dp->aux,
DP_PROTOCOL_CONVERTER_CONTROL_1, tmp) != 1) DP_PROTOCOL_CONVERTER_CONTROL_1, tmp) != 1)
drm_dbg_kms(&i915->drm, drm_dbg_kms(&i915->drm,
"Failed to set protocol converter YCbCr 4:2:0 conversion mode to %s\n", "Failed to %s protocol converter YCbCr 4:2:0 conversion mode\n",
enableddisabled(intel_dp->dfp.ycbcr_444_to_420)); enabledisable(intel_dp->dfp.ycbcr_444_to_420));
tmp = 0; tmp = 0;
if (intel_dp->dfp.rgb_to_ycbcr) { if (intel_dp->dfp.rgb_to_ycbcr) {
@ -2291,8 +2315,8 @@ void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp,
if (drm_dp_pcon_convert_rgb_to_ycbcr(&intel_dp->aux, tmp) < 0) if (drm_dp_pcon_convert_rgb_to_ycbcr(&intel_dp->aux, tmp) < 0)
drm_dbg_kms(&i915->drm, drm_dbg_kms(&i915->drm,
"Failed to set protocol converter RGB->YCbCr conversion mode to %s\n", "Failed to %s protocol converter RGB->YCbCr conversion mode\n",
enableddisabled(tmp ? true : false)); enabledisable(tmp));
} }
@ -2812,31 +2836,25 @@ void intel_dp_set_infoframes(struct intel_encoder *encoder,
const struct drm_connector_state *conn_state) const struct drm_connector_state *conn_state)
{ {
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
i915_reg_t reg = HSW_TVIDEO_DIP_CTL(crtc_state->cpu_transcoder); i915_reg_t reg = HSW_TVIDEO_DIP_CTL(crtc_state->cpu_transcoder);
u32 dip_enable = VIDEO_DIP_ENABLE_AVI_HSW | VIDEO_DIP_ENABLE_GCP_HSW | u32 dip_enable = VIDEO_DIP_ENABLE_AVI_HSW | VIDEO_DIP_ENABLE_GCP_HSW |
VIDEO_DIP_ENABLE_VS_HSW | VIDEO_DIP_ENABLE_GMP_HSW | VIDEO_DIP_ENABLE_VS_HSW | VIDEO_DIP_ENABLE_GMP_HSW |
VIDEO_DIP_ENABLE_SPD_HSW | VIDEO_DIP_ENABLE_DRM_GLK; VIDEO_DIP_ENABLE_SPD_HSW | VIDEO_DIP_ENABLE_DRM_GLK;
u32 val = intel_de_read(dev_priv, reg); u32 val = intel_de_read(dev_priv, reg) & ~dip_enable;
/* TODO: Add DSC case (DIP_ENABLE_PPS) */ /* TODO: Add DSC case (DIP_ENABLE_PPS) */
/* When PSR is enabled, this routine doesn't disable VSC DIP */ /* When PSR is enabled, this routine doesn't disable VSC DIP */
if (intel_psr_enabled(intel_dp)) if (!crtc_state->has_psr)
val &= ~dip_enable; val &= ~VIDEO_DIP_ENABLE_VSC_HSW;
else
val &= ~(dip_enable | VIDEO_DIP_ENABLE_VSC_HSW);
if (!enable) {
intel_de_write(dev_priv, reg, val);
intel_de_posting_read(dev_priv, reg);
return;
}
intel_de_write(dev_priv, reg, val); intel_de_write(dev_priv, reg, val);
intel_de_posting_read(dev_priv, reg); intel_de_posting_read(dev_priv, reg);
if (!enable)
return;
/* When PSR is enabled, VSC SDP is handled by PSR routine */ /* When PSR is enabled, VSC SDP is handled by PSR routine */
if (!intel_psr_enabled(intel_dp)) if (!crtc_state->has_psr)
intel_write_dp_sdp(encoder, crtc_state, DP_SDP_VSC); intel_write_dp_sdp(encoder, crtc_state, DP_SDP_VSC);
intel_write_dp_sdp(encoder, crtc_state, HDMI_PACKET_TYPE_GAMUT_METADATA); intel_write_dp_sdp(encoder, crtc_state, HDMI_PACKET_TYPE_GAMUT_METADATA);
@ -2963,14 +2981,13 @@ static void intel_read_dp_vsc_sdp(struct intel_encoder *encoder,
struct drm_dp_vsc_sdp *vsc) struct drm_dp_vsc_sdp *vsc)
{ {
struct intel_digital_port *dig_port = enc_to_dig_port(encoder); struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
unsigned int type = DP_SDP_VSC; unsigned int type = DP_SDP_VSC;
struct dp_sdp sdp = {}; struct dp_sdp sdp = {};
int ret; int ret;
/* When PSR is enabled, VSC SDP is handled by PSR routine */ /* When PSR is enabled, VSC SDP is handled by PSR routine */
if (intel_psr_enabled(intel_dp)) if (crtc_state->has_psr)
return; return;
if ((crtc_state->infoframes.enable & if ((crtc_state->infoframes.enable &
@ -5359,7 +5376,7 @@ intel_dp_init_connector(struct intel_digital_port *dig_port,
intel_dp_add_properties(intel_dp, connector); intel_dp_add_properties(intel_dp, connector);
if (is_hdcp_supported(dev_priv, port) && !intel_dp_is_edp(intel_dp)) { if (is_hdcp_supported(dev_priv, port) && !intel_dp_is_edp(intel_dp)) {
int ret = intel_dp_init_hdcp(dig_port, intel_connector); int ret = intel_dp_hdcp_init(dig_port, intel_connector);
if (ret) if (ret)
drm_dbg_kms(&dev_priv->drm, drm_dbg_kms(&dev_priv->drm,
"HDCP init failed, skipping.\n"); "HDCP init failed, skipping.\n");
@ -5392,6 +5409,9 @@ void intel_dp_mst_suspend(struct drm_i915_private *dev_priv)
{ {
struct intel_encoder *encoder; struct intel_encoder *encoder;
if (!HAS_DISPLAY(dev_priv))
return;
for_each_intel_encoder(&dev_priv->drm, encoder) { for_each_intel_encoder(&dev_priv->drm, encoder) {
struct intel_dp *intel_dp; struct intel_dp *intel_dp;
@ -5412,6 +5432,9 @@ void intel_dp_mst_resume(struct drm_i915_private *dev_priv)
{ {
struct intel_encoder *encoder; struct intel_encoder *encoder;
if (!HAS_DISPLAY(dev_priv))
return;
for_each_intel_encoder(&dev_priv->drm, encoder) { for_each_intel_encoder(&dev_priv->drm, encoder) {
struct intel_dp *intel_dp; struct intel_dp *intel_dp;
int ret; int ret;

View file

@ -119,9 +119,6 @@ void intel_ddi_update_pipe(struct intel_atomic_state *state,
const struct intel_crtc_state *crtc_state, const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state); const struct drm_connector_state *conn_state);
int intel_dp_init_hdcp(struct intel_digital_port *dig_port,
struct intel_connector *intel_connector);
bool intel_dp_initial_fastset_check(struct intel_encoder *encoder, bool intel_dp_initial_fastset_check(struct intel_encoder *encoder,
struct intel_crtc_state *crtc_state); struct intel_crtc_state *crtc_state);
void intel_dp_sync_state(struct intel_encoder *encoder, void intel_dp_sync_state(struct intel_encoder *encoder,

View file

@ -126,12 +126,7 @@ static u32 g4x_get_aux_send_ctl(struct intel_dp *intel_dp,
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
struct drm_i915_private *dev_priv = struct drm_i915_private *dev_priv =
to_i915(dig_port->base.base.dev); to_i915(dig_port->base.base.dev);
u32 precharge, timeout; u32 timeout;
if (IS_SANDYBRIDGE(dev_priv))
precharge = 3;
else
precharge = 5;
/* Max timeout value on G4x-BDW: 1.6ms */ /* Max timeout value on G4x-BDW: 1.6ms */
if (IS_BROADWELL(dev_priv)) if (IS_BROADWELL(dev_priv))
@ -146,7 +141,7 @@ static u32 g4x_get_aux_send_ctl(struct intel_dp *intel_dp,
timeout | timeout |
DP_AUX_CH_CTL_RECEIVE_ERROR | DP_AUX_CH_CTL_RECEIVE_ERROR |
(send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) |
(precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) | (3 << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) |
(aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT); (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT);
} }
@ -607,8 +602,8 @@ static i915_reg_t tgl_aux_ctl_reg(struct intel_dp *intel_dp)
case AUX_CH_USBC2: case AUX_CH_USBC2:
case AUX_CH_USBC3: case AUX_CH_USBC3:
case AUX_CH_USBC4: case AUX_CH_USBC4:
case AUX_CH_USBC5: case AUX_CH_USBC5: /* aka AUX_CH_D_XELPD */
case AUX_CH_USBC6: case AUX_CH_USBC6: /* aka AUX_CH_E_XELPD */
return DP_AUX_CH_CTL(aux_ch); return DP_AUX_CH_CTL(aux_ch);
default: default:
MISSING_CASE(aux_ch); MISSING_CASE(aux_ch);
@ -630,8 +625,8 @@ static i915_reg_t tgl_aux_data_reg(struct intel_dp *intel_dp, int index)
case AUX_CH_USBC2: case AUX_CH_USBC2:
case AUX_CH_USBC3: case AUX_CH_USBC3:
case AUX_CH_USBC4: case AUX_CH_USBC4:
case AUX_CH_USBC5: case AUX_CH_USBC5: /* aka AUX_CH_D_XELPD */
case AUX_CH_USBC6: case AUX_CH_USBC6: /* aka AUX_CH_E_XELPD */
return DP_AUX_CH_DATA(aux_ch, index); return DP_AUX_CH_DATA(aux_ch, index);
default: default:
MISSING_CASE(aux_ch); MISSING_CASE(aux_ch);
@ -686,7 +681,11 @@ void intel_dp_aux_init(struct intel_dp *intel_dp)
drm_dp_aux_init(&intel_dp->aux); drm_dp_aux_init(&intel_dp->aux);
/* Failure to allocate our preferred name is not critical */ /* Failure to allocate our preferred name is not critical */
if (DISPLAY_VER(dev_priv) >= 12 && aux_ch >= AUX_CH_USBC1) if (DISPLAY_VER(dev_priv) >= 13 && aux_ch >= AUX_CH_D_XELPD)
intel_dp->aux.name = kasprintf(GFP_KERNEL, "AUX %c/%s",
aux_ch_name(aux_ch - AUX_CH_D_XELPD + AUX_CH_D),
encoder->base.name);
else if (DISPLAY_VER(dev_priv) >= 12 && aux_ch >= AUX_CH_USBC1)
intel_dp->aux.name = kasprintf(GFP_KERNEL, "AUX USBC%c/%s", intel_dp->aux.name = kasprintf(GFP_KERNEL, "AUX USBC%c/%s",
aux_ch - AUX_CH_USBC1 + '1', aux_ch - AUX_CH_USBC1 + '1',
encoder->base.name); encoder->base.name);

View file

@ -291,7 +291,7 @@ static void set_vesa_backlight_enable(struct intel_dp *intel_dp, bool enable)
if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_EDP_DISPLAY_CONTROL_REGISTER, if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_EDP_DISPLAY_CONTROL_REGISTER,
reg_val) != 1) { reg_val) != 1) {
drm_dbg_kms(&i915->drm, "Failed to %s aux backlight\n", drm_dbg_kms(&i915->drm, "Failed to %s aux backlight\n",
enable ? "enable" : "disable"); enabledisable(enable));
} }
} }

View file

@ -11,9 +11,11 @@
#include <drm/drm_hdcp.h> #include <drm/drm_hdcp.h>
#include <drm/drm_print.h> #include <drm/drm_print.h>
#include "intel_display_types.h"
#include "intel_ddi.h" #include "intel_ddi.h"
#include "intel_de.h"
#include "intel_display_types.h"
#include "intel_dp.h" #include "intel_dp.h"
#include "intel_dp_hdcp.h"
#include "intel_hdcp.h" #include "intel_hdcp.h"
static unsigned int transcoder_to_stream_enc_status(enum transcoder cpu_transcoder) static unsigned int transcoder_to_stream_enc_status(enum transcoder cpu_transcoder)
@ -532,7 +534,7 @@ int intel_dp_hdcp2_read_msg(struct intel_digital_port *dig_port,
u8 *byte = buf; u8 *byte = buf;
ssize_t ret, bytes_to_recv, len; ssize_t ret, bytes_to_recv, len;
const struct hdcp2_dp_msg_data *hdcp2_msg_data; const struct hdcp2_dp_msg_data *hdcp2_msg_data;
ktime_t msg_end; ktime_t msg_end = ktime_set(0, 0);
bool msg_expired; bool msg_expired;
hdcp2_msg_data = get_hdcp2_dp_msg_data(msg_id); hdcp2_msg_data = get_hdcp2_dp_msg_data(msg_id);
@ -835,7 +837,7 @@ static const struct intel_hdcp_shim intel_dp_mst_hdcp_shim = {
.protocol = HDCP_PROTOCOL_DP, .protocol = HDCP_PROTOCOL_DP,
}; };
int intel_dp_init_hdcp(struct intel_digital_port *dig_port, int intel_dp_hdcp_init(struct intel_digital_port *dig_port,
struct intel_connector *intel_connector) struct intel_connector *intel_connector)
{ {
struct drm_device *dev = intel_connector->base.dev; struct drm_device *dev = intel_connector->base.dev;

View file

@ -0,0 +1,15 @@
/* SPDX-License-Identifier: MIT */
/*
* Copyright © 2021 Intel Corporation
*/
#ifndef __INTEL_DP_HDCP___
#define __INTEL_DP_HDCP___
struct intel_connector;
struct intel_digital_port;
int intel_dp_hdcp_init(struct intel_digital_port *dig_port,
struct intel_connector *intel_connector);
#endif /* __INTEL_DP_HDCP___ */

View file

@ -37,7 +37,7 @@ intel_dp_dump_link_status(struct drm_device *drm,
static void intel_dp_reset_lttpr_common_caps(struct intel_dp *intel_dp) static void intel_dp_reset_lttpr_common_caps(struct intel_dp *intel_dp)
{ {
memset(&intel_dp->lttpr_common_caps, 0, sizeof(intel_dp->lttpr_common_caps)); memset(intel_dp->lttpr_common_caps, 0, sizeof(intel_dp->lttpr_common_caps));
} }
static void intel_dp_reset_lttpr_count(struct intel_dp *intel_dp) static void intel_dp_reset_lttpr_count(struct intel_dp *intel_dp)

View file

@ -32,13 +32,16 @@
#include "intel_atomic.h" #include "intel_atomic.h"
#include "intel_audio.h" #include "intel_audio.h"
#include "intel_connector.h" #include "intel_connector.h"
#include "intel_crtc.h"
#include "intel_ddi.h" #include "intel_ddi.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_hotplug.h"
#include "intel_dp.h" #include "intel_dp.h"
#include "intel_dp_hdcp.h"
#include "intel_dp_mst.h" #include "intel_dp_mst.h"
#include "intel_dpio_phy.h" #include "intel_dpio_phy.h"
#include "intel_hdcp.h" #include "intel_hdcp.h"
#include "intel_hotplug.h"
#include "skl_scaler.h" #include "skl_scaler.h"
static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder, static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
@ -155,7 +158,7 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
pipe_config->limited_color_range = pipe_config->limited_color_range =
intel_dp_limited_color_range(pipe_config, conn_state); intel_dp_limited_color_range(pipe_config, conn_state);
if (IS_GEN9_LP(dev_priv)) if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
pipe_config->lane_lat_optim_mask = pipe_config->lane_lat_optim_mask =
bxt_ddi_phy_calc_lane_lat_optim_mask(pipe_config->lane_count); bxt_ddi_phy_calc_lane_lat_optim_mask(pipe_config->lane_count);
@ -833,7 +836,7 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
intel_attach_broadcast_rgb_property(connector); intel_attach_broadcast_rgb_property(connector);
if (DISPLAY_VER(dev_priv) <= 12) { if (DISPLAY_VER(dev_priv) <= 12) {
ret = intel_dp_init_hdcp(dig_port, intel_connector); ret = intel_dp_hdcp_init(dig_port, intel_connector);
if (ret) if (ret)
drm_dbg_kms(&dev_priv->drm, "[%s:%d] HDCP MST init failed, skipping.\n", drm_dbg_kms(&dev_priv->drm, "[%s:%d] HDCP MST init failed, skipping.\n",
connector->name, connector->base.id); connector->name, connector->base.id);

View file

@ -23,6 +23,7 @@
#include "display/intel_dp.h" #include "display/intel_dp.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_dpio_phy.h" #include "intel_dpio_phy.h"
#include "intel_sideband.h" #include "intel_sideband.h"

View file

@ -4,6 +4,7 @@
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
#include "intel_crtc.h" #include "intel_crtc.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_display.h" #include "intel_display.h"
#include "intel_dpll.h" #include "intel_dpll.h"
@ -366,13 +367,11 @@ static bool intel_pll_is_valid(struct drm_i915_private *dev_priv,
if (clock->m1 < limit->m1.min || limit->m1.max < clock->m1) if (clock->m1 < limit->m1.min || limit->m1.max < clock->m1)
return false; return false;
if (!IS_PINEVIEW(dev_priv) && !IS_VALLEYVIEW(dev_priv) && if (!IS_PINEVIEW(dev_priv) && !IS_LP(dev_priv))
!IS_CHERRYVIEW(dev_priv) && !IS_GEN9_LP(dev_priv))
if (clock->m1 <= clock->m2) if (clock->m1 <= clock->m2)
return false; return false;
if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv) && if (!IS_LP(dev_priv)) {
!IS_GEN9_LP(dev_priv)) {
if (clock->p < limit->p.min || limit->p.max < clock->p) if (clock->p < limit->p.min || limit->p.max < clock->p)
return false; return false;
if (clock->m < limit->m.min || limit->m.max < clock->m) if (clock->m < limit->m.min || limit->m.max < clock->m)
@ -1358,7 +1357,7 @@ intel_dpll_init_clock_hook(struct drm_i915_private *dev_priv)
dev_priv->display.crtc_compute_clock = g4x_crtc_compute_clock; dev_priv->display.crtc_compute_clock = g4x_crtc_compute_clock;
else if (IS_PINEVIEW(dev_priv)) else if (IS_PINEVIEW(dev_priv))
dev_priv->display.crtc_compute_clock = pnv_crtc_compute_clock; dev_priv->display.crtc_compute_clock = pnv_crtc_compute_clock;
else if (!IS_DISPLAY_VER(dev_priv, 2)) else if (DISPLAY_VER(dev_priv) != 2)
dev_priv->display.crtc_compute_clock = i9xx_crtc_compute_clock; dev_priv->display.crtc_compute_clock = i9xx_crtc_compute_clock;
else else
dev_priv->display.crtc_compute_clock = i8xx_crtc_compute_clock; dev_priv->display.crtc_compute_clock = i8xx_crtc_compute_clock;

View file

@ -6,6 +6,8 @@
#ifndef _INTEL_DPLL_H_ #ifndef _INTEL_DPLL_H_
#define _INTEL_DPLL_H_ #define _INTEL_DPLL_H_
#include <linux/types.h>
struct dpll; struct dpll;
struct drm_i915_private; struct drm_i915_private;
struct intel_crtc; struct intel_crtc;
@ -37,5 +39,8 @@ void vlv_prepare_pll(struct intel_crtc *crtc,
const struct intel_crtc_state *pipe_config); const struct intel_crtc_state *pipe_config);
void chv_prepare_pll(struct intel_crtc *crtc, void chv_prepare_pll(struct intel_crtc *crtc,
const struct intel_crtc_state *pipe_config); const struct intel_crtc_state *pipe_config);
bool bxt_find_best_dpll(struct intel_crtc_state *crtc_state,
struct dpll *best_clock);
int chv_calc_dpll_params(int refclk, struct dpll *pll_clock);
#endif #endif

View file

@ -21,8 +21,10 @@
* DEALINGS IN THE SOFTWARE. * DEALINGS IN THE SOFTWARE.
*/ */
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_dpio_phy.h" #include "intel_dpio_phy.h"
#include "intel_dpll.h"
#include "intel_dpll_mgr.h" #include "intel_dpll_mgr.h"
/** /**
@ -4441,10 +4443,10 @@ void intel_shared_dpll_init(struct drm_device *dev)
dpll_mgr = &icl_pll_mgr; dpll_mgr = &icl_pll_mgr;
else if (IS_CANNONLAKE(dev_priv)) else if (IS_CANNONLAKE(dev_priv))
dpll_mgr = &cnl_pll_mgr; dpll_mgr = &cnl_pll_mgr;
else if (IS_GEN9_BC(dev_priv)) else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
dpll_mgr = &skl_pll_mgr;
else if (IS_GEN9_LP(dev_priv))
dpll_mgr = &bxt_pll_mgr; dpll_mgr = &bxt_pll_mgr;
else if (DISPLAY_VER(dev_priv) == 9)
dpll_mgr = &skl_pll_mgr;
else if (HAS_DDI(dev_priv)) else if (HAS_DDI(dev_priv))
dpll_mgr = &hsw_pll_mgr; dpll_mgr = &hsw_pll_mgr;
else if (HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv)) else if (HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv))

View file

@ -5,6 +5,7 @@
*/ */
#include "i915_drv.h" #include "i915_drv.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#define DSB_BUF_SIZE (2 * PAGE_SIZE) #define DSB_BUF_SIZE (2 * PAGE_SIZE)

View file

@ -124,6 +124,7 @@ struct intel_dsi {
u16 panel_on_delay; u16 panel_on_delay;
u16 panel_off_delay; u16 panel_off_delay;
u16 panel_pwr_cycle_delay; u16 panel_pwr_cycle_delay;
ktime_t panel_power_off_time;
}; };
struct intel_dsi_host { struct intel_dsi_host {

View file

@ -33,6 +33,7 @@
#include "i915_drv.h" #include "i915_drv.h"
#include "intel_connector.h" #include "intel_connector.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_dvo.h" #include "intel_dvo.h"
#include "intel_dvo_dev.h" #include "intel_dvo_dev.h"

View file

@ -30,14 +30,6 @@ bool is_gen12_ccs_cc_plane(const struct drm_framebuffer *fb, int plane)
plane == 2; plane == 2;
} }
bool is_aux_plane(const struct drm_framebuffer *fb, int plane)
{
if (is_ccs_modifier(fb->modifier))
return is_ccs_plane(fb, plane);
return plane == 1;
}
bool is_semiplanar_uv_plane(const struct drm_framebuffer *fb, int color_plane) bool is_semiplanar_uv_plane(const struct drm_framebuffer *fb, int color_plane)
{ {
return intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) && return intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) &&
@ -84,7 +76,7 @@ int skl_main_to_aux_plane(const struct drm_framebuffer *fb, int main_plane)
unsigned int intel_tile_size(const struct drm_i915_private *i915) unsigned int intel_tile_size(const struct drm_i915_private *i915)
{ {
return IS_DISPLAY_VER(i915, 2) ? 2048 : 4096; return DISPLAY_VER(i915) == 2 ? 2048 : 4096;
} }
unsigned int intel_tile_height(const struct drm_framebuffer *fb, int color_plane) unsigned int intel_tile_height(const struct drm_framebuffer *fb, int color_plane)
@ -171,17 +163,17 @@ void intel_fb_plane_get_subsampling(int *hsub, int *vsub,
*vsub = 32; *vsub = 32;
} }
static void intel_fb_plane_dims(int *w, int *h, struct drm_framebuffer *fb, int color_plane) static void intel_fb_plane_dims(const struct intel_framebuffer *fb, int color_plane, int *w, int *h)
{ {
int main_plane = is_ccs_plane(fb, color_plane) ? int main_plane = is_ccs_plane(&fb->base, color_plane) ?
skl_ccs_to_main_plane(fb, color_plane) : 0; skl_ccs_to_main_plane(&fb->base, color_plane) : 0;
int main_hsub, main_vsub; int main_hsub, main_vsub;
int hsub, vsub; int hsub, vsub;
intel_fb_plane_get_subsampling(&main_hsub, &main_vsub, fb, main_plane); intel_fb_plane_get_subsampling(&main_hsub, &main_vsub, &fb->base, main_plane);
intel_fb_plane_get_subsampling(&hsub, &vsub, fb, color_plane); intel_fb_plane_get_subsampling(&hsub, &vsub, &fb->base, color_plane);
*w = fb->width / main_hsub / hsub; *w = fb->base.width / main_hsub / hsub;
*h = fb->height / main_vsub / vsub; *h = fb->base.height / main_vsub / vsub;
} }
static u32 intel_adjust_tile_offset(int *x, int *y, static u32 intel_adjust_tile_offset(int *x, int *y,
@ -486,9 +478,12 @@ static bool intel_plane_can_remap(const struct intel_plane_state *plane_state)
return true; return true;
} }
static bool intel_fb_needs_pot_stride_remap(const struct intel_framebuffer *fb) bool intel_fb_needs_pot_stride_remap(const struct intel_framebuffer *fb)
{ {
return false; struct drm_i915_private *i915 = to_i915(fb->base.dev);
return IS_ALDERLAKE_P(i915) && fb->base.modifier != DRM_FORMAT_MOD_LINEAR &&
!is_ccs_modifier(fb->base.modifier);
} }
static int intel_fb_pitch(const struct intel_framebuffer *fb, int color_plane, unsigned int rotation) static int intel_fb_pitch(const struct intel_framebuffer *fb, int color_plane, unsigned int rotation)
@ -609,7 +604,11 @@ plane_view_dst_stride_tiles(const struct intel_framebuffer *fb, int color_plane,
unsigned int pitch_tiles) unsigned int pitch_tiles)
{ {
if (intel_fb_needs_pot_stride_remap(fb)) if (intel_fb_needs_pot_stride_remap(fb))
return roundup_pow_of_two(pitch_tiles); /*
* ADL_P, the only platform needing a POT stride has a minimum
* of 8 stride tiles.
*/
return roundup_pow_of_two(max(pitch_tiles, 8u));
else else
return pitch_tiles; return pitch_tiles;
} }
@ -743,19 +742,34 @@ static void intel_fb_view_init(struct intel_fb_view *view, enum i915_ggtt_view_t
view->gtt.type = view_type; view->gtt.type = view_type;
} }
int intel_fill_fb_info(struct drm_i915_private *i915, struct drm_framebuffer *fb) bool intel_fb_supports_90_270_rotation(const struct intel_framebuffer *fb)
{ {
struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); if (DISPLAY_VER(to_i915(fb->base.dev)) >= 13)
struct drm_i915_gem_object *obj = intel_fb_obj(fb); return false;
return fb->base.modifier == I915_FORMAT_MOD_Y_TILED ||
fb->base.modifier == I915_FORMAT_MOD_Yf_TILED;
}
int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer *fb)
{
struct drm_i915_gem_object *obj = intel_fb_obj(&fb->base);
u32 gtt_offset_rotated = 0; u32 gtt_offset_rotated = 0;
u32 gtt_offset_remapped = 0; u32 gtt_offset_remapped = 0;
unsigned int max_size = 0; unsigned int max_size = 0;
int i, num_planes = fb->format->num_planes; int i, num_planes = fb->base.format->num_planes;
unsigned int tile_size = intel_tile_size(i915); unsigned int tile_size = intel_tile_size(i915);
intel_fb_view_init(&intel_fb->normal_view, I915_GGTT_VIEW_NORMAL); intel_fb_view_init(&fb->normal_view, I915_GGTT_VIEW_NORMAL);
intel_fb_view_init(&intel_fb->rotated_view, I915_GGTT_VIEW_ROTATED);
intel_fb_view_init(&intel_fb->remapped_view, I915_GGTT_VIEW_REMAPPED); drm_WARN_ON(&i915->drm,
intel_fb_supports_90_270_rotation(fb) &&
intel_fb_needs_pot_stride_remap(fb));
if (intel_fb_supports_90_270_rotation(fb))
intel_fb_view_init(&fb->rotated_view, I915_GGTT_VIEW_ROTATED);
if (intel_fb_needs_pot_stride_remap(fb))
intel_fb_view_init(&fb->remapped_view, I915_GGTT_VIEW_REMAPPED);
for (i = 0; i < num_planes; i++) { for (i = 0; i < num_planes; i++) {
struct fb_plane_view_dims view_dims; struct fb_plane_view_dims view_dims;
@ -770,45 +784,43 @@ int intel_fill_fb_info(struct drm_i915_private *i915, struct drm_framebuffer *fb
* is consumed by the driver and not passed to DE. Skip the * is consumed by the driver and not passed to DE. Skip the
* arithmetic related to alignment and offset calculation. * arithmetic related to alignment and offset calculation.
*/ */
if (is_gen12_ccs_cc_plane(fb, i)) { if (is_gen12_ccs_cc_plane(&fb->base, i)) {
if (IS_ALIGNED(fb->offsets[i], PAGE_SIZE)) if (IS_ALIGNED(fb->base.offsets[i], PAGE_SIZE))
continue; continue;
else else
return -EINVAL; return -EINVAL;
} }
cpp = fb->format->cpp[i]; cpp = fb->base.format->cpp[i];
intel_fb_plane_dims(&width, &height, fb, i); intel_fb_plane_dims(fb, i, &width, &height);
ret = convert_plane_offset_to_xy(intel_fb, i, width, &x, &y); ret = convert_plane_offset_to_xy(fb, i, width, &x, &y);
if (ret) if (ret)
return ret; return ret;
init_plane_view_dims(intel_fb, i, width, height, &view_dims); init_plane_view_dims(fb, i, width, height, &view_dims);
/* /*
* First pixel of the framebuffer from * First pixel of the framebuffer from
* the start of the normal gtt mapping. * the start of the normal gtt mapping.
*/ */
intel_fb->normal_view.color_plane[i].x = x; fb->normal_view.color_plane[i].x = x;
intel_fb->normal_view.color_plane[i].y = y; fb->normal_view.color_plane[i].y = y;
intel_fb->normal_view.color_plane[i].stride = intel_fb->base.pitches[i]; fb->normal_view.color_plane[i].stride = fb->base.pitches[i];
offset = calc_plane_aligned_offset(intel_fb, i, &x, &y); offset = calc_plane_aligned_offset(fb, i, &x, &y);
/* Y or Yf modifiers required for 90/270 rotation */ if (intel_fb_supports_90_270_rotation(fb))
if (fb->modifier == I915_FORMAT_MOD_Y_TILED || gtt_offset_rotated += calc_plane_remap_info(fb, i, &view_dims,
fb->modifier == I915_FORMAT_MOD_Yf_TILED)
gtt_offset_rotated += calc_plane_remap_info(intel_fb, i, &view_dims,
offset, gtt_offset_rotated, x, y, offset, gtt_offset_rotated, x, y,
&intel_fb->rotated_view); &fb->rotated_view);
if (intel_fb_needs_pot_stride_remap(intel_fb)) if (intel_fb_needs_pot_stride_remap(fb))
gtt_offset_remapped += calc_plane_remap_info(intel_fb, i, &view_dims, gtt_offset_remapped += calc_plane_remap_info(fb, i, &view_dims,
offset, gtt_offset_remapped, x, y, offset, gtt_offset_remapped, x, y,
&intel_fb->remapped_view); &fb->remapped_view);
size = calc_plane_normal_size(intel_fb, i, &view_dims, x, y); size = calc_plane_normal_size(fb, i, &view_dims, x, y);
/* how many tiles in total needed in the bo */ /* how many tiles in total needed in the bo */
max_size = max(max_size, offset + size); max_size = max(max_size, offset + size);
} }

View file

@ -19,7 +19,6 @@ struct intel_plane_state;
bool is_ccs_plane(const struct drm_framebuffer *fb, int plane); bool is_ccs_plane(const struct drm_framebuffer *fb, int plane);
bool is_gen12_ccs_plane(const struct drm_framebuffer *fb, int plane); bool is_gen12_ccs_plane(const struct drm_framebuffer *fb, int plane);
bool is_gen12_ccs_cc_plane(const struct drm_framebuffer *fb, int plane); bool is_gen12_ccs_cc_plane(const struct drm_framebuffer *fb, int plane);
bool is_aux_plane(const struct drm_framebuffer *fb, int plane);
bool is_semiplanar_uv_plane(const struct drm_framebuffer *fb, int color_plane); bool is_semiplanar_uv_plane(const struct drm_framebuffer *fb, int color_plane);
bool is_surface_linear(const struct drm_framebuffer *fb, int color_plane); bool is_surface_linear(const struct drm_framebuffer *fb, int color_plane);
@ -46,7 +45,10 @@ u32 intel_plane_compute_aligned_offset(int *x, int *y,
const struct intel_plane_state *state, const struct intel_plane_state *state,
int color_plane); int color_plane);
int intel_fill_fb_info(struct drm_i915_private *i915, struct drm_framebuffer *fb); bool intel_fb_needs_pot_stride_remap(const struct intel_framebuffer *fb);
bool intel_fb_supports_90_270_rotation(const struct intel_framebuffer *fb);
int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer *fb);
void intel_fb_fill_view(const struct intel_framebuffer *fb, unsigned int rotation, void intel_fb_fill_view(const struct intel_framebuffer *fb, unsigned int rotation,
struct intel_fb_view *view); struct intel_fb_view *view);
int intel_plane_compute_gtt(struct intel_plane_state *plane_state); int intel_plane_compute_gtt(struct intel_plane_state *plane_state);

View file

@ -43,6 +43,7 @@
#include "i915_drv.h" #include "i915_drv.h"
#include "i915_trace.h" #include "i915_trace.h"
#include "i915_vgpu.h" #include "i915_vgpu.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_fbc.h" #include "intel_fbc.h"
#include "intel_frontbuffer.h" #include "intel_frontbuffer.h"
@ -67,7 +68,7 @@ static int intel_fbc_calculate_cfb_size(struct drm_i915_private *dev_priv,
int lines; int lines;
intel_fbc_get_plane_source_size(cache, NULL, &lines); intel_fbc_get_plane_source_size(cache, NULL, &lines);
if (IS_DISPLAY_VER(dev_priv, 7)) if (DISPLAY_VER(dev_priv) == 7)
lines = min(lines, 2048); lines = min(lines, 2048);
else if (DISPLAY_VER(dev_priv) >= 8) else if (DISPLAY_VER(dev_priv) >= 8)
lines = min(lines, 2560); lines = min(lines, 2560);
@ -109,7 +110,7 @@ static void i8xx_fbc_activate(struct drm_i915_private *dev_priv)
cfb_pitch = params->fb.stride; cfb_pitch = params->fb.stride;
/* FBC_CTL wants 32B or 64B units */ /* FBC_CTL wants 32B or 64B units */
if (IS_DISPLAY_VER(dev_priv, 2)) if (DISPLAY_VER(dev_priv) == 2)
cfb_pitch = (cfb_pitch / 32) - 1; cfb_pitch = (cfb_pitch / 32) - 1;
else else
cfb_pitch = (cfb_pitch / 64) - 1; cfb_pitch = (cfb_pitch / 64) - 1;
@ -118,7 +119,7 @@ static void i8xx_fbc_activate(struct drm_i915_private *dev_priv)
for (i = 0; i < (FBC_LL_SIZE / 32) + 1; i++) for (i = 0; i < (FBC_LL_SIZE / 32) + 1; i++)
intel_de_write(dev_priv, FBC_TAG(i), 0); intel_de_write(dev_priv, FBC_TAG(i), 0);
if (IS_DISPLAY_VER(dev_priv, 4)) { if (DISPLAY_VER(dev_priv) == 4) {
u32 fbc_ctl2; u32 fbc_ctl2;
/* Set it up... */ /* Set it up... */
@ -302,7 +303,7 @@ static void gen7_fbc_activate(struct drm_i915_private *dev_priv)
int threshold = dev_priv->fbc.threshold; int threshold = dev_priv->fbc.threshold;
/* Display WA #0529: skl, kbl, bxt. */ /* Display WA #0529: skl, kbl, bxt. */
if (IS_GEN9_BC(dev_priv) || IS_BROXTON(dev_priv)) { if (DISPLAY_VER(dev_priv) == 9) {
u32 val = intel_de_read(dev_priv, CHICKEN_MISC_4); u32 val = intel_de_read(dev_priv, CHICKEN_MISC_4);
val &= ~(FBC_STRIDE_OVERRIDE | FBC_STRIDE_MASK); val &= ~(FBC_STRIDE_OVERRIDE | FBC_STRIDE_MASK);
@ -445,7 +446,8 @@ static int find_compression_threshold(struct drm_i915_private *dev_priv,
* reserved range size, so it always assumes the maximum (8mb) is used. * reserved range size, so it always assumes the maximum (8mb) is used.
* If we enable FBC using a CFB on that memory range we'll get FIFO * If we enable FBC using a CFB on that memory range we'll get FIFO
* underruns, even if that range is not reserved by the BIOS. */ * underruns, even if that range is not reserved by the BIOS. */
if (IS_BROADWELL(dev_priv) || IS_GEN9_BC(dev_priv)) if (IS_BROADWELL(dev_priv) || (DISPLAY_VER(dev_priv) == 9 &&
!IS_BROXTON(dev_priv)))
end = resource_size(&dev_priv->dsm) - 8 * 1024 * 1024; end = resource_size(&dev_priv->dsm) - 8 * 1024 * 1024;
else else
end = U64_MAX; end = U64_MAX;
@ -590,14 +592,14 @@ static bool stride_is_valid(struct drm_i915_private *dev_priv,
if (stride < 512) if (stride < 512)
return false; return false;
if (IS_DISPLAY_VER(dev_priv, 2) || IS_DISPLAY_VER(dev_priv, 3)) if (DISPLAY_VER(dev_priv) == 2 || DISPLAY_VER(dev_priv) == 3)
return stride == 4096 || stride == 8192; return stride == 4096 || stride == 8192;
if (IS_DISPLAY_VER(dev_priv, 4) && !IS_G4X(dev_priv) && stride < 2048) if (DISPLAY_VER(dev_priv) == 4 && !IS_G4X(dev_priv) && stride < 2048)
return false; return false;
/* Display WA #1105: skl,bxt,kbl,cfl,glk */ /* Display WA #1105: skl,bxt,kbl,cfl,glk */
if ((IS_DISPLAY_VER(dev_priv, 9) || IS_GEMINILAKE(dev_priv)) && if ((DISPLAY_VER(dev_priv) == 9 || IS_GEMINILAKE(dev_priv)) &&
modifier == DRM_FORMAT_MOD_LINEAR && stride & 511) modifier == DRM_FORMAT_MOD_LINEAR && stride & 511)
return false; return false;
@ -617,7 +619,7 @@ static bool pixel_format_is_valid(struct drm_i915_private *dev_priv,
case DRM_FORMAT_XRGB1555: case DRM_FORMAT_XRGB1555:
case DRM_FORMAT_RGB565: case DRM_FORMAT_RGB565:
/* 16bpp not supported on gen2 */ /* 16bpp not supported on gen2 */
if (IS_DISPLAY_VER(dev_priv, 2)) if (DISPLAY_VER(dev_priv) == 2)
return false; return false;
/* WaFbcOnly1to1Ratio:ctg */ /* WaFbcOnly1to1Ratio:ctg */
if (IS_G4X(dev_priv)) if (IS_G4X(dev_priv))
@ -735,11 +737,11 @@ static void intel_fbc_update_state_cache(struct intel_crtc *crtc,
cache->fence_y_offset = intel_plane_fence_y_offset(plane_state); cache->fence_y_offset = intel_plane_fence_y_offset(plane_state);
drm_WARN_ON(&dev_priv->drm, plane_state->flags & PLANE_HAS_FENCE && drm_WARN_ON(&dev_priv->drm, plane_state->flags & PLANE_HAS_FENCE &&
!plane_state->vma->fence); !plane_state->ggtt_vma->fence);
if (plane_state->flags & PLANE_HAS_FENCE && if (plane_state->flags & PLANE_HAS_FENCE &&
plane_state->vma->fence) plane_state->ggtt_vma->fence)
cache->fence_id = plane_state->vma->fence->id; cache->fence_id = plane_state->ggtt_vma->fence->id;
else else
cache->fence_id = -1; cache->fence_id = -1;
@ -759,7 +761,7 @@ static u16 intel_fbc_gen9_wa_cfb_stride(struct drm_i915_private *dev_priv)
struct intel_fbc *fbc = &dev_priv->fbc; struct intel_fbc *fbc = &dev_priv->fbc;
struct intel_fbc_state_cache *cache = &fbc->state_cache; struct intel_fbc_state_cache *cache = &fbc->state_cache;
if ((IS_GEN9_BC(dev_priv) || IS_BROXTON(dev_priv)) && if ((DISPLAY_VER(dev_priv) == 9) &&
cache->fb.modifier != I915_FORMAT_MOD_X_TILED) cache->fb.modifier != I915_FORMAT_MOD_X_TILED)
return DIV_ROUND_UP(cache->plane.src_w, 32 * fbc->threshold) * 8; return DIV_ROUND_UP(cache->plane.src_w, 32 * fbc->threshold) * 8;
else else

View file

@ -5,6 +5,7 @@
#include "intel_atomic.h" #include "intel_atomic.h"
#include "intel_ddi.h" #include "intel_ddi.h"
#include "intel_ddi_buf_trans.h" #include "intel_ddi_buf_trans.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_fdi.h" #include "intel_fdi.h"

View file

@ -27,6 +27,7 @@
#include "i915_drv.h" #include "i915_drv.h"
#include "i915_trace.h" #include "i915_trace.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_fbc.h" #include "intel_fbc.h"
#include "intel_fifo_underrun.h" #include "intel_fifo_underrun.h"
@ -271,7 +272,7 @@ static bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
i9xx_set_fifo_underrun_reporting(dev, pipe, enable, old); i9xx_set_fifo_underrun_reporting(dev, pipe, enable, old);
else if (IS_IRONLAKE(dev_priv) || IS_SANDYBRIDGE(dev_priv)) else if (IS_IRONLAKE(dev_priv) || IS_SANDYBRIDGE(dev_priv))
ilk_set_fifo_underrun_reporting(dev, pipe, enable); ilk_set_fifo_underrun_reporting(dev, pipe, enable);
else if (IS_DISPLAY_VER(dev_priv, 7)) else if (DISPLAY_VER(dev_priv) == 7)
ivb_set_fifo_underrun_reporting(dev, pipe, enable, old); ivb_set_fifo_underrun_reporting(dev, pipe, enable, old);
else if (DISPLAY_VER(dev_priv) >= 8) else if (DISPLAY_VER(dev_priv) >= 8)
bdw_set_fifo_underrun_reporting(dev, pipe, enable); bdw_set_fifo_underrun_reporting(dev, pipe, enable);
@ -432,7 +433,7 @@ void intel_check_cpu_fifo_underruns(struct drm_i915_private *dev_priv)
if (HAS_GMCH(dev_priv)) if (HAS_GMCH(dev_priv))
i9xx_check_fifo_underruns(crtc); i9xx_check_fifo_underruns(crtc);
else if (IS_DISPLAY_VER(dev_priv, 7)) else if (DISPLAY_VER(dev_priv) == 7)
ivb_check_fifo_underruns(crtc); ivb_check_fifo_underruns(crtc);
} }

View file

@ -58,6 +58,7 @@
#include "display/intel_dp.h" #include "display/intel_dp.h"
#include "i915_drv.h" #include "i915_drv.h"
#include "i915_trace.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_fbc.h" #include "intel_fbc.h"
#include "intel_frontbuffer.h" #include "intel_frontbuffer.h"
@ -87,6 +88,8 @@ static void frontbuffer_flush(struct drm_i915_private *i915,
if (!frontbuffer_bits) if (!frontbuffer_bits)
return; return;
trace_intel_frontbuffer_flush(frontbuffer_bits, origin);
might_sleep(); might_sleep();
intel_edp_drrs_flush(i915, frontbuffer_bits); intel_edp_drrs_flush(i915, frontbuffer_bits);
intel_psr_flush(i915, frontbuffer_bits, origin); intel_psr_flush(i915, frontbuffer_bits, origin);
@ -173,6 +176,8 @@ void __intel_fb_invalidate(struct intel_frontbuffer *front,
spin_unlock(&i915->fb_tracking.lock); spin_unlock(&i915->fb_tracking.lock);
} }
trace_intel_frontbuffer_invalidate(frontbuffer_bits, origin);
might_sleep(); might_sleep();
intel_psr_invalidate(i915, frontbuffer_bits, origin); intel_psr_invalidate(i915, frontbuffer_bits, origin);
intel_edp_drrs_invalidate(i915, frontbuffer_bits); intel_edp_drrs_invalidate(i915, frontbuffer_bits);

View file

@ -34,6 +34,7 @@
#include <drm/drm_hdcp.h> #include <drm/drm_hdcp.h>
#include "i915_drv.h" #include "i915_drv.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_gmbus.h" #include "intel_gmbus.h"
@ -107,9 +108,9 @@ static const struct gmbus_pin *get_gmbus_pin(struct drm_i915_private *dev_priv,
return &gmbus_pins_icp[pin]; return &gmbus_pins_icp[pin];
else if (HAS_PCH_CNP(dev_priv)) else if (HAS_PCH_CNP(dev_priv))
return &gmbus_pins_cnp[pin]; return &gmbus_pins_cnp[pin];
else if (IS_GEN9_LP(dev_priv)) else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
return &gmbus_pins_bxt[pin]; return &gmbus_pins_bxt[pin];
else if (IS_GEN9_BC(dev_priv)) else if (DISPLAY_VER(dev_priv) == 9)
return &gmbus_pins_skl[pin]; return &gmbus_pins_skl[pin];
else if (IS_BROADWELL(dev_priv)) else if (IS_BROADWELL(dev_priv))
return &gmbus_pins_bdw[pin]; return &gmbus_pins_bdw[pin];
@ -128,9 +129,9 @@ bool intel_gmbus_is_valid_pin(struct drm_i915_private *dev_priv,
size = ARRAY_SIZE(gmbus_pins_icp); size = ARRAY_SIZE(gmbus_pins_icp);
else if (HAS_PCH_CNP(dev_priv)) else if (HAS_PCH_CNP(dev_priv))
size = ARRAY_SIZE(gmbus_pins_cnp); size = ARRAY_SIZE(gmbus_pins_cnp);
else if (IS_GEN9_LP(dev_priv)) else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
size = ARRAY_SIZE(gmbus_pins_bxt); size = ARRAY_SIZE(gmbus_pins_bxt);
else if (IS_GEN9_BC(dev_priv)) else if (DISPLAY_VER(dev_priv) == 9)
size = ARRAY_SIZE(gmbus_pins_skl); size = ARRAY_SIZE(gmbus_pins_skl);
else if (IS_BROADWELL(dev_priv)) else if (IS_BROADWELL(dev_priv))
size = ARRAY_SIZE(gmbus_pins_bdw); size = ARRAY_SIZE(gmbus_pins_bdw);
@ -600,7 +601,7 @@ do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num,
int ret = 0; int ret = 0;
/* Display WA #0868: skl,bxt,kbl,cfl,glk,cnl */ /* Display WA #0868: skl,bxt,kbl,cfl,glk,cnl */
if (IS_GEN9_LP(dev_priv)) if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
bxt_gmbus_clock_gating(dev_priv, false); bxt_gmbus_clock_gating(dev_priv, false);
else if (HAS_PCH_SPT(dev_priv) || HAS_PCH_CNP(dev_priv)) else if (HAS_PCH_SPT(dev_priv) || HAS_PCH_CNP(dev_priv))
pch_gmbus_clock_gating(dev_priv, false); pch_gmbus_clock_gating(dev_priv, false);
@ -713,7 +714,7 @@ do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num,
out: out:
/* Display WA #0868: skl,bxt,kbl,cfl,glk,cnl */ /* Display WA #0868: skl,bxt,kbl,cfl,glk,cnl */
if (IS_GEN9_LP(dev_priv)) if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
bxt_gmbus_clock_gating(dev_priv, true); bxt_gmbus_clock_gating(dev_priv, true);
else if (HAS_PCH_SPT(dev_priv) || HAS_PCH_CNP(dev_priv)) else if (HAS_PCH_SPT(dev_priv) || HAS_PCH_CNP(dev_priv))
pch_gmbus_clock_gating(dev_priv, true); pch_gmbus_clock_gating(dev_priv, true);
@ -845,9 +846,6 @@ int intel_gmbus_setup(struct drm_i915_private *dev_priv)
unsigned int pin; unsigned int pin;
int ret; int ret;
if (!HAS_DISPLAY(dev_priv))
return 0;
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
dev_priv->gpio_mmio_base = VLV_DISPLAY_BASE; dev_priv->gpio_mmio_base = VLV_DISPLAY_BASE;
else if (!HAS_GMCH(dev_priv)) else if (!HAS_GMCH(dev_priv))

View file

@ -18,6 +18,7 @@
#include "i915_drv.h" #include "i915_drv.h"
#include "i915_reg.h" #include "i915_reg.h"
#include "intel_display_power.h" #include "intel_display_power.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_hdcp.h" #include "intel_hdcp.h"
#include "intel_sideband.h" #include "intel_sideband.h"
@ -286,11 +287,12 @@ static int intel_hdcp_load_keys(struct drm_i915_private *dev_priv)
/* /*
* Initiate loading the HDCP key from fuses. * Initiate loading the HDCP key from fuses.
* *
* BXT+ platforms, HDCP key needs to be loaded by SW. Only Gen 9 * BXT+ platforms, HDCP key needs to be loaded by SW. Only display
* platforms except BXT and GLK, differ in the key load trigger process * version 9 platforms (minus BXT) differ in the key load trigger
* from other platforms. So GEN9_BC uses the GT Driver Mailbox i/f. * process from other platforms. These platforms use the GT Driver
* Mailbox interface.
*/ */
if (IS_GEN9_BC(dev_priv)) { if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv)) {
ret = sandybridge_pcode_write(dev_priv, ret = sandybridge_pcode_write(dev_priv,
SKL_PCODE_LOAD_HDCP_KEYS, 1); SKL_PCODE_LOAD_HDCP_KEYS, 1);
if (ret) { if (ret) {

View file

@ -43,6 +43,7 @@
#include "intel_atomic.h" #include "intel_atomic.h"
#include "intel_connector.h" #include "intel_connector.h"
#include "intel_ddi.h" #include "intel_ddi.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_dp.h" #include "intel_dp.h"
#include "intel_gmbus.h" #include "intel_gmbus.h"
@ -531,6 +532,11 @@ void hsw_write_infoframe(struct intel_encoder *encoder,
hsw_dip_data_reg(dev_priv, cpu_transcoder, type, i >> 2), hsw_dip_data_reg(dev_priv, cpu_transcoder, type, i >> 2),
0); 0);
/* Wa_14013475917 */
if (DISPLAY_VER(dev_priv) == 13 && crtc_state->has_psr &&
type == DP_SDP_VSC)
return;
val |= hsw_infoframe_enable(type); val |= hsw_infoframe_enable(type);
intel_de_write(dev_priv, ctl_reg, val); intel_de_write(dev_priv, ctl_reg, val);
intel_de_posting_read(dev_priv, ctl_reg); intel_de_posting_read(dev_priv, ctl_reg);
@ -542,11 +548,9 @@ void hsw_read_infoframe(struct intel_encoder *encoder,
{ {
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
u32 val, *data = frame; u32 *data = frame;
int i; int i;
val = intel_de_read(dev_priv, HSW_TVIDEO_DIP_CTL(cpu_transcoder));
for (i = 0; i < len; i += 4) for (i = 0; i < len; i += 4)
*data++ = intel_de_read(dev_priv, *data++ = intel_de_read(dev_priv,
hsw_dip_data_reg(dev_priv, cpu_transcoder, type, i >> 2)); hsw_dip_data_reg(dev_priv, cpu_transcoder, type, i >> 2));
@ -1840,7 +1844,8 @@ hdmi_port_clock_valid(struct intel_hdmi *hdmi,
return MODE_CLOCK_RANGE; return MODE_CLOCK_RANGE;
/* BXT/GLK DPLL can't generate 223-240 MHz */ /* BXT/GLK DPLL can't generate 223-240 MHz */
if (IS_GEN9_LP(dev_priv) && clock > 223333 && clock < 240000) if ((IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) &&
clock > 223333 && clock < 240000)
return MODE_CLOCK_RANGE; return MODE_CLOCK_RANGE;
/* CHV DPLL can't generate 216-240 MHz */ /* CHV DPLL can't generate 216-240 MHz */
@ -1861,34 +1866,11 @@ static int intel_hdmi_port_clock(int clock, int bpc)
} }
static enum drm_mode_status static enum drm_mode_status
intel_hdmi_mode_valid(struct drm_connector *connector, intel_hdmi_mode_clock_valid(struct intel_hdmi *hdmi, int clock, bool has_hdmi_sink)
struct drm_display_mode *mode)
{ {
struct intel_hdmi *hdmi = intel_attached_hdmi(to_intel_connector(connector));
struct drm_device *dev = intel_hdmi_to_dev(hdmi); struct drm_device *dev = intel_hdmi_to_dev(hdmi);
struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_private *dev_priv = to_i915(dev);
enum drm_mode_status status; enum drm_mode_status status;
int clock = mode->clock;
int max_dotclk = to_i915(connector->dev)->max_dotclk_freq;
bool has_hdmi_sink = intel_has_hdmi_sink(hdmi, connector->state);
if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
return MODE_NO_DBLESCAN;
if ((mode->flags & DRM_MODE_FLAG_3D_MASK) == DRM_MODE_FLAG_3D_FRAME_PACKING)
clock *= 2;
if (clock > max_dotclk)
return MODE_CLOCK_HIGH;
if (mode->flags & DRM_MODE_FLAG_DBLCLK) {
if (!has_hdmi_sink)
return MODE_CLOCK_LOW;
clock *= 2;
}
if (drm_mode_is_420_only(&connector->display_info, mode))
clock /= 2;
/* check if we can do 8bpc */ /* check if we can do 8bpc */
status = hdmi_port_clock_valid(hdmi, intel_hdmi_port_clock(clock, 8), status = hdmi_port_clock_valid(hdmi, intel_hdmi_port_clock(clock, 8),
@ -1905,8 +1887,54 @@ intel_hdmi_mode_valid(struct drm_connector *connector,
status = hdmi_port_clock_valid(hdmi, intel_hdmi_port_clock(clock, 10), status = hdmi_port_clock_valid(hdmi, intel_hdmi_port_clock(clock, 10),
true, has_hdmi_sink); true, has_hdmi_sink);
} }
if (status != MODE_OK)
return status; return status;
}
static enum drm_mode_status
intel_hdmi_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
struct intel_hdmi *hdmi = intel_attached_hdmi(to_intel_connector(connector));
struct drm_device *dev = intel_hdmi_to_dev(hdmi);
struct drm_i915_private *dev_priv = to_i915(dev);
enum drm_mode_status status;
int clock = mode->clock;
int max_dotclk = to_i915(connector->dev)->max_dotclk_freq;
bool has_hdmi_sink = intel_has_hdmi_sink(hdmi, connector->state);
bool ycbcr_420_only;
if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
return MODE_NO_DBLESCAN;
if ((mode->flags & DRM_MODE_FLAG_3D_MASK) == DRM_MODE_FLAG_3D_FRAME_PACKING)
clock *= 2;
if (clock > max_dotclk)
return MODE_CLOCK_HIGH;
if (mode->flags & DRM_MODE_FLAG_DBLCLK) {
if (!has_hdmi_sink)
return MODE_CLOCK_LOW;
clock *= 2;
}
ycbcr_420_only = drm_mode_is_420_only(&connector->display_info, mode);
if (ycbcr_420_only)
clock /= 2;
status = intel_hdmi_mode_clock_valid(hdmi, clock, has_hdmi_sink);
if (status != MODE_OK) {
if (ycbcr_420_only ||
!connector->ycbcr_420_allowed ||
!drm_mode_is_420_also(&connector->display_info, mode))
return status;
clock /= 2;
status = intel_hdmi_mode_clock_valid(hdmi, clock, has_hdmi_sink);
if (status != MODE_OK)
return status;
}
return intel_mode_valid_max_plane_size(dev_priv, mode, false); return intel_mode_valid_max_plane_size(dev_priv, mode, false);
} }
@ -1976,7 +2004,7 @@ static bool hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
/* Display Wa_1405510057:icl,ehl */ /* Display Wa_1405510057:icl,ehl */
if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 && if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 &&
bpc == 10 && IS_DISPLAY_VER(dev_priv, 11) && bpc == 10 && DISPLAY_VER(dev_priv) == 11 &&
(adjusted_mode->crtc_hblank_end - (adjusted_mode->crtc_hblank_end -
adjusted_mode->crtc_hblank_start) % 8 == 2) adjusted_mode->crtc_hblank_start) % 8 == 2)
return false; return false;
@ -1987,29 +2015,6 @@ static bool hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
INTEL_OUTPUT_FORMAT_YCBCR420); INTEL_OUTPUT_FORMAT_YCBCR420);
} }
static int
intel_hdmi_ycbcr420_config(struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state)
{
struct drm_connector *connector = conn_state->connector;
struct drm_i915_private *i915 = to_i915(connector->dev);
const struct drm_display_mode *adjusted_mode =
&crtc_state->hw.adjusted_mode;
if (!drm_mode_is_420_only(&connector->display_info, adjusted_mode))
return 0;
if (!connector->ycbcr_420_allowed) {
drm_err(&i915->drm,
"Platform doesn't support YCBCR420 output\n");
return -EINVAL;
}
crtc_state->output_format = INTEL_OUTPUT_FORMAT_YCBCR420;
return intel_pch_panel_fitting(crtc_state, conn_state);
}
static int intel_hdmi_compute_bpc(struct intel_encoder *encoder, static int intel_hdmi_compute_bpc(struct intel_encoder *encoder,
struct intel_crtc_state *crtc_state, struct intel_crtc_state *crtc_state,
int clock) int clock)
@ -2116,6 +2121,39 @@ static bool intel_hdmi_has_audio(struct intel_encoder *encoder,
return intel_conn_state->force_audio == HDMI_AUDIO_ON; return intel_conn_state->force_audio == HDMI_AUDIO_ON;
} }
static int intel_hdmi_compute_output_format(struct intel_encoder *encoder,
struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state)
{
struct drm_connector *connector = conn_state->connector;
struct drm_i915_private *i915 = to_i915(connector->dev);
const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
int ret;
bool ycbcr_420_only;
ycbcr_420_only = drm_mode_is_420_only(&connector->display_info, adjusted_mode);
if (connector->ycbcr_420_allowed && ycbcr_420_only) {
crtc_state->output_format = INTEL_OUTPUT_FORMAT_YCBCR420;
} else {
if (!connector->ycbcr_420_allowed && ycbcr_420_only)
drm_dbg_kms(&i915->drm,
"YCbCr 4:2:0 mode but YCbCr 4:2:0 output not possible. Falling back to RGB.\n");
crtc_state->output_format = INTEL_OUTPUT_FORMAT_RGB;
}
ret = intel_hdmi_compute_clock(encoder, crtc_state);
if (ret) {
if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_YCBCR420 &&
connector->ycbcr_420_allowed &&
drm_mode_is_420_also(&connector->display_info, adjusted_mode)) {
crtc_state->output_format = INTEL_OUTPUT_FORMAT_YCBCR420;
ret = intel_hdmi_compute_clock(encoder, crtc_state);
}
}
return ret;
}
int intel_hdmi_compute_config(struct intel_encoder *encoder, int intel_hdmi_compute_config(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config, struct intel_crtc_state *pipe_config,
struct drm_connector_state *conn_state) struct drm_connector_state *conn_state)
@ -2140,23 +2178,25 @@ int intel_hdmi_compute_config(struct intel_encoder *encoder,
if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK) if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK)
pipe_config->pixel_multiplier = 2; pipe_config->pixel_multiplier = 2;
ret = intel_hdmi_ycbcr420_config(pipe_config, conn_state);
if (ret)
return ret;
pipe_config->limited_color_range =
intel_hdmi_limited_color_range(pipe_config, conn_state);
if (HAS_PCH_SPLIT(dev_priv) && !HAS_DDI(dev_priv)) if (HAS_PCH_SPLIT(dev_priv) && !HAS_DDI(dev_priv))
pipe_config->has_pch_encoder = true; pipe_config->has_pch_encoder = true;
pipe_config->has_audio = pipe_config->has_audio =
intel_hdmi_has_audio(encoder, pipe_config, conn_state); intel_hdmi_has_audio(encoder, pipe_config, conn_state);
ret = intel_hdmi_compute_clock(encoder, pipe_config); ret = intel_hdmi_compute_output_format(encoder, pipe_config, conn_state);
if (ret) if (ret)
return ret; return ret;
if (pipe_config->output_format == INTEL_OUTPUT_FORMAT_YCBCR420) {
ret = intel_pch_panel_fitting(pipe_config, conn_state);
if (ret)
return ret;
}
pipe_config->limited_color_range =
intel_hdmi_limited_color_range(pipe_config, conn_state);
if (conn_state->picture_aspect_ratio) if (conn_state->picture_aspect_ratio)
adjusted_mode->picture_aspect_ratio = adjusted_mode->picture_aspect_ratio =
conn_state->picture_aspect_ratio; conn_state->picture_aspect_ratio;
@ -2706,13 +2746,13 @@ static u8 intel_hdmi_ddc_pin(struct intel_encoder *encoder)
return ddc_pin; return ddc_pin;
} }
if (HAS_PCH_ADP(dev_priv)) if (IS_ALDERLAKE_S(dev_priv))
ddc_pin = adls_port_to_ddc_pin(dev_priv, port); ddc_pin = adls_port_to_ddc_pin(dev_priv, port);
else if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG1) else if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG1)
ddc_pin = dg1_port_to_ddc_pin(dev_priv, port); ddc_pin = dg1_port_to_ddc_pin(dev_priv, port);
else if (IS_ROCKETLAKE(dev_priv)) else if (IS_ROCKETLAKE(dev_priv))
ddc_pin = rkl_port_to_ddc_pin(dev_priv, port); ddc_pin = rkl_port_to_ddc_pin(dev_priv, port);
else if (IS_GEN9_BC(dev_priv) && HAS_PCH_TGP(dev_priv)) else if (DISPLAY_VER(dev_priv) == 9 && HAS_PCH_TGP(dev_priv))
ddc_pin = gen9bc_tgp_port_to_ddc_pin(dev_priv, port); ddc_pin = gen9bc_tgp_port_to_ddc_pin(dev_priv, port);
else if (HAS_PCH_MCC(dev_priv)) else if (HAS_PCH_MCC(dev_priv))
ddc_pin = mcc_port_to_ddc_pin(dev_priv, port); ddc_pin = mcc_port_to_ddc_pin(dev_priv, port);
@ -2720,7 +2760,7 @@ static u8 intel_hdmi_ddc_pin(struct intel_encoder *encoder)
ddc_pin = icl_port_to_ddc_pin(dev_priv, port); ddc_pin = icl_port_to_ddc_pin(dev_priv, port);
else if (HAS_PCH_CNP(dev_priv)) else if (HAS_PCH_CNP(dev_priv))
ddc_pin = cnp_port_to_ddc_pin(dev_priv, port); ddc_pin = cnp_port_to_ddc_pin(dev_priv, port);
else if (IS_GEN9_LP(dev_priv)) else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
ddc_pin = bxt_port_to_ddc_pin(dev_priv, port); ddc_pin = bxt_port_to_ddc_pin(dev_priv, port);
else if (IS_CHERRYVIEW(dev_priv)) else if (IS_CHERRYVIEW(dev_priv))
ddc_pin = chv_port_to_ddc_pin(dev_priv, port); ddc_pin = chv_port_to_ddc_pin(dev_priv, port);

View file

@ -595,6 +595,9 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
{ {
int i; int i;
if (!HAS_DISPLAY(dev_priv))
return;
for_each_hpd_pin(i) { for_each_hpd_pin(i) {
dev_priv->hotplug.stats[i].count = 0; dev_priv->hotplug.stats[i].count = 0;
dev_priv->hotplug.stats[i].state = HPD_ENABLED; dev_priv->hotplug.stats[i].state = HPD_ENABLED;
@ -670,6 +673,9 @@ static void i915_hpd_poll_init_work(struct work_struct *work)
*/ */
void intel_hpd_poll_enable(struct drm_i915_private *dev_priv) void intel_hpd_poll_enable(struct drm_i915_private *dev_priv)
{ {
if (!HAS_DISPLAY(dev_priv))
return;
WRITE_ONCE(dev_priv->hotplug.poll_enabled, true); WRITE_ONCE(dev_priv->hotplug.poll_enabled, true);
/* /*
@ -702,6 +708,9 @@ void intel_hpd_poll_enable(struct drm_i915_private *dev_priv)
*/ */
void intel_hpd_poll_disable(struct drm_i915_private *dev_priv) void intel_hpd_poll_disable(struct drm_i915_private *dev_priv)
{ {
if (!HAS_DISPLAY(dev_priv))
return;
WRITE_ONCE(dev_priv->hotplug.poll_enabled, false); WRITE_ONCE(dev_priv->hotplug.poll_enabled, false);
schedule_work(&dev_priv->hotplug.poll_init_work); schedule_work(&dev_priv->hotplug.poll_init_work);
} }
@ -718,6 +727,9 @@ void intel_hpd_init_work(struct drm_i915_private *dev_priv)
void intel_hpd_cancel_work(struct drm_i915_private *dev_priv) void intel_hpd_cancel_work(struct drm_i915_private *dev_priv)
{ {
if (!HAS_DISPLAY(dev_priv))
return;
spin_lock_irq(&dev_priv->irq_lock); spin_lock_irq(&dev_priv->irq_lock);
dev_priv->hotplug.long_port_mask = 0; dev_priv->hotplug.long_port_mask = 0;

View file

@ -27,6 +27,7 @@
#include <drm/drm_dp_dual_mode_helper.h> #include <drm/drm_dp_dual_mode_helper.h>
#include <drm/drm_edid.h> #include <drm/drm_edid.h>
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_dp.h" #include "intel_dp.h"
#include "intel_lspcon.h" #include "intel_lspcon.h"

View file

@ -41,6 +41,7 @@
#include "i915_drv.h" #include "i915_drv.h"
#include "intel_atomic.h" #include "intel_atomic.h"
#include "intel_connector.h" #include "intel_connector.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_gmbus.h" #include "intel_gmbus.h"
#include "intel_lvds.h" #include "intel_lvds.h"
@ -280,7 +281,7 @@ static void intel_pre_enable_lvds(struct intel_atomic_state *state,
* special lvds dither control bit on pch-split platforms, dithering is * special lvds dither control bit on pch-split platforms, dithering is
* only controlled through the PIPECONF reg. * only controlled through the PIPECONF reg.
*/ */
if (IS_DISPLAY_VER(dev_priv, 4)) { if (DISPLAY_VER(dev_priv) == 4) {
/* /*
* Bspec wording suggests that LVDS port dithering only exists * Bspec wording suggests that LVDS port dithering only exists
* for 18bpp panels. * for 18bpp panels.

View file

@ -34,6 +34,7 @@
#include "i915_drv.h" #include "i915_drv.h"
#include "i915_reg.h" #include "i915_reg.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_frontbuffer.h" #include "intel_frontbuffer.h"
#include "intel_overlay.h" #include "intel_overlay.h"
@ -550,7 +551,7 @@ static u32 calc_swidthsw(struct drm_i915_private *dev_priv, u32 offset, u32 widt
{ {
u32 sw; u32 sw;
if (IS_DISPLAY_VER(dev_priv, 2)) if (DISPLAY_VER(dev_priv) == 2)
sw = ALIGN((offset & 31) + width, 32); sw = ALIGN((offset & 31) + width, 32);
else else
sw = ALIGN((offset & 63) + width, 64); sw = ALIGN((offset & 63) + width, 64);
@ -820,7 +821,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
oconfig |= OCONF_CC_OUT_8BIT; oconfig |= OCONF_CC_OUT_8BIT;
if (crtc_state->gamma_enable) if (crtc_state->gamma_enable)
oconfig |= OCONF_GAMMA2_ENABLE; oconfig |= OCONF_GAMMA2_ENABLE;
if (IS_DISPLAY_VER(dev_priv, 4)) if (DISPLAY_VER(dev_priv) == 4)
oconfig |= OCONF_CSC_MODE_BT709; oconfig |= OCONF_CSC_MODE_BT709;
oconfig |= pipe == 0 ? oconfig |= pipe == 0 ?
OCONF_PIPE_A : OCONF_PIPE_B; OCONF_PIPE_A : OCONF_PIPE_B;
@ -1054,7 +1055,7 @@ static int check_overlay_src(struct drm_i915_private *dev_priv,
if (rec->stride_Y & stride_mask || rec->stride_UV & stride_mask) if (rec->stride_Y & stride_mask || rec->stride_UV & stride_mask)
return -EINVAL; return -EINVAL;
if (IS_DISPLAY_VER(dev_priv, 4) && rec->stride_Y < 512) if (DISPLAY_VER(dev_priv) == 4 && rec->stride_Y < 512)
return -EINVAL; return -EINVAL;
tmp = (rec->flags & I915_OVERLAY_TYPE_MASK) == I915_OVERLAY_YUV_PLANAR ? tmp = (rec->flags & I915_OVERLAY_TYPE_MASK) == I915_OVERLAY_YUV_PLANAR ?
@ -1281,7 +1282,7 @@ int intel_overlay_attrs_ioctl(struct drm_device *dev, void *data,
attrs->contrast = overlay->contrast; attrs->contrast = overlay->contrast;
attrs->saturation = overlay->saturation; attrs->saturation = overlay->saturation;
if (!IS_DISPLAY_VER(dev_priv, 2)) { if (DISPLAY_VER(dev_priv) != 2) {
attrs->gamma0 = intel_de_read(dev_priv, OGAMC0); attrs->gamma0 = intel_de_read(dev_priv, OGAMC0);
attrs->gamma1 = intel_de_read(dev_priv, OGAMC1); attrs->gamma1 = intel_de_read(dev_priv, OGAMC1);
attrs->gamma2 = intel_de_read(dev_priv, OGAMC2); attrs->gamma2 = intel_de_read(dev_priv, OGAMC2);
@ -1305,7 +1306,7 @@ int intel_overlay_attrs_ioctl(struct drm_device *dev, void *data,
update_reg_attrs(overlay, overlay->regs); update_reg_attrs(overlay, overlay->regs);
if (attrs->flags & I915_OVERLAY_UPDATE_GAMMA) { if (attrs->flags & I915_OVERLAY_UPDATE_GAMMA) {
if (IS_DISPLAY_VER(dev_priv, 2)) if (DISPLAY_VER(dev_priv) == 2)
goto out_unlock; goto out_unlock;
if (overlay->active) { if (overlay->active) {

View file

@ -35,6 +35,7 @@
#include <linux/pwm.h> #include <linux/pwm.h>
#include "intel_connector.h" #include "intel_connector.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_dp_aux_backlight.h" #include "intel_dp_aux_backlight.h"
#include "intel_dsi_dcs_backlight.h" #include "intel_dsi_dcs_backlight.h"
@ -667,7 +668,7 @@ static void i9xx_set_backlight(const struct drm_connector_state *conn_state, u32
pci_write_config_byte(to_pci_dev(dev_priv->drm.dev), LBPC, lbpc); pci_write_config_byte(to_pci_dev(dev_priv->drm.dev), LBPC, lbpc);
} }
if (IS_DISPLAY_VER(dev_priv, 4)) { if (DISPLAY_VER(dev_priv) == 4) {
mask = BACKLIGHT_DUTY_CYCLE_MASK; mask = BACKLIGHT_DUTY_CYCLE_MASK;
} else { } else {
level <<= 1; level <<= 1;
@ -1040,7 +1041,7 @@ static void i9xx_enable_backlight(const struct intel_crtc_state *crtc_state,
* 855gm only, but checking for gen2 is safe, as 855gm is the only gen2 * 855gm only, but checking for gen2 is safe, as 855gm is the only gen2
* that has backlight. * that has backlight.
*/ */
if (IS_DISPLAY_VER(dev_priv, 2)) if (DISPLAY_VER(dev_priv) == 2)
intel_de_write(dev_priv, BLC_HIST_CTL, BLM_HISTOGRAM_ENABLE); intel_de_write(dev_priv, BLC_HIST_CTL, BLM_HISTOGRAM_ENABLE);
} }
@ -1372,6 +1373,9 @@ int intel_backlight_device_register(struct intel_connector *connector)
struct drm_i915_private *i915 = to_i915(connector->base.dev); struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct intel_panel *panel = &connector->panel; struct intel_panel *panel = &connector->panel;
struct backlight_properties props; struct backlight_properties props;
struct backlight_device *bd;
const char *name;
int ret = 0;
if (WARN_ON(panel->backlight.device)) if (WARN_ON(panel->backlight.device))
return -ENODEV; return -ENODEV;
@ -1398,28 +1402,49 @@ int intel_backlight_device_register(struct intel_connector *connector)
else else
props.power = FB_BLANK_POWERDOWN; props.power = FB_BLANK_POWERDOWN;
/* name = kstrdup("intel_backlight", GFP_KERNEL);
* Note: using the same name independent of the connector prevents if (!name)
* registration of multiple backlight devices in the driver. return -ENOMEM;
*/
panel->backlight.device =
backlight_device_register("intel_backlight",
connector->base.kdev,
connector,
&intel_backlight_device_ops, &props);
if (IS_ERR(panel->backlight.device)) { bd = backlight_device_register(name, connector->base.kdev, connector,
drm_err(&i915->drm, "Failed to register backlight: %ld\n", &intel_backlight_device_ops, &props);
PTR_ERR(panel->backlight.device));
panel->backlight.device = NULL; /*
return -ENODEV; * Using the same name independent of the drm device or connector
* prevents registration of multiple backlight devices in the
* driver. However, we need to use the default name for backward
* compatibility. Use unique names for subsequent backlight devices as a
* fallback when the default name already exists.
*/
if (IS_ERR(bd) && PTR_ERR(bd) == -EEXIST) {
kfree(name);
name = kasprintf(GFP_KERNEL, "card%d-%s-backlight",
i915->drm.primary->index, connector->base.name);
if (!name)
return -ENOMEM;
bd = backlight_device_register(name, connector->base.kdev, connector,
&intel_backlight_device_ops, &props);
} }
drm_dbg_kms(&i915->drm, if (IS_ERR(bd)) {
"Connector %s backlight sysfs interface registered\n", drm_err(&i915->drm,
connector->base.name); "[CONNECTOR:%d:%s] backlight device %s register failed: %ld\n",
connector->base.base.id, connector->base.name, name, PTR_ERR(bd));
ret = PTR_ERR(bd);
goto out;
}
return 0; panel->backlight.device = bd;
drm_dbg_kms(&i915->drm,
"[CONNECTOR:%d:%s] backlight device %s registered\n",
connector->base.base.id, connector->base.name, name);
out:
kfree(name);
return ret;
} }
void intel_backlight_device_unregister(struct intel_connector *connector) void intel_backlight_device_unregister(struct intel_connector *connector)
@ -1728,7 +1753,7 @@ static int i9xx_setup_backlight(struct intel_connector *connector, enum pipe unu
ctl = intel_de_read(dev_priv, BLC_PWM_CTL); ctl = intel_de_read(dev_priv, BLC_PWM_CTL);
if (IS_DISPLAY_VER(dev_priv, 2) || IS_I915GM(dev_priv) || IS_I945GM(dev_priv)) if (DISPLAY_VER(dev_priv) == 2 || IS_I915GM(dev_priv) || IS_I945GM(dev_priv))
panel->backlight.combination_mode = ctl & BLM_LEGACY_MODE; panel->backlight.combination_mode = ctl & BLM_LEGACY_MODE;
if (IS_PINEVIEW(dev_priv)) if (IS_PINEVIEW(dev_priv))
@ -2161,7 +2186,7 @@ intel_panel_init_backlight_funcs(struct intel_panel *panel)
intel_dsi_dcs_init_backlight_funcs(connector) == 0) intel_dsi_dcs_init_backlight_funcs(connector) == 0)
return; return;
if (IS_GEN9_LP(dev_priv)) { if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) {
panel->backlight.pwm_funcs = &bxt_pwm_funcs; panel->backlight.pwm_funcs = &bxt_pwm_funcs;
} else if (INTEL_PCH_TYPE(dev_priv) >= PCH_CNP) { } else if (INTEL_PCH_TYPE(dev_priv) >= PCH_CNP) {
panel->backlight.pwm_funcs = &cnp_pwm_funcs; panel->backlight.pwm_funcs = &cnp_pwm_funcs;
@ -2178,7 +2203,7 @@ intel_panel_init_backlight_funcs(struct intel_panel *panel)
} else { } else {
panel->backlight.pwm_funcs = &vlv_pwm_funcs; panel->backlight.pwm_funcs = &vlv_pwm_funcs;
} }
} else if (IS_DISPLAY_VER(dev_priv, 4)) { } else if (DISPLAY_VER(dev_priv) == 4) {
panel->backlight.pwm_funcs = &i965_pwm_funcs; panel->backlight.pwm_funcs = &i965_pwm_funcs;
} else { } else {
panel->backlight.pwm_funcs = &i9xx_pwm_funcs; panel->backlight.pwm_funcs = &i9xx_pwm_funcs;

View file

@ -30,6 +30,7 @@
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include "intel_atomic.h" #include "intel_atomic.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_pipe_crc.h" #include "intel_pipe_crc.h"
@ -409,7 +410,7 @@ static int get_new_crc_ctl_reg(struct drm_i915_private *dev_priv,
enum pipe pipe, enum pipe pipe,
enum intel_pipe_crc_source *source, u32 *val) enum intel_pipe_crc_source *source, u32 *val)
{ {
if (IS_DISPLAY_VER(dev_priv, 2)) if (DISPLAY_VER(dev_priv) == 2)
return i8xx_pipe_crc_ctl_reg(source, val); return i8xx_pipe_crc_ctl_reg(source, val);
else if (DISPLAY_VER(dev_priv) < 5) else if (DISPLAY_VER(dev_priv) < 5)
return i9xx_pipe_crc_ctl_reg(dev_priv, pipe, source, val); return i9xx_pipe_crc_ctl_reg(dev_priv, pipe, source, val);
@ -539,7 +540,7 @@ static int
intel_is_valid_crc_source(struct drm_i915_private *dev_priv, intel_is_valid_crc_source(struct drm_i915_private *dev_priv,
const enum intel_pipe_crc_source source) const enum intel_pipe_crc_source source)
{ {
if (IS_DISPLAY_VER(dev_priv, 2)) if (DISPLAY_VER(dev_priv) == 2)
return i8xx_crc_source_valid(dev_priv, source); return i8xx_crc_source_valid(dev_priv, source);
else if (DISPLAY_VER(dev_priv) < 5) else if (DISPLAY_VER(dev_priv) < 5)
return i9xx_crc_source_valid(dev_priv, source); return i9xx_crc_source_valid(dev_priv, source);
@ -580,13 +581,14 @@ int intel_crtc_verify_crc_source(struct drm_crtc *crtc, const char *source_name,
return -EINVAL; return -EINVAL;
} }
int intel_crtc_set_crc_source(struct drm_crtc *crtc, const char *source_name) int intel_crtc_set_crc_source(struct drm_crtc *_crtc, const char *source_name)
{ {
struct drm_i915_private *dev_priv = to_i915(crtc->dev); struct intel_crtc *crtc = to_intel_crtc(_crtc);
struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
struct intel_pipe_crc *pipe_crc = &intel_crtc->pipe_crc; struct intel_pipe_crc *pipe_crc = &crtc->pipe_crc;
enum intel_display_power_domain power_domain; enum intel_display_power_domain power_domain;
enum intel_pipe_crc_source source; enum intel_pipe_crc_source source;
enum pipe pipe = crtc->pipe;
intel_wakeref_t wakeref; intel_wakeref_t wakeref;
u32 val = 0; /* shut up gcc */ u32 val = 0; /* shut up gcc */
int ret = 0; int ret = 0;
@ -597,7 +599,7 @@ int intel_crtc_set_crc_source(struct drm_crtc *crtc, const char *source_name)
return -EINVAL; return -EINVAL;
} }
power_domain = POWER_DOMAIN_PIPE(crtc->index); power_domain = POWER_DOMAIN_PIPE(pipe);
wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
if (!wakeref) { if (!wakeref) {
drm_dbg_kms(&dev_priv->drm, drm_dbg_kms(&dev_priv->drm,
@ -607,64 +609,64 @@ int intel_crtc_set_crc_source(struct drm_crtc *crtc, const char *source_name)
enable = source != INTEL_PIPE_CRC_SOURCE_NONE; enable = source != INTEL_PIPE_CRC_SOURCE_NONE;
if (enable) if (enable)
intel_crtc_crc_setup_workarounds(to_intel_crtc(crtc), true); intel_crtc_crc_setup_workarounds(crtc, true);
ret = get_new_crc_ctl_reg(dev_priv, crtc->index, &source, &val); ret = get_new_crc_ctl_reg(dev_priv, pipe, &source, &val);
if (ret != 0) if (ret != 0)
goto out; goto out;
pipe_crc->source = source; pipe_crc->source = source;
intel_de_write(dev_priv, PIPE_CRC_CTL(crtc->index), val); intel_de_write(dev_priv, PIPE_CRC_CTL(pipe), val);
intel_de_posting_read(dev_priv, PIPE_CRC_CTL(crtc->index)); intel_de_posting_read(dev_priv, PIPE_CRC_CTL(pipe));
if (!source) { if (!source) {
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
vlv_undo_pipe_scramble_reset(dev_priv, crtc->index); vlv_undo_pipe_scramble_reset(dev_priv, pipe);
} }
pipe_crc->skipped = 0; pipe_crc->skipped = 0;
out: out:
if (!enable) if (!enable)
intel_crtc_crc_setup_workarounds(to_intel_crtc(crtc), false); intel_crtc_crc_setup_workarounds(crtc, false);
intel_display_power_put(dev_priv, power_domain, wakeref); intel_display_power_put(dev_priv, power_domain, wakeref);
return ret; return ret;
} }
void intel_crtc_enable_pipe_crc(struct intel_crtc *intel_crtc) void intel_crtc_enable_pipe_crc(struct intel_crtc *crtc)
{ {
struct drm_crtc *crtc = &intel_crtc->base; struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
struct drm_i915_private *dev_priv = to_i915(crtc->dev); struct intel_pipe_crc *pipe_crc = &crtc->pipe_crc;
struct intel_pipe_crc *pipe_crc = &intel_crtc->pipe_crc; enum pipe pipe = crtc->pipe;
u32 val = 0; u32 val = 0;
if (!crtc->crc.opened) if (!crtc->base.crc.opened)
return; return;
if (get_new_crc_ctl_reg(dev_priv, crtc->index, &pipe_crc->source, &val) < 0) if (get_new_crc_ctl_reg(dev_priv, pipe, &pipe_crc->source, &val) < 0)
return; return;
/* Don't need pipe_crc->lock here, IRQs are not generated. */ /* Don't need pipe_crc->lock here, IRQs are not generated. */
pipe_crc->skipped = 0; pipe_crc->skipped = 0;
intel_de_write(dev_priv, PIPE_CRC_CTL(crtc->index), val); intel_de_write(dev_priv, PIPE_CRC_CTL(pipe), val);
intel_de_posting_read(dev_priv, PIPE_CRC_CTL(crtc->index)); intel_de_posting_read(dev_priv, PIPE_CRC_CTL(pipe));
} }
void intel_crtc_disable_pipe_crc(struct intel_crtc *intel_crtc) void intel_crtc_disable_pipe_crc(struct intel_crtc *crtc)
{ {
struct drm_crtc *crtc = &intel_crtc->base; struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
struct drm_i915_private *dev_priv = to_i915(crtc->dev); struct intel_pipe_crc *pipe_crc = &crtc->pipe_crc;
struct intel_pipe_crc *pipe_crc = &intel_crtc->pipe_crc; enum pipe pipe = crtc->pipe;
/* Swallow crc's until we stop generating them. */ /* Swallow crc's until we stop generating them. */
spin_lock_irq(&pipe_crc->lock); spin_lock_irq(&pipe_crc->lock);
pipe_crc->skipped = INT_MIN; pipe_crc->skipped = INT_MIN;
spin_unlock_irq(&pipe_crc->lock); spin_unlock_irq(&pipe_crc->lock);
intel_de_write(dev_priv, PIPE_CRC_CTL(crtc->index), 0); intel_de_write(dev_priv, PIPE_CRC_CTL(pipe), 0);
intel_de_posting_read(dev_priv, PIPE_CRC_CTL(crtc->index)); intel_de_posting_read(dev_priv, PIPE_CRC_CTL(pipe));
intel_synchronize_irq(dev_priv); intel_synchronize_irq(dev_priv);
} }

View file

@ -5,6 +5,7 @@
#include "g4x_dp.h" #include "g4x_dp.h"
#include "i915_drv.h" #include "i915_drv.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_dp.h" #include "intel_dp.h"
#include "intel_dpll.h" #include "intel_dpll.h"
@ -313,10 +314,10 @@ void intel_pps_reset_all(struct drm_i915_private *dev_priv)
{ {
struct intel_encoder *encoder; struct intel_encoder *encoder;
if (drm_WARN_ON(&dev_priv->drm, if (drm_WARN_ON(&dev_priv->drm, !IS_LP(dev_priv)))
!(IS_VALLEYVIEW(dev_priv) || return;
IS_CHERRYVIEW(dev_priv) ||
IS_GEN9_LP(dev_priv)))) if (!HAS_DISPLAY(dev_priv))
return; return;
/* /*
@ -338,7 +339,7 @@ void intel_pps_reset_all(struct drm_i915_private *dev_priv)
if (encoder->type != INTEL_OUTPUT_EDP) if (encoder->type != INTEL_OUTPUT_EDP)
continue; continue;
if (IS_GEN9_LP(dev_priv)) if (DISPLAY_VER(dev_priv) >= 9)
intel_dp->pps.pps_reset = true; intel_dp->pps.pps_reset = true;
else else
intel_dp->pps.pps_pipe = INVALID_PIPE; intel_dp->pps.pps_pipe = INVALID_PIPE;
@ -361,7 +362,7 @@ static void intel_pps_get_registers(struct intel_dp *intel_dp,
memset(regs, 0, sizeof(*regs)); memset(regs, 0, sizeof(*regs));
if (IS_GEN9_LP(dev_priv)) if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
pps_idx = bxt_power_sequencer_idx(intel_dp); pps_idx = bxt_power_sequencer_idx(intel_dp);
else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
pps_idx = vlv_power_sequencer_pipe(intel_dp); pps_idx = vlv_power_sequencer_pipe(intel_dp);
@ -372,7 +373,8 @@ static void intel_pps_get_registers(struct intel_dp *intel_dp,
regs->pp_off = PP_OFF_DELAYS(pps_idx); regs->pp_off = PP_OFF_DELAYS(pps_idx);
/* Cycle delay moved from PP_DIVISOR to PP_CONTROL */ /* Cycle delay moved from PP_DIVISOR to PP_CONTROL */
if (IS_GEN9_LP(dev_priv) || INTEL_PCH_TYPE(dev_priv) >= PCH_CNP) if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv) ||
INTEL_PCH_TYPE(dev_priv) >= PCH_CNP)
regs->pp_div = INVALID_MMIO_REG; regs->pp_div = INVALID_MMIO_REG;
else else
regs->pp_div = PP_DIVISOR(pps_idx); regs->pp_div = PP_DIVISOR(pps_idx);
@ -1378,7 +1380,7 @@ void intel_pps_unlock_regs_wa(struct drm_i915_private *dev_priv)
int pps_num; int pps_num;
int pps_idx; int pps_idx;
if (HAS_DDI(dev_priv)) if (!HAS_DISPLAY(dev_priv) || HAS_DDI(dev_priv))
return; return;
/* /*
* This w/a is needed at least on CPT/PPT, but to be sure apply it * This w/a is needed at least on CPT/PPT, but to be sure apply it
@ -1399,7 +1401,7 @@ void intel_pps_unlock_regs_wa(struct drm_i915_private *dev_priv)
void intel_pps_setup(struct drm_i915_private *i915) void intel_pps_setup(struct drm_i915_private *i915)
{ {
if (HAS_PCH_SPLIT(i915) || IS_GEN9_LP(i915)) if (HAS_PCH_SPLIT(i915) || IS_GEMINILAKE(i915) || IS_BROXTON(i915))
i915->pps_mmio_base = PCH_PPS_BASE; i915->pps_mmio_base = PCH_PPS_BASE;
else if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) else if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915))
i915->pps_mmio_base = VLV_PPS_BASE; i915->pps_mmio_base = VLV_PPS_BASE;

View file

@ -27,6 +27,7 @@
#include "i915_drv.h" #include "i915_drv.h"
#include "intel_atomic.h" #include "intel_atomic.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_dp_aux.h" #include "intel_dp_aux.h"
#include "intel_hdmi.h" #include "intel_hdmi.h"
@ -524,7 +525,7 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
val = psr_compute_idle_frames(intel_dp) << EDP_PSR2_IDLE_FRAME_SHIFT; val = psr_compute_idle_frames(intel_dp) << EDP_PSR2_IDLE_FRAME_SHIFT;
val |= EDP_PSR2_ENABLE | EDP_SU_TRACK_ENABLE; val |= EDP_PSR2_ENABLE | EDP_SU_TRACK_ENABLE;
if (DISPLAY_VER(dev_priv) >= 10) if (DISPLAY_VER(dev_priv) >= 10 && DISPLAY_VER(dev_priv) <= 12)
val |= EDP_Y_COORDINATE_ENABLE; val |= EDP_Y_COORDINATE_ENABLE;
val |= EDP_PSR2_FRAME_BEFORE_SU(intel_dp->psr.sink_sync_latency + 1); val |= EDP_PSR2_FRAME_BEFORE_SU(intel_dp->psr.sink_sync_latency + 1);
@ -654,6 +655,13 @@ tgl_dc3co_exitline_compute_config(struct intel_dp *intel_dp,
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
u32 exit_scanlines; u32 exit_scanlines;
/*
* FIXME: Due to the changed sequence of activating/deactivating DC3CO,
* disable DC3CO until the changed dc3co activating/deactivating sequence
* is applied. B.Specs:49196
*/
return;
/* /*
* DMC's DC3CO exit mechanism has an issue with Selective Fecth * DMC's DC3CO exit mechanism has an issue with Selective Fecth
* TODO: when the issue is addressed, this restriction should be removed. * TODO: when the issue is addressed, this restriction should be removed.
@ -712,6 +720,13 @@ static bool intel_psr2_sel_fetch_config_valid(struct intel_dp *intel_dp,
} }
} }
/* Wa_14010254185 Wa_14010103792 */
if (IS_TGL_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B1)) {
drm_dbg_kms(&dev_priv->drm,
"PSR2 sel fetch not enabled, missing the implementation of WAs\n");
return false;
}
return crtc_state->enable_psr2_sel_fetch = true; return crtc_state->enable_psr2_sel_fetch = true;
} }
@ -732,6 +747,12 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
return false; return false;
} }
/* Wa_16011181250 */
if (IS_ROCKETLAKE(dev_priv) || IS_ALDERLAKE_S(dev_priv)) {
drm_dbg_kms(&dev_priv->drm, "PSR2 is defeatured for this platform\n");
return false;
}
if (!transcoder_has_psr2(dev_priv, crtc_state->cpu_transcoder)) { if (!transcoder_has_psr2(dev_priv, crtc_state->cpu_transcoder)) {
drm_dbg_kms(&dev_priv->drm, drm_dbg_kms(&dev_priv->drm,
"PSR2 not supported in transcoder %s\n", "PSR2 not supported in transcoder %s\n",
@ -769,7 +790,7 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
psr_max_h = 4096; psr_max_h = 4096;
psr_max_v = 2304; psr_max_v = 2304;
max_bpp = 24; max_bpp = 24;
} else if (IS_DISPLAY_VER(dev_priv, 9)) { } else if (DISPLAY_VER(dev_priv) == 9) {
psr_max_h = 3640; psr_max_h = 3640;
psr_max_v = 2304; psr_max_v = 2304;
max_bpp = 24; max_bpp = 24;
@ -804,6 +825,13 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
} }
} }
/* Wa_2209313811 */
if (!crtc_state->enable_psr2_sel_fetch &&
IS_TGL_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B1)) {
drm_dbg_kms(&dev_priv->drm, "PSR2 HW tracking is not supported this Display stepping\n");
return false;
}
if (!crtc_state->enable_psr2_sel_fetch && if (!crtc_state->enable_psr2_sel_fetch &&
(crtc_hdisplay > psr_max_h || crtc_vdisplay > psr_max_v)) { (crtc_hdisplay > psr_max_h || crtc_vdisplay > psr_max_v)) {
drm_dbg_kms(&dev_priv->drm, drm_dbg_kms(&dev_priv->drm,
@ -873,6 +901,51 @@ void intel_psr_compute_config(struct intel_dp *intel_dp,
crtc_state->infoframes.enable |= intel_hdmi_infoframe_enable(DP_SDP_VSC); crtc_state->infoframes.enable |= intel_hdmi_infoframe_enable(DP_SDP_VSC);
} }
void intel_psr_get_config(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
struct intel_dp *intel_dp;
u32 val;
if (!dig_port)
return;
intel_dp = &dig_port->dp;
if (!CAN_PSR(intel_dp))
return;
mutex_lock(&intel_dp->psr.lock);
if (!intel_dp->psr.enabled)
goto unlock;
/*
* Not possible to read EDP_PSR/PSR2_CTL registers as it is
* enabled/disabled because of frontbuffer tracking and others.
*/
pipe_config->has_psr = true;
pipe_config->has_psr2 = intel_dp->psr.psr2_enabled;
pipe_config->infoframes.enable |= intel_hdmi_infoframe_enable(DP_SDP_VSC);
if (!intel_dp->psr.psr2_enabled)
goto unlock;
if (HAS_PSR2_SEL_FETCH(dev_priv)) {
val = intel_de_read(dev_priv, PSR2_MAN_TRK_CTL(intel_dp->psr.transcoder));
if (val & PSR2_MAN_TRK_CTL_ENABLE)
pipe_config->enable_psr2_sel_fetch = true;
}
if (DISPLAY_VER(dev_priv) >= 12) {
val = intel_de_read(dev_priv, EXITLINE(intel_dp->psr.transcoder));
val &= EXITLINE_MASK;
pipe_config->dc3co_exitline = val;
}
unlock:
mutex_unlock(&intel_dp->psr.lock);
}
static void intel_psr_activate(struct intel_dp *intel_dp) static void intel_psr_activate(struct intel_dp *intel_dp)
{ {
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
@ -909,7 +982,7 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp,
if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
hsw_psr_setup_aux(intel_dp); hsw_psr_setup_aux(intel_dp);
if (intel_dp->psr.psr2_enabled && IS_DISPLAY_VER(dev_priv, 9)) { if (intel_dp->psr.psr2_enabled && DISPLAY_VER(dev_priv) == 9) {
i915_reg_t reg = CHICKEN_TRANS(cpu_transcoder); i915_reg_t reg = CHICKEN_TRANS(cpu_transcoder);
u32 chicken = intel_de_read(dev_priv, reg); u32 chicken = intel_de_read(dev_priv, reg);
@ -1154,21 +1227,7 @@ static void psr_force_hw_tracking_exit(struct intel_dp *intel_dp)
{ {
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
if (IS_TIGERLAKE(dev_priv)) if (DISPLAY_VER(dev_priv) >= 9)
/*
* Writes to CURSURFLIVE in TGL are causing IOMMU errors and
* visual glitches that are often reproduced when executing
* CPU intensive workloads while a eDP 4K panel is attached.
*
* Manually exiting PSR causes the frontbuffer to be updated
* without glitches and the IOMMU errors are also gone but
* this comes at the cost of less time with PSR active.
*
* So using this workaround until this issue is root caused
* and a better fix is found.
*/
intel_psr_exit(intel_dp);
else if (DISPLAY_VER(dev_priv) >= 9)
/* /*
* Display WA #0884: skl+ * Display WA #0884: skl+
* This documented WA for bxt can be safely applied * This documented WA for bxt can be safely applied

View file

@ -17,6 +17,7 @@ struct intel_crtc;
struct intel_atomic_state; struct intel_atomic_state;
struct intel_plane_state; struct intel_plane_state;
struct intel_plane; struct intel_plane;
struct intel_encoder;
void intel_psr_init_dpcd(struct intel_dp *intel_dp); void intel_psr_init_dpcd(struct intel_dp *intel_dp);
void intel_psr_enable(struct intel_dp *intel_dp, void intel_psr_enable(struct intel_dp *intel_dp,
@ -37,6 +38,8 @@ void intel_psr_flush(struct drm_i915_private *dev_priv,
void intel_psr_init(struct intel_dp *intel_dp); void intel_psr_init(struct intel_dp *intel_dp);
void intel_psr_compute_config(struct intel_dp *intel_dp, void intel_psr_compute_config(struct intel_dp *intel_dp,
struct intel_crtc_state *crtc_state); struct intel_crtc_state *crtc_state);
void intel_psr_get_config(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config);
void intel_psr_irq_handler(struct intel_dp *intel_dp, u32 psr_iir); void intel_psr_irq_handler(struct intel_dp *intel_dp, u32 psr_iir);
void intel_psr_short_pulse(struct intel_dp *intel_dp); void intel_psr_short_pulse(struct intel_dp *intel_dp);
void intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state); void intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state);

View file

@ -38,6 +38,8 @@
#include "i915_drv.h" #include "i915_drv.h"
#include "intel_atomic.h" #include "intel_atomic.h"
#include "intel_connector.h" #include "intel_connector.h"
#include "intel_crtc.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_fifo_underrun.h" #include "intel_fifo_underrun.h"
#include "intel_gmbus.h" #include "intel_gmbus.h"

View file

@ -43,6 +43,7 @@
#include "i915_trace.h" #include "i915_trace.h"
#include "i915_vgpu.h" #include "i915_vgpu.h"
#include "intel_atomic_plane.h" #include "intel_atomic_plane.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_frontbuffer.h" #include "intel_frontbuffer.h"
#include "intel_sprite.h" #include "intel_sprite.h"

View file

@ -28,7 +28,7 @@ tc_cold_get_power_domain(struct intel_digital_port *dig_port)
{ {
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
if (IS_DISPLAY_VER(i915, 11)) if (DISPLAY_VER(i915) == 11)
return intel_legacy_aux_to_power_domain(dig_port->aux_ch); return intel_legacy_aux_to_power_domain(dig_port->aux_ch);
else else
return POWER_DOMAIN_TC_COLD_OFF; return POWER_DOMAIN_TC_COLD_OFF;
@ -40,7 +40,7 @@ tc_cold_block(struct intel_digital_port *dig_port)
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
enum intel_display_power_domain domain; enum intel_display_power_domain domain;
if (IS_DISPLAY_VER(i915, 11) && !dig_port->tc_legacy_port) if (DISPLAY_VER(i915) == 11 && !dig_port->tc_legacy_port)
return 0; return 0;
domain = tc_cold_get_power_domain(dig_port); domain = tc_cold_get_power_domain(dig_port);
@ -71,7 +71,7 @@ assert_tc_cold_blocked(struct intel_digital_port *dig_port)
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
bool enabled; bool enabled;
if (IS_DISPLAY_VER(i915, 11) && !dig_port->tc_legacy_port) if (DISPLAY_VER(i915) == 11 && !dig_port->tc_legacy_port)
return; return;
enabled = intel_display_power_is_enabled(i915, enabled = intel_display_power_is_enabled(i915,
@ -256,8 +256,8 @@ static bool icl_tc_phy_status_complete(struct intel_digital_port *dig_port)
return val & DP_PHY_MODE_STATUS_COMPLETED(dig_port->tc_phy_fia_idx); return val & DP_PHY_MODE_STATUS_COMPLETED(dig_port->tc_phy_fia_idx);
} }
static bool icl_tc_phy_set_safe_mode(struct intel_digital_port *dig_port, static bool icl_tc_phy_take_ownership(struct intel_digital_port *dig_port,
bool enable) bool take)
{ {
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
struct intel_uncore *uncore = &i915->uncore; struct intel_uncore *uncore = &i915->uncore;
@ -267,20 +267,20 @@ static bool icl_tc_phy_set_safe_mode(struct intel_digital_port *dig_port,
PORT_TX_DFLEXDPCSSS(dig_port->tc_phy_fia)); PORT_TX_DFLEXDPCSSS(dig_port->tc_phy_fia));
if (val == 0xffffffff) { if (val == 0xffffffff) {
drm_dbg_kms(&i915->drm, drm_dbg_kms(&i915->drm,
"Port %s: PHY in TCCOLD, can't set safe-mode to %s\n", "Port %s: PHY in TCCOLD, can't %s ownership\n",
dig_port->tc_port_name, enableddisabled(enable)); dig_port->tc_port_name, take ? "take" : "release");
return false; return false;
} }
val &= ~DP_PHY_MODE_STATUS_NOT_SAFE(dig_port->tc_phy_fia_idx); val &= ~DP_PHY_MODE_STATUS_NOT_SAFE(dig_port->tc_phy_fia_idx);
if (!enable) if (take)
val |= DP_PHY_MODE_STATUS_NOT_SAFE(dig_port->tc_phy_fia_idx); val |= DP_PHY_MODE_STATUS_NOT_SAFE(dig_port->tc_phy_fia_idx);
intel_uncore_write(uncore, intel_uncore_write(uncore,
PORT_TX_DFLEXDPCSSS(dig_port->tc_phy_fia), val); PORT_TX_DFLEXDPCSSS(dig_port->tc_phy_fia), val);
if (enable && wait_for(!icl_tc_phy_status_complete(dig_port), 10)) if (!take && wait_for(!icl_tc_phy_status_complete(dig_port), 10))
drm_dbg_kms(&i915->drm, drm_dbg_kms(&i915->drm,
"Port %s: PHY complete clear timed out\n", "Port %s: PHY complete clear timed out\n",
dig_port->tc_port_name); dig_port->tc_port_name);
@ -288,7 +288,7 @@ static bool icl_tc_phy_set_safe_mode(struct intel_digital_port *dig_port,
return true; return true;
} }
static bool icl_tc_phy_is_in_safe_mode(struct intel_digital_port *dig_port) static bool icl_tc_phy_is_owned(struct intel_digital_port *dig_port)
{ {
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
struct intel_uncore *uncore = &i915->uncore; struct intel_uncore *uncore = &i915->uncore;
@ -303,7 +303,7 @@ static bool icl_tc_phy_is_in_safe_mode(struct intel_digital_port *dig_port)
return true; return true;
} }
return !(val & DP_PHY_MODE_STATUS_NOT_SAFE(dig_port->tc_phy_fia_idx)); return val & DP_PHY_MODE_STATUS_NOT_SAFE(dig_port->tc_phy_fia_idx);
} }
/* /*
@ -329,7 +329,7 @@ static void icl_tc_phy_connect(struct intel_digital_port *dig_port,
goto out_set_tbt_alt_mode; goto out_set_tbt_alt_mode;
} }
if (!icl_tc_phy_set_safe_mode(dig_port, false) && if (!icl_tc_phy_take_ownership(dig_port, true) &&
!drm_WARN_ON(&i915->drm, dig_port->tc_legacy_port)) !drm_WARN_ON(&i915->drm, dig_port->tc_legacy_port))
goto out_set_tbt_alt_mode; goto out_set_tbt_alt_mode;
@ -348,7 +348,7 @@ static void icl_tc_phy_connect(struct intel_digital_port *dig_port,
if (!(tc_port_live_status_mask(dig_port) & BIT(TC_PORT_DP_ALT))) { if (!(tc_port_live_status_mask(dig_port) & BIT(TC_PORT_DP_ALT))) {
drm_dbg_kms(&i915->drm, "Port %s: PHY sudden disconnect\n", drm_dbg_kms(&i915->drm, "Port %s: PHY sudden disconnect\n",
dig_port->tc_port_name); dig_port->tc_port_name);
goto out_set_safe_mode; goto out_release_phy;
} }
if (max_lanes < required_lanes) { if (max_lanes < required_lanes) {
@ -356,15 +356,15 @@ static void icl_tc_phy_connect(struct intel_digital_port *dig_port,
"Port %s: PHY max lanes %d < required lanes %d\n", "Port %s: PHY max lanes %d < required lanes %d\n",
dig_port->tc_port_name, dig_port->tc_port_name,
max_lanes, required_lanes); max_lanes, required_lanes);
goto out_set_safe_mode; goto out_release_phy;
} }
dig_port->tc_mode = TC_PORT_DP_ALT; dig_port->tc_mode = TC_PORT_DP_ALT;
return; return;
out_set_safe_mode: out_release_phy:
icl_tc_phy_set_safe_mode(dig_port, true); icl_tc_phy_take_ownership(dig_port, false);
out_set_tbt_alt_mode: out_set_tbt_alt_mode:
dig_port->tc_mode = TC_PORT_TBT_ALT; dig_port->tc_mode = TC_PORT_TBT_ALT;
} }
@ -380,7 +380,7 @@ static void icl_tc_phy_disconnect(struct intel_digital_port *dig_port)
/* Nothing to do, we never disconnect from legacy mode */ /* Nothing to do, we never disconnect from legacy mode */
break; break;
case TC_PORT_DP_ALT: case TC_PORT_DP_ALT:
icl_tc_phy_set_safe_mode(dig_port, true); icl_tc_phy_take_ownership(dig_port, false);
dig_port->tc_mode = TC_PORT_TBT_ALT; dig_port->tc_mode = TC_PORT_TBT_ALT;
break; break;
case TC_PORT_TBT_ALT: case TC_PORT_TBT_ALT:
@ -401,8 +401,8 @@ static bool icl_tc_phy_is_connected(struct intel_digital_port *dig_port)
return dig_port->tc_mode == TC_PORT_TBT_ALT; return dig_port->tc_mode == TC_PORT_TBT_ALT;
} }
if (icl_tc_phy_is_in_safe_mode(dig_port)) { if (!icl_tc_phy_is_owned(dig_port)) {
drm_dbg_kms(&i915->drm, "Port %s: PHY still in safe mode\n", drm_dbg_kms(&i915->drm, "Port %s: PHY not owned\n",
dig_port->tc_port_name); dig_port->tc_port_name);
return false; return false;
@ -417,10 +417,9 @@ intel_tc_port_get_current_mode(struct intel_digital_port *dig_port)
{ {
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
u32 live_status_mask = tc_port_live_status_mask(dig_port); u32 live_status_mask = tc_port_live_status_mask(dig_port);
bool in_safe_mode = icl_tc_phy_is_in_safe_mode(dig_port);
enum tc_port_mode mode; enum tc_port_mode mode;
if (in_safe_mode || if (!icl_tc_phy_is_owned(dig_port) ||
drm_WARN_ON(&i915->drm, !icl_tc_phy_status_complete(dig_port))) drm_WARN_ON(&i915->drm, !icl_tc_phy_status_complete(dig_port)))
return TC_PORT_TBT_ALT; return TC_PORT_TBT_ALT;
@ -625,6 +624,10 @@ tc_has_modular_fia(struct drm_i915_private *i915, struct intel_digital_port *dig
if (!INTEL_INFO(i915)->display.has_modular_fia) if (!INTEL_INFO(i915)->display.has_modular_fia)
return false; return false;
/* TODO: check if in real HW MODULAR_FIA_MASK is set, if so remove this block */
if (IS_ALDERLAKE_P(i915))
return true;
wakeref = tc_cold_block(dig_port); wakeref = tc_cold_block(dig_port);
val = intel_uncore_read(&i915->uncore, PORT_TX_DFLEXDPSP(FIA1)); val = intel_uncore_read(&i915->uncore, PORT_TX_DFLEXDPSP(FIA1));
tc_cold_unblock(dig_port, wakeref); tc_cold_unblock(dig_port, wakeref);

View file

@ -36,6 +36,7 @@
#include "i915_drv.h" #include "i915_drv.h"
#include "intel_connector.h" #include "intel_connector.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_hotplug.h" #include "intel_hotplug.h"
#include "intel_tv.h" #include "intel_tv.h"
@ -1165,7 +1166,7 @@ intel_tv_get_config(struct intel_encoder *encoder,
static bool intel_tv_source_too_wide(struct drm_i915_private *dev_priv, static bool intel_tv_source_too_wide(struct drm_i915_private *dev_priv,
int hdisplay) int hdisplay)
{ {
return IS_DISPLAY_VER(dev_priv, 3) && hdisplay > 1024; return DISPLAY_VER(dev_priv) == 3 && hdisplay > 1024;
} }
static bool intel_tv_vert_scaling(const struct drm_display_mode *tv_mode, static bool intel_tv_vert_scaling(const struct drm_display_mode *tv_mode,
@ -1789,7 +1790,7 @@ intel_tv_get_modes(struct drm_connector *connector)
continue; continue;
/* no vertical scaling with wide sources on gen3 */ /* no vertical scaling with wide sources on gen3 */
if (IS_DISPLAY_VER(dev_priv, 3) && input->w > 1024 && if (DISPLAY_VER(dev_priv) == 3 && input->w > 1024 &&
input->h > intel_tv_mode_vdisplay(tv_mode)) input->h > intel_tv_mode_vdisplay(tv_mode))
continue; continue;
@ -1978,7 +1979,7 @@ intel_tv_init(struct drm_i915_private *dev_priv)
/* Create TV properties then attach current values */ /* Create TV properties then attach current values */
for (i = 0; i < ARRAY_SIZE(tv_modes); i++) { for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
/* 1080p50/1080p60 not supported on gen3 */ /* 1080p50/1080p60 not supported on gen3 */
if (IS_DISPLAY_VER(dev_priv, 3) && if (DISPLAY_VER(dev_priv) == 3 &&
tv_modes[i].oversample == 1) tv_modes[i].oversample == 1)
break; break;

View file

@ -7,6 +7,7 @@
*/ */
#include "i915_drv.h" #include "i915_drv.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_dsi.h" #include "intel_dsi.h"
#include "intel_vdsc.h" #include "intel_vdsc.h"
@ -469,13 +470,13 @@ intel_dsc_power_domain(const struct intel_crtc_state *crtc_state)
* POWER_DOMAIN_TRANSCODER_VDSC_PW2 power domain in two cases: * POWER_DOMAIN_TRANSCODER_VDSC_PW2 power domain in two cases:
* *
* - ICL eDP/DSI transcoder * - ICL eDP/DSI transcoder
* - Gen12+ (except RKL) pipe A * - Display version 12 (except RKL) pipe A
* *
* For any other pipe, VDSC/joining uses the power well associated with * For any other pipe, VDSC/joining uses the power well associated with
* the pipe in use. Hence another reference on the pipe power domain * the pipe in use. Hence another reference on the pipe power domain
* will suffice. (Except no VDSC/joining on ICL pipe A.) * will suffice. (Except no VDSC/joining on ICL pipe A.)
*/ */
if (DISPLAY_VER(i915) >= 12 && !IS_ROCKETLAKE(i915) && pipe == PIPE_A) if (DISPLAY_VER(i915) == 12 && !IS_ROCKETLAKE(i915) && pipe == PIPE_A)
return POWER_DOMAIN_TRANSCODER_VDSC_PW2; return POWER_DOMAIN_TRANSCODER_VDSC_PW2;
else if (is_pipe_dsc(crtc_state)) else if (is_pipe_dsc(crtc_state))
return POWER_DOMAIN_PIPE(pipe); return POWER_DOMAIN_PIPE(pipe);
@ -1020,6 +1021,22 @@ static i915_reg_t dss_ctl2_reg(const struct intel_crtc_state *crtc_state)
return is_pipe_dsc(crtc_state) ? ICL_PIPE_DSS_CTL2(pipe) : DSS_CTL2; return is_pipe_dsc(crtc_state) ? ICL_PIPE_DSS_CTL2(pipe) : DSS_CTL2;
} }
void intel_uncompressed_joiner_enable(const struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
u32 dss_ctl1_val = 0;
if (crtc_state->bigjoiner && !crtc_state->dsc.compression_enable) {
if (crtc_state->bigjoiner_slave)
dss_ctl1_val |= UNCOMPRESSED_JOINER_SLAVE;
else
dss_ctl1_val |= UNCOMPRESSED_JOINER_MASTER;
intel_de_write(dev_priv, dss_ctl1_reg(crtc_state), dss_ctl1_val);
}
}
void intel_dsc_enable(struct intel_encoder *encoder, void intel_dsc_enable(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state) const struct intel_crtc_state *crtc_state)
{ {
@ -1059,13 +1076,35 @@ void intel_dsc_disable(const struct intel_crtc_state *old_crtc_state)
struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc); struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
if (!old_crtc_state->dsc.compression_enable) if (!(old_crtc_state->dsc.compression_enable &&
old_crtc_state->bigjoiner))
return; return;
intel_de_write(dev_priv, dss_ctl1_reg(old_crtc_state), 0); intel_de_write(dev_priv, dss_ctl1_reg(old_crtc_state), 0);
intel_de_write(dev_priv, dss_ctl2_reg(old_crtc_state), 0); intel_de_write(dev_priv, dss_ctl2_reg(old_crtc_state), 0);
} }
void intel_uncompressed_joiner_get_config(struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
u32 dss_ctl1;
dss_ctl1 = intel_de_read(dev_priv, dss_ctl1_reg(crtc_state));
if (dss_ctl1 & UNCOMPRESSED_JOINER_MASTER) {
crtc_state->bigjoiner = true;
if (!WARN_ON(INTEL_NUM_PIPES(dev_priv) == crtc->pipe + 1))
crtc_state->bigjoiner_linked_crtc =
intel_get_crtc_for_pipe(dev_priv, crtc->pipe + 1);
} else if (dss_ctl1 & UNCOMPRESSED_JOINER_SLAVE) {
crtc_state->bigjoiner = true;
crtc_state->bigjoiner_slave = true;
if (!WARN_ON(crtc->pipe == PIPE_A))
crtc_state->bigjoiner_linked_crtc =
intel_get_crtc_for_pipe(dev_priv, crtc->pipe - 1);
}
}
void intel_dsc_get_config(struct intel_crtc_state *crtc_state) void intel_dsc_get_config(struct intel_crtc_state *crtc_state)
{ {
struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config; struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;

View file

@ -12,11 +12,13 @@ struct intel_encoder;
struct intel_crtc_state; struct intel_crtc_state;
bool intel_dsc_source_support(const struct intel_crtc_state *crtc_state); bool intel_dsc_source_support(const struct intel_crtc_state *crtc_state);
void intel_uncompressed_joiner_enable(const struct intel_crtc_state *crtc_state);
void intel_dsc_enable(struct intel_encoder *encoder, void intel_dsc_enable(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state); const struct intel_crtc_state *crtc_state);
void intel_dsc_disable(const struct intel_crtc_state *crtc_state); void intel_dsc_disable(const struct intel_crtc_state *crtc_state);
int intel_dsc_compute_params(struct intel_encoder *encoder, int intel_dsc_compute_params(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config); struct intel_crtc_state *pipe_config);
void intel_uncompressed_joiner_get_config(struct intel_crtc_state *crtc_state);
void intel_dsc_get_config(struct intel_crtc_state *crtc_state); void intel_dsc_get_config(struct intel_crtc_state *crtc_state);
enum intel_display_power_domain enum intel_display_power_domain
intel_dsc_power_domain(const struct intel_crtc_state *crtc_state); intel_dsc_power_domain(const struct intel_crtc_state *crtc_state);

View file

@ -5,6 +5,7 @@
*/ */
#include "i915_drv.h" #include "i915_drv.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_vrr.h" #include "intel_vrr.h"

View file

@ -2,6 +2,7 @@
/* /*
* Copyright © 2020 Intel Corporation * Copyright © 2020 Intel Corporation
*/ */
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "skl_scaler.h" #include "skl_scaler.h"
#include "skl_universal_plane.h" #include "skl_universal_plane.h"

View file

@ -10,6 +10,7 @@
#include "i915_drv.h" #include "i915_drv.h"
#include "intel_atomic_plane.h" #include "intel_atomic_plane.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_fb.h" #include "intel_fb.h"
#include "intel_pm.h" #include "intel_pm.h"
@ -198,6 +199,13 @@ static const u64 gen12_plane_format_modifiers_rc_ccs[] = {
DRM_FORMAT_MOD_INVALID DRM_FORMAT_MOD_INVALID
}; };
static const u64 adlp_step_a_plane_format_modifiers[] = {
I915_FORMAT_MOD_Y_TILED,
I915_FORMAT_MOD_X_TILED,
DRM_FORMAT_MOD_LINEAR,
DRM_FORMAT_MOD_INVALID
};
int skl_format_to_fourcc(int format, bool rgb_order, bool alpha) int skl_format_to_fourcc(int format, bool rgb_order, bool alpha)
{ {
switch (format) { switch (format) {
@ -267,7 +275,7 @@ int skl_format_to_fourcc(int format, bool rgb_order, bool alpha)
static u8 icl_nv12_y_plane_mask(struct drm_i915_private *i915) static u8 icl_nv12_y_plane_mask(struct drm_i915_private *i915)
{ {
if (HAS_D12_PLANE_MINIMIZATION(i915)) if (DISPLAY_VER(i915) >= 13 || HAS_D12_PLANE_MINIMIZATION(i915))
return BIT(PLANE_SPRITE2) | BIT(PLANE_SPRITE3); return BIT(PLANE_SPRITE2) | BIT(PLANE_SPRITE3);
else else
return BIT(PLANE_SPRITE4) | BIT(PLANE_SPRITE5); return BIT(PLANE_SPRITE4) | BIT(PLANE_SPRITE5);
@ -286,22 +294,51 @@ bool icl_is_hdr_plane(struct drm_i915_private *dev_priv, enum plane_id plane_id)
icl_hdr_plane_mask() & BIT(plane_id); icl_hdr_plane_mask() & BIT(plane_id);
} }
static int icl_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
{
unsigned int pixel_rate = intel_plane_pixel_rate(crtc_state, plane_state);
/* two pixels per clock */
return DIV_ROUND_UP(pixel_rate, 2);
}
static void static void
skl_plane_ratio(const struct intel_crtc_state *crtc_state, glk_plane_ratio(const struct intel_plane_state *plane_state,
const struct intel_plane_state *plane_state,
unsigned int *num, unsigned int *den) unsigned int *num, unsigned int *den)
{ {
struct drm_i915_private *dev_priv = to_i915(plane_state->uapi.plane->dev);
const struct drm_framebuffer *fb = plane_state->hw.fb; const struct drm_framebuffer *fb = plane_state->hw.fb;
if (fb->format->cpp[0] == 8) { if (fb->format->cpp[0] == 8) {
if (DISPLAY_VER(dev_priv) >= 10) { *num = 10;
*num = 10; *den = 8;
*den = 8; } else {
} else { *num = 1;
*num = 9; *den = 1;
*den = 8; }
} }
static int glk_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state)
{
unsigned int pixel_rate = intel_plane_pixel_rate(crtc_state, plane_state);
unsigned int num, den;
glk_plane_ratio(plane_state, &num, &den);
/* two pixels per clock */
return DIV_ROUND_UP(pixel_rate * num, 2 * den);
}
static void
skl_plane_ratio(const struct intel_plane_state *plane_state,
unsigned int *num, unsigned int *den)
{
const struct drm_framebuffer *fb = plane_state->hw.fb;
if (fb->format->cpp[0] == 8) {
*num = 9;
*den = 8;
} else { } else {
*num = 1; *num = 1;
*den = 1; *den = 1;
@ -311,15 +348,10 @@ skl_plane_ratio(const struct intel_crtc_state *crtc_state,
static int skl_plane_min_cdclk(const struct intel_crtc_state *crtc_state, static int skl_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
const struct intel_plane_state *plane_state) const struct intel_plane_state *plane_state)
{ {
struct drm_i915_private *dev_priv = to_i915(plane_state->uapi.plane->dev);
unsigned int num, den;
unsigned int pixel_rate = intel_plane_pixel_rate(crtc_state, plane_state); unsigned int pixel_rate = intel_plane_pixel_rate(crtc_state, plane_state);
unsigned int num, den;
skl_plane_ratio(crtc_state, plane_state, &num, &den); skl_plane_ratio(plane_state, &num, &den);
/* two pixels per clock on glk+ */
if (DISPLAY_VER(dev_priv) >= 10)
den *= 2;
return DIV_ROUND_UP(pixel_rate * num, den); return DIV_ROUND_UP(pixel_rate * num, den);
} }
@ -457,17 +489,35 @@ skl_plane_max_stride(struct intel_plane *plane,
u32 pixel_format, u64 modifier, u32 pixel_format, u64 modifier,
unsigned int rotation) unsigned int rotation)
{ {
struct drm_i915_private *i915 = to_i915(plane->base.dev);
const struct drm_format_info *info = drm_format_info(pixel_format); const struct drm_format_info *info = drm_format_info(pixel_format);
int cpp = info->cpp[0]; int cpp = info->cpp[0];
int max_horizontal_pixels = 8192;
int max_stride_bytes;
if (DISPLAY_VER(i915) >= 13) {
/*
* The stride in bytes must not exceed of the size
* of 128K bytes. For pixel formats of 64bpp will allow
* for a 16K pixel surface.
*/
max_stride_bytes = 131072;
if (cpp == 8)
max_horizontal_pixels = 16384;
else
max_horizontal_pixels = 65536;
} else {
/*
* "The stride in bytes must not exceed the
* of the size of 8K pixels and 32K bytes."
*/
max_stride_bytes = 32768;
}
/*
* "The stride in bytes must not exceed the
* of the size of 8K pixels and 32K bytes."
*/
if (drm_rotation_90_or_270(rotation)) if (drm_rotation_90_or_270(rotation))
return min(8192, 32768 / cpp); return min(max_horizontal_pixels, max_stride_bytes / cpp);
else else
return min(8192 * cpp, 32768); return min(max_horizontal_pixels * cpp, max_stride_bytes);
} }
@ -829,7 +879,7 @@ static u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state,
plane_ctl = PLANE_CTL_ENABLE; plane_ctl = PLANE_CTL_ENABLE;
if (DISPLAY_VER(dev_priv) < 10 && !IS_GEMINILAKE(dev_priv)) { if (DISPLAY_VER(dev_priv) < 10) {
plane_ctl |= skl_plane_ctl_alpha(plane_state); plane_ctl |= skl_plane_ctl_alpha(plane_state);
plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE; plane_ctl |= PLANE_CTL_PLANE_GAMMA_DISABLE;
@ -909,6 +959,21 @@ static u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state,
return plane_color_ctl; return plane_color_ctl;
} }
static u32 skl_surf_address(const struct intel_plane_state *plane_state,
int color_plane)
{
const struct drm_framebuffer *fb = plane_state->hw.fb;
u32 offset = plane_state->view.color_plane[color_plane].offset;
if (intel_fb_uses_dpt(fb)) {
WARN_ON(offset & 0x1fffff);
return offset >> 9;
} else {
WARN_ON(offset & 0xfff);
return offset;
}
}
static void static void
skl_program_plane(struct intel_plane *plane, skl_program_plane(struct intel_plane *plane,
const struct intel_crtc_state *crtc_state, const struct intel_crtc_state *crtc_state,
@ -919,7 +984,7 @@ skl_program_plane(struct intel_plane *plane,
enum plane_id plane_id = plane->id; enum plane_id plane_id = plane->id;
enum pipe pipe = plane->pipe; enum pipe pipe = plane->pipe;
const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
u32 surf_addr = plane_state->view.color_plane[color_plane].offset; u32 surf_addr = skl_surf_address(plane_state, color_plane);
u32 stride = skl_plane_stride(plane_state, color_plane); u32 stride = skl_plane_stride(plane_state, color_plane);
const struct drm_framebuffer *fb = plane_state->hw.fb; const struct drm_framebuffer *fb = plane_state->hw.fb;
int aux_plane = skl_main_to_aux_plane(fb, color_plane); int aux_plane = skl_main_to_aux_plane(fb, color_plane);
@ -958,7 +1023,7 @@ skl_program_plane(struct intel_plane *plane,
} }
if (aux_plane) { if (aux_plane) {
aux_dist = plane_state->view.color_plane[aux_plane].offset - surf_addr; aux_dist = skl_surf_address(plane_state, aux_plane) - surf_addr;
if (DISPLAY_VER(dev_priv) < 12) if (DISPLAY_VER(dev_priv) < 12)
aux_dist |= skl_plane_stride(plane_state, aux_plane); aux_dist |= skl_plane_stride(plane_state, aux_plane);
@ -1007,6 +1072,14 @@ skl_program_plane(struct intel_plane *plane,
if (!drm_atomic_crtc_needs_modeset(&crtc_state->uapi)) if (!drm_atomic_crtc_needs_modeset(&crtc_state->uapi))
intel_psr2_program_plane_sel_fetch(plane, crtc_state, plane_state, color_plane); intel_psr2_program_plane_sel_fetch(plane, crtc_state, plane_state, color_plane);
/*
* Enable the scaler before the plane so that we don't
* get a catastrophic underrun even if the two operations
* end up happening in two different frames.
*/
if (plane_state->scaler_id >= 0)
skl_program_plane_scaler(plane, crtc_state, plane_state);
/* /*
* The control register self-arms if the plane was previously * The control register self-arms if the plane was previously
* disabled. Try to make the plane enable atomic by writing * disabled. Try to make the plane enable atomic by writing
@ -1016,9 +1089,6 @@ skl_program_plane(struct intel_plane *plane,
intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id),
intel_plane_ggtt_offset(plane_state) + surf_addr); intel_plane_ggtt_offset(plane_state) + surf_addr);
if (plane_state->scaler_id >= 0)
skl_program_plane_scaler(plane, crtc_state, plane_state);
spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
} }
@ -1102,8 +1172,7 @@ static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state,
} }
if (drm_rotation_90_or_270(rotation)) { if (drm_rotation_90_or_270(rotation)) {
if (fb->modifier != I915_FORMAT_MOD_Y_TILED && if (!intel_fb_supports_90_270_rotation(to_intel_framebuffer(fb))) {
fb->modifier != I915_FORMAT_MOD_Yf_TILED) {
drm_dbg_kms(&dev_priv->drm, drm_dbg_kms(&dev_priv->drm,
"Y/Yf tiling required for 90/270!\n"); "Y/Yf tiling required for 90/270!\n");
return -EINVAL; return -EINVAL;
@ -1182,7 +1251,7 @@ static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_s
* than the cursor ending less than 4 pixels from the left edge of the * than the cursor ending less than 4 pixels from the left edge of the
* screen may cause FIFO underflow and display corruption. * screen may cause FIFO underflow and display corruption.
*/ */
if (IS_DISPLAY_VER(dev_priv, 10) && if (DISPLAY_VER(dev_priv) == 10 &&
(crtc_x + crtc_w < 4 || crtc_x > pipe_src_w - 4)) { (crtc_x + crtc_w < 4 || crtc_x > pipe_src_w - 4)) {
drm_dbg_kms(&dev_priv->drm, drm_dbg_kms(&dev_priv->drm,
"requested plane X %s position %d invalid (valid range %d-%d)\n", "requested plane X %s position %d invalid (valid range %d-%d)\n",
@ -1410,7 +1479,10 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state)
} }
} }
drm_WARN_ON(&dev_priv->drm, x > 8191 || y > 8191); if (DISPLAY_VER(dev_priv) >= 13)
drm_WARN_ON(&dev_priv->drm, x > 65535 || y > 65535);
else
drm_WARN_ON(&dev_priv->drm, x > 8191 || y > 8191);
plane_state->view.color_plane[0].offset = offset; plane_state->view.color_plane[0].offset = offset;
plane_state->view.color_plane[0].x = x; plane_state->view.color_plane[0].x = x;
@ -1484,7 +1556,10 @@ static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state)
} }
} }
drm_WARN_ON(&i915->drm, x > 8191 || y > 8191); if (DISPLAY_VER(i915) >= 13)
drm_WARN_ON(&i915->drm, x > 65535 || y > 65535);
else
drm_WARN_ON(&i915->drm, x > 8191 || y > 8191);
plane_state->view.color_plane[uv_plane].offset = offset; plane_state->view.color_plane[uv_plane].offset = offset;
plane_state->view.color_plane[uv_plane].x = x; plane_state->view.color_plane[uv_plane].x = x;
@ -1669,7 +1744,7 @@ static bool skl_plane_has_planar(struct drm_i915_private *dev_priv,
if (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv)) if (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv))
return false; return false;
if (IS_DISPLAY_VER(dev_priv, 9) && pipe == PIPE_C) if (DISPLAY_VER(dev_priv) == 9 && pipe == PIPE_C)
return false; return false;
if (plane_id != PLANE_PRIMARY && plane_id != PLANE_SPRITE0) if (plane_id != PLANE_PRIMARY && plane_id != PLANE_SPRITE0)
@ -1811,6 +1886,10 @@ static bool gen12_plane_supports_mc_ccs(struct drm_i915_private *dev_priv,
IS_TGL_DISPLAY_STEP(dev_priv, STEP_A0, STEP_C0)) IS_TGL_DISPLAY_STEP(dev_priv, STEP_A0, STEP_C0))
return false; return false;
/* Wa_22011186057 */
if (IS_ADLP_DISPLAY_STEP(dev_priv, STEP_A0, STEP_A0))
return false;
return plane_id < PLANE_SPRITE4; return plane_id < PLANE_SPRITE4;
} }
@ -1828,8 +1907,12 @@ static bool gen12_plane_format_mod_supported(struct drm_plane *_plane,
case DRM_FORMAT_MOD_LINEAR: case DRM_FORMAT_MOD_LINEAR:
case I915_FORMAT_MOD_X_TILED: case I915_FORMAT_MOD_X_TILED:
case I915_FORMAT_MOD_Y_TILED: case I915_FORMAT_MOD_Y_TILED:
break;
case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS: case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC: case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC:
/* Wa_22011186057 */
if (IS_ADLP_DISPLAY_STEP(dev_priv, STEP_A0, STEP_A0))
return false;
break; break;
default: default:
return false; return false;
@ -1884,7 +1967,10 @@ static bool gen12_plane_format_mod_supported(struct drm_plane *_plane,
static const u64 *gen12_get_plane_modifiers(struct drm_i915_private *dev_priv, static const u64 *gen12_get_plane_modifiers(struct drm_i915_private *dev_priv,
enum plane_id plane_id) enum plane_id plane_id)
{ {
if (gen12_plane_supports_mc_ccs(dev_priv, plane_id)) /* Wa_22011186057 */
if (IS_ADLP_DISPLAY_STEP(dev_priv, STEP_A0, STEP_A0))
return adlp_step_a_plane_format_modifiers;
else if (gen12_plane_supports_mc_ccs(dev_priv, plane_id))
return gen12_plane_format_modifiers_mc_ccs; return gen12_plane_format_modifiers_mc_ccs;
else else
return gen12_plane_format_modifiers_rc_ccs; return gen12_plane_format_modifiers_rc_ccs;
@ -1963,12 +2049,15 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv,
plane->min_width = icl_plane_min_width; plane->min_width = icl_plane_min_width;
plane->max_width = icl_plane_max_width; plane->max_width = icl_plane_max_width;
plane->max_height = icl_plane_max_height; plane->max_height = icl_plane_max_height;
plane->min_cdclk = icl_plane_min_cdclk;
} else if (DISPLAY_VER(dev_priv) >= 10) { } else if (DISPLAY_VER(dev_priv) >= 10) {
plane->max_width = glk_plane_max_width; plane->max_width = glk_plane_max_width;
plane->max_height = skl_plane_max_height; plane->max_height = skl_plane_max_height;
plane->min_cdclk = glk_plane_min_cdclk;
} else { } else {
plane->max_width = skl_plane_max_width; plane->max_width = skl_plane_max_width;
plane->max_height = skl_plane_max_height; plane->max_height = skl_plane_max_height;
plane->min_cdclk = skl_plane_min_cdclk;
} }
plane->max_stride = skl_plane_max_stride; plane->max_stride = skl_plane_max_stride;
@ -1976,11 +2065,10 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv,
plane->disable_plane = skl_disable_plane; plane->disable_plane = skl_disable_plane;
plane->get_hw_state = skl_plane_get_hw_state; plane->get_hw_state = skl_plane_get_hw_state;
plane->check_plane = skl_plane_check; plane->check_plane = skl_plane_check;
plane->min_cdclk = skl_plane_min_cdclk;
if (plane_id == PLANE_PRIMARY) { if (plane_id == PLANE_PRIMARY) {
plane->need_async_flip_disable_wa = IS_DISPLAY_RANGE(dev_priv, plane->need_async_flip_disable_wa = IS_DISPLAY_VER(dev_priv,
9, 10); 9, 10);
plane->async_flip = skl_plane_async_flip; plane->async_flip = skl_plane_async_flip;
plane->enable_flip_done = skl_plane_enable_flip_done; plane->enable_flip_done = skl_plane_enable_flip_done;
plane->disable_flip_done = skl_plane_disable_flip_done; plane->disable_flip_done = skl_plane_disable_flip_done;
@ -2022,9 +2110,12 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv,
if (ret) if (ret)
goto fail; goto fail;
supported_rotations = if (DISPLAY_VER(dev_priv) >= 13)
DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 | supported_rotations = DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180;
DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270; else
supported_rotations =
DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 |
DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270;
if (DISPLAY_VER(dev_priv) >= 11 || IS_CANNONLAKE(dev_priv)) if (DISPLAY_VER(dev_priv) >= 11 || IS_CANNONLAKE(dev_priv))
supported_rotations |= DRM_MODE_REFLECT_X; supported_rotations |= DRM_MODE_REFLECT_X;
@ -2195,7 +2286,11 @@ skl_get_initial_plane_config(struct intel_crtc *crtc,
val = intel_de_read(dev_priv, PLANE_STRIDE(pipe, plane_id)); val = intel_de_read(dev_priv, PLANE_STRIDE(pipe, plane_id));
stride_mult = skl_plane_stride_mult(fb, 0, DRM_MODE_ROTATE_0); stride_mult = skl_plane_stride_mult(fb, 0, DRM_MODE_ROTATE_0);
fb->pitches[0] = (val & 0x3ff) * stride_mult;
if (DISPLAY_VER(dev_priv) >= 13)
fb->pitches[0] = (val & PLANE_STRIDE_MASK_XELPD) * stride_mult;
else
fb->pitches[0] = (val & PLANE_STRIDE_MASK) * stride_mult;
aligned_height = intel_fb_align_height(fb, 0, fb->height); aligned_height = intel_fb_align_height(fb, 0, fb->height);
@ -2213,4 +2308,3 @@ skl_get_initial_plane_config(struct intel_crtc *crtc,
error: error:
kfree(intel_fb); kfree(intel_fb);
} }

View file

@ -33,6 +33,8 @@
#include "i915_drv.h" #include "i915_drv.h"
#include "intel_atomic.h" #include "intel_atomic.h"
#include "intel_connector.h" #include "intel_connector.h"
#include "intel_crtc.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_dsi.h" #include "intel_dsi.h"
#include "intel_fifo_underrun.h" #include "intel_fifo_underrun.h"
@ -297,7 +299,7 @@ static int intel_dsi_compute_config(struct intel_encoder *encoder,
else else
pipe_config->pipe_bpp = 18; pipe_config->pipe_bpp = 18;
if (IS_GEN9_LP(dev_priv)) { if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) {
/* Enable Frame time stamp based scanline reporting */ /* Enable Frame time stamp based scanline reporting */
pipe_config->mode_flags |= pipe_config->mode_flags |=
I915_MODE_FLAG_GET_SCANLINE_FROM_TIMESTAMP; I915_MODE_FLAG_GET_SCANLINE_FROM_TIMESTAMP;
@ -522,7 +524,7 @@ static void intel_dsi_device_ready(struct intel_encoder *encoder)
if (IS_GEMINILAKE(dev_priv)) if (IS_GEMINILAKE(dev_priv))
glk_dsi_device_ready(encoder); glk_dsi_device_ready(encoder);
else if (IS_GEN9_LP(dev_priv)) else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
bxt_dsi_device_ready(encoder); bxt_dsi_device_ready(encoder);
else else
vlv_dsi_device_ready(encoder); vlv_dsi_device_ready(encoder);
@ -601,7 +603,7 @@ static void vlv_dsi_clear_device_ready(struct intel_encoder *encoder)
drm_dbg_kms(&dev_priv->drm, "\n"); drm_dbg_kms(&dev_priv->drm, "\n");
for_each_dsi_port(port, intel_dsi->ports) { for_each_dsi_port(port, intel_dsi->ports) {
/* Common bit for both MIPI Port A & MIPI Port C on VLV/CHV */ /* Common bit for both MIPI Port A & MIPI Port C on VLV/CHV */
i915_reg_t port_ctrl = IS_GEN9_LP(dev_priv) ? i915_reg_t port_ctrl = IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv) ?
BXT_MIPI_PORT_CTRL(port) : MIPI_PORT_CTRL(PORT_A); BXT_MIPI_PORT_CTRL(port) : MIPI_PORT_CTRL(PORT_A);
u32 val; u32 val;
@ -621,7 +623,7 @@ static void vlv_dsi_clear_device_ready(struct intel_encoder *encoder)
* On VLV/CHV, wait till Clock lanes are in LP-00 state for MIPI * On VLV/CHV, wait till Clock lanes are in LP-00 state for MIPI
* Port A only. MIPI Port C has no similar bit for checking. * Port A only. MIPI Port C has no similar bit for checking.
*/ */
if ((IS_GEN9_LP(dev_priv) || port == PORT_A) && if ((IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv) || port == PORT_A) &&
intel_de_wait_for_clear(dev_priv, port_ctrl, intel_de_wait_for_clear(dev_priv, port_ctrl,
AFE_LATCHOUT, 30)) AFE_LATCHOUT, 30))
drm_err(&dev_priv->drm, "DSI LP not going Low\n"); drm_err(&dev_priv->drm, "DSI LP not going Low\n");
@ -646,7 +648,7 @@ static void intel_dsi_port_enable(struct intel_encoder *encoder,
if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK) { if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK) {
u32 temp; u32 temp;
if (IS_GEN9_LP(dev_priv)) { if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) {
for_each_dsi_port(port, intel_dsi->ports) { for_each_dsi_port(port, intel_dsi->ports) {
temp = intel_de_read(dev_priv, temp = intel_de_read(dev_priv,
MIPI_CTRL(port)); MIPI_CTRL(port));
@ -666,7 +668,7 @@ static void intel_dsi_port_enable(struct intel_encoder *encoder,
} }
for_each_dsi_port(port, intel_dsi->ports) { for_each_dsi_port(port, intel_dsi->ports) {
i915_reg_t port_ctrl = IS_GEN9_LP(dev_priv) ? i915_reg_t port_ctrl = IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv) ?
BXT_MIPI_PORT_CTRL(port) : MIPI_PORT_CTRL(port); BXT_MIPI_PORT_CTRL(port) : MIPI_PORT_CTRL(port);
u32 temp; u32 temp;
@ -703,7 +705,7 @@ static void intel_dsi_port_disable(struct intel_encoder *encoder)
enum port port; enum port port;
for_each_dsi_port(port, intel_dsi->ports) { for_each_dsi_port(port, intel_dsi->ports) {
i915_reg_t port_ctrl = IS_GEN9_LP(dev_priv) ? i915_reg_t port_ctrl = IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv) ?
BXT_MIPI_PORT_CTRL(port) : MIPI_PORT_CTRL(port); BXT_MIPI_PORT_CTRL(port) : MIPI_PORT_CTRL(port);
u32 temp; u32 temp;
@ -714,6 +716,19 @@ static void intel_dsi_port_disable(struct intel_encoder *encoder)
} }
} }
static void intel_dsi_wait_panel_power_cycle(struct intel_dsi *intel_dsi)
{
ktime_t panel_power_on_time;
s64 panel_power_off_duration;
panel_power_on_time = ktime_get_boottime();
panel_power_off_duration = ktime_ms_delta(panel_power_on_time,
intel_dsi->panel_power_off_time);
if (panel_power_off_duration < (s64)intel_dsi->panel_pwr_cycle_delay)
msleep(intel_dsi->panel_pwr_cycle_delay - panel_power_off_duration);
}
static void intel_dsi_prepare(struct intel_encoder *intel_encoder, static void intel_dsi_prepare(struct intel_encoder *intel_encoder,
const struct intel_crtc_state *pipe_config); const struct intel_crtc_state *pipe_config);
static void intel_dsi_unprepare(struct intel_encoder *encoder); static void intel_dsi_unprepare(struct intel_encoder *encoder);
@ -775,13 +790,15 @@ static void intel_dsi_pre_enable(struct intel_atomic_state *state,
drm_dbg_kms(&dev_priv->drm, "\n"); drm_dbg_kms(&dev_priv->drm, "\n");
intel_dsi_wait_panel_power_cycle(intel_dsi);
intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
/* /*
* The BIOS may leave the PLL in a wonky state where it doesn't * The BIOS may leave the PLL in a wonky state where it doesn't
* lock. It needs to be fully powered down to fix it. * lock. It needs to be fully powered down to fix it.
*/ */
if (IS_GEN9_LP(dev_priv)) { if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) {
bxt_dsi_pll_disable(encoder); bxt_dsi_pll_disable(encoder);
bxt_dsi_pll_enable(encoder, pipe_config); bxt_dsi_pll_enable(encoder, pipe_config);
} else { } else {
@ -846,8 +863,10 @@ static void intel_dsi_pre_enable(struct intel_atomic_state *state,
/* Send initialization commands in LP mode */ /* Send initialization commands in LP mode */
intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_INIT_OTP); intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_INIT_OTP);
/* Enable port in pre-enable phase itself because as per hw team /*
* recommendation, port should be enabled befor plane & pipe */ * Enable port in pre-enable phase itself because as per hw team
* recommendation, port should be enabled before plane & pipe
*/
if (is_cmd_mode(intel_dsi)) { if (is_cmd_mode(intel_dsi)) {
for_each_dsi_port(port, intel_dsi->ports) for_each_dsi_port(port, intel_dsi->ports)
intel_de_write(dev_priv, intel_de_write(dev_priv,
@ -932,7 +951,7 @@ static void intel_dsi_post_disable(struct intel_atomic_state *state,
drm_dbg_kms(&dev_priv->drm, "\n"); drm_dbg_kms(&dev_priv->drm, "\n");
if (IS_GEN9_LP(dev_priv)) { if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) {
intel_crtc_vblank_off(old_crtc_state); intel_crtc_vblank_off(old_crtc_state);
skl_scaler_disable(old_crtc_state); skl_scaler_disable(old_crtc_state);
@ -971,7 +990,7 @@ static void intel_dsi_post_disable(struct intel_atomic_state *state,
val & ~MIPIO_RST_CTRL); val & ~MIPIO_RST_CTRL);
} }
if (IS_GEN9_LP(dev_priv)) { if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) {
bxt_dsi_pll_disable(encoder); bxt_dsi_pll_disable(encoder);
} else { } else {
u32 val; u32 val;
@ -989,18 +1008,14 @@ static void intel_dsi_post_disable(struct intel_atomic_state *state,
intel_dsi_msleep(intel_dsi, intel_dsi->panel_off_delay); intel_dsi_msleep(intel_dsi, intel_dsi->panel_off_delay);
intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_POWER_OFF); intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_POWER_OFF);
/* intel_dsi->panel_power_off_time = ktime_get_boottime();
* FIXME As we do with eDP, just make a note of the time here
* and perform the wait before the next panel power on.
*/
msleep(intel_dsi->panel_pwr_cycle_delay);
} }
static void intel_dsi_shutdown(struct intel_encoder *encoder) static void intel_dsi_shutdown(struct intel_encoder *encoder)
{ {
struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
msleep(intel_dsi->panel_pwr_cycle_delay); intel_dsi_wait_panel_power_cycle(intel_dsi);
} }
static bool intel_dsi_get_hw_state(struct intel_encoder *encoder, static bool intel_dsi_get_hw_state(struct intel_encoder *encoder,
@ -1024,12 +1039,13 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder,
* configuration, otherwise accessing DSI registers will hang the * configuration, otherwise accessing DSI registers will hang the
* machine. See BSpec North Display Engine registers/MIPI[BXT]. * machine. See BSpec North Display Engine registers/MIPI[BXT].
*/ */
if (IS_GEN9_LP(dev_priv) && !bxt_dsi_pll_is_enabled(dev_priv)) if ((IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) &&
!bxt_dsi_pll_is_enabled(dev_priv))
goto out_put_power; goto out_put_power;
/* XXX: this only works for one DSI output */ /* XXX: this only works for one DSI output */
for_each_dsi_port(port, intel_dsi->ports) { for_each_dsi_port(port, intel_dsi->ports) {
i915_reg_t ctrl_reg = IS_GEN9_LP(dev_priv) ? i915_reg_t ctrl_reg = IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv) ?
BXT_MIPI_PORT_CTRL(port) : MIPI_PORT_CTRL(port); BXT_MIPI_PORT_CTRL(port) : MIPI_PORT_CTRL(port);
bool enabled = intel_de_read(dev_priv, ctrl_reg) & DPI_ENABLE; bool enabled = intel_de_read(dev_priv, ctrl_reg) & DPI_ENABLE;
@ -1055,7 +1071,7 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder,
if (!(intel_de_read(dev_priv, MIPI_DEVICE_READY(port)) & DEVICE_READY)) if (!(intel_de_read(dev_priv, MIPI_DEVICE_READY(port)) & DEVICE_READY))
continue; continue;
if (IS_GEN9_LP(dev_priv)) { if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) {
u32 tmp = intel_de_read(dev_priv, MIPI_CTRL(port)); u32 tmp = intel_de_read(dev_priv, MIPI_CTRL(port));
tmp &= BXT_PIPE_SELECT_MASK; tmp &= BXT_PIPE_SELECT_MASK;
tmp >>= BXT_PIPE_SELECT_SHIFT; tmp >>= BXT_PIPE_SELECT_SHIFT;
@ -1251,7 +1267,7 @@ static void intel_dsi_get_config(struct intel_encoder *encoder,
pipe_config->output_types |= BIT(INTEL_OUTPUT_DSI); pipe_config->output_types |= BIT(INTEL_OUTPUT_DSI);
if (IS_GEN9_LP(dev_priv)) { if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) {
bxt_dsi_get_pipe_config(encoder, pipe_config); bxt_dsi_get_pipe_config(encoder, pipe_config);
pclk = bxt_dsi_get_pclk(encoder, pipe_config); pclk = bxt_dsi_get_pclk(encoder, pipe_config);
} else { } else {
@ -1317,7 +1333,7 @@ static void set_dsi_timings(struct drm_encoder *encoder,
hbp = txbyteclkhs(hbp, bpp, lane_count, intel_dsi->burst_mode_ratio); hbp = txbyteclkhs(hbp, bpp, lane_count, intel_dsi->burst_mode_ratio);
for_each_dsi_port(port, intel_dsi->ports) { for_each_dsi_port(port, intel_dsi->ports) {
if (IS_GEN9_LP(dev_priv)) { if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) {
/* /*
* Program hdisplay and vdisplay on MIPI transcoder. * Program hdisplay and vdisplay on MIPI transcoder.
* This is different from calculated hactive and * This is different from calculated hactive and
@ -1407,7 +1423,7 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder,
tmp &= ~READ_REQUEST_PRIORITY_MASK; tmp &= ~READ_REQUEST_PRIORITY_MASK;
intel_de_write(dev_priv, MIPI_CTRL(port), intel_de_write(dev_priv, MIPI_CTRL(port),
tmp | READ_REQUEST_PRIORITY_HIGH); tmp | READ_REQUEST_PRIORITY_HIGH);
} else if (IS_GEN9_LP(dev_priv)) { } else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) {
enum pipe pipe = intel_crtc->pipe; enum pipe pipe = intel_crtc->pipe;
tmp = intel_de_read(dev_priv, MIPI_CTRL(port)); tmp = intel_de_read(dev_priv, MIPI_CTRL(port));
@ -1445,7 +1461,7 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder,
if (intel_dsi->clock_stop) if (intel_dsi->clock_stop)
tmp |= CLOCKSTOP; tmp |= CLOCKSTOP;
if (IS_GEN9_LP(dev_priv)) { if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) {
tmp |= BXT_DPHY_DEFEATURE_EN; tmp |= BXT_DPHY_DEFEATURE_EN;
if (!is_cmd_mode(intel_dsi)) if (!is_cmd_mode(intel_dsi))
tmp |= BXT_DEFEATURE_DPI_FIFO_CTR; tmp |= BXT_DEFEATURE_DPI_FIFO_CTR;
@ -1492,7 +1508,8 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder,
intel_de_write(dev_priv, MIPI_INIT_COUNT(port), intel_de_write(dev_priv, MIPI_INIT_COUNT(port),
txclkesc(intel_dsi->escape_clk_div, 100)); txclkesc(intel_dsi->escape_clk_div, 100));
if (IS_GEN9_LP(dev_priv) && (!intel_dsi->dual_link)) { if ((IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) &&
!intel_dsi->dual_link) {
/* /*
* BXT spec says write MIPI_INIT_COUNT for * BXT spec says write MIPI_INIT_COUNT for
* both the ports, even if only one is * both the ports, even if only one is
@ -1570,7 +1587,7 @@ static void intel_dsi_unprepare(struct intel_encoder *encoder)
/* Panel commands can be sent when clock is in LP11 */ /* Panel commands can be sent when clock is in LP11 */
intel_de_write(dev_priv, MIPI_DEVICE_READY(port), 0x0); intel_de_write(dev_priv, MIPI_DEVICE_READY(port), 0x0);
if (IS_GEN9_LP(dev_priv)) if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
bxt_dsi_reset_clocks(encoder, port); bxt_dsi_reset_clocks(encoder, port);
else else
vlv_dsi_reset_clocks(encoder, port); vlv_dsi_reset_clocks(encoder, port);
@ -1828,7 +1845,7 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv)
if (!intel_bios_is_dsi_present(dev_priv, &port)) if (!intel_bios_is_dsi_present(dev_priv, &port))
return; return;
if (IS_GEN9_LP(dev_priv)) if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
dev_priv->mipi_mmio_base = BXT_MIPI_BASE; dev_priv->mipi_mmio_base = BXT_MIPI_BASE;
else else
dev_priv->mipi_mmio_base = VLV_MIPI_BASE; dev_priv->mipi_mmio_base = VLV_MIPI_BASE;
@ -1854,7 +1871,7 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv)
intel_encoder->compute_config = intel_dsi_compute_config; intel_encoder->compute_config = intel_dsi_compute_config;
intel_encoder->pre_enable = intel_dsi_pre_enable; intel_encoder->pre_enable = intel_dsi_pre_enable;
if (IS_GEN9_LP(dev_priv)) if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
intel_encoder->enable = bxt_dsi_enable; intel_encoder->enable = bxt_dsi_enable;
intel_encoder->disable = intel_dsi_disable; intel_encoder->disable = intel_dsi_disable;
intel_encoder->post_disable = intel_dsi_post_disable; intel_encoder->post_disable = intel_dsi_post_disable;
@ -1874,13 +1891,15 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv)
* On BYT/CHV, pipe A maps to MIPI DSI port A, pipe B maps to MIPI DSI * On BYT/CHV, pipe A maps to MIPI DSI port A, pipe B maps to MIPI DSI
* port C. BXT isn't limited like this. * port C. BXT isn't limited like this.
*/ */
if (IS_GEN9_LP(dev_priv)) if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
intel_encoder->pipe_mask = ~0; intel_encoder->pipe_mask = ~0;
else if (port == PORT_A) else if (port == PORT_A)
intel_encoder->pipe_mask = BIT(PIPE_A); intel_encoder->pipe_mask = BIT(PIPE_A);
else else
intel_encoder->pipe_mask = BIT(PIPE_B); intel_encoder->pipe_mask = BIT(PIPE_B);
intel_dsi->panel_power_off_time = ktime_get_boottime();
if (dev_priv->vbt.dsi.config->dual_link) if (dev_priv->vbt.dsi.config->dual_link)
intel_dsi->ports = BIT(PORT_A) | BIT(PORT_C); intel_dsi->ports = BIT(PORT_A) | BIT(PORT_C);
else else

View file

@ -28,6 +28,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include "i915_drv.h" #include "i915_drv.h"
#include "intel_de.h"
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_dsi.h" #include "intel_dsi.h"
#include "intel_sideband.h" #include "intel_sideband.h"

View file

@ -274,7 +274,7 @@ struct i915_execbuffer {
struct drm_mm_node node; /** temporary GTT binding */ struct drm_mm_node node; /** temporary GTT binding */
unsigned long vaddr; /** Current kmap address */ unsigned long vaddr; /** Current kmap address */
unsigned long page; /** Currently mapped page index */ unsigned long page; /** Currently mapped page index */
unsigned int gen; /** Cached value of INTEL_GEN */ unsigned int graphics_ver; /** Cached value of GRAPHICS_VER */
bool use_64bit_reloc : 1; bool use_64bit_reloc : 1;
bool has_llc : 1; bool has_llc : 1;
bool has_fence : 1; bool has_fence : 1;
@ -1049,10 +1049,10 @@ static void reloc_cache_init(struct reloc_cache *cache,
cache->page = -1; cache->page = -1;
cache->vaddr = 0; cache->vaddr = 0;
/* Must be a variable in the struct to allow GCC to unroll. */ /* Must be a variable in the struct to allow GCC to unroll. */
cache->gen = INTEL_GEN(i915); cache->graphics_ver = GRAPHICS_VER(i915);
cache->has_llc = HAS_LLC(i915); cache->has_llc = HAS_LLC(i915);
cache->use_64bit_reloc = HAS_64BIT_RELOC(i915); cache->use_64bit_reloc = HAS_64BIT_RELOC(i915);
cache->has_fence = cache->gen < 4; cache->has_fence = cache->graphics_ver < 4;
cache->needs_unfenced = INTEL_INFO(i915)->unfenced_needs_alignment; cache->needs_unfenced = INTEL_INFO(i915)->unfenced_needs_alignment;
cache->node.flags = 0; cache->node.flags = 0;
reloc_cache_clear(cache); reloc_cache_clear(cache);
@ -1402,7 +1402,7 @@ static int __reloc_gpu_alloc(struct i915_execbuffer *eb,
err = eb->engine->emit_bb_start(rq, err = eb->engine->emit_bb_start(rq,
batch->node.start, PAGE_SIZE, batch->node.start, PAGE_SIZE,
cache->gen > 5 ? 0 : I915_DISPATCH_SECURE); cache->graphics_ver > 5 ? 0 : I915_DISPATCH_SECURE);
if (err) if (err)
goto skip_request; goto skip_request;
@ -1503,14 +1503,14 @@ static int __reloc_entry_gpu(struct i915_execbuffer *eb,
u64 offset, u64 offset,
u64 target_addr) u64 target_addr)
{ {
const unsigned int gen = eb->reloc_cache.gen; const unsigned int ver = eb->reloc_cache.graphics_ver;
unsigned int len; unsigned int len;
u32 *batch; u32 *batch;
u64 addr; u64 addr;
if (gen >= 8) if (ver >= 8)
len = offset & 7 ? 8 : 5; len = offset & 7 ? 8 : 5;
else if (gen >= 4) else if (ver >= 4)
len = 4; len = 4;
else else
len = 3; len = 3;
@ -1522,7 +1522,7 @@ static int __reloc_entry_gpu(struct i915_execbuffer *eb,
return false; return false;
addr = gen8_canonical_addr(vma->node.start + offset); addr = gen8_canonical_addr(vma->node.start + offset);
if (gen >= 8) { if (ver >= 8) {
if (offset & 7) { if (offset & 7) {
*batch++ = MI_STORE_DWORD_IMM_GEN4; *batch++ = MI_STORE_DWORD_IMM_GEN4;
*batch++ = lower_32_bits(addr); *batch++ = lower_32_bits(addr);
@ -1542,7 +1542,7 @@ static int __reloc_entry_gpu(struct i915_execbuffer *eb,
*batch++ = lower_32_bits(target_addr); *batch++ = lower_32_bits(target_addr);
*batch++ = upper_32_bits(target_addr); *batch++ = upper_32_bits(target_addr);
} }
} else if (gen >= 6) { } else if (ver >= 6) {
*batch++ = MI_STORE_DWORD_IMM_GEN4; *batch++ = MI_STORE_DWORD_IMM_GEN4;
*batch++ = 0; *batch++ = 0;
*batch++ = addr; *batch++ = addr;
@ -1552,12 +1552,12 @@ static int __reloc_entry_gpu(struct i915_execbuffer *eb,
*batch++ = 0; *batch++ = 0;
*batch++ = vma_phys_addr(vma, offset); *batch++ = vma_phys_addr(vma, offset);
*batch++ = target_addr; *batch++ = target_addr;
} else if (gen >= 4) { } else if (ver >= 4) {
*batch++ = MI_STORE_DWORD_IMM_GEN4 | MI_USE_GGTT; *batch++ = MI_STORE_DWORD_IMM_GEN4 | MI_USE_GGTT;
*batch++ = 0; *batch++ = 0;
*batch++ = addr; *batch++ = addr;
*batch++ = target_addr; *batch++ = target_addr;
} else if (gen >= 3 && } else if (ver >= 3 &&
!(IS_I915G(eb->i915) || IS_I915GM(eb->i915))) { !(IS_I915G(eb->i915) || IS_I915GM(eb->i915))) {
*batch++ = MI_STORE_DWORD_IMM | MI_MEM_VIRTUAL; *batch++ = MI_STORE_DWORD_IMM | MI_MEM_VIRTUAL;
*batch++ = addr; *batch++ = addr;

View file

@ -397,7 +397,10 @@ static void emit_batch(struct i915_vma * const vma,
gen7_emit_pipeline_invalidate(&cmds); gen7_emit_pipeline_invalidate(&cmds);
batch_add(&cmds, MI_LOAD_REGISTER_IMM(2)); batch_add(&cmds, MI_LOAD_REGISTER_IMM(2));
batch_add(&cmds, i915_mmio_reg_offset(CACHE_MODE_0_GEN7)); batch_add(&cmds, i915_mmio_reg_offset(CACHE_MODE_0_GEN7));
batch_add(&cmds, 0xffff0000); batch_add(&cmds, 0xffff0000 |
((IS_IVB_GT1(i915) || IS_VALLEYVIEW(i915)) ?
HIZ_RAW_STALL_OPT_DISABLE :
0));
batch_add(&cmds, i915_mmio_reg_offset(CACHE_MODE_1)); batch_add(&cmds, i915_mmio_reg_offset(CACHE_MODE_1));
batch_add(&cmds, 0xffff0000 | PIXEL_SUBSPAN_COLLECT_OPT_DISABLE); batch_add(&cmds, 0xffff0000 | PIXEL_SUBSPAN_COLLECT_OPT_DISABLE);
gen7_emit_pipeline_invalidate(&cmds); gen7_emit_pipeline_invalidate(&cmds);

View file

@ -6,8 +6,15 @@
#ifndef __GEN8_PPGTT_H__ #ifndef __GEN8_PPGTT_H__
#define __GEN8_PPGTT_H__ #define __GEN8_PPGTT_H__
#include <linux/kernel.h>
struct i915_address_space;
struct intel_gt; struct intel_gt;
enum i915_cache_level;
struct i915_ppgtt *gen8_ppgtt_create(struct intel_gt *gt); struct i915_ppgtt *gen8_ppgtt_create(struct intel_gt *gt);
u64 gen8_ggtt_pte_encode(dma_addr_t addr,
enum i915_cache_level level,
u32 flags);
#endif #endif

View file

@ -45,9 +45,9 @@ struct engine_info {
unsigned int hw_id; unsigned int hw_id;
u8 class; u8 class;
u8 instance; u8 instance;
/* mmio bases table *must* be sorted in reverse gen order */ /* mmio bases table *must* be sorted in reverse graphics_ver order */
struct engine_mmio_base { struct engine_mmio_base {
u32 gen : 8; u32 graphics_ver : 8;
u32 base : 24; u32 base : 24;
} mmio_bases[MAX_MMIO_BASES]; } mmio_bases[MAX_MMIO_BASES];
}; };
@ -58,7 +58,7 @@ static const struct engine_info intel_engines[] = {
.class = RENDER_CLASS, .class = RENDER_CLASS,
.instance = 0, .instance = 0,
.mmio_bases = { .mmio_bases = {
{ .gen = 1, .base = RENDER_RING_BASE } { .graphics_ver = 1, .base = RENDER_RING_BASE }
}, },
}, },
[BCS0] = { [BCS0] = {
@ -66,7 +66,7 @@ static const struct engine_info intel_engines[] = {
.class = COPY_ENGINE_CLASS, .class = COPY_ENGINE_CLASS,
.instance = 0, .instance = 0,
.mmio_bases = { .mmio_bases = {
{ .gen = 6, .base = BLT_RING_BASE } { .graphics_ver = 6, .base = BLT_RING_BASE }
}, },
}, },
[VCS0] = { [VCS0] = {
@ -74,9 +74,9 @@ static const struct engine_info intel_engines[] = {
.class = VIDEO_DECODE_CLASS, .class = VIDEO_DECODE_CLASS,
.instance = 0, .instance = 0,
.mmio_bases = { .mmio_bases = {
{ .gen = 11, .base = GEN11_BSD_RING_BASE }, { .graphics_ver = 11, .base = GEN11_BSD_RING_BASE },
{ .gen = 6, .base = GEN6_BSD_RING_BASE }, { .graphics_ver = 6, .base = GEN6_BSD_RING_BASE },
{ .gen = 4, .base = BSD_RING_BASE } { .graphics_ver = 4, .base = BSD_RING_BASE }
}, },
}, },
[VCS1] = { [VCS1] = {
@ -84,8 +84,8 @@ static const struct engine_info intel_engines[] = {
.class = VIDEO_DECODE_CLASS, .class = VIDEO_DECODE_CLASS,
.instance = 1, .instance = 1,
.mmio_bases = { .mmio_bases = {
{ .gen = 11, .base = GEN11_BSD2_RING_BASE }, { .graphics_ver = 11, .base = GEN11_BSD2_RING_BASE },
{ .gen = 8, .base = GEN8_BSD2_RING_BASE } { .graphics_ver = 8, .base = GEN8_BSD2_RING_BASE }
}, },
}, },
[VCS2] = { [VCS2] = {
@ -93,7 +93,7 @@ static const struct engine_info intel_engines[] = {
.class = VIDEO_DECODE_CLASS, .class = VIDEO_DECODE_CLASS,
.instance = 2, .instance = 2,
.mmio_bases = { .mmio_bases = {
{ .gen = 11, .base = GEN11_BSD3_RING_BASE } { .graphics_ver = 11, .base = GEN11_BSD3_RING_BASE }
}, },
}, },
[VCS3] = { [VCS3] = {
@ -101,7 +101,7 @@ static const struct engine_info intel_engines[] = {
.class = VIDEO_DECODE_CLASS, .class = VIDEO_DECODE_CLASS,
.instance = 3, .instance = 3,
.mmio_bases = { .mmio_bases = {
{ .gen = 11, .base = GEN11_BSD4_RING_BASE } { .graphics_ver = 11, .base = GEN11_BSD4_RING_BASE }
}, },
}, },
[VECS0] = { [VECS0] = {
@ -109,8 +109,8 @@ static const struct engine_info intel_engines[] = {
.class = VIDEO_ENHANCEMENT_CLASS, .class = VIDEO_ENHANCEMENT_CLASS,
.instance = 0, .instance = 0,
.mmio_bases = { .mmio_bases = {
{ .gen = 11, .base = GEN11_VEBOX_RING_BASE }, { .graphics_ver = 11, .base = GEN11_VEBOX_RING_BASE },
{ .gen = 7, .base = VEBOX_RING_BASE } { .graphics_ver = 7, .base = VEBOX_RING_BASE }
}, },
}, },
[VECS1] = { [VECS1] = {
@ -118,7 +118,7 @@ static const struct engine_info intel_engines[] = {
.class = VIDEO_ENHANCEMENT_CLASS, .class = VIDEO_ENHANCEMENT_CLASS,
.instance = 1, .instance = 1,
.mmio_bases = { .mmio_bases = {
{ .gen = 11, .base = GEN11_VEBOX2_RING_BASE } { .graphics_ver = 11, .base = GEN11_VEBOX2_RING_BASE }
}, },
}, },
}; };
@ -146,9 +146,9 @@ u32 intel_engine_context_size(struct intel_gt *gt, u8 class)
switch (class) { switch (class) {
case RENDER_CLASS: case RENDER_CLASS:
switch (INTEL_GEN(gt->i915)) { switch (GRAPHICS_VER(gt->i915)) {
default: default:
MISSING_CASE(INTEL_GEN(gt->i915)); MISSING_CASE(GRAPHICS_VER(gt->i915));
return DEFAULT_LR_CONTEXT_RENDER_SIZE; return DEFAULT_LR_CONTEXT_RENDER_SIZE;
case 12: case 12:
case 11: case 11:
@ -184,8 +184,8 @@ u32 intel_engine_context_size(struct intel_gt *gt, u8 class)
*/ */
cxt_size = intel_uncore_read(uncore, CXT_SIZE) + 1; cxt_size = intel_uncore_read(uncore, CXT_SIZE) + 1;
drm_dbg(&gt->i915->drm, drm_dbg(&gt->i915->drm,
"gen%d CXT_SIZE = %d bytes [0x%08x]\n", "graphics_ver = %d CXT_SIZE = %d bytes [0x%08x]\n",
INTEL_GEN(gt->i915), cxt_size * 64, GRAPHICS_VER(gt->i915), cxt_size * 64,
cxt_size - 1); cxt_size - 1);
return round_up(cxt_size * 64, PAGE_SIZE); return round_up(cxt_size * 64, PAGE_SIZE);
case 3: case 3:
@ -201,7 +201,7 @@ u32 intel_engine_context_size(struct intel_gt *gt, u8 class)
case VIDEO_DECODE_CLASS: case VIDEO_DECODE_CLASS:
case VIDEO_ENHANCEMENT_CLASS: case VIDEO_ENHANCEMENT_CLASS:
case COPY_ENGINE_CLASS: case COPY_ENGINE_CLASS:
if (INTEL_GEN(gt->i915) < 8) if (GRAPHICS_VER(gt->i915) < 8)
return 0; return 0;
return GEN8_LR_CONTEXT_OTHER_SIZE; return GEN8_LR_CONTEXT_OTHER_SIZE;
} }
@ -213,7 +213,7 @@ static u32 __engine_mmio_base(struct drm_i915_private *i915,
int i; int i;
for (i = 0; i < MAX_MMIO_BASES; i++) for (i = 0; i < MAX_MMIO_BASES; i++)
if (INTEL_GEN(i915) >= bases[i].gen) if (GRAPHICS_VER(i915) >= bases[i].graphics_ver)
break; break;
GEM_BUG_ON(i == MAX_MMIO_BASES); GEM_BUG_ON(i == MAX_MMIO_BASES);

View file

@ -18,6 +18,7 @@
#include "i915_vgpu.h" #include "i915_vgpu.h"
#include "intel_gtt.h" #include "intel_gtt.h"
#include "gen8_ppgtt.h"
static int static int
i915_get_ggtt_vma_pages(struct i915_vma *vma); i915_get_ggtt_vma_pages(struct i915_vma *vma);
@ -187,9 +188,9 @@ static void gmch_ggtt_invalidate(struct i915_ggtt *ggtt)
intel_gtt_chipset_flush(); intel_gtt_chipset_flush();
} }
static u64 gen8_ggtt_pte_encode(dma_addr_t addr, u64 gen8_ggtt_pte_encode(dma_addr_t addr,
enum i915_cache_level level, enum i915_cache_level level,
u32 flags) u32 flags)
{ {
gen8_pte_t pte = addr | _PAGE_PRESENT; gen8_pte_t pte = addr | _PAGE_PRESENT;

View file

@ -245,6 +245,7 @@ struct i915_address_space {
struct dma_resv resv; /* reservation lock for all pd objects, and buffer pool */ struct dma_resv resv; /* reservation lock for all pd objects, and buffer pool */
#define VM_CLASS_GGTT 0 #define VM_CLASS_GGTT 0
#define VM_CLASS_PPGTT 1 #define VM_CLASS_PPGTT 1
#define VM_CLASS_DPT 2
struct drm_i915_gem_object *scratch[4]; struct drm_i915_gem_object *scratch[4];
/** /**
@ -255,6 +256,9 @@ struct i915_address_space {
/* Global GTT */ /* Global GTT */
bool is_ggtt:1; bool is_ggtt:1;
/* Display page table */
bool is_dpt:1;
/* Some systems support read-only mappings for GGTT and/or PPGTT */ /* Some systems support read-only mappings for GGTT and/or PPGTT */
bool has_read_only:1; bool has_read_only:1;
@ -351,6 +355,7 @@ struct i915_ppgtt {
}; };
#define i915_is_ggtt(vm) ((vm)->is_ggtt) #define i915_is_ggtt(vm) ((vm)->is_ggtt)
#define i915_is_dpt(vm) ((vm)->is_dpt)
int __must_check int __must_check
i915_vm_lock_objects(struct i915_address_space *vm, struct i915_gem_ww_ctx *ww); i915_vm_lock_objects(struct i915_address_space *vm, struct i915_gem_ww_ctx *ww);

View file

@ -376,34 +376,34 @@ static int intel_mmio_bases_check(void *arg)
u8 prev = U8_MAX; u8 prev = U8_MAX;
for (j = 0; j < MAX_MMIO_BASES; j++) { for (j = 0; j < MAX_MMIO_BASES; j++) {
u8 gen = info->mmio_bases[j].gen; u8 ver = info->mmio_bases[j].graphics_ver;
u32 base = info->mmio_bases[j].base; u32 base = info->mmio_bases[j].base;
if (gen >= prev) { if (ver >= prev) {
pr_err("%s(%s, class:%d, instance:%d): mmio base for gen %x is before the one for gen %x\n", pr_err("%s(%s, class:%d, instance:%d): mmio base for graphics ver %u is before the one for ver %u\n",
__func__, __func__,
intel_engine_class_repr(info->class), intel_engine_class_repr(info->class),
info->class, info->instance, info->class, info->instance,
prev, gen); prev, ver);
return -EINVAL; return -EINVAL;
} }
if (gen == 0) if (ver == 0)
break; break;
if (!base) { if (!base) {
pr_err("%s(%s, class:%d, instance:%d): invalid mmio base (%x) for gen %x at entry %u\n", pr_err("%s(%s, class:%d, instance:%d): invalid mmio base (%x) for graphics ver %u at entry %u\n",
__func__, __func__,
intel_engine_class_repr(info->class), intel_engine_class_repr(info->class),
info->class, info->instance, info->class, info->instance,
base, gen, j); base, ver, j);
return -EINVAL; return -EINVAL;
} }
prev = gen; prev = ver;
} }
pr_debug("%s: min gen supported for %s%d is %d\n", pr_debug("%s: min graphics version supported for %s%d is %u\n",
__func__, __func__,
intel_engine_class_repr(info->class), intel_engine_class_repr(info->class),
info->instance, info->instance,

View file

@ -927,7 +927,7 @@ static int scrub_whitelisted_registers(struct intel_context *ce)
struct regmask { struct regmask {
i915_reg_t reg; i915_reg_t reg;
unsigned long gen_mask; u8 graphics_ver;
}; };
static bool find_reg(struct drm_i915_private *i915, static bool find_reg(struct drm_i915_private *i915,
@ -938,7 +938,7 @@ static bool find_reg(struct drm_i915_private *i915,
u32 offset = i915_mmio_reg_offset(reg); u32 offset = i915_mmio_reg_offset(reg);
while (count--) { while (count--) {
if (INTEL_INFO(i915)->gen_mask & tbl->gen_mask && if (GRAPHICS_VER(i915) == tbl->graphics_ver &&
i915_mmio_reg_offset(tbl->reg) == offset) i915_mmio_reg_offset(tbl->reg) == offset)
return true; return true;
tbl++; tbl++;
@ -951,8 +951,8 @@ static bool pardon_reg(struct drm_i915_private *i915, i915_reg_t reg)
{ {
/* Alas, we must pardon some whitelists. Mistakes already made */ /* Alas, we must pardon some whitelists. Mistakes already made */
static const struct regmask pardon[] = { static const struct regmask pardon[] = {
{ GEN9_CTX_PREEMPT_REG, INTEL_GEN_MASK(9, 9) }, { GEN9_CTX_PREEMPT_REG, 9 },
{ GEN8_L3SQCREG4, INTEL_GEN_MASK(9, 9) }, { GEN8_L3SQCREG4, 9 },
}; };
return find_reg(i915, reg, pardon, ARRAY_SIZE(pardon)); return find_reg(i915, reg, pardon, ARRAY_SIZE(pardon));
@ -974,7 +974,7 @@ static bool writeonly_reg(struct drm_i915_private *i915, i915_reg_t reg)
{ {
/* Some registers do not seem to behave and our writes unreadable */ /* Some registers do not seem to behave and our writes unreadable */
static const struct regmask wo[] = { static const struct regmask wo[] = {
{ GEN9_SLICE_COMMON_ECO_CHICKEN1, INTEL_GEN_MASK(9, 9) }, { GEN9_SLICE_COMMON_ECO_CHICKEN1, 9 },
}; };
return find_reg(i915, reg, wo, ARRAY_SIZE(wo)); return find_reg(i915, reg, wo, ARRAY_SIZE(wo));

View file

@ -121,4 +121,3 @@ void intel_guc_log_debugfs_register(struct intel_guc_log *log,
intel_gt_debugfs_register_files(root, files, ARRAY_SIZE(files), log); intel_gt_debugfs_register_files(root, files, ARRAY_SIZE(files), log);
} }

View file

@ -768,8 +768,6 @@ i915_driver_create(struct pci_dev *pdev, const struct pci_device_id *ent)
memcpy(device_info, match_info, sizeof(*device_info)); memcpy(device_info, match_info, sizeof(*device_info));
RUNTIME_INFO(i915)->device_id = pdev->device; RUNTIME_INFO(i915)->device_id = pdev->device;
BUG_ON(device_info->gen > BITS_PER_TYPE(device_info->gen_mask));
return i915; return i915;
} }
@ -796,7 +794,7 @@ int i915_driver_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
return PTR_ERR(i915); return PTR_ERR(i915);
/* Disable nuclear pageflip by default on pre-ILK */ /* Disable nuclear pageflip by default on pre-ILK */
if (!i915->params.nuclear_pageflip && match_info->gen < 5) if (!i915->params.nuclear_pageflip && match_info->graphics_ver < 5)
i915->drm.driver_features &= ~DRIVER_ATOMIC; i915->drm.driver_features &= ~DRIVER_ATOMIC;
/* /*
@ -973,8 +971,12 @@ static int i915_driver_open(struct drm_device *dev, struct drm_file *file)
*/ */
static void i915_driver_lastclose(struct drm_device *dev) static void i915_driver_lastclose(struct drm_device *dev)
{ {
struct drm_i915_private *i915 = to_i915(dev);
intel_fbdev_restore_mode(dev); intel_fbdev_restore_mode(dev);
vga_switcheroo_process_delayed_switch();
if (HAS_DISPLAY(i915))
vga_switcheroo_process_delayed_switch();
} }
static void i915_driver_postclose(struct drm_device *dev, struct drm_file *file) static void i915_driver_postclose(struct drm_device *dev, struct drm_file *file)
@ -994,6 +996,9 @@ static void intel_suspend_encoders(struct drm_i915_private *dev_priv)
struct drm_device *dev = &dev_priv->drm; struct drm_device *dev = &dev_priv->drm;
struct intel_encoder *encoder; struct intel_encoder *encoder;
if (!HAS_DISPLAY(dev_priv))
return;
drm_modeset_lock_all(dev); drm_modeset_lock_all(dev);
for_each_intel_encoder(dev, encoder) for_each_intel_encoder(dev, encoder)
if (encoder->suspend) if (encoder->suspend)
@ -1006,6 +1011,9 @@ static void intel_shutdown_encoders(struct drm_i915_private *dev_priv)
struct drm_device *dev = &dev_priv->drm; struct drm_device *dev = &dev_priv->drm;
struct intel_encoder *encoder; struct intel_encoder *encoder;
if (!HAS_DISPLAY(dev_priv))
return;
drm_modeset_lock_all(dev); drm_modeset_lock_all(dev);
for_each_intel_encoder(dev, encoder) for_each_intel_encoder(dev, encoder)
if (encoder->shutdown) if (encoder->shutdown)
@ -1021,9 +1029,11 @@ void i915_driver_shutdown(struct drm_i915_private *i915)
i915_gem_suspend(i915); i915_gem_suspend(i915);
drm_kms_helper_poll_disable(&i915->drm); if (HAS_DISPLAY(i915)) {
drm_kms_helper_poll_disable(&i915->drm);
drm_atomic_helper_shutdown(&i915->drm); drm_atomic_helper_shutdown(&i915->drm);
}
intel_dp_mst_suspend(i915); intel_dp_mst_suspend(i915);
@ -1033,10 +1043,18 @@ void i915_driver_shutdown(struct drm_i915_private *i915)
intel_suspend_encoders(i915); intel_suspend_encoders(i915);
intel_shutdown_encoders(i915); intel_shutdown_encoders(i915);
intel_csr_ucode_suspend(i915);
/* /*
* The only requirement is to reboot with display DC states disabled, * The only requirement is to reboot with display DC states disabled,
* for now leaving all display power wells in the INIT power domain * for now leaving all display power wells in the INIT power domain
* enabled matching the driver reload sequence. * enabled.
*
* TODO:
* - unify the pci_driver::shutdown sequence here with the
* pci_driver.driver.pm.poweroff,poweroff_late sequence.
* - unify the driver remove and system/runtime suspend sequences with
* the above unified shutdown/poweroff sequence.
*/ */
intel_power_domains_driver_remove(i915); intel_power_domains_driver_remove(i915);
enable_rpm_wakeref_asserts(&i915->runtime_pm); enable_rpm_wakeref_asserts(&i915->runtime_pm);
@ -1079,8 +1097,8 @@ static int i915_drm_suspend(struct drm_device *dev)
/* We do a lot of poking in a lot of registers, make sure they work /* We do a lot of poking in a lot of registers, make sure they work
* properly. */ * properly. */
intel_power_domains_disable(dev_priv); intel_power_domains_disable(dev_priv);
if (HAS_DISPLAY(dev_priv))
drm_kms_helper_poll_disable(dev); drm_kms_helper_poll_disable(dev);
pci_save_state(pdev); pci_save_state(pdev);
@ -1227,7 +1245,8 @@ static int i915_drm_resume(struct drm_device *dev)
*/ */
intel_runtime_pm_enable_interrupts(dev_priv); intel_runtime_pm_enable_interrupts(dev_priv);
drm_mode_config_reset(dev); if (HAS_DISPLAY(dev_priv))
drm_mode_config_reset(dev);
i915_gem_resume(dev_priv); i915_gem_resume(dev_priv);
@ -1240,7 +1259,8 @@ static int i915_drm_resume(struct drm_device *dev)
intel_display_resume(dev); intel_display_resume(dev);
intel_hpd_poll_disable(dev_priv); intel_hpd_poll_disable(dev_priv);
drm_kms_helper_poll_enable(dev); if (HAS_DISPLAY(dev_priv))
drm_kms_helper_poll_enable(dev);
intel_opregion_resume(dev_priv); intel_opregion_resume(dev_priv);

View file

@ -1234,30 +1234,38 @@ static inline struct drm_i915_private *pdev_to_i915(struct pci_dev *pdev)
#define RUNTIME_INFO(dev_priv) (&(dev_priv)->__runtime) #define RUNTIME_INFO(dev_priv) (&(dev_priv)->__runtime)
#define DRIVER_CAPS(dev_priv) (&(dev_priv)->caps) #define DRIVER_CAPS(dev_priv) (&(dev_priv)->caps)
#define INTEL_GEN(dev_priv) (INTEL_INFO(dev_priv)->gen)
#define INTEL_DEVID(dev_priv) (RUNTIME_INFO(dev_priv)->device_id) #define INTEL_DEVID(dev_priv) (RUNTIME_INFO(dev_priv)->device_id)
#define DISPLAY_VER(i915) (INTEL_INFO(i915)->display.version) /*
#define IS_DISPLAY_RANGE(i915, from, until) \ * Deprecated: this will be replaced by individual IP checks:
* GRAPHICS_VER(), MEDIA_VER() and DISPLAY_VER()
*/
#define INTEL_GEN(dev_priv) GRAPHICS_VER(dev_priv)
/*
* Deprecated: use IS_GRAPHICS_VER(), IS_MEDIA_VER() and IS_DISPLAY_VER() as
* appropriate.
*/
#define IS_GEN_RANGE(dev_priv, s, e) IS_GRAPHICS_VER(dev_priv, (s), (e))
/*
* Deprecated: use GRAPHICS_VER(), MEDIA_VER() and DISPLAY_VER() as appropriate.
*/
#define IS_GEN(dev_priv, n) (GRAPHICS_VER(dev_priv) == (n))
#define GRAPHICS_VER(i915) (INTEL_INFO(i915)->graphics_ver)
#define IS_GRAPHICS_VER(i915, from, until) \
(GRAPHICS_VER(i915) >= (from) && GRAPHICS_VER(i915) <= (until))
#define MEDIA_VER(i915) (INTEL_INFO(i915)->media_ver)
#define IS_MEDIA_VER(i915, from, until) \
(MEDIA_VER(i915) >= (from) && MEDIA_VER(i915) <= (until))
#define DISPLAY_VER(i915) (INTEL_INFO(i915)->display.ver)
#define IS_DISPLAY_VER(i915, from, until) \
(DISPLAY_VER(i915) >= (from) && DISPLAY_VER(i915) <= (until)) (DISPLAY_VER(i915) >= (from) && DISPLAY_VER(i915) <= (until))
#define IS_DISPLAY_VER(i915, v) (DISPLAY_VER(i915) == (v))
#define REVID_FOREVER 0xff #define REVID_FOREVER 0xff
#define INTEL_REVID(dev_priv) (to_pci_dev((dev_priv)->drm.dev)->revision) #define INTEL_REVID(dev_priv) (to_pci_dev((dev_priv)->drm.dev)->revision)
#define INTEL_GEN_MASK(s, e) ( \
BUILD_BUG_ON_ZERO(!__builtin_constant_p(s)) + \
BUILD_BUG_ON_ZERO(!__builtin_constant_p(e)) + \
GENMASK((e) - 1, (s) - 1))
/* Returns true if Gen is in inclusive range [Start, End] */
#define IS_GEN_RANGE(dev_priv, s, e) \
(!!(INTEL_INFO(dev_priv)->gen_mask & INTEL_GEN_MASK((s), (e))))
#define IS_GEN(dev_priv, n) \
(BUILD_BUG_ON_ZERO(!__builtin_constant_p(n)) + \
INTEL_INFO(dev_priv)->gen == (n))
#define HAS_DSB(dev_priv) (INTEL_INFO(dev_priv)->display.has_dsb) #define HAS_DSB(dev_priv) (INTEL_INFO(dev_priv)->display.has_dsb)
/* /*
@ -1384,6 +1392,7 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
#define IS_ROCKETLAKE(dev_priv) IS_PLATFORM(dev_priv, INTEL_ROCKETLAKE) #define IS_ROCKETLAKE(dev_priv) IS_PLATFORM(dev_priv, INTEL_ROCKETLAKE)
#define IS_DG1(dev_priv) IS_PLATFORM(dev_priv, INTEL_DG1) #define IS_DG1(dev_priv) IS_PLATFORM(dev_priv, INTEL_DG1)
#define IS_ALDERLAKE_S(dev_priv) IS_PLATFORM(dev_priv, INTEL_ALDERLAKE_S) #define IS_ALDERLAKE_S(dev_priv) IS_PLATFORM(dev_priv, INTEL_ALDERLAKE_S)
#define IS_ALDERLAKE_P(dev_priv) IS_PLATFORM(dev_priv, INTEL_ALDERLAKE_P)
#define IS_HSW_EARLY_SDV(dev_priv) (IS_HASWELL(dev_priv) && \ #define IS_HSW_EARLY_SDV(dev_priv) (IS_HASWELL(dev_priv) && \
(INTEL_DEVID(dev_priv) & 0xFF00) == 0x0C00) (INTEL_DEVID(dev_priv) & 0xFF00) == 0x0C00)
#define IS_BDW_ULT(dev_priv) \ #define IS_BDW_ULT(dev_priv) \
@ -1534,6 +1543,14 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
(IS_ALDERLAKE_S(__i915) && \ (IS_ALDERLAKE_S(__i915) && \
IS_GT_STEP(__i915, since, until)) IS_GT_STEP(__i915, since, until))
#define IS_ADLP_DISPLAY_STEP(__i915, since, until) \
(IS_ALDERLAKE_P(__i915) && \
IS_DISPLAY_STEP(__i915, since, until))
#define IS_ADLP_GT_STEP(__i915, since, until) \
(IS_ALDERLAKE_P(__i915) && \
IS_GT_STEP(__i915, since, until))
#define IS_LP(dev_priv) (INTEL_INFO(dev_priv)->is_lp) #define IS_LP(dev_priv) (INTEL_INFO(dev_priv)->is_lp)
#define IS_GEN9_LP(dev_priv) (IS_GEN(dev_priv, 9) && IS_LP(dev_priv)) #define IS_GEN9_LP(dev_priv) (IS_GEN(dev_priv, 9) && IS_LP(dev_priv))
#define IS_GEN9_BC(dev_priv) (IS_GEN(dev_priv, 9) && !IS_LP(dev_priv)) #define IS_GEN9_BC(dev_priv) (IS_GEN(dev_priv, 9) && !IS_LP(dev_priv))

View file

@ -36,7 +36,6 @@
#include <drm/drm_print.h> #include <drm/drm_print.h>
#include "display/intel_atomic.h"
#include "display/intel_csr.h" #include "display/intel_csr.h"
#include "display/intel_overlay.h" #include "display/intel_overlay.h"
@ -808,9 +807,6 @@ static void __err_print_to_sgl(struct drm_i915_error_state_buf *m,
if (error->overlay) if (error->overlay)
intel_overlay_print_error_state(m, error->overlay); intel_overlay_print_error_state(m, error->overlay);
if (error->display)
intel_display_print_error_state(m, error->display);
err_print_capabilities(m, error); err_print_capabilities(m, error);
err_print_params(m, &error->params); err_print_params(m, &error->params);
} }
@ -974,7 +970,6 @@ void __i915_gpu_coredump_free(struct kref *error_ref)
} }
kfree(error->overlay); kfree(error->overlay);
kfree(error->display);
cleanup_params(error); cleanup_params(error);
@ -1826,7 +1821,6 @@ i915_gpu_coredump(struct intel_gt *gt, intel_engine_mask_t engine_mask)
} }
error->overlay = intel_overlay_capture_error_state(i915); error->overlay = intel_overlay_capture_error_state(i915);
error->display = intel_display_capture_error_state(i915);
return error; return error;
} }

View file

@ -29,7 +29,6 @@ struct drm_i915_private;
struct i915_vma_compress; struct i915_vma_compress;
struct intel_engine_capture_vma; struct intel_engine_capture_vma;
struct intel_overlay_error_state; struct intel_overlay_error_state;
struct intel_display_error_state;
struct i915_vma_coredump { struct i915_vma_coredump {
struct i915_vma_coredump *next; struct i915_vma_coredump *next;
@ -182,7 +181,6 @@ struct i915_gpu_coredump {
struct i915_params params; struct i915_params params;
struct intel_overlay_error_state *overlay; struct intel_overlay_error_state *overlay;
struct intel_display_error_state *display;
struct scatterlist *sgl, *fit; struct scatterlist *sgl, *fit;
}; };

View file

@ -35,6 +35,7 @@
#include <drm/drm_drv.h> #include <drm/drm_drv.h>
#include <drm/drm_irq.h> #include <drm/drm_irq.h>
#include "display/intel_de.h"
#include "display/intel_display_types.h" #include "display/intel_display_types.h"
#include "display/intel_fifo_underrun.h" #include "display/intel_fifo_underrun.h"
#include "display/intel_hotplug.h" #include "display/intel_hotplug.h"
@ -194,7 +195,7 @@ static void intel_hpd_init_pins(struct drm_i915_private *dev_priv)
if (DISPLAY_VER(dev_priv) >= 11) if (DISPLAY_VER(dev_priv) >= 11)
hpd->hpd = hpd_gen11; hpd->hpd = hpd_gen11;
else if (IS_GEN9_LP(dev_priv)) else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
hpd->hpd = hpd_bxt; hpd->hpd = hpd_bxt;
else if (DISPLAY_VER(dev_priv) >= 8) else if (DISPLAY_VER(dev_priv) >= 8)
hpd->hpd = hpd_bdw; hpd->hpd = hpd_bdw;
@ -806,7 +807,7 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc)
if (mode->flags & DRM_MODE_FLAG_INTERLACE) if (mode->flags & DRM_MODE_FLAG_INTERLACE)
vtotal /= 2; vtotal /= 2;
if (IS_DISPLAY_VER(dev_priv, 2)) if (DISPLAY_VER(dev_priv) == 2)
position = intel_de_read_fw(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN2; position = intel_de_read_fw(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN2;
else else
position = intel_de_read_fw(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN3; position = intel_de_read_fw(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN3;
@ -857,7 +858,7 @@ static bool i915_get_crtc_scanoutpos(struct drm_crtc *_crtc,
int vbl_start, vbl_end, hsync_start, htotal, vtotal; int vbl_start, vbl_end, hsync_start, htotal, vtotal;
unsigned long irqflags; unsigned long irqflags;
bool use_scanline_counter = DISPLAY_VER(dev_priv) >= 5 || bool use_scanline_counter = DISPLAY_VER(dev_priv) >= 5 ||
IS_G4X(dev_priv) || IS_DISPLAY_VER(dev_priv, 2) || IS_G4X(dev_priv) || DISPLAY_VER(dev_priv) == 2 ||
crtc->mode_flags & I915_MODE_FLAG_USE_SCANLINE_COUNTER; crtc->mode_flags & I915_MODE_FLAG_USE_SCANLINE_COUNTER;
if (drm_WARN_ON(&dev_priv->drm, !mode->crtc_clock)) { if (drm_WARN_ON(&dev_priv->drm, !mode->crtc_clock)) {
@ -2077,7 +2078,7 @@ static void ilk_display_irq_handler(struct drm_i915_private *dev_priv,
intel_uncore_write(&dev_priv->uncore, SDEIIR, pch_iir); intel_uncore_write(&dev_priv->uncore, SDEIIR, pch_iir);
} }
if (IS_DISPLAY_VER(dev_priv, 5) && de_iir & DE_PCU_EVENT) if (DISPLAY_VER(dev_priv) == 5 && de_iir & DE_PCU_EVENT)
gen5_rps_irq_handler(&dev_priv->gt.rps); gen5_rps_irq_handler(&dev_priv->gt.rps);
} }
@ -2269,7 +2270,17 @@ static u32 gen8_de_port_aux_mask(struct drm_i915_private *dev_priv)
{ {
u32 mask; u32 mask;
if (DISPLAY_VER(dev_priv) >= 12) if (DISPLAY_VER(dev_priv) >= 13)
return TGL_DE_PORT_AUX_DDIA |
TGL_DE_PORT_AUX_DDIB |
TGL_DE_PORT_AUX_DDIC |
XELPD_DE_PORT_AUX_DDID |
XELPD_DE_PORT_AUX_DDIE |
TGL_DE_PORT_AUX_USBC1 |
TGL_DE_PORT_AUX_USBC2 |
TGL_DE_PORT_AUX_USBC3 |
TGL_DE_PORT_AUX_USBC4;
else if (DISPLAY_VER(dev_priv) >= 12)
return TGL_DE_PORT_AUX_DDIA | return TGL_DE_PORT_AUX_DDIA |
TGL_DE_PORT_AUX_DDIB | TGL_DE_PORT_AUX_DDIB |
TGL_DE_PORT_AUX_DDIC | TGL_DE_PORT_AUX_DDIC |
@ -2287,10 +2298,10 @@ static u32 gen8_de_port_aux_mask(struct drm_i915_private *dev_priv)
GEN9_AUX_CHANNEL_C | GEN9_AUX_CHANNEL_C |
GEN9_AUX_CHANNEL_D; GEN9_AUX_CHANNEL_D;
if (IS_CNL_WITH_PORT_F(dev_priv) || IS_DISPLAY_VER(dev_priv, 11)) if (IS_CNL_WITH_PORT_F(dev_priv) || DISPLAY_VER(dev_priv) == 11)
mask |= CNL_AUX_CHANNEL_F; mask |= CNL_AUX_CHANNEL_F;
if (IS_DISPLAY_VER(dev_priv, 11)) if (DISPLAY_VER(dev_priv) == 11)
mask |= ICL_AUX_CHANNEL_E; mask |= ICL_AUX_CHANNEL_E;
return mask; return mask;
@ -2298,7 +2309,7 @@ static u32 gen8_de_port_aux_mask(struct drm_i915_private *dev_priv)
static u32 gen8_de_pipe_fault_mask(struct drm_i915_private *dev_priv) static u32 gen8_de_pipe_fault_mask(struct drm_i915_private *dev_priv)
{ {
if (HAS_D12_PLANE_MINIMIZATION(dev_priv)) if (DISPLAY_VER(dev_priv) >= 13 || HAS_D12_PLANE_MINIMIZATION(dev_priv))
return RKL_DE_PIPE_IRQ_FAULT_ERRORS; return RKL_DE_PIPE_IRQ_FAULT_ERRORS;
else if (DISPLAY_VER(dev_priv) >= 11) else if (DISPLAY_VER(dev_priv) >= 11)
return GEN11_DE_PIPE_IRQ_FAULT_ERRORS; return GEN11_DE_PIPE_IRQ_FAULT_ERRORS;
@ -2421,6 +2432,8 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl)
u32 iir; u32 iir;
enum pipe pipe; enum pipe pipe;
drm_WARN_ON_ONCE(&dev_priv->drm, !HAS_DISPLAY(dev_priv));
if (master_ctl & GEN8_DE_MISC_IRQ) { if (master_ctl & GEN8_DE_MISC_IRQ) {
iir = intel_uncore_read(&dev_priv->uncore, GEN8_DE_MISC_IIR); iir = intel_uncore_read(&dev_priv->uncore, GEN8_DE_MISC_IIR);
if (iir) { if (iir) {
@ -2458,7 +2471,7 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl)
found = true; found = true;
} }
if (IS_GEN9_LP(dev_priv)) { if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) {
u32 hotplug_trigger = iir & BXT_DE_PORT_HOTPLUG_MASK; u32 hotplug_trigger = iir & BXT_DE_PORT_HOTPLUG_MASK;
if (hotplug_trigger) { if (hotplug_trigger) {
@ -2474,7 +2487,8 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl)
} }
} }
if (IS_GEN9_LP(dev_priv) && (iir & BXT_DE_PORT_GMBUS)) { if ((IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) &&
(iir & BXT_DE_PORT_GMBUS)) {
gmbus_irq_handler(dev_priv); gmbus_irq_handler(dev_priv);
found = true; found = true;
} }
@ -3058,14 +3072,13 @@ static void cnp_display_clock_wa(struct drm_i915_private *dev_priv)
} }
} }
static void gen8_irq_reset(struct drm_i915_private *dev_priv) static void gen8_display_irq_reset(struct drm_i915_private *dev_priv)
{ {
struct intel_uncore *uncore = &dev_priv->uncore; struct intel_uncore *uncore = &dev_priv->uncore;
enum pipe pipe; enum pipe pipe;
gen8_master_intr_disable(dev_priv->uncore.regs); if (!HAS_DISPLAY(dev_priv))
return;
gen8_gt_irq_reset(&dev_priv->gt);
intel_uncore_write(uncore, EDP_PSR_IMR, 0xffffffff); intel_uncore_write(uncore, EDP_PSR_IMR, 0xffffffff);
intel_uncore_write(uncore, EDP_PSR_IIR, 0xffffffff); intel_uncore_write(uncore, EDP_PSR_IIR, 0xffffffff);
@ -3077,6 +3090,16 @@ static void gen8_irq_reset(struct drm_i915_private *dev_priv)
GEN3_IRQ_RESET(uncore, GEN8_DE_PORT_); GEN3_IRQ_RESET(uncore, GEN8_DE_PORT_);
GEN3_IRQ_RESET(uncore, GEN8_DE_MISC_); GEN3_IRQ_RESET(uncore, GEN8_DE_MISC_);
}
static void gen8_irq_reset(struct drm_i915_private *dev_priv)
{
struct intel_uncore *uncore = &dev_priv->uncore;
gen8_master_intr_disable(dev_priv->uncore.regs);
gen8_gt_irq_reset(&dev_priv->gt);
gen8_display_irq_reset(dev_priv);
GEN3_IRQ_RESET(uncore, GEN8_PCU_); GEN3_IRQ_RESET(uncore, GEN8_PCU_);
if (HAS_PCH_SPLIT(dev_priv)) if (HAS_PCH_SPLIT(dev_priv))
@ -3092,6 +3115,9 @@ static void gen11_display_irq_reset(struct drm_i915_private *dev_priv)
u32 trans_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | u32 trans_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |
BIT(TRANSCODER_C) | BIT(TRANSCODER_D); BIT(TRANSCODER_C) | BIT(TRANSCODER_D);
if (!HAS_DISPLAY(dev_priv))
return;
intel_uncore_write(uncore, GEN11_DISPLAY_INT_CTL, 0); intel_uncore_write(uncore, GEN11_DISPLAY_INT_CTL, 0);
if (DISPLAY_VER(dev_priv) >= 12) { if (DISPLAY_VER(dev_priv) >= 12) {
@ -3714,10 +3740,13 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
BIT(TRANSCODER_C) | BIT(TRANSCODER_D); BIT(TRANSCODER_C) | BIT(TRANSCODER_D);
enum pipe pipe; enum pipe pipe;
if (!HAS_DISPLAY(dev_priv))
return;
if (DISPLAY_VER(dev_priv) <= 10) if (DISPLAY_VER(dev_priv) <= 10)
de_misc_masked |= GEN8_DE_MISC_GSE; de_misc_masked |= GEN8_DE_MISC_GSE;
if (IS_GEN9_LP(dev_priv)) if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
de_port_masked |= BXT_DE_PORT_GMBUS; de_port_masked |= BXT_DE_PORT_GMBUS;
if (DISPLAY_VER(dev_priv) >= 11) { if (DISPLAY_VER(dev_priv) >= 11) {
@ -3732,7 +3761,7 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
gen8_de_pipe_flip_done_mask(dev_priv); gen8_de_pipe_flip_done_mask(dev_priv);
de_port_enables = de_port_masked; de_port_enables = de_port_masked;
if (IS_GEN9_LP(dev_priv)) if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
de_port_enables |= BXT_DE_PORT_HOTPLUG_MASK; de_port_enables |= BXT_DE_PORT_HOTPLUG_MASK;
else if (IS_BROADWELL(dev_priv)) else if (IS_BROADWELL(dev_priv))
de_port_enables |= BDW_DE_PORT_HOTPLUG_MASK; de_port_enables |= BDW_DE_PORT_HOTPLUG_MASK;
@ -3797,6 +3826,16 @@ static void gen8_irq_postinstall(struct drm_i915_private *dev_priv)
gen8_master_intr_enable(dev_priv->uncore.regs); gen8_master_intr_enable(dev_priv->uncore.regs);
} }
static void gen11_de_irq_postinstall(struct drm_i915_private *dev_priv)
{
if (!HAS_DISPLAY(dev_priv))
return;
gen8_de_irq_postinstall(dev_priv);
intel_uncore_write(&dev_priv->uncore, GEN11_DISPLAY_INT_CTL,
GEN11_DISPLAY_IRQ_ENABLE);
}
static void gen11_irq_postinstall(struct drm_i915_private *dev_priv) static void gen11_irq_postinstall(struct drm_i915_private *dev_priv)
{ {
@ -3807,12 +3846,10 @@ static void gen11_irq_postinstall(struct drm_i915_private *dev_priv)
icp_irq_postinstall(dev_priv); icp_irq_postinstall(dev_priv);
gen11_gt_irq_postinstall(&dev_priv->gt); gen11_gt_irq_postinstall(&dev_priv->gt);
gen8_de_irq_postinstall(dev_priv); gen11_de_irq_postinstall(dev_priv);
GEN3_IRQ_INIT(uncore, GEN11_GU_MISC_, ~gu_misc_masked, gu_misc_masked); GEN3_IRQ_INIT(uncore, GEN11_GU_MISC_, ~gu_misc_masked, gu_misc_masked);
intel_uncore_write(&dev_priv->uncore, GEN11_DISPLAY_INT_CTL, GEN11_DISPLAY_IRQ_ENABLE);
if (HAS_MASTER_UNIT_IRQ(dev_priv)) { if (HAS_MASTER_UNIT_IRQ(dev_priv)) {
dg1_master_intr_enable(uncore->regs); dg1_master_intr_enable(uncore->regs);
intel_uncore_posting_read(&dev_priv->uncore, DG1_MSTR_UNIT_INTR); intel_uncore_posting_read(&dev_priv->uncore, DG1_MSTR_UNIT_INTR);
@ -4317,7 +4354,7 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
dev_priv->display.hpd_irq_setup = dg1_hpd_irq_setup; dev_priv->display.hpd_irq_setup = dg1_hpd_irq_setup;
else if (DISPLAY_VER(dev_priv) >= 11) else if (DISPLAY_VER(dev_priv) >= 11)
dev_priv->display.hpd_irq_setup = gen11_hpd_irq_setup; dev_priv->display.hpd_irq_setup = gen11_hpd_irq_setup;
else if (IS_GEN9_LP(dev_priv)) else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
dev_priv->display.hpd_irq_setup = bxt_hpd_irq_setup; dev_priv->display.hpd_irq_setup = bxt_hpd_irq_setup;
else if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP) else if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP)
dev_priv->display.hpd_irq_setup = icp_hpd_irq_setup; dev_priv->display.hpd_irq_setup = icp_hpd_irq_setup;

View file

@ -47,7 +47,7 @@ int remap_io_sg(struct vm_area_struct *vma,
struct scatterlist *sgl, resource_size_t iobase) struct scatterlist *sgl, resource_size_t iobase)
{ {
unsigned long pfn, len, remapped = 0; unsigned long pfn, len, remapped = 0;
int err; int err = 0;
/* We rely on prevalidation of the io-mapping to skip track_pfn(). */ /* We rely on prevalidation of the io-mapping to skip track_pfn(). */
GEM_BUG_ON((vma->vm_flags & EXPECTED_FLAGS) != EXPECTED_FLAGS); GEM_BUG_ON((vma->vm_flags & EXPECTED_FLAGS) != EXPECTED_FLAGS);

View file

@ -97,4 +97,3 @@ void i915_params_copy(struct i915_params *dest, const struct i915_params *src);
void i915_params_free(struct i915_params *params); void i915_params_free(struct i915_params *params);
#endif #endif

View file

@ -36,7 +36,10 @@
#include "i915_selftest.h" #include "i915_selftest.h"
#define PLATFORM(x) .platform = (x) #define PLATFORM(x) .platform = (x)
#define GEN(x) .gen = (x), .gen_mask = BIT((x) - 1), .display.version = (x) #define GEN(x) \
.graphics_ver = (x), \
.media_ver = (x), \
.display.ver = (x)
#define I845_PIPE_OFFSETS \ #define I845_PIPE_OFFSETS \
.pipe_offsets = { \ .pipe_offsets = { \
@ -644,8 +647,8 @@ static const struct intel_device_info chv_info = {
.has_gt_uc = 1, \ .has_gt_uc = 1, \
.display.has_hdcp = 1, \ .display.has_hdcp = 1, \
.display.has_ipc = 1, \ .display.has_ipc = 1, \
.ddb_size = 896, \ .dbuf.size = 896 - 4, /* 4 blocks for bypass path allocation */ \
.num_supported_dbuf_slices = 1 .dbuf.slice_mask = BIT(DBUF_S1)
#define SKL_PLATFORM \ #define SKL_PLATFORM \
GEN9_FEATURES, \ GEN9_FEATURES, \
@ -680,7 +683,7 @@ static const struct intel_device_info skl_gt4_info = {
#define GEN9_LP_FEATURES \ #define GEN9_LP_FEATURES \
GEN(9), \ GEN(9), \
.is_lp = 1, \ .is_lp = 1, \
.num_supported_dbuf_slices = 1, \ .dbuf.slice_mask = BIT(DBUF_S1), \
.display.has_hotplug = 1, \ .display.has_hotplug = 1, \
.platform_engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0) | BIT(VECS0), \ .platform_engine_mask = BIT(RCS0) | BIT(VCS0) | BIT(BCS0) | BIT(VECS0), \
.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C), \ .pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C), \
@ -717,14 +720,14 @@ static const struct intel_device_info skl_gt4_info = {
static const struct intel_device_info bxt_info = { static const struct intel_device_info bxt_info = {
GEN9_LP_FEATURES, GEN9_LP_FEATURES,
PLATFORM(INTEL_BROXTON), PLATFORM(INTEL_BROXTON),
.ddb_size = 512, .dbuf.size = 512 - 4, /* 4 blocks for bypass path allocation */
}; };
static const struct intel_device_info glk_info = { static const struct intel_device_info glk_info = {
GEN9_LP_FEATURES, GEN9_LP_FEATURES,
PLATFORM(INTEL_GEMINILAKE), PLATFORM(INTEL_GEMINILAKE),
.display.version = 10, .display.ver = 10,
.ddb_size = 1024, .dbuf.size = 1024 - 4, /* 4 blocks for bypass path allocation */
GLK_COLORS, GLK_COLORS,
}; };
@ -787,7 +790,7 @@ static const struct intel_device_info cml_gt2_info = {
#define GEN10_FEATURES \ #define GEN10_FEATURES \
GEN9_FEATURES, \ GEN9_FEATURES, \
GEN(10), \ GEN(10), \
.ddb_size = 1024, \ .dbuf.size = 1024 - 4, /* 4 blocks for bypass path allocation */ \
.display.has_dsc = 1, \ .display.has_dsc = 1, \
.has_coherent_ggtt = false, \ .has_coherent_ggtt = false, \
GLK_COLORS GLK_COLORS
@ -827,8 +830,8 @@ static const struct intel_device_info cnl_info = {
[TRANSCODER_DSI_1] = TRANSCODER_DSI1_OFFSET, \ [TRANSCODER_DSI_1] = TRANSCODER_DSI1_OFFSET, \
}, \ }, \
GEN(11), \ GEN(11), \
.ddb_size = 2048, \ .dbuf.size = 2048, \
.num_supported_dbuf_slices = 2, \ .dbuf.slice_mask = BIT(DBUF_S1) | BIT(DBUF_S2), \
.has_logical_ring_elsq = 1, \ .has_logical_ring_elsq = 1, \
.color = { .degamma_lut_size = 33, .gamma_lut_size = 262145 } .color = { .degamma_lut_size = 33, .gamma_lut_size = 262145 }
@ -904,8 +907,7 @@ static const struct intel_device_info rkl_info = {
BIT(RCS0) | BIT(BCS0) | BIT(VECS0) | BIT(VCS0), BIT(RCS0) | BIT(BCS0) | BIT(VECS0) | BIT(VCS0),
}; };
#define GEN12_DGFX_FEATURES \ #define DGFX_FEATURES \
GEN12_FEATURES, \
.memory_regions = REGION_SMEM | REGION_LMEM, \ .memory_regions = REGION_SMEM | REGION_LMEM, \
.has_master_unit_irq = 1, \ .has_master_unit_irq = 1, \
.has_llc = 0, \ .has_llc = 0, \
@ -913,7 +915,8 @@ static const struct intel_device_info rkl_info = {
.is_dgfx = 1 .is_dgfx = 1
static const struct intel_device_info dg1_info __maybe_unused = { static const struct intel_device_info dg1_info __maybe_unused = {
GEN12_DGFX_FEATURES, GEN12_FEATURES,
DGFX_FEATURES,
PLATFORM(INTEL_DG1), PLATFORM(INTEL_DG1),
.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D), .pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D),
.require_force_probe = 1, .require_force_probe = 1,
@ -936,6 +939,28 @@ static const struct intel_device_info adl_s_info = {
.dma_mask_size = 46, .dma_mask_size = 46,
}; };
#define XE_LPD_FEATURES \
.display.ver = 13, \
.display.has_psr_hw_tracking = 0, \
.abox_mask = GENMASK(1, 0), \
.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D), \
.cpu_transcoder_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | \
BIT(TRANSCODER_C) | BIT(TRANSCODER_D), \
.dbuf.size = 4096, \
.dbuf.slice_mask = BIT(DBUF_S1) | BIT(DBUF_S2) | BIT(DBUF_S3) | BIT(DBUF_S4)
static const struct intel_device_info adl_p_info = {
GEN12_FEATURES,
XE_LPD_FEATURES,
PLATFORM(INTEL_ALDERLAKE_P),
.require_force_probe = 1,
.display.has_modular_fia = 1,
.platform_engine_mask =
BIT(RCS0) | BIT(BCS0) | BIT(VECS0) | BIT(VCS0) | BIT(VCS2),
.ppgtt_size = 48,
.dma_mask_size = 39,
};
#undef GEN #undef GEN
#undef PLATFORM #undef PLATFORM
@ -1013,6 +1038,7 @@ static const struct pci_device_id pciidlist[] = {
INTEL_TGL_12_IDS(&tgl_info), INTEL_TGL_12_IDS(&tgl_info),
INTEL_RKL_IDS(&rkl_info), INTEL_RKL_IDS(&rkl_info),
INTEL_ADLS_IDS(&adl_s_info), INTEL_ADLS_IDS(&adl_s_info),
INTEL_ADLP_IDS(&adl_p_info),
{0, 0, 0} {0, 0, 0}
}; };
MODULE_DEVICE_TABLE(pci, pciidlist); MODULE_DEVICE_TABLE(pci, pciidlist);

View file

@ -4318,6 +4318,7 @@ static void oa_init_supported_formats(struct i915_perf *perf)
case INTEL_ROCKETLAKE: case INTEL_ROCKETLAKE:
case INTEL_DG1: case INTEL_DG1:
case INTEL_ALDERLAKE_S: case INTEL_ALDERLAKE_S:
case INTEL_ALDERLAKE_P:
oa_format_add(perf, I915_OA_FORMAT_A12); oa_format_add(perf, I915_OA_FORMAT_A12);
oa_format_add(perf, I915_OA_FORMAT_A12_B8_C8); oa_format_add(perf, I915_OA_FORMAT_A12_B8_C8);
oa_format_add(perf, I915_OA_FORMAT_A32u40_A4u32_B8_C8); oa_format_add(perf, I915_OA_FORMAT_A32u40_A4u32_B8_C8);

View file

@ -4170,6 +4170,9 @@ enum {
#define GEN9_CLKGATE_DIS_4 _MMIO(0x4653C) #define GEN9_CLKGATE_DIS_4 _MMIO(0x4653C)
#define BXT_GMBUS_GATING_DIS (1 << 14) #define BXT_GMBUS_GATING_DIS (1 << 14)
#define GEN9_CLKGATE_DIS_5 _MMIO(0x46540)
#define DPCE_GATING_DIS REG_BIT(17)
#define _CLKGATE_DIS_PSL_A 0x46520 #define _CLKGATE_DIS_PSL_A 0x46520
#define _CLKGATE_DIS_PSL_B 0x46524 #define _CLKGATE_DIS_PSL_B 0x46524
#define _CLKGATE_DIS_PSL_C 0x46528 #define _CLKGATE_DIS_PSL_C 0x46528
@ -4563,8 +4566,7 @@ enum {
#define EDP_SU_TRACK_ENABLE (1 << 30) #define EDP_SU_TRACK_ENABLE (1 << 30)
#define TGL_EDP_PSR2_BLOCK_COUNT_NUM_2 (0 << 28) #define TGL_EDP_PSR2_BLOCK_COUNT_NUM_2 (0 << 28)
#define TGL_EDP_PSR2_BLOCK_COUNT_NUM_3 (1 << 28) #define TGL_EDP_PSR2_BLOCK_COUNT_NUM_3 (1 << 28)
#define EDP_Y_COORDINATE_VALID (1 << 26) /* GLK and CNL+ */ #define EDP_Y_COORDINATE_ENABLE REG_BIT(25) /* display 10, 11 and 12 */
#define EDP_Y_COORDINATE_ENABLE (1 << 25) /* GLK and CNL+ */
#define EDP_MAX_SU_DISABLE_TIME(t) ((t) << 20) #define EDP_MAX_SU_DISABLE_TIME(t) ((t) << 20)
#define EDP_MAX_SU_DISABLE_TIME_MASK (0x1f << 20) #define EDP_MAX_SU_DISABLE_TIME_MASK (0x1f << 20)
#define EDP_PSR2_IO_BUFFER_WAKE_MAX_LINES 8 #define EDP_PSR2_IO_BUFFER_WAKE_MAX_LINES 8
@ -6430,9 +6432,8 @@ enum {
#define _CUR_WM_TRANS_B_0 0x71168 #define _CUR_WM_TRANS_B_0 0x71168
#define PLANE_WM_EN (1 << 31) #define PLANE_WM_EN (1 << 31)
#define PLANE_WM_IGNORE_LINES (1 << 30) #define PLANE_WM_IGNORE_LINES (1 << 30)
#define PLANE_WM_LINES_SHIFT 14 #define PLANE_WM_LINES_MASK REG_GENMASK(26, 14)
#define PLANE_WM_LINES_MASK 0x1f #define PLANE_WM_BLOCKS_MASK REG_GENMASK(11, 0)
#define PLANE_WM_BLOCKS_MASK 0x7ff /* skl+: 10 bits, icl+ 11 bits */
#define _CUR_WM_0(pipe) _PIPE(pipe, _CUR_WM_A_0, _CUR_WM_B_0) #define _CUR_WM_0(pipe) _PIPE(pipe, _CUR_WM_A_0, _CUR_WM_B_0)
#define CUR_WM(pipe, level) _MMIO(_CUR_WM_0(pipe) + ((4) * (level))) #define CUR_WM(pipe, level) _MMIO(_CUR_WM_0(pipe) + ((4) * (level)))
@ -7207,6 +7208,8 @@ enum {
_PIPE(pipe, _PLANE_STRIDE_3_A, _PLANE_STRIDE_3_B) _PIPE(pipe, _PLANE_STRIDE_3_A, _PLANE_STRIDE_3_B)
#define PLANE_STRIDE(pipe, plane) \ #define PLANE_STRIDE(pipe, plane) \
_MMIO_PLANE(plane, _PLANE_STRIDE_1(pipe), _PLANE_STRIDE_2(pipe)) _MMIO_PLANE(plane, _PLANE_STRIDE_1(pipe), _PLANE_STRIDE_2(pipe))
#define PLANE_STRIDE_MASK REG_GENMASK(10, 0)
#define PLANE_STRIDE_MASK_XELPD REG_GENMASK(11, 0)
#define _PLANE_POS_1_B 0x7118c #define _PLANE_POS_1_B 0x7118c
#define _PLANE_POS_2_B 0x7128c #define _PLANE_POS_2_B 0x7128c
@ -7784,6 +7787,8 @@ enum {
#define GEN8_GT_BCS_IRQ (1 << 1) #define GEN8_GT_BCS_IRQ (1 << 1)
#define GEN8_GT_RCS_IRQ (1 << 0) #define GEN8_GT_RCS_IRQ (1 << 0)
#define XELPD_DISPLAY_ERR_FATAL_MASK _MMIO(0x4421c)
#define GEN8_GT_ISR(which) _MMIO(0x44300 + (0x10 * (which))) #define GEN8_GT_ISR(which) _MMIO(0x44300 + (0x10 * (which)))
#define GEN8_GT_IMR(which) _MMIO(0x44304 + (0x10 * (which))) #define GEN8_GT_IMR(which) _MMIO(0x44304 + (0x10 * (which)))
#define GEN8_GT_IIR(which) _MMIO(0x44308 + (0x10 * (which))) #define GEN8_GT_IIR(which) _MMIO(0x44308 + (0x10 * (which)))
@ -7866,15 +7871,17 @@ enum {
#define BDW_DE_PORT_HOTPLUG_MASK GEN8_DE_PORT_HOTPLUG(HPD_PORT_A) #define BDW_DE_PORT_HOTPLUG_MASK GEN8_DE_PORT_HOTPLUG(HPD_PORT_A)
#define BXT_DE_PORT_GMBUS (1 << 1) #define BXT_DE_PORT_GMBUS (1 << 1)
#define GEN8_AUX_CHANNEL_A (1 << 0) #define GEN8_AUX_CHANNEL_A (1 << 0)
#define TGL_DE_PORT_AUX_USBC6 (1 << 13) #define TGL_DE_PORT_AUX_USBC6 REG_BIT(13)
#define TGL_DE_PORT_AUX_USBC5 (1 << 12) #define XELPD_DE_PORT_AUX_DDIE REG_BIT(13)
#define TGL_DE_PORT_AUX_USBC4 (1 << 11) #define TGL_DE_PORT_AUX_USBC5 REG_BIT(12)
#define TGL_DE_PORT_AUX_USBC3 (1 << 10) #define XELPD_DE_PORT_AUX_DDID REG_BIT(12)
#define TGL_DE_PORT_AUX_USBC2 (1 << 9) #define TGL_DE_PORT_AUX_USBC4 REG_BIT(11)
#define TGL_DE_PORT_AUX_USBC1 (1 << 8) #define TGL_DE_PORT_AUX_USBC3 REG_BIT(10)
#define TGL_DE_PORT_AUX_DDIC (1 << 2) #define TGL_DE_PORT_AUX_USBC2 REG_BIT(9)
#define TGL_DE_PORT_AUX_DDIB (1 << 1) #define TGL_DE_PORT_AUX_USBC1 REG_BIT(8)
#define TGL_DE_PORT_AUX_DDIA (1 << 0) #define TGL_DE_PORT_AUX_DDIC REG_BIT(2)
#define TGL_DE_PORT_AUX_DDIB REG_BIT(1)
#define TGL_DE_PORT_AUX_DDIA REG_BIT(0)
#define GEN8_DE_MISC_ISR _MMIO(0x44460) #define GEN8_DE_MISC_ISR _MMIO(0x44460)
#define GEN8_DE_MISC_IMR _MMIO(0x44464) #define GEN8_DE_MISC_IMR _MMIO(0x44464)
@ -9632,6 +9639,12 @@ enum {
#define ICL_PW_CTL_IDX_PW_2 1 #define ICL_PW_CTL_IDX_PW_2 1
#define ICL_PW_CTL_IDX_PW_1 0 #define ICL_PW_CTL_IDX_PW_1 0
/* XE_LPD - power wells */
#define XELPD_PW_CTL_IDX_PW_D 8
#define XELPD_PW_CTL_IDX_PW_C 7
#define XELPD_PW_CTL_IDX_PW_B 6
#define XELPD_PW_CTL_IDX_PW_A 5
#define ICL_PWR_WELL_CTL_AUX1 _MMIO(0x45440) #define ICL_PWR_WELL_CTL_AUX1 _MMIO(0x45440)
#define ICL_PWR_WELL_CTL_AUX2 _MMIO(0x45444) #define ICL_PWR_WELL_CTL_AUX2 _MMIO(0x45444)
#define ICL_PWR_WELL_CTL_AUX4 _MMIO(0x4544C) #define ICL_PWR_WELL_CTL_AUX4 _MMIO(0x4544C)
@ -9646,7 +9659,9 @@ enum {
#define TGL_PW_CTL_IDX_AUX_TBT1 9 #define TGL_PW_CTL_IDX_AUX_TBT1 9
#define ICL_PW_CTL_IDX_AUX_TBT1 8 #define ICL_PW_CTL_IDX_AUX_TBT1 8
#define TGL_PW_CTL_IDX_AUX_TC6 8 #define TGL_PW_CTL_IDX_AUX_TC6 8
#define XELPD_PW_CTL_IDX_AUX_E 8
#define TGL_PW_CTL_IDX_AUX_TC5 7 #define TGL_PW_CTL_IDX_AUX_TC5 7
#define XELPD_PW_CTL_IDX_AUX_D 7
#define TGL_PW_CTL_IDX_AUX_TC4 6 #define TGL_PW_CTL_IDX_AUX_TC4 6
#define ICL_PW_CTL_IDX_AUX_F 5 #define ICL_PW_CTL_IDX_AUX_F 5
#define TGL_PW_CTL_IDX_AUX_TC3 5 #define TGL_PW_CTL_IDX_AUX_TC3 5
@ -9661,7 +9676,9 @@ enum {
#define ICL_PWR_WELL_CTL_DDI1 _MMIO(0x45450) #define ICL_PWR_WELL_CTL_DDI1 _MMIO(0x45450)
#define ICL_PWR_WELL_CTL_DDI2 _MMIO(0x45454) #define ICL_PWR_WELL_CTL_DDI2 _MMIO(0x45454)
#define ICL_PWR_WELL_CTL_DDI4 _MMIO(0x4545C) #define ICL_PWR_WELL_CTL_DDI4 _MMIO(0x4545C)
#define XELPD_PW_CTL_IDX_DDI_E 8
#define TGL_PW_CTL_IDX_DDI_TC6 8 #define TGL_PW_CTL_IDX_DDI_TC6 8
#define XELPD_PW_CTL_IDX_DDI_D 7
#define TGL_PW_CTL_IDX_DDI_TC5 7 #define TGL_PW_CTL_IDX_DDI_TC5 7
#define TGL_PW_CTL_IDX_DDI_TC4 6 #define TGL_PW_CTL_IDX_DDI_TC4 6
#define ICL_PW_CTL_IDX_DDI_F 5 #define ICL_PW_CTL_IDX_DDI_F 5
@ -10811,6 +10828,7 @@ enum skl_power_gate {
_DKL_TX_DPCNTL1) _DKL_TX_DPCNTL1)
#define _DKL_TX_DPCNTL2 0x2C8 #define _DKL_TX_DPCNTL2 0x2C8
#define DKL_TX_LOADGEN_SHARING_PMD_DISABLE REG_BIT(12)
#define DKL_TX_DP20BITMODE (1 << 2) #define DKL_TX_DP20BITMODE (1 << 2)
#define DKL_TX_DPCNTL2(tc_port) _MMIO(_PORT(tc_port, \ #define DKL_TX_DPCNTL2(tc_port) _MMIO(_PORT(tc_port, \
_DKL_PHY1_BASE, \ _DKL_PHY1_BASE, \
@ -11472,6 +11490,8 @@ enum skl_power_gate {
#define SPLITTER_CONFIGURATION_MASK REG_GENMASK(26, 25) #define SPLITTER_CONFIGURATION_MASK REG_GENMASK(26, 25)
#define SPLITTER_CONFIGURATION_2_SEGMENT REG_FIELD_PREP(SPLITTER_CONFIGURATION_MASK, 0) #define SPLITTER_CONFIGURATION_2_SEGMENT REG_FIELD_PREP(SPLITTER_CONFIGURATION_MASK, 0)
#define SPLITTER_CONFIGURATION_4_SEGMENT REG_FIELD_PREP(SPLITTER_CONFIGURATION_MASK, 1) #define SPLITTER_CONFIGURATION_4_SEGMENT REG_FIELD_PREP(SPLITTER_CONFIGURATION_MASK, 1)
#define UNCOMPRESSED_JOINER_MASTER (1 << 21)
#define UNCOMPRESSED_JOINER_SLAVE (1 << 20)
#define _ICL_PIPE_DSS_CTL2_PB 0x78204 #define _ICL_PIPE_DSS_CTL2_PB 0x78204
#define _ICL_PIPE_DSS_CTL2_PC 0x78404 #define _ICL_PIPE_DSS_CTL2_PC 0x78404
@ -12549,4 +12569,7 @@ enum skl_power_gate {
#define TGL_ROOT_DEVICE_SKU_ULX 0x2 #define TGL_ROOT_DEVICE_SKU_ULX 0x2
#define TGL_ROOT_DEVICE_SKU_ULT 0x4 #define TGL_ROOT_DEVICE_SKU_ULT 0x4
#define CLKREQ_POLICY _MMIO(0x101038)
#define CLKREQ_POLICY_MEM_UP_OVRD REG_BIT(1)
#endif /* _I915_REG_H_ */ #endif /* _I915_REG_H_ */

View file

@ -87,6 +87,9 @@ void i915_save_display(struct drm_i915_private *dev_priv)
{ {
struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev); struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
if (!HAS_DISPLAY(dev_priv))
return;
/* Display arbitration control */ /* Display arbitration control */
if (INTEL_GEN(dev_priv) <= 4) if (INTEL_GEN(dev_priv) <= 4)
dev_priv->regfile.saveDSPARB = intel_de_read(dev_priv, DSPARB); dev_priv->regfile.saveDSPARB = intel_de_read(dev_priv, DSPARB);
@ -102,6 +105,9 @@ void i915_restore_display(struct drm_i915_private *dev_priv)
{ {
struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev); struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
if (!HAS_DISPLAY(dev_priv))
return;
intel_restore_swf(dev_priv); intel_restore_swf(dev_priv);
if (IS_GEN(dev_priv, 4)) if (IS_GEN(dev_priv, 4))

View file

@ -72,7 +72,7 @@ show_rc6_mask(struct device *kdev, struct device_attribute *attr, char *buf)
if (HAS_RC6pp(dev_priv)) if (HAS_RC6pp(dev_priv))
mask |= BIT(2); mask |= BIT(2);
return snprintf(buf, PAGE_SIZE, "%x\n", mask); return sysfs_emit(buf, "%x\n", mask);
} }
static ssize_t static ssize_t
@ -80,7 +80,7 @@ show_rc6_ms(struct device *kdev, struct device_attribute *attr, char *buf)
{ {
struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev); struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
u32 rc6_residency = calc_residency(dev_priv, GEN6_GT_GFX_RC6); u32 rc6_residency = calc_residency(dev_priv, GEN6_GT_GFX_RC6);
return snprintf(buf, PAGE_SIZE, "%u\n", rc6_residency); return sysfs_emit(buf, "%u\n", rc6_residency);
} }
static ssize_t static ssize_t
@ -88,7 +88,7 @@ show_rc6p_ms(struct device *kdev, struct device_attribute *attr, char *buf)
{ {
struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev); struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
u32 rc6p_residency = calc_residency(dev_priv, GEN6_GT_GFX_RC6p); u32 rc6p_residency = calc_residency(dev_priv, GEN6_GT_GFX_RC6p);
return snprintf(buf, PAGE_SIZE, "%u\n", rc6p_residency); return sysfs_emit(buf, "%u\n", rc6p_residency);
} }
static ssize_t static ssize_t
@ -96,7 +96,7 @@ show_rc6pp_ms(struct device *kdev, struct device_attribute *attr, char *buf)
{ {
struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev); struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
u32 rc6pp_residency = calc_residency(dev_priv, GEN6_GT_GFX_RC6pp); u32 rc6pp_residency = calc_residency(dev_priv, GEN6_GT_GFX_RC6pp);
return snprintf(buf, PAGE_SIZE, "%u\n", rc6pp_residency); return sysfs_emit(buf, "%u\n", rc6pp_residency);
} }
static ssize_t static ssize_t
@ -104,7 +104,7 @@ show_media_rc6_ms(struct device *kdev, struct device_attribute *attr, char *buf)
{ {
struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev); struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
u32 rc6_residency = calc_residency(dev_priv, VLV_GT_MEDIA_RC6); u32 rc6_residency = calc_residency(dev_priv, VLV_GT_MEDIA_RC6);
return snprintf(buf, PAGE_SIZE, "%u\n", rc6_residency); return sysfs_emit(buf, "%u\n", rc6_residency);
} }
static DEVICE_ATTR(rc6_enable, S_IRUGO, show_rc6_mask, NULL); static DEVICE_ATTR(rc6_enable, S_IRUGO, show_rc6_mask, NULL);
@ -263,8 +263,7 @@ static ssize_t gt_act_freq_mhz_show(struct device *kdev,
struct drm_i915_private *i915 = kdev_minor_to_i915(kdev); struct drm_i915_private *i915 = kdev_minor_to_i915(kdev);
struct intel_rps *rps = &i915->gt.rps; struct intel_rps *rps = &i915->gt.rps;
return snprintf(buf, PAGE_SIZE, "%d\n", return sysfs_emit(buf, "%d\n", intel_rps_read_actual_frequency(rps));
intel_rps_read_actual_frequency(rps));
} }
static ssize_t gt_cur_freq_mhz_show(struct device *kdev, static ssize_t gt_cur_freq_mhz_show(struct device *kdev,
@ -273,8 +272,7 @@ static ssize_t gt_cur_freq_mhz_show(struct device *kdev,
struct drm_i915_private *i915 = kdev_minor_to_i915(kdev); struct drm_i915_private *i915 = kdev_minor_to_i915(kdev);
struct intel_rps *rps = &i915->gt.rps; struct intel_rps *rps = &i915->gt.rps;
return snprintf(buf, PAGE_SIZE, "%d\n", return sysfs_emit(buf, "%d\n", intel_gpu_freq(rps, rps->cur_freq));
intel_gpu_freq(rps, rps->cur_freq));
} }
static ssize_t gt_boost_freq_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf) static ssize_t gt_boost_freq_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf)
@ -282,8 +280,7 @@ static ssize_t gt_boost_freq_mhz_show(struct device *kdev, struct device_attribu
struct drm_i915_private *i915 = kdev_minor_to_i915(kdev); struct drm_i915_private *i915 = kdev_minor_to_i915(kdev);
struct intel_rps *rps = &i915->gt.rps; struct intel_rps *rps = &i915->gt.rps;
return snprintf(buf, PAGE_SIZE, "%d\n", return sysfs_emit(buf, "%d\n", intel_gpu_freq(rps, rps->boost_freq));
intel_gpu_freq(rps, rps->boost_freq));
} }
static ssize_t gt_boost_freq_mhz_store(struct device *kdev, static ssize_t gt_boost_freq_mhz_store(struct device *kdev,
@ -323,8 +320,7 @@ static ssize_t vlv_rpe_freq_mhz_show(struct device *kdev,
struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev); struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
struct intel_rps *rps = &dev_priv->gt.rps; struct intel_rps *rps = &dev_priv->gt.rps;
return snprintf(buf, PAGE_SIZE, "%d\n", return sysfs_emit(buf, "%d\n", intel_gpu_freq(rps, rps->efficient_freq));
intel_gpu_freq(rps, rps->efficient_freq));
} }
static ssize_t gt_max_freq_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf) static ssize_t gt_max_freq_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf)
@ -332,8 +328,7 @@ static ssize_t gt_max_freq_mhz_show(struct device *kdev, struct device_attribute
struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev); struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
struct intel_rps *rps = &dev_priv->gt.rps; struct intel_rps *rps = &dev_priv->gt.rps;
return snprintf(buf, PAGE_SIZE, "%d\n", return sysfs_emit(buf, "%d\n", intel_gpu_freq(rps, rps->max_freq_softlimit));
intel_gpu_freq(rps, rps->max_freq_softlimit));
} }
static ssize_t gt_max_freq_mhz_store(struct device *kdev, static ssize_t gt_max_freq_mhz_store(struct device *kdev,
@ -387,8 +382,7 @@ static ssize_t gt_min_freq_mhz_show(struct device *kdev, struct device_attribute
struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev); struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
struct intel_rps *rps = &dev_priv->gt.rps; struct intel_rps *rps = &dev_priv->gt.rps;
return snprintf(buf, PAGE_SIZE, "%d\n", return sysfs_emit(buf, "%d\n", intel_gpu_freq(rps, rps->min_freq_softlimit));
intel_gpu_freq(rps, rps->min_freq_softlimit));
} }
static ssize_t gt_min_freq_mhz_store(struct device *kdev, static ssize_t gt_min_freq_mhz_store(struct device *kdev,
@ -462,7 +456,7 @@ static ssize_t gt_rp_mhz_show(struct device *kdev, struct device_attribute *attr
else else
BUG(); BUG();
return snprintf(buf, PAGE_SIZE, "%d\n", val); return sysfs_emit(buf, "%d\n", val);
} }
static const struct attribute * const gen6_attrs[] = { static const struct attribute * const gen6_attrs[] = {

View file

@ -8,6 +8,7 @@
#include <drm/drm_drv.h> #include <drm/drm_drv.h>
#include "display/intel_crtc.h"
#include "display/intel_display_types.h" #include "display/intel_display_types.h"
#include "gt/intel_engine.h" #include "gt/intel_engine.h"
@ -474,6 +475,44 @@ TRACE_EVENT(intel_pipe_update_end,
__entry->scanline) __entry->scanline)
); );
/* frontbuffer tracking */
TRACE_EVENT(intel_frontbuffer_invalidate,
TP_PROTO(unsigned int frontbuffer_bits, unsigned int origin),
TP_ARGS(frontbuffer_bits, origin),
TP_STRUCT__entry(
__field(unsigned int, frontbuffer_bits)
__field(unsigned int, origin)
),
TP_fast_assign(
__entry->frontbuffer_bits = frontbuffer_bits;
__entry->origin = origin;
),
TP_printk("frontbuffer_bits=0x%08x, origin=%u",
__entry->frontbuffer_bits, __entry->origin)
);
TRACE_EVENT(intel_frontbuffer_flush,
TP_PROTO(unsigned int frontbuffer_bits, unsigned int origin),
TP_ARGS(frontbuffer_bits, origin),
TP_STRUCT__entry(
__field(unsigned int, frontbuffer_bits)
__field(unsigned int, origin)
),
TP_fast_assign(
__entry->frontbuffer_bits = frontbuffer_bits;
__entry->origin = origin;
),
TP_printk("frontbuffer_bits=0x%08x, origin=%u",
__entry->frontbuffer_bits, __entry->origin)
);
/* object tracking */ /* object tracking */
TRACE_EVENT(i915_gem_object_create, TRACE_EVENT(i915_gem_object_create,

View file

@ -418,6 +418,11 @@ static inline const char *onoff(bool v)
return v ? "on" : "off"; return v ? "on" : "off";
} }
static inline const char *enabledisable(bool v)
{
return v ? "enable" : "disable";
}
static inline const char *enableddisabled(bool v) static inline const char *enableddisabled(bool v)
{ {
return v ? "enabled" : "disabled"; return v ? "enabled" : "disabled";

View file

@ -286,4 +286,3 @@ struct i915_vma {
}; };
#endif #endif

View file

@ -67,6 +67,7 @@ static const char * const platform_names[] = {
PLATFORM_NAME(ROCKETLAKE), PLATFORM_NAME(ROCKETLAKE),
PLATFORM_NAME(DG1), PLATFORM_NAME(DG1),
PLATFORM_NAME(ALDERLAKE_S), PLATFORM_NAME(ALDERLAKE_S),
PLATFORM_NAME(ALDERLAKE_P),
}; };
#undef PLATFORM_NAME #undef PLATFORM_NAME
@ -95,7 +96,9 @@ static const char *iommu_name(void)
void intel_device_info_print_static(const struct intel_device_info *info, void intel_device_info_print_static(const struct intel_device_info *info,
struct drm_printer *p) struct drm_printer *p)
{ {
drm_printf(p, "gen: %d\n", info->gen); drm_printf(p, "graphics_ver: %u\n", info->graphics_ver);
drm_printf(p, "media_ver: %u\n", info->media_ver);
drm_printf(p, "display_ver: %u\n", info->display.ver);
drm_printf(p, "gt: %d\n", info->gt); drm_printf(p, "gt: %d\n", info->gt);
drm_printf(p, "iommu: %s\n", iommu_name()); drm_printf(p, "iommu: %s\n", iommu_name());
drm_printf(p, "memory-regions: %x\n", info->memory_regions); drm_printf(p, "memory-regions: %x\n", info->memory_regions);
@ -265,7 +268,7 @@ void intel_device_info_runtime_init(struct drm_i915_private *dev_priv)
BUILD_BUG_ON(BITS_PER_TYPE(intel_engine_mask_t) < I915_NUM_ENGINES); BUILD_BUG_ON(BITS_PER_TYPE(intel_engine_mask_t) < I915_NUM_ENGINES);
if (HAS_D12_PLANE_MINIMIZATION(dev_priv)) if (DISPLAY_VER(dev_priv) >= 13 || HAS_D12_PLANE_MINIMIZATION(dev_priv))
for_each_pipe(dev_priv, pipe) for_each_pipe(dev_priv, pipe)
runtime->num_sprites[pipe] = 4; runtime->num_sprites[pipe] = 4;
else if (INTEL_GEN(dev_priv) >= 11) else if (INTEL_GEN(dev_priv) >= 11)

View file

@ -87,6 +87,7 @@ enum intel_platform {
INTEL_ROCKETLAKE, INTEL_ROCKETLAKE,
INTEL_DG1, INTEL_DG1,
INTEL_ALDERLAKE_S, INTEL_ALDERLAKE_S,
INTEL_ALDERLAKE_P,
INTEL_MAX_PLATFORMS INTEL_MAX_PLATFORMS
}; };
@ -160,9 +161,9 @@ enum intel_ppgtt_type {
func(supports_tv); func(supports_tv);
struct intel_device_info { struct intel_device_info {
u16 gen_mask; u8 graphics_ver;
u8 media_ver;
u8 gen;
u8 gt; /* GT number, 0 if undefined */ u8 gt; /* GT number, 0 if undefined */
intel_engine_mask_t platform_engine_mask; /* Engines supported by the HW */ intel_engine_mask_t platform_engine_mask; /* Engines supported by the HW */
@ -189,15 +190,17 @@ struct intel_device_info {
#undef DEFINE_FLAG #undef DEFINE_FLAG
struct { struct {
u8 version; u8 ver;
#define DEFINE_FLAG(name) u8 name:1 #define DEFINE_FLAG(name) u8 name:1
DEV_INFO_DISPLAY_FOR_EACH_FLAG(DEFINE_FLAG); DEV_INFO_DISPLAY_FOR_EACH_FLAG(DEFINE_FLAG);
#undef DEFINE_FLAG #undef DEFINE_FLAG
} display; } display;
u16 ddb_size; /* in blocks */ struct {
u8 num_supported_dbuf_slices; /* number of DBuf slices */ u16 size; /* in blocks */
u8 slice_mask;
} dbuf;
/* Register offsets for the various display pipes and transcoders */ /* Register offsets for the various display pipes and transcoders */
int pipe_offsets[I915_MAX_TRANSCODERS]; int pipe_offsets[I915_MAX_TRANSCODERS];

View file

@ -130,8 +130,10 @@ intel_pch_type(const struct drm_i915_private *dev_priv, unsigned short id)
drm_WARN_ON(&dev_priv->drm, !IS_JSL_EHL(dev_priv)); drm_WARN_ON(&dev_priv->drm, !IS_JSL_EHL(dev_priv));
return PCH_JSP; return PCH_JSP;
case INTEL_PCH_ADP_DEVICE_ID_TYPE: case INTEL_PCH_ADP_DEVICE_ID_TYPE:
case INTEL_PCH_ADP2_DEVICE_ID_TYPE:
drm_dbg_kms(&dev_priv->drm, "Found Alder Lake PCH\n"); drm_dbg_kms(&dev_priv->drm, "Found Alder Lake PCH\n");
drm_WARN_ON(&dev_priv->drm, !IS_ALDERLAKE_S(dev_priv)); drm_WARN_ON(&dev_priv->drm, !IS_ALDERLAKE_S(dev_priv) &&
!IS_ALDERLAKE_P(dev_priv));
return PCH_ADP; return PCH_ADP;
default: default:
return PCH_NONE; return PCH_NONE;
@ -161,7 +163,7 @@ intel_virt_detect_pch(const struct drm_i915_private *dev_priv,
* make an educated guess as to which PCH is really there. * make an educated guess as to which PCH is really there.
*/ */
if (IS_ALDERLAKE_S(dev_priv)) if (IS_ALDERLAKE_S(dev_priv) || IS_ALDERLAKE_P(dev_priv))
id = INTEL_PCH_ADP_DEVICE_ID_TYPE; id = INTEL_PCH_ADP_DEVICE_ID_TYPE;
else if (IS_TIGERLAKE(dev_priv) || IS_ROCKETLAKE(dev_priv)) else if (IS_TIGERLAKE(dev_priv) || IS_ROCKETLAKE(dev_priv))
id = INTEL_PCH_TGP_DEVICE_ID_TYPE; id = INTEL_PCH_TGP_DEVICE_ID_TYPE;

View file

@ -55,6 +55,7 @@ enum intel_pch {
#define INTEL_PCH_JSP_DEVICE_ID_TYPE 0x4D80 #define INTEL_PCH_JSP_DEVICE_ID_TYPE 0x4D80
#define INTEL_PCH_JSP2_DEVICE_ID_TYPE 0x3880 #define INTEL_PCH_JSP2_DEVICE_ID_TYPE 0x3880
#define INTEL_PCH_ADP_DEVICE_ID_TYPE 0x7A80 #define INTEL_PCH_ADP_DEVICE_ID_TYPE 0x7A80
#define INTEL_PCH_ADP2_DEVICE_ID_TYPE 0x5180
#define INTEL_PCH_P2X_DEVICE_ID_TYPE 0x7100 #define INTEL_PCH_P2X_DEVICE_ID_TYPE 0x7100
#define INTEL_PCH_P3X_DEVICE_ID_TYPE 0x7000 #define INTEL_PCH_P3X_DEVICE_ID_TYPE 0x7000
#define INTEL_PCH_QEMU_DEVICE_ID_TYPE 0x2900 /* qemu q35 has 2918 */ #define INTEL_PCH_QEMU_DEVICE_ID_TYPE 0x2900 /* qemu q35 has 2918 */

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