mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-12 21:57:43 +00:00
- Hotplug code clean-up and organization (Jani, Gustavo)
- More VBT specific code clean-up, doc, organization, and improvements (Ville) - More MTL enabling work (Matt, RK, Anusha, Jose) - FBC related clean-ups and improvements (Ville) - Removing unused sw_fence_await_reservation (Niranjana) - Big chunch of display house clean-up (Ville) - Many Watermark fixes and clean-ups (Ville) - Fix device info for devices without display (Jani) - Fix TC port PLLs after readout (Ville) - DPLL ID clean-ups (Ville) - Prep work for finishing (de)gamma readout (Ville) - PSR fixes and improvements (Jouni, Jose) - Reject excessive dotclocks early (Ville) - DRRS related improvements (Ville) - Simplify uncore register updates (Andrzej) - Fix simulated GPU reset wrt. encoder HW readout (Imre) - Add a ADL-P workaround (Jose) - Fix clear mask in GEN7_MISCCPCTL update (Andrzej) - Temporarily disable runtime_pm for discrete (Anshuman) - Improve fbdev debugs (Nirmoy) - Fix DP FRL link training status (Ankit) - Other small display fixes (Ankit, Suraj) - Allow panel fixed modes to have differing sync polarities (Ville) - Clean up crtc state flag checks (Ville) - Fix race conditions during DKL PHY accesses (Imre) - Prep-work for cdclock squash and crawl modes (Anusha) - ELD precompute and readout (Ville) -----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEbSBwaO7dZQkcLOKj+mJfZA7rE8oFAmNcHTsACgkQ+mJfZA7r E8pXrwgAgYH8DQu+/C+gu4cB7wOQC+flrCAinCRaxE88q7iWDoQoY+XFdBLq9vEM QWNAmnUG53+z1rW1+EAVoIDhRz7yYnsxScLj/FijJl52hNNP3QkZP4iZuAMJyQy2 NYDOQyzvLBGmOIDgz+4YBtqk28eiX8x0+sYSA/JuLU5lL1zXFeXt2pFt2kcAnT/S Fe1MajA3TxLO9lAhnEzEUD3X/xLz5D/91BQS+7OL8n24Hxb9kBZ0N1UbwDOCDegc NEGpQmJTJnkGTAEQ8tlqnvMgHUbGmm3OEImamfC2QGvIdolF8zax9baNKoUts7BZ CaBDK2NK//W+sYl52Tig4pCv36bPdw== =91XL -----END PGP SIGNATURE----- Merge tag 'drm-intel-next-2022-10-28' of git://anongit.freedesktop.org/drm/drm-intel into drm-next - Hotplug code clean-up and organization (Jani, Gustavo) - More VBT specific code clean-up, doc, organization, and improvements (Ville) - More MTL enabling work (Matt, RK, Anusha, Jose) - FBC related clean-ups and improvements (Ville) - Removing unused sw_fence_await_reservation (Niranjana) - Big chunch of display house clean-up (Ville) - Many Watermark fixes and clean-ups (Ville) - Fix device info for devices without display (Jani) - Fix TC port PLLs after readout (Ville) - DPLL ID clean-ups (Ville) - Prep work for finishing (de)gamma readout (Ville) - PSR fixes and improvements (Jouni, Jose) - Reject excessive dotclocks early (Ville) - DRRS related improvements (Ville) - Simplify uncore register updates (Andrzej) - Fix simulated GPU reset wrt. encoder HW readout (Imre) - Add a ADL-P workaround (Jose) - Fix clear mask in GEN7_MISCCPCTL update (Andrzej) - Temporarily disable runtime_pm for discrete (Anshuman) - Improve fbdev debugs (Nirmoy) - Fix DP FRL link training status (Ankit) - Other small display fixes (Ankit, Suraj) - Allow panel fixed modes to have differing sync polarities (Ville) - Clean up crtc state flag checks (Ville) - Fix race conditions during DKL PHY accesses (Imre) - Prep-work for cdclock squash and crawl modes (Anusha) - ELD precompute and readout (Ville) Signed-off-by: Dave Airlie <airlied@redhat.com> From: Rodrigo Vivi <rodrigo.vivi@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/Y1wd6ZJ8LdJpCfZL@intel.com
This commit is contained in:
commit
f80c71f7a8
82 changed files with 2500 additions and 2096 deletions
|
@ -282,6 +282,7 @@ i915-y += \
|
|||
display/intel_ddi.o \
|
||||
display/intel_ddi_buf_trans.o \
|
||||
display/intel_display_trace.o \
|
||||
display/intel_dkl_phy.o \
|
||||
display/intel_dp.o \
|
||||
display/intel_dp_aux.o \
|
||||
display/intel_dp_aux_backlight.o \
|
||||
|
|
|
@ -585,7 +585,7 @@ void g4x_hdmi_init(struct drm_i915_private *dev_priv,
|
|||
} else {
|
||||
intel_encoder->pipe_mask = ~0;
|
||||
}
|
||||
intel_encoder->cloneable = 1 << INTEL_OUTPUT_ANALOG;
|
||||
intel_encoder->cloneable = BIT(INTEL_OUTPUT_ANALOG);
|
||||
intel_encoder->hpd_pin = intel_hpd_pin_default(dev_priv, port);
|
||||
/*
|
||||
* BSpec is unclear about HDMI+HDMI cloning on g4x, but it seems
|
||||
|
@ -593,7 +593,7 @@ void g4x_hdmi_init(struct drm_i915_private *dev_priv,
|
|||
* only one port anyway, nothing is lost by allowing it.
|
||||
*/
|
||||
if (IS_G4X(dev_priv))
|
||||
intel_encoder->cloneable |= 1 << INTEL_OUTPUT_HDMI;
|
||||
intel_encoder->cloneable |= BIT(INTEL_OUTPUT_HDMI);
|
||||
|
||||
dig_port->hdmi.hdmi_reg = hdmi_reg;
|
||||
dig_port->dp.output_reg = INVALID_MMIO_REG;
|
||||
|
|
|
@ -104,8 +104,7 @@ static bool hsw_ips_need_disable(struct intel_atomic_state *state,
|
|||
* Disable IPS before we program the LUT.
|
||||
*/
|
||||
if (IS_HASWELL(i915) &&
|
||||
(new_crtc_state->uapi.color_mgmt_changed ||
|
||||
new_crtc_state->update_pipe) &&
|
||||
intel_crtc_needs_color_update(new_crtc_state) &&
|
||||
new_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)
|
||||
return true;
|
||||
|
||||
|
@ -146,8 +145,7 @@ static bool hsw_ips_need_enable(struct intel_atomic_state *state,
|
|||
* Re-enable IPS after the LUT has been programmed.
|
||||
*/
|
||||
if (IS_HASWELL(i915) &&
|
||||
(new_crtc_state->uapi.color_mgmt_changed ||
|
||||
new_crtc_state->update_pipe) &&
|
||||
intel_crtc_needs_color_update(new_crtc_state) &&
|
||||
new_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)
|
||||
return true;
|
||||
|
||||
|
@ -155,7 +153,7 @@ static bool hsw_ips_need_enable(struct intel_atomic_state *state,
|
|||
* We can't read out IPS on broadwell, assume the worst and
|
||||
* forcibly enable IPS on the first fastset.
|
||||
*/
|
||||
if (new_crtc_state->update_pipe && old_crtc_state->inherited)
|
||||
if (intel_crtc_needs_fastset(new_crtc_state) && old_crtc_state->inherited)
|
||||
return true;
|
||||
|
||||
return !old_crtc_state->ips_enabled;
|
||||
|
|
|
@ -1974,16 +1974,8 @@ static void icl_dsi_add_properties(struct intel_connector *connector)
|
|||
{
|
||||
const struct drm_display_mode *fixed_mode =
|
||||
intel_panel_preferred_fixed_mode(connector);
|
||||
u32 allowed_scalers;
|
||||
|
||||
allowed_scalers = BIT(DRM_MODE_SCALE_ASPECT) |
|
||||
BIT(DRM_MODE_SCALE_FULLSCREEN) |
|
||||
BIT(DRM_MODE_SCALE_CENTER);
|
||||
|
||||
drm_connector_attach_scaling_mode_property(&connector->base,
|
||||
allowed_scalers);
|
||||
|
||||
connector->base.state->scaling_mode = DRM_MODE_SCALE_ASPECT;
|
||||
intel_attach_scaling_mode_property(&connector->base);
|
||||
|
||||
drm_connector_set_panel_orientation_with_quirk(&connector->base,
|
||||
intel_dsi_get_panel_orientation(connector),
|
||||
|
@ -1993,7 +1985,6 @@ static void icl_dsi_add_properties(struct intel_connector *connector)
|
|||
|
||||
void icl_dsi_init(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
struct intel_dsi *intel_dsi;
|
||||
struct intel_encoder *encoder;
|
||||
struct intel_connector *intel_connector;
|
||||
|
@ -2018,7 +2009,7 @@ void icl_dsi_init(struct drm_i915_private *dev_priv)
|
|||
connector = &intel_connector->base;
|
||||
|
||||
/* register DSI encoder with DRM subsystem */
|
||||
drm_encoder_init(dev, &encoder->base, &gen11_dsi_encoder_funcs,
|
||||
drm_encoder_init(&dev_priv->drm, &encoder->base, &gen11_dsi_encoder_funcs,
|
||||
DRM_MODE_ENCODER_DSI, "DSI %c", port_name(port));
|
||||
|
||||
encoder->pre_pll_enable = gen11_dsi_pre_pll_enable;
|
||||
|
@ -2042,12 +2033,10 @@ void icl_dsi_init(struct drm_i915_private *dev_priv)
|
|||
encoder->is_clock_enabled = gen11_dsi_is_clock_enabled;
|
||||
|
||||
/* register DSI connector with DRM subsystem */
|
||||
drm_connector_init(dev, connector, &gen11_dsi_connector_funcs,
|
||||
drm_connector_init(&dev_priv->drm, connector, &gen11_dsi_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_DSI);
|
||||
drm_connector_helper_add(connector, &gen11_dsi_connector_helper_funcs);
|
||||
connector->display_info.subpixel_order = SubPixelHorizontalRGB;
|
||||
connector->interlace_allowed = false;
|
||||
connector->doublescan_allowed = false;
|
||||
intel_connector->get_hw_state = intel_connector_get_hw_state;
|
||||
|
||||
/* attach connector to encoder */
|
||||
|
@ -2055,9 +2044,9 @@ void icl_dsi_init(struct drm_i915_private *dev_priv)
|
|||
|
||||
intel_bios_init_panel(dev_priv, &intel_connector->panel, NULL, NULL);
|
||||
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
mutex_lock(&dev_priv->drm.mode_config.mutex);
|
||||
intel_panel_add_vbt_lfp_fixed_mode(intel_connector);
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
mutex_unlock(&dev_priv->drm.mode_config.mutex);
|
||||
|
||||
if (!intel_panel_preferred_fixed_mode(intel_connector)) {
|
||||
drm_err(&dev_priv->drm, "DSI fixed mode info missing\n");
|
||||
|
|
|
@ -252,6 +252,11 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
|
|||
if (crtc_state->hw.gamma_lut)
|
||||
drm_property_blob_get(crtc_state->hw.gamma_lut);
|
||||
|
||||
if (crtc_state->pre_csc_lut)
|
||||
drm_property_blob_get(crtc_state->pre_csc_lut);
|
||||
if (crtc_state->post_csc_lut)
|
||||
drm_property_blob_get(crtc_state->post_csc_lut);
|
||||
|
||||
crtc_state->update_pipe = false;
|
||||
crtc_state->disable_lp_wm = false;
|
||||
crtc_state->disable_cxsr = false;
|
||||
|
@ -274,6 +279,9 @@ static void intel_crtc_put_color_blobs(struct intel_crtc_state *crtc_state)
|
|||
drm_property_blob_put(crtc_state->hw.degamma_lut);
|
||||
drm_property_blob_put(crtc_state->hw.gamma_lut);
|
||||
drm_property_blob_put(crtc_state->hw.ctm);
|
||||
|
||||
drm_property_blob_put(crtc_state->pre_csc_lut);
|
||||
drm_property_blob_put(crtc_state->post_csc_lut);
|
||||
}
|
||||
|
||||
void intel_crtc_free_hw_state(struct intel_crtc_state *crtc_state)
|
||||
|
|
|
@ -425,6 +425,47 @@ static bool intel_plane_do_async_flip(struct intel_plane *plane,
|
|||
return DISPLAY_VER(i915) < 13 || old_crtc_state->uapi.async_flip;
|
||||
}
|
||||
|
||||
static bool i9xx_must_disable_cxsr(const struct intel_crtc_state *new_crtc_state,
|
||||
const struct intel_plane_state *old_plane_state,
|
||||
const struct intel_plane_state *new_plane_state)
|
||||
{
|
||||
struct intel_plane *plane = to_intel_plane(new_plane_state->uapi.plane);
|
||||
bool old_visible = old_plane_state->uapi.visible;
|
||||
bool new_visible = new_plane_state->uapi.visible;
|
||||
u32 old_ctl = old_plane_state->ctl;
|
||||
u32 new_ctl = new_plane_state->ctl;
|
||||
bool modeset, turn_on, turn_off;
|
||||
|
||||
if (plane->id == PLANE_CURSOR)
|
||||
return false;
|
||||
|
||||
modeset = intel_crtc_needs_modeset(new_crtc_state);
|
||||
turn_off = old_visible && (!new_visible || modeset);
|
||||
turn_on = new_visible && (!old_visible || modeset);
|
||||
|
||||
/* Must disable CxSR around plane enable/disable */
|
||||
if (turn_on || turn_off)
|
||||
return true;
|
||||
|
||||
if (!old_visible || !new_visible)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Most plane control register updates are blocked while in CxSR.
|
||||
*
|
||||
* Tiling mode is one exception where the primary plane can
|
||||
* apparently handle it, whereas the sprites can not (the
|
||||
* sprite issue being only relevant on VLV/CHV where CxSR
|
||||
* is actually possible with a sprite enabled).
|
||||
*/
|
||||
if (plane->id == PLANE_PRIMARY) {
|
||||
old_ctl &= ~DISP_TILED;
|
||||
new_ctl &= ~DISP_TILED;
|
||||
}
|
||||
|
||||
return old_ctl != new_ctl;
|
||||
}
|
||||
|
||||
static int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_state,
|
||||
struct intel_crtc_state *new_crtc_state,
|
||||
const struct intel_plane_state *old_plane_state,
|
||||
|
@ -482,17 +523,9 @@ static int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_cr
|
|||
if (turn_on) {
|
||||
if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv))
|
||||
new_crtc_state->update_wm_pre = true;
|
||||
|
||||
/* must disable cxsr around plane enable/disable */
|
||||
if (plane->id != PLANE_CURSOR)
|
||||
new_crtc_state->disable_cxsr = true;
|
||||
} else if (turn_off) {
|
||||
if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv))
|
||||
new_crtc_state->update_wm_post = true;
|
||||
|
||||
/* must disable cxsr around plane enable/disable */
|
||||
if (plane->id != PLANE_CURSOR)
|
||||
new_crtc_state->disable_cxsr = true;
|
||||
} else if (intel_wm_need_update(old_plane_state, new_plane_state)) {
|
||||
if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv)) {
|
||||
/* FIXME bollocks */
|
||||
|
@ -504,6 +537,10 @@ static int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_cr
|
|||
if (visible || was_visible)
|
||||
new_crtc_state->fb_bits |= plane->frontbuffer_bit;
|
||||
|
||||
if (HAS_GMCH(dev_priv) &&
|
||||
i9xx_must_disable_cxsr(new_crtc_state, old_plane_state, new_plane_state))
|
||||
new_crtc_state->disable_cxsr = true;
|
||||
|
||||
/*
|
||||
* ILK/SNB DVSACNTR/Sprite Enable
|
||||
* IVB SPR_CTL/Sprite Enable
|
||||
|
@ -1005,7 +1042,7 @@ intel_prepare_plane_fb(struct drm_plane *_plane,
|
|||
*/
|
||||
if (intel_crtc_needs_modeset(crtc_state)) {
|
||||
ret = i915_sw_fence_await_reservation(&state->commit_ready,
|
||||
old_obj->base.resv, NULL,
|
||||
old_obj->base.resv,
|
||||
false, 0,
|
||||
GFP_KERNEL);
|
||||
if (ret < 0)
|
||||
|
@ -1039,8 +1076,7 @@ intel_prepare_plane_fb(struct drm_plane *_plane,
|
|||
struct dma_fence *fence;
|
||||
|
||||
ret = i915_sw_fence_await_reservation(&state->commit_ready,
|
||||
obj->base.resv, NULL,
|
||||
false,
|
||||
obj->base.resv, false,
|
||||
i915_fence_timeout(dev_priv),
|
||||
GFP_KERNEL);
|
||||
if (ret < 0)
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -8,16 +8,11 @@
|
|||
|
||||
#include "i915_reg_defs.h"
|
||||
|
||||
#define G4X_AUD_VID_DID _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x62020)
|
||||
#define INTEL_AUDIO_DEVCL 0x808629FB
|
||||
#define INTEL_AUDIO_DEVBLC 0x80862801
|
||||
#define INTEL_AUDIO_DEVCTG 0x80862802
|
||||
|
||||
#define G4X_AUD_CNTL_ST _MMIO(0x620B4)
|
||||
#define G4X_ELDV_DEVCL_DEVBLC (1 << 13)
|
||||
#define G4X_ELDV_DEVCTG (1 << 14)
|
||||
#define G4X_ELD_ADDR_MASK (0xf << 5)
|
||||
#define G4X_ELD_ACK (1 << 4)
|
||||
#define G4X_ELD_VALID REG_BIT(14)
|
||||
#define G4X_ELD_BUFFER_SIZE_MASK REG_GENMASK(13, 9)
|
||||
#define G4X_ELD_ADDRESS_MASK REG_GENMASK(8, 5)
|
||||
#define G4X_ELD_ACK REG_BIT(4)
|
||||
#define G4X_HDMIW_HDMIEDID _MMIO(0x6210C)
|
||||
|
||||
#define _IBX_HDMIW_HDMIEDID_A 0xE2050
|
||||
|
@ -28,12 +23,12 @@
|
|||
#define _IBX_AUD_CNTL_ST_B 0xE21B4
|
||||
#define IBX_AUD_CNTL_ST(pipe) _MMIO_PIPE(pipe, _IBX_AUD_CNTL_ST_A, \
|
||||
_IBX_AUD_CNTL_ST_B)
|
||||
#define IBX_ELD_BUFFER_SIZE_MASK (0x1f << 10)
|
||||
#define IBX_ELD_ADDRESS_MASK (0x1f << 5)
|
||||
#define IBX_ELD_ACK (1 << 4)
|
||||
#define IBX_ELD_BUFFER_SIZE_MASK REG_GENMASK(14, 10)
|
||||
#define IBX_ELD_ADDRESS_MASK REG_GENMASK(9, 5)
|
||||
#define IBX_ELD_ACK REG_BIT(4)
|
||||
#define IBX_AUD_CNTL_ST2 _MMIO(0xE20C0)
|
||||
#define IBX_CP_READY(port) ((1 << 1) << (((port) - 1) * 4))
|
||||
#define IBX_ELD_VALID(port) ((1 << 0) << (((port) - 1) * 4))
|
||||
#define IBX_CP_READY(port) REG_BIT(((port) - 1) * 4 + 1)
|
||||
#define IBX_ELD_VALID(port) REG_BIT(((port) - 1) * 4 + 0)
|
||||
|
||||
#define _CPT_HDMIW_HDMIEDID_A 0xE5050
|
||||
#define _CPT_HDMIW_HDMIEDID_B 0xE5150
|
||||
|
@ -60,34 +55,30 @@
|
|||
#define _VLV_AUD_CONFIG_A (VLV_DISPLAY_BASE + 0x62000)
|
||||
#define _VLV_AUD_CONFIG_B (VLV_DISPLAY_BASE + 0x62100)
|
||||
#define VLV_AUD_CFG(pipe) _MMIO_PIPE(pipe, _VLV_AUD_CONFIG_A, _VLV_AUD_CONFIG_B)
|
||||
|
||||
#define AUD_CONFIG_N_VALUE_INDEX (1 << 29)
|
||||
#define AUD_CONFIG_N_PROG_ENABLE (1 << 28)
|
||||
#define AUD_CONFIG_UPPER_N_SHIFT 20
|
||||
#define AUD_CONFIG_UPPER_N_MASK (0xff << 20)
|
||||
#define AUD_CONFIG_LOWER_N_SHIFT 4
|
||||
#define AUD_CONFIG_LOWER_N_MASK (0xfff << 4)
|
||||
#define AUD_CONFIG_N_MASK (AUD_CONFIG_UPPER_N_MASK | AUD_CONFIG_LOWER_N_MASK)
|
||||
#define AUD_CONFIG_N(n) \
|
||||
(((((n) >> 12) & 0xff) << AUD_CONFIG_UPPER_N_SHIFT) | \
|
||||
(((n) & 0xfff) << AUD_CONFIG_LOWER_N_SHIFT))
|
||||
#define AUD_CONFIG_PIXEL_CLOCK_HDMI_SHIFT 16
|
||||
#define AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK (0xf << 16)
|
||||
#define AUD_CONFIG_PIXEL_CLOCK_HDMI_25175 (0 << 16)
|
||||
#define AUD_CONFIG_PIXEL_CLOCK_HDMI_25200 (1 << 16)
|
||||
#define AUD_CONFIG_PIXEL_CLOCK_HDMI_27000 (2 << 16)
|
||||
#define AUD_CONFIG_PIXEL_CLOCK_HDMI_27027 (3 << 16)
|
||||
#define AUD_CONFIG_PIXEL_CLOCK_HDMI_54000 (4 << 16)
|
||||
#define AUD_CONFIG_PIXEL_CLOCK_HDMI_54054 (5 << 16)
|
||||
#define AUD_CONFIG_PIXEL_CLOCK_HDMI_74176 (6 << 16)
|
||||
#define AUD_CONFIG_PIXEL_CLOCK_HDMI_74250 (7 << 16)
|
||||
#define AUD_CONFIG_PIXEL_CLOCK_HDMI_148352 (8 << 16)
|
||||
#define AUD_CONFIG_PIXEL_CLOCK_HDMI_148500 (9 << 16)
|
||||
#define AUD_CONFIG_PIXEL_CLOCK_HDMI_296703 (10 << 16)
|
||||
#define AUD_CONFIG_PIXEL_CLOCK_HDMI_297000 (11 << 16)
|
||||
#define AUD_CONFIG_PIXEL_CLOCK_HDMI_593407 (12 << 16)
|
||||
#define AUD_CONFIG_PIXEL_CLOCK_HDMI_594000 (13 << 16)
|
||||
#define AUD_CONFIG_DISABLE_NCTS (1 << 3)
|
||||
#define AUD_CONFIG_N_VALUE_INDEX REG_BIT(29)
|
||||
#define AUD_CONFIG_N_PROG_ENABLE REG_BIT(28)
|
||||
#define AUD_CONFIG_UPPER_N_MASK REG_GENMASK(27, 20)
|
||||
#define AUD_CONFIG_LOWER_N_MASK REG_GENMASK(15, 4)
|
||||
#define AUD_CONFIG_N_MASK (AUD_CONFIG_UPPER_N_MASK | \
|
||||
AUD_CONFIG_LOWER_N_MASK)
|
||||
#define AUD_CONFIG_N(n) (REG_FIELD_PREP(AUD_CONFIG_UPPER_N_MASK, (n) >> 12) | \
|
||||
REG_FIELD_PREP(AUD_CONFIG_LOWER_N_MASK, (n) & 0xfff))
|
||||
#define AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK REG_GENMASK(19, 16)
|
||||
#define AUD_CONFIG_PIXEL_CLOCK_HDMI_25175 REG_FIELD_PREP(AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK, 0)
|
||||
#define AUD_CONFIG_PIXEL_CLOCK_HDMI_25200 REG_FIELD_PREP(AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK, 1)
|
||||
#define AUD_CONFIG_PIXEL_CLOCK_HDMI_27000 REG_FIELD_PREP(AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK, 2)
|
||||
#define AUD_CONFIG_PIXEL_CLOCK_HDMI_27027 REG_FIELD_PREP(AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK, 3)
|
||||
#define AUD_CONFIG_PIXEL_CLOCK_HDMI_54000 REG_FIELD_PREP(AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK, 4)
|
||||
#define AUD_CONFIG_PIXEL_CLOCK_HDMI_54054 REG_FIELD_PREP(AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK, 5)
|
||||
#define AUD_CONFIG_PIXEL_CLOCK_HDMI_74176 REG_FIELD_PREP(AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK, 6)
|
||||
#define AUD_CONFIG_PIXEL_CLOCK_HDMI_74250 REG_FIELD_PREP(AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK, 7)
|
||||
#define AUD_CONFIG_PIXEL_CLOCK_HDMI_148352 REG_FIELD_PREP(AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK, 8)
|
||||
#define AUD_CONFIG_PIXEL_CLOCK_HDMI_148500 REG_FIELD_PREP(AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK, 9)
|
||||
#define AUD_CONFIG_PIXEL_CLOCK_HDMI_296703 REG_FIELD_PREP(AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK, 10)
|
||||
#define AUD_CONFIG_PIXEL_CLOCK_HDMI_297000 REG_FIELD_PREP(AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK, 11)
|
||||
#define AUD_CONFIG_PIXEL_CLOCK_HDMI_593407 REG_FIELD_PREP(AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK, 12)
|
||||
#define AUD_CONFIG_PIXEL_CLOCK_HDMI_594000 REG_FIELD_PREP(AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK, 13)
|
||||
#define AUD_CONFIG_DISABLE_NCTS REG_BIT(3)
|
||||
|
||||
#define _HSW_AUD_CONFIG_A 0x65000
|
||||
#define _HSW_AUD_CONFIG_B 0x65100
|
||||
|
@ -100,9 +91,9 @@
|
|||
#define _HSW_AUD_M_CTS_ENABLE_A 0x65028
|
||||
#define _HSW_AUD_M_CTS_ENABLE_B 0x65128
|
||||
#define HSW_AUD_M_CTS_ENABLE(trans) _MMIO_TRANS(trans, _HSW_AUD_M_CTS_ENABLE_A, _HSW_AUD_M_CTS_ENABLE_B)
|
||||
#define AUD_M_CTS_M_VALUE_INDEX (1 << 21)
|
||||
#define AUD_M_CTS_M_PROG_ENABLE (1 << 20)
|
||||
#define AUD_CONFIG_M_MASK 0xfffff
|
||||
#define AUD_M_CTS_M_VALUE_INDEX REG_BIT(21)
|
||||
#define AUD_M_CTS_M_PROG_ENABLE REG_BIT(20)
|
||||
#define AUD_CONFIG_M_MASK REG_GENMASK(19, 0)
|
||||
|
||||
#define _HSW_AUD_DIP_ELD_CTRL_ST_A 0x650b4
|
||||
#define _HSW_AUD_DIP_ELD_CTRL_ST_B 0x651b4
|
||||
|
@ -130,11 +121,11 @@
|
|||
#define AUD_DP_2DOT0_CTRL(trans) _MMIO_TRANS(trans, _AUD_TCA_DP_2DOT0_CTRL, _AUD_TCB_DP_2DOT0_CTRL)
|
||||
#define AUD_ENABLE_SDP_SPLIT REG_BIT(31)
|
||||
|
||||
#define HSW_AUD_CHICKENBIT _MMIO(0x65f10)
|
||||
#define SKL_AUD_CODEC_WAKE_SIGNAL (1 << 15)
|
||||
#define HSW_AUD_CHICKENBIT _MMIO(0x65f10)
|
||||
#define SKL_AUD_CODEC_WAKE_SIGNAL REG_BIT(15)
|
||||
|
||||
#define AUD_FREQ_CNTRL _MMIO(0x65900)
|
||||
#define AUD_PIN_BUF_CTL _MMIO(0x48414)
|
||||
#define AUD_PIN_BUF_CTL _MMIO(0x48414)
|
||||
#define AUD_PIN_BUF_ENABLE REG_BIT(31)
|
||||
|
||||
#define AUD_TS_CDCLK_M _MMIO(0x65ea0)
|
||||
|
|
|
@ -2188,7 +2188,7 @@ static u8 map_ddc_pin(struct drm_i915_private *i915, u8 vbt_pin)
|
|||
const u8 *ddc_pin_map;
|
||||
int n_entries;
|
||||
|
||||
if (IS_ALDERLAKE_P(i915)) {
|
||||
if (HAS_PCH_MTP(i915) || IS_ALDERLAKE_P(i915)) {
|
||||
ddc_pin_map = adlp_ddc_pin_map;
|
||||
n_entries = ARRAY_SIZE(adlp_ddc_pin_map);
|
||||
} else if (IS_ALDERLAKE_S(i915)) {
|
||||
|
@ -2676,6 +2676,14 @@ static void print_ddi_port(const struct intel_bios_encoder_data *devdata,
|
|||
drm_dbg_kms(&i915->drm,
|
||||
"Port %c VBT DP max link rate: %d\n",
|
||||
port_name(port), dp_max_link_rate);
|
||||
|
||||
/*
|
||||
* FIXME need to implement support for VBT
|
||||
* vswing/preemph tables should this ever trigger.
|
||||
*/
|
||||
drm_WARN(&i915->drm, child->use_vbt_vswing,
|
||||
"Port %c asks to use VBT vswing/preemph tables\n",
|
||||
port_name(port));
|
||||
}
|
||||
|
||||
static void parse_ddi_port(struct intel_bios_encoder_data *devdata)
|
||||
|
|
|
@ -1220,11 +1220,6 @@ static void skl_cdclk_uninit_hw(struct drm_i915_private *dev_priv)
|
|||
skl_set_cdclk(dev_priv, &cdclk_config, INVALID_PIPE);
|
||||
}
|
||||
|
||||
static bool has_cdclk_squasher(struct drm_i915_private *i915)
|
||||
{
|
||||
return IS_DG2(i915);
|
||||
}
|
||||
|
||||
struct intel_cdclk_vals {
|
||||
u32 cdclk;
|
||||
u16 refclk;
|
||||
|
@ -1520,7 +1515,7 @@ static void bxt_get_cdclk(struct drm_i915_private *dev_priv,
|
|||
return;
|
||||
}
|
||||
|
||||
if (has_cdclk_squasher(dev_priv))
|
||||
if (HAS_CDCLK_SQUASH(dev_priv))
|
||||
squash_ctl = intel_de_read(dev_priv, CDCLK_SQUASH_CTL);
|
||||
|
||||
if (squash_ctl & CDCLK_SQUASH_ENABLE) {
|
||||
|
@ -1689,6 +1684,38 @@ static u32 cdclk_squash_waveform(struct drm_i915_private *dev_priv,
|
|||
return 0xffff;
|
||||
}
|
||||
|
||||
static void icl_cdclk_pll_update(struct drm_i915_private *i915, int vco)
|
||||
{
|
||||
if (i915->display.cdclk.hw.vco != 0 &&
|
||||
i915->display.cdclk.hw.vco != vco)
|
||||
icl_cdclk_pll_disable(i915);
|
||||
|
||||
if (i915->display.cdclk.hw.vco != vco)
|
||||
icl_cdclk_pll_enable(i915, vco);
|
||||
}
|
||||
|
||||
static void bxt_cdclk_pll_update(struct drm_i915_private *i915, int vco)
|
||||
{
|
||||
if (i915->display.cdclk.hw.vco != 0 &&
|
||||
i915->display.cdclk.hw.vco != vco)
|
||||
bxt_de_pll_disable(i915);
|
||||
|
||||
if (i915->display.cdclk.hw.vco != vco)
|
||||
bxt_de_pll_enable(i915, vco);
|
||||
}
|
||||
|
||||
static void dg2_cdclk_squash_program(struct drm_i915_private *i915,
|
||||
u16 waveform)
|
||||
{
|
||||
u32 squash_ctl = 0;
|
||||
|
||||
if (waveform)
|
||||
squash_ctl = CDCLK_SQUASH_ENABLE |
|
||||
CDCLK_SQUASH_WINDOW_SIZE(0xf) | waveform;
|
||||
|
||||
intel_de_write(i915, CDCLK_SQUASH_CTL, squash_ctl);
|
||||
}
|
||||
|
||||
static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
|
||||
const struct intel_cdclk_config *cdclk_config,
|
||||
enum pipe pipe)
|
||||
|
@ -1724,21 +1751,10 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
|
|||
if (HAS_CDCLK_CRAWL(dev_priv) && dev_priv->display.cdclk.hw.vco > 0 && vco > 0) {
|
||||
if (dev_priv->display.cdclk.hw.vco != vco)
|
||||
adlp_cdclk_pll_crawl(dev_priv, vco);
|
||||
} else if (DISPLAY_VER(dev_priv) >= 11) {
|
||||
if (dev_priv->display.cdclk.hw.vco != 0 &&
|
||||
dev_priv->display.cdclk.hw.vco != vco)
|
||||
icl_cdclk_pll_disable(dev_priv);
|
||||
|
||||
if (dev_priv->display.cdclk.hw.vco != vco)
|
||||
icl_cdclk_pll_enable(dev_priv, vco);
|
||||
} else {
|
||||
if (dev_priv->display.cdclk.hw.vco != 0 &&
|
||||
dev_priv->display.cdclk.hw.vco != vco)
|
||||
bxt_de_pll_disable(dev_priv);
|
||||
|
||||
if (dev_priv->display.cdclk.hw.vco != vco)
|
||||
bxt_de_pll_enable(dev_priv, vco);
|
||||
}
|
||||
} else if (DISPLAY_VER(dev_priv) >= 11)
|
||||
icl_cdclk_pll_update(dev_priv, vco);
|
||||
else
|
||||
bxt_cdclk_pll_update(dev_priv, vco);
|
||||
|
||||
waveform = cdclk_squash_waveform(dev_priv, cdclk);
|
||||
|
||||
|
@ -1747,15 +1763,8 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
|
|||
else
|
||||
clock = cdclk;
|
||||
|
||||
if (has_cdclk_squasher(dev_priv)) {
|
||||
u32 squash_ctl = 0;
|
||||
|
||||
if (waveform)
|
||||
squash_ctl = CDCLK_SQUASH_ENABLE |
|
||||
CDCLK_SQUASH_WINDOW_SIZE(0xf) | waveform;
|
||||
|
||||
intel_de_write(dev_priv, CDCLK_SQUASH_CTL, squash_ctl);
|
||||
}
|
||||
if (HAS_CDCLK_SQUASH(dev_priv))
|
||||
dg2_cdclk_squash_program(dev_priv, waveform);
|
||||
|
||||
val = bxt_cdclk_cd2x_div_sel(dev_priv, clock, vco) |
|
||||
bxt_cdclk_cd2x_pipe(dev_priv, pipe) |
|
||||
|
@ -1845,7 +1854,7 @@ static void bxt_sanitize_cdclk(struct drm_i915_private *dev_priv)
|
|||
expected = skl_cdclk_decimal(cdclk);
|
||||
|
||||
/* Figure out what CD2X divider we should be using for this cdclk */
|
||||
if (has_cdclk_squasher(dev_priv))
|
||||
if (HAS_CDCLK_SQUASH(dev_priv))
|
||||
clock = dev_priv->display.cdclk.hw.vco / 2;
|
||||
else
|
||||
clock = dev_priv->display.cdclk.hw.cdclk;
|
||||
|
@ -1976,7 +1985,7 @@ static bool intel_cdclk_can_squash(struct drm_i915_private *dev_priv,
|
|||
* the moment all platforms with squasher use a fixed cd2x
|
||||
* divider.
|
||||
*/
|
||||
if (!has_cdclk_squasher(dev_priv))
|
||||
if (!HAS_CDCLK_SQUASH(dev_priv))
|
||||
return false;
|
||||
|
||||
return a->cdclk != b->cdclk &&
|
||||
|
@ -2028,7 +2037,7 @@ static bool intel_cdclk_can_cd2x_update(struct drm_i915_private *dev_priv,
|
|||
* the moment all platforms with squasher use a fixed cd2x
|
||||
* divider.
|
||||
*/
|
||||
if (has_cdclk_squasher(dev_priv))
|
||||
if (HAS_CDCLK_SQUASH(dev_priv))
|
||||
return false;
|
||||
|
||||
return a->cdclk != b->cdclk &&
|
||||
|
@ -2464,10 +2473,6 @@ static int bdw_modeset_calc_cdclk(struct intel_cdclk_state *cdclk_state)
|
|||
if (min_cdclk < 0)
|
||||
return min_cdclk;
|
||||
|
||||
/*
|
||||
* FIXME should also account for plane ratio
|
||||
* once 64bpp pixel formats are supported.
|
||||
*/
|
||||
cdclk = bdw_calc_cdclk(min_cdclk);
|
||||
|
||||
cdclk_state->logical.cdclk = cdclk;
|
||||
|
@ -2534,10 +2539,6 @@ static int skl_modeset_calc_cdclk(struct intel_cdclk_state *cdclk_state)
|
|||
|
||||
vco = skl_dpll0_vco(cdclk_state);
|
||||
|
||||
/*
|
||||
* FIXME should also account for plane ratio
|
||||
* once 64bpp pixel formats are supported.
|
||||
*/
|
||||
cdclk = skl_calc_cdclk(min_cdclk, vco);
|
||||
|
||||
cdclk_state->logical.vco = vco;
|
||||
|
@ -2762,12 +2763,12 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state)
|
|||
&old_cdclk_state->actual,
|
||||
&new_cdclk_state->actual)) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"Can change cdclk via squasher\n");
|
||||
"Can change cdclk via squashing\n");
|
||||
} else if (intel_cdclk_can_crawl(dev_priv,
|
||||
&old_cdclk_state->actual,
|
||||
&new_cdclk_state->actual)) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"Can change cdclk via crawl\n");
|
||||
"Can change cdclk via crawling\n");
|
||||
} else if (pipe != INVALID_PIPE) {
|
||||
new_cdclk_state->pipe = pipe;
|
||||
|
||||
|
@ -2777,7 +2778,7 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state)
|
|||
} else if (intel_cdclk_needs_modeset(&old_cdclk_state->actual,
|
||||
&new_cdclk_state->actual)) {
|
||||
/* All pipes must be switched off while we change the cdclk. */
|
||||
ret = intel_modeset_all_pipes(state);
|
||||
ret = intel_modeset_all_pipes(state, "CDCLK change");
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -25,9 +25,7 @@
|
|||
#include "intel_color.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dpll.h"
|
||||
#include "intel_dsb.h"
|
||||
#include "vlv_dsi_pll.h"
|
||||
|
||||
struct intel_color_funcs {
|
||||
int (*color_check)(struct intel_crtc_state *crtc_state);
|
||||
|
@ -559,6 +557,32 @@ static void skl_color_commit_arm(const struct intel_crtc_state *crtc_state)
|
|||
crtc_state->csc_mode);
|
||||
}
|
||||
|
||||
static struct drm_property_blob *
|
||||
create_linear_lut(struct drm_i915_private *i915, int lut_size)
|
||||
{
|
||||
struct drm_property_blob *blob;
|
||||
struct drm_color_lut *lut;
|
||||
int i;
|
||||
|
||||
blob = drm_property_create_blob(&i915->drm,
|
||||
sizeof(struct drm_color_lut) * lut_size,
|
||||
NULL);
|
||||
if (IS_ERR(blob))
|
||||
return blob;
|
||||
|
||||
lut = blob->data;
|
||||
|
||||
for (i = 0; i < lut_size; i++) {
|
||||
u16 val = 0xffff * i / (lut_size - 1);
|
||||
|
||||
lut[i].red = val;
|
||||
lut[i].green = val;
|
||||
lut[i].blue = val;
|
||||
}
|
||||
|
||||
return blob;
|
||||
}
|
||||
|
||||
static void i9xx_load_lut_8(struct intel_crtc *crtc,
|
||||
const struct drm_property_blob *blob)
|
||||
{
|
||||
|
@ -580,12 +604,9 @@ static void i9xx_load_lut_8(struct intel_crtc *crtc,
|
|||
static void i9xx_load_luts(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);
|
||||
const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
|
||||
const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
|
||||
|
||||
assert_pll_enabled(dev_priv, crtc->pipe);
|
||||
|
||||
i9xx_load_lut_8(crtc, gamma_lut);
|
||||
i9xx_load_lut_8(crtc, post_csc_lut);
|
||||
}
|
||||
|
||||
static void i965_load_lut_10p6(struct intel_crtc *crtc,
|
||||
|
@ -611,18 +632,12 @@ static void i965_load_lut_10p6(struct intel_crtc *crtc,
|
|||
static void i965_load_luts(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);
|
||||
const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
|
||||
|
||||
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI))
|
||||
assert_dsi_pll_enabled(dev_priv);
|
||||
else
|
||||
assert_pll_enabled(dev_priv, crtc->pipe);
|
||||
const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
|
||||
|
||||
if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
|
||||
i9xx_load_lut_8(crtc, gamma_lut);
|
||||
i9xx_load_lut_8(crtc, post_csc_lut);
|
||||
else
|
||||
i965_load_lut_10p6(crtc, gamma_lut);
|
||||
i965_load_lut_10p6(crtc, post_csc_lut);
|
||||
}
|
||||
|
||||
static void ilk_load_lut_8(struct intel_crtc *crtc,
|
||||
|
@ -659,14 +674,16 @@ static void ilk_load_lut_10(struct intel_crtc *crtc,
|
|||
static void ilk_load_luts(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
|
||||
const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
|
||||
const struct drm_property_blob *pre_csc_lut = crtc_state->pre_csc_lut;
|
||||
const struct drm_property_blob *blob = post_csc_lut ?: pre_csc_lut;
|
||||
|
||||
switch (crtc_state->gamma_mode) {
|
||||
case GAMMA_MODE_MODE_8BIT:
|
||||
ilk_load_lut_8(crtc, gamma_lut);
|
||||
ilk_load_lut_8(crtc, blob);
|
||||
break;
|
||||
case GAMMA_MODE_MODE_10BIT:
|
||||
ilk_load_lut_10(crtc, gamma_lut);
|
||||
ilk_load_lut_10(crtc, blob);
|
||||
break;
|
||||
default:
|
||||
MISSING_CASE(crtc_state->gamma_mode);
|
||||
|
@ -773,19 +790,19 @@ static void ivb_load_lut_ext_max(const struct intel_crtc_state *crtc_state)
|
|||
static void ivb_load_luts(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
|
||||
const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
|
||||
const struct drm_property_blob *blob = gamma_lut ?: degamma_lut;
|
||||
const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
|
||||
const struct drm_property_blob *pre_csc_lut = crtc_state->pre_csc_lut;
|
||||
const struct drm_property_blob *blob = post_csc_lut ?: pre_csc_lut;
|
||||
|
||||
switch (crtc_state->gamma_mode) {
|
||||
case GAMMA_MODE_MODE_8BIT:
|
||||
ilk_load_lut_8(crtc, blob);
|
||||
break;
|
||||
case GAMMA_MODE_MODE_SPLIT:
|
||||
ivb_load_lut_10(crtc, degamma_lut, PAL_PREC_SPLIT_MODE |
|
||||
ivb_load_lut_10(crtc, pre_csc_lut, PAL_PREC_SPLIT_MODE |
|
||||
PAL_PREC_INDEX_VALUE(0));
|
||||
ivb_load_lut_ext_max(crtc_state);
|
||||
ivb_load_lut_10(crtc, gamma_lut, PAL_PREC_SPLIT_MODE |
|
||||
ivb_load_lut_10(crtc, post_csc_lut, PAL_PREC_SPLIT_MODE |
|
||||
PAL_PREC_INDEX_VALUE(512));
|
||||
break;
|
||||
case GAMMA_MODE_MODE_10BIT:
|
||||
|
@ -802,19 +819,19 @@ static void ivb_load_luts(const struct intel_crtc_state *crtc_state)
|
|||
static void bdw_load_luts(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
|
||||
const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
|
||||
const struct drm_property_blob *blob = gamma_lut ?: degamma_lut;
|
||||
const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
|
||||
const struct drm_property_blob *pre_csc_lut = crtc_state->pre_csc_lut;
|
||||
const struct drm_property_blob *blob = post_csc_lut ?: pre_csc_lut;
|
||||
|
||||
switch (crtc_state->gamma_mode) {
|
||||
case GAMMA_MODE_MODE_8BIT:
|
||||
ilk_load_lut_8(crtc, blob);
|
||||
break;
|
||||
case GAMMA_MODE_MODE_SPLIT:
|
||||
bdw_load_lut_10(crtc, degamma_lut, PAL_PREC_SPLIT_MODE |
|
||||
bdw_load_lut_10(crtc, pre_csc_lut, PAL_PREC_SPLIT_MODE |
|
||||
PAL_PREC_INDEX_VALUE(0));
|
||||
ivb_load_lut_ext_max(crtc_state);
|
||||
bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_SPLIT_MODE |
|
||||
bdw_load_lut_10(crtc, post_csc_lut, PAL_PREC_SPLIT_MODE |
|
||||
PAL_PREC_INDEX_VALUE(512));
|
||||
break;
|
||||
case GAMMA_MODE_MODE_10BIT:
|
||||
|
@ -837,13 +854,14 @@ static int glk_degamma_lut_size(struct drm_i915_private *i915)
|
|||
return 35;
|
||||
}
|
||||
|
||||
static void glk_load_degamma_lut(const struct intel_crtc_state *crtc_state)
|
||||
static void glk_load_degamma_lut(const struct intel_crtc_state *crtc_state,
|
||||
const struct drm_property_blob *blob)
|
||||
{
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||
const struct drm_color_lut *lut = blob->data;
|
||||
int i, lut_size = drm_color_lut_size(blob);
|
||||
enum pipe pipe = crtc->pipe;
|
||||
int i, lut_size = INTEL_INFO(dev_priv)->display.color.degamma_lut_size;
|
||||
const struct drm_color_lut *lut = crtc_state->hw.degamma_lut->data;
|
||||
|
||||
/*
|
||||
* When setting the auto-increment bit, the hardware seems to
|
||||
|
@ -879,59 +897,21 @@ static void glk_load_degamma_lut(const struct intel_crtc_state *crtc_state)
|
|||
intel_de_write_fw(dev_priv, PRE_CSC_GAMC_INDEX(pipe), 0);
|
||||
}
|
||||
|
||||
static void glk_load_degamma_lut_linear(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);
|
||||
enum pipe pipe = crtc->pipe;
|
||||
int i, lut_size = INTEL_INFO(dev_priv)->display.color.degamma_lut_size;
|
||||
|
||||
/*
|
||||
* When setting the auto-increment bit, the hardware seems to
|
||||
* ignore the index bits, so we need to reset it to index 0
|
||||
* separately.
|
||||
*/
|
||||
intel_de_write_fw(dev_priv, PRE_CSC_GAMC_INDEX(pipe), 0);
|
||||
intel_de_write_fw(dev_priv, PRE_CSC_GAMC_INDEX(pipe),
|
||||
PRE_CSC_GAMC_AUTO_INCREMENT);
|
||||
|
||||
for (i = 0; i < lut_size; i++) {
|
||||
u32 v = (i << 16) / (lut_size - 1);
|
||||
|
||||
intel_de_write_fw(dev_priv, PRE_CSC_GAMC_DATA(pipe), v);
|
||||
}
|
||||
|
||||
/* Clamp values > 1.0. */
|
||||
while (i++ < 35)
|
||||
intel_de_write_fw(dev_priv, PRE_CSC_GAMC_DATA(pipe), 1 << 16);
|
||||
|
||||
intel_de_write_fw(dev_priv, PRE_CSC_GAMC_INDEX(pipe), 0);
|
||||
}
|
||||
|
||||
static void glk_load_luts(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
|
||||
const struct drm_property_blob *pre_csc_lut = crtc_state->pre_csc_lut;
|
||||
const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
|
||||
/*
|
||||
* On GLK+ both pipe CSC and degamma LUT are controlled
|
||||
* by csc_enable. Hence for the cases where the CSC is
|
||||
* needed but degamma LUT is not we need to load a
|
||||
* linear degamma LUT. In fact we'll just always load
|
||||
* the degama LUT so that we don't have to reload
|
||||
* it every time the pipe CSC is being enabled.
|
||||
*/
|
||||
if (crtc_state->hw.degamma_lut)
|
||||
glk_load_degamma_lut(crtc_state);
|
||||
else
|
||||
glk_load_degamma_lut_linear(crtc_state);
|
||||
if (pre_csc_lut)
|
||||
glk_load_degamma_lut(crtc_state, pre_csc_lut);
|
||||
|
||||
switch (crtc_state->gamma_mode) {
|
||||
case GAMMA_MODE_MODE_8BIT:
|
||||
ilk_load_lut_8(crtc, gamma_lut);
|
||||
ilk_load_lut_8(crtc, post_csc_lut);
|
||||
break;
|
||||
case GAMMA_MODE_MODE_10BIT:
|
||||
bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0));
|
||||
bdw_load_lut_10(crtc, post_csc_lut, PAL_PREC_INDEX_VALUE(0));
|
||||
ivb_load_lut_ext_max(crtc_state);
|
||||
break;
|
||||
default:
|
||||
|
@ -971,7 +951,7 @@ static void
|
|||
icl_program_gamma_superfine_segment(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
const struct drm_property_blob *blob = crtc_state->hw.gamma_lut;
|
||||
const struct drm_property_blob *blob = crtc_state->post_csc_lut;
|
||||
const struct drm_color_lut *lut = blob->data;
|
||||
enum pipe pipe = crtc->pipe;
|
||||
int i;
|
||||
|
@ -1000,7 +980,7 @@ static void
|
|||
icl_program_gamma_multi_segment(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
const struct drm_property_blob *blob = crtc_state->hw.gamma_lut;
|
||||
const struct drm_property_blob *blob = crtc_state->post_csc_lut;
|
||||
const struct drm_color_lut *lut = blob->data;
|
||||
const struct drm_color_lut *entry;
|
||||
enum pipe pipe = crtc->pipe;
|
||||
|
@ -1054,22 +1034,23 @@ icl_program_gamma_multi_segment(const struct intel_crtc_state *crtc_state)
|
|||
|
||||
static void icl_load_luts(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
|
||||
const struct drm_property_blob *pre_csc_lut = crtc_state->pre_csc_lut;
|
||||
const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
|
||||
if (crtc_state->hw.degamma_lut)
|
||||
glk_load_degamma_lut(crtc_state);
|
||||
if (pre_csc_lut)
|
||||
glk_load_degamma_lut(crtc_state, pre_csc_lut);
|
||||
|
||||
switch (crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) {
|
||||
case GAMMA_MODE_MODE_8BIT:
|
||||
ilk_load_lut_8(crtc, gamma_lut);
|
||||
ilk_load_lut_8(crtc, post_csc_lut);
|
||||
break;
|
||||
case GAMMA_MODE_MODE_12BIT_MULTI_SEGMENTED:
|
||||
icl_program_gamma_superfine_segment(crtc_state);
|
||||
icl_program_gamma_multi_segment(crtc_state);
|
||||
break;
|
||||
case GAMMA_MODE_MODE_10BIT:
|
||||
bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0));
|
||||
bdw_load_lut_10(crtc, post_csc_lut, PAL_PREC_INDEX_VALUE(0));
|
||||
ivb_load_lut_ext_max(crtc_state);
|
||||
break;
|
||||
default:
|
||||
|
@ -1145,18 +1126,18 @@ static void chv_load_luts(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);
|
||||
const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
|
||||
const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
|
||||
const struct drm_property_blob *pre_csc_lut = crtc_state->pre_csc_lut;
|
||||
const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
|
||||
const struct drm_property_blob *ctm = crtc_state->hw.ctm;
|
||||
|
||||
if (crtc_state->cgm_mode & CGM_PIPE_MODE_CSC)
|
||||
chv_load_cgm_csc(crtc, ctm);
|
||||
|
||||
if (crtc_state->cgm_mode & CGM_PIPE_MODE_DEGAMMA)
|
||||
chv_load_cgm_degamma(crtc, degamma_lut);
|
||||
chv_load_cgm_degamma(crtc, pre_csc_lut);
|
||||
|
||||
if (crtc_state->cgm_mode & CGM_PIPE_MODE_GAMMA)
|
||||
chv_load_cgm_gamma(crtc, gamma_lut);
|
||||
chv_load_cgm_gamma(crtc, post_csc_lut);
|
||||
else
|
||||
i965_load_luts(crtc_state);
|
||||
|
||||
|
@ -1194,8 +1175,8 @@ static bool intel_can_preload_luts(const struct intel_crtc_state *new_crtc_state
|
|||
const struct intel_crtc_state *old_crtc_state =
|
||||
intel_atomic_get_old_crtc_state(state, crtc);
|
||||
|
||||
return !old_crtc_state->hw.gamma_lut &&
|
||||
!old_crtc_state->hw.degamma_lut;
|
||||
return !old_crtc_state->post_csc_lut &&
|
||||
!old_crtc_state->pre_csc_lut;
|
||||
}
|
||||
|
||||
static bool chv_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
|
||||
|
@ -1214,25 +1195,7 @@ static bool chv_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
|
|||
if (old_crtc_state->cgm_mode || new_crtc_state->cgm_mode)
|
||||
return false;
|
||||
|
||||
return !old_crtc_state->hw.gamma_lut;
|
||||
}
|
||||
|
||||
static bool glk_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
|
||||
{
|
||||
struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
|
||||
struct intel_atomic_state *state =
|
||||
to_intel_atomic_state(new_crtc_state->uapi.state);
|
||||
const struct intel_crtc_state *old_crtc_state =
|
||||
intel_atomic_get_old_crtc_state(state, crtc);
|
||||
|
||||
/*
|
||||
* The hardware degamma is active whenever the pipe
|
||||
* CSC is active. Thus even if the old state has no
|
||||
* software degamma we need to avoid clobbering the
|
||||
* linear hardware degamma mid scanout.
|
||||
*/
|
||||
return !old_crtc_state->csc_enable &&
|
||||
!old_crtc_state->hw.gamma_lut;
|
||||
return !old_crtc_state->post_csc_lut;
|
||||
}
|
||||
|
||||
int intel_color_check(struct intel_crtc_state *crtc_state)
|
||||
|
@ -1295,6 +1258,10 @@ intel_color_add_affected_planes(struct intel_crtc_state *new_crtc_state)
|
|||
return PTR_ERR(plane_state);
|
||||
|
||||
new_crtc_state->update_planes |= BIT(plane->id);
|
||||
|
||||
/* plane control register changes blocked by CxSR */
|
||||
if (HAS_GMCH(dev_priv))
|
||||
new_crtc_state->disable_cxsr = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1361,6 +1328,40 @@ static u32 i9xx_gamma_mode(struct intel_crtc_state *crtc_state)
|
|||
return GAMMA_MODE_MODE_10BIT; /* i965+ only */
|
||||
}
|
||||
|
||||
void intel_color_assert_luts(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
|
||||
|
||||
/* make sure {pre,post}_csc_lut were correctly assigned */
|
||||
if (DISPLAY_VER(i915) >= 11 || HAS_GMCH(i915)) {
|
||||
drm_WARN_ON(&i915->drm,
|
||||
crtc_state->pre_csc_lut != crtc_state->hw.degamma_lut);
|
||||
drm_WARN_ON(&i915->drm,
|
||||
crtc_state->post_csc_lut != crtc_state->hw.gamma_lut);
|
||||
} else if (DISPLAY_VER(i915) == 10) {
|
||||
drm_WARN_ON(&i915->drm,
|
||||
crtc_state->pre_csc_lut != crtc_state->hw.degamma_lut &&
|
||||
crtc_state->pre_csc_lut != i915->display.color.glk_linear_degamma_lut);
|
||||
drm_WARN_ON(&i915->drm,
|
||||
crtc_state->post_csc_lut != crtc_state->hw.gamma_lut);
|
||||
} else {
|
||||
drm_WARN_ON(&i915->drm,
|
||||
crtc_state->pre_csc_lut != crtc_state->hw.degamma_lut &&
|
||||
crtc_state->pre_csc_lut != crtc_state->hw.gamma_lut);
|
||||
drm_WARN_ON(&i915->drm,
|
||||
crtc_state->post_csc_lut != crtc_state->hw.degamma_lut &&
|
||||
crtc_state->post_csc_lut != crtc_state->hw.gamma_lut);
|
||||
}
|
||||
}
|
||||
|
||||
static void intel_assign_luts(struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
drm_property_replace_blob(&crtc_state->pre_csc_lut,
|
||||
crtc_state->hw.degamma_lut);
|
||||
drm_property_replace_blob(&crtc_state->post_csc_lut,
|
||||
crtc_state->hw.gamma_lut);
|
||||
}
|
||||
|
||||
static int i9xx_color_check(struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
int ret;
|
||||
|
@ -1379,6 +1380,8 @@ static int i9xx_color_check(struct intel_crtc_state *crtc_state)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
intel_assign_luts(crtc_state);
|
||||
|
||||
crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
|
||||
|
||||
return 0;
|
||||
|
@ -1433,6 +1436,8 @@ static int chv_color_check(struct intel_crtc_state *crtc_state)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
intel_assign_luts(crtc_state);
|
||||
|
||||
crtc_state->preload_luts = chv_can_preload_luts(crtc_state);
|
||||
|
||||
return 0;
|
||||
|
@ -1458,10 +1463,29 @@ static u32 ilk_csc_mode(const struct intel_crtc_state *crtc_state)
|
|||
if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB)
|
||||
return CSC_BLACK_SCREEN_OFFSET;
|
||||
|
||||
if (crtc_state->hw.degamma_lut)
|
||||
return CSC_MODE_YUV_TO_RGB;
|
||||
|
||||
return CSC_MODE_YUV_TO_RGB |
|
||||
CSC_POSITION_BEFORE_GAMMA;
|
||||
}
|
||||
|
||||
static void ilk_assign_luts(struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
if (crtc_state->hw.degamma_lut ||
|
||||
crtc_state->csc_mode & CSC_POSITION_BEFORE_GAMMA) {
|
||||
drm_property_replace_blob(&crtc_state->pre_csc_lut,
|
||||
crtc_state->hw.degamma_lut);
|
||||
drm_property_replace_blob(&crtc_state->post_csc_lut,
|
||||
crtc_state->hw.gamma_lut);
|
||||
} else {
|
||||
drm_property_replace_blob(&crtc_state->pre_csc_lut,
|
||||
crtc_state->hw.gamma_lut);
|
||||
drm_property_replace_blob(&crtc_state->post_csc_lut,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static int ilk_color_check(struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
int ret;
|
||||
|
@ -1489,6 +1513,8 @@ static int ilk_color_check(struct intel_crtc_state *crtc_state)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ilk_assign_luts(crtc_state);
|
||||
|
||||
crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
|
||||
|
||||
return 0;
|
||||
|
@ -1556,6 +1582,8 @@ static int ivb_color_check(struct intel_crtc_state *crtc_state)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ilk_assign_luts(crtc_state);
|
||||
|
||||
crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
|
||||
|
||||
return 0;
|
||||
|
@ -1570,6 +1598,23 @@ static u32 glk_gamma_mode(const struct intel_crtc_state *crtc_state)
|
|||
return GAMMA_MODE_MODE_10BIT;
|
||||
}
|
||||
|
||||
static void glk_assign_luts(struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
|
||||
|
||||
intel_assign_luts(crtc_state);
|
||||
|
||||
/*
|
||||
* On GLK+ both pipe CSC and degamma LUT are controlled
|
||||
* by csc_enable. Hence for the cases where the CSC is
|
||||
* needed but degamma LUT is not we need to load a
|
||||
* linear degamma LUT.
|
||||
*/
|
||||
if (crtc_state->csc_enable && !crtc_state->pre_csc_lut)
|
||||
drm_property_replace_blob(&crtc_state->pre_csc_lut,
|
||||
i915->display.color.glk_linear_degamma_lut);
|
||||
}
|
||||
|
||||
static int glk_color_check(struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
|
||||
|
@ -1604,7 +1649,9 @@ static int glk_color_check(struct intel_crtc_state *crtc_state)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
crtc_state->preload_luts = glk_can_preload_luts(crtc_state);
|
||||
glk_assign_luts(crtc_state);
|
||||
|
||||
crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1664,6 +1711,8 @@ static int icl_color_check(struct intel_crtc_state *crtc_state)
|
|||
|
||||
crtc_state->csc_mode = icl_csc_mode(crtc_state);
|
||||
|
||||
intel_assign_luts(crtc_state);
|
||||
|
||||
crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
|
||||
|
||||
return 0;
|
||||
|
@ -1869,7 +1918,7 @@ static void i9xx_read_luts(struct intel_crtc_state *crtc_state)
|
|||
if (!crtc_state->gamma_enable)
|
||||
return;
|
||||
|
||||
crtc_state->hw.gamma_lut = i9xx_read_lut_8(crtc);
|
||||
crtc_state->post_csc_lut = i9xx_read_lut_8(crtc);
|
||||
}
|
||||
|
||||
static struct drm_property_blob *i965_read_lut_10p6(struct intel_crtc *crtc)
|
||||
|
@ -1910,9 +1959,9 @@ static void i965_read_luts(struct intel_crtc_state *crtc_state)
|
|||
return;
|
||||
|
||||
if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
|
||||
crtc_state->hw.gamma_lut = i9xx_read_lut_8(crtc);
|
||||
crtc_state->post_csc_lut = i9xx_read_lut_8(crtc);
|
||||
else
|
||||
crtc_state->hw.gamma_lut = i965_read_lut_10p6(crtc);
|
||||
crtc_state->post_csc_lut = i965_read_lut_10p6(crtc);
|
||||
}
|
||||
|
||||
static struct drm_property_blob *chv_read_cgm_gamma(struct intel_crtc *crtc)
|
||||
|
@ -1946,7 +1995,7 @@ static void chv_read_luts(struct intel_crtc_state *crtc_state)
|
|||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
|
||||
if (crtc_state->cgm_mode & CGM_PIPE_MODE_GAMMA)
|
||||
crtc_state->hw.gamma_lut = chv_read_cgm_gamma(crtc);
|
||||
crtc_state->post_csc_lut = chv_read_cgm_gamma(crtc);
|
||||
else
|
||||
i965_read_luts(crtc_state);
|
||||
}
|
||||
|
@ -2013,10 +2062,10 @@ static void ilk_read_luts(struct intel_crtc_state *crtc_state)
|
|||
|
||||
switch (crtc_state->gamma_mode) {
|
||||
case GAMMA_MODE_MODE_8BIT:
|
||||
crtc_state->hw.gamma_lut = ilk_read_lut_8(crtc);
|
||||
crtc_state->post_csc_lut = ilk_read_lut_8(crtc);
|
||||
break;
|
||||
case GAMMA_MODE_MODE_10BIT:
|
||||
crtc_state->hw.gamma_lut = ilk_read_lut_10(crtc);
|
||||
crtc_state->post_csc_lut = ilk_read_lut_10(crtc);
|
||||
break;
|
||||
default:
|
||||
MISSING_CASE(crtc_state->gamma_mode);
|
||||
|
@ -2068,10 +2117,10 @@ static void glk_read_luts(struct intel_crtc_state *crtc_state)
|
|||
|
||||
switch (crtc_state->gamma_mode) {
|
||||
case GAMMA_MODE_MODE_8BIT:
|
||||
crtc_state->hw.gamma_lut = ilk_read_lut_8(crtc);
|
||||
crtc_state->post_csc_lut = ilk_read_lut_8(crtc);
|
||||
break;
|
||||
case GAMMA_MODE_MODE_10BIT:
|
||||
crtc_state->hw.gamma_lut = bdw_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
|
||||
crtc_state->post_csc_lut = bdw_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
|
||||
break;
|
||||
default:
|
||||
MISSING_CASE(crtc_state->gamma_mode);
|
||||
|
@ -2126,13 +2175,13 @@ static void icl_read_luts(struct intel_crtc_state *crtc_state)
|
|||
|
||||
switch (crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) {
|
||||
case GAMMA_MODE_MODE_8BIT:
|
||||
crtc_state->hw.gamma_lut = ilk_read_lut_8(crtc);
|
||||
crtc_state->post_csc_lut = ilk_read_lut_8(crtc);
|
||||
break;
|
||||
case GAMMA_MODE_MODE_10BIT:
|
||||
crtc_state->hw.gamma_lut = bdw_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
|
||||
crtc_state->post_csc_lut = bdw_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
|
||||
break;
|
||||
case GAMMA_MODE_MODE_12BIT_MULTI_SEGMENTED:
|
||||
crtc_state->hw.gamma_lut = icl_read_lut_multi_segment(crtc);
|
||||
crtc_state->post_csc_lut = icl_read_lut_multi_segment(crtc);
|
||||
break;
|
||||
default:
|
||||
MISSING_CASE(crtc_state->gamma_mode);
|
||||
|
@ -2217,41 +2266,58 @@ static const struct intel_color_funcs ilk_color_funcs = {
|
|||
.read_luts = ilk_read_luts,
|
||||
};
|
||||
|
||||
void intel_color_init(struct intel_crtc *crtc)
|
||||
void intel_color_crtc_init(struct intel_crtc *crtc)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||
bool has_ctm = INTEL_INFO(dev_priv)->display.color.degamma_lut_size != 0;
|
||||
|
||||
drm_mode_crtc_set_gamma_size(&crtc->base, 256);
|
||||
|
||||
if (HAS_GMCH(dev_priv)) {
|
||||
if (IS_CHERRYVIEW(dev_priv)) {
|
||||
dev_priv->display.funcs.color = &chv_color_funcs;
|
||||
} else if (DISPLAY_VER(dev_priv) >= 4) {
|
||||
dev_priv->display.funcs.color = &i965_color_funcs;
|
||||
} else {
|
||||
dev_priv->display.funcs.color = &i9xx_color_funcs;
|
||||
}
|
||||
} else {
|
||||
if (DISPLAY_VER(dev_priv) >= 11)
|
||||
dev_priv->display.funcs.color = &icl_color_funcs;
|
||||
else if (DISPLAY_VER(dev_priv) == 10)
|
||||
dev_priv->display.funcs.color = &glk_color_funcs;
|
||||
else if (DISPLAY_VER(dev_priv) == 9)
|
||||
dev_priv->display.funcs.color = &skl_color_funcs;
|
||||
else if (DISPLAY_VER(dev_priv) == 8)
|
||||
dev_priv->display.funcs.color = &bdw_color_funcs;
|
||||
else if (DISPLAY_VER(dev_priv) == 7) {
|
||||
if (IS_HASWELL(dev_priv))
|
||||
dev_priv->display.funcs.color = &hsw_color_funcs;
|
||||
else
|
||||
dev_priv->display.funcs.color = &ivb_color_funcs;
|
||||
} else
|
||||
dev_priv->display.funcs.color = &ilk_color_funcs;
|
||||
}
|
||||
|
||||
drm_crtc_enable_color_mgmt(&crtc->base,
|
||||
INTEL_INFO(dev_priv)->display.color.degamma_lut_size,
|
||||
has_ctm,
|
||||
INTEL_INFO(dev_priv)->display.color.gamma_lut_size);
|
||||
}
|
||||
|
||||
int intel_color_init(struct drm_i915_private *i915)
|
||||
{
|
||||
struct drm_property_blob *blob;
|
||||
|
||||
if (DISPLAY_VER(i915) != 10)
|
||||
return 0;
|
||||
|
||||
blob = create_linear_lut(i915, INTEL_INFO(i915)->display.color.degamma_lut_size);
|
||||
if (IS_ERR(blob))
|
||||
return PTR_ERR(blob);
|
||||
|
||||
i915->display.color.glk_linear_degamma_lut = blob;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void intel_color_init_hooks(struct drm_i915_private *i915)
|
||||
{
|
||||
if (HAS_GMCH(i915)) {
|
||||
if (IS_CHERRYVIEW(i915))
|
||||
i915->display.funcs.color = &chv_color_funcs;
|
||||
else if (DISPLAY_VER(i915) >= 4)
|
||||
i915->display.funcs.color = &i965_color_funcs;
|
||||
else
|
||||
i915->display.funcs.color = &i9xx_color_funcs;
|
||||
} else {
|
||||
if (DISPLAY_VER(i915) >= 11)
|
||||
i915->display.funcs.color = &icl_color_funcs;
|
||||
else if (DISPLAY_VER(i915) == 10)
|
||||
i915->display.funcs.color = &glk_color_funcs;
|
||||
else if (DISPLAY_VER(i915) == 9)
|
||||
i915->display.funcs.color = &skl_color_funcs;
|
||||
else if (DISPLAY_VER(i915) == 8)
|
||||
i915->display.funcs.color = &bdw_color_funcs;
|
||||
else if (IS_HASWELL(i915))
|
||||
i915->display.funcs.color = &hsw_color_funcs;
|
||||
else if (DISPLAY_VER(i915) == 7)
|
||||
i915->display.funcs.color = &ivb_color_funcs;
|
||||
else
|
||||
i915->display.funcs.color = &ilk_color_funcs;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,9 +10,12 @@
|
|||
|
||||
struct intel_crtc_state;
|
||||
struct intel_crtc;
|
||||
struct drm_i915_private;
|
||||
struct drm_property_blob;
|
||||
|
||||
void intel_color_init(struct intel_crtc *crtc);
|
||||
void intel_color_init_hooks(struct drm_i915_private *i915);
|
||||
int intel_color_init(struct drm_i915_private *i915);
|
||||
void intel_color_crtc_init(struct intel_crtc *crtc);
|
||||
int intel_color_check(struct intel_crtc_state *crtc_state);
|
||||
void intel_color_commit_noarm(const struct intel_crtc_state *crtc_state);
|
||||
void intel_color_commit_arm(const struct intel_crtc_state *crtc_state);
|
||||
|
@ -22,5 +25,6 @@ int intel_color_get_gamma_bit_precision(const struct intel_crtc_state *crtc_stat
|
|||
bool intel_color_lut_equal(struct drm_property_blob *blob1,
|
||||
struct drm_property_blob *blob2,
|
||||
u32 gamma_mode, u32 bit_precision);
|
||||
void intel_color_assert_luts(const struct intel_crtc_state *crtc_state);
|
||||
|
||||
#endif /* __INTEL_COLOR_H__ */
|
||||
|
|
|
@ -53,7 +53,6 @@ static const struct icl_procmon {
|
|||
static const struct icl_procmon *
|
||||
icl_get_procmon_ref_values(struct drm_i915_private *dev_priv, enum phy phy)
|
||||
{
|
||||
const struct icl_procmon *procmon;
|
||||
u32 val;
|
||||
|
||||
val = intel_de_read(dev_priv, ICL_PORT_COMP_DW3(phy));
|
||||
|
@ -62,23 +61,16 @@ icl_get_procmon_ref_values(struct drm_i915_private *dev_priv, enum phy phy)
|
|||
MISSING_CASE(val);
|
||||
fallthrough;
|
||||
case VOLTAGE_INFO_0_85V | PROCESS_INFO_DOT_0:
|
||||
procmon = &icl_procmon_values[PROCMON_0_85V_DOT_0];
|
||||
break;
|
||||
return &icl_procmon_values[PROCMON_0_85V_DOT_0];
|
||||
case VOLTAGE_INFO_0_95V | PROCESS_INFO_DOT_0:
|
||||
procmon = &icl_procmon_values[PROCMON_0_95V_DOT_0];
|
||||
break;
|
||||
return &icl_procmon_values[PROCMON_0_95V_DOT_0];
|
||||
case VOLTAGE_INFO_0_95V | PROCESS_INFO_DOT_1:
|
||||
procmon = &icl_procmon_values[PROCMON_0_95V_DOT_1];
|
||||
break;
|
||||
return &icl_procmon_values[PROCMON_0_95V_DOT_1];
|
||||
case VOLTAGE_INFO_1_05V | PROCESS_INFO_DOT_0:
|
||||
procmon = &icl_procmon_values[PROCMON_1_05V_DOT_0];
|
||||
break;
|
||||
return &icl_procmon_values[PROCMON_1_05V_DOT_0];
|
||||
case VOLTAGE_INFO_1_05V | PROCESS_INFO_DOT_1:
|
||||
procmon = &icl_procmon_values[PROCMON_1_05V_DOT_1];
|
||||
break;
|
||||
return &icl_procmon_values[PROCMON_1_05V_DOT_1];
|
||||
}
|
||||
|
||||
return procmon;
|
||||
}
|
||||
|
||||
static void icl_set_procmon_ref_values(struct drm_i915_private *dev_priv,
|
||||
|
|
|
@ -293,3 +293,21 @@ intel_attach_dp_colorspace_property(struct drm_connector *connector)
|
|||
if (!drm_mode_create_dp_colorspace_property(connector))
|
||||
drm_connector_attach_colorspace_property(connector);
|
||||
}
|
||||
|
||||
void
|
||||
intel_attach_scaling_mode_property(struct drm_connector *connector)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(connector->dev);
|
||||
u32 scaling_modes;
|
||||
|
||||
scaling_modes = BIT(DRM_MODE_SCALE_ASPECT) |
|
||||
BIT(DRM_MODE_SCALE_FULLSCREEN);
|
||||
|
||||
/* On GMCH platforms borders are only possible on the LVDS port */
|
||||
if (!HAS_GMCH(i915) || connector->connector_type == DRM_MODE_CONNECTOR_LVDS)
|
||||
scaling_modes |= BIT(DRM_MODE_SCALE_CENTER);
|
||||
|
||||
drm_connector_attach_scaling_mode_property(connector, scaling_modes);
|
||||
|
||||
connector->state->scaling_mode = DRM_MODE_SCALE_ASPECT;
|
||||
}
|
||||
|
|
|
@ -32,5 +32,6 @@ void intel_attach_broadcast_rgb_property(struct drm_connector *connector);
|
|||
void intel_attach_aspect_ratio_property(struct drm_connector *connector);
|
||||
void intel_attach_hdmi_colorspace_property(struct drm_connector *connector);
|
||||
void intel_attach_dp_colorspace_property(struct drm_connector *connector);
|
||||
void intel_attach_scaling_mode_property(struct drm_connector *connector);
|
||||
|
||||
#endif /* __INTEL_CONNECTOR_H__ */
|
||||
|
|
|
@ -1044,17 +1044,14 @@ void intel_crt_init(struct drm_i915_private *dev_priv)
|
|||
intel_connector_attach_encoder(intel_connector, &crt->base);
|
||||
|
||||
crt->base.type = INTEL_OUTPUT_ANALOG;
|
||||
crt->base.cloneable = (1 << INTEL_OUTPUT_DVO) | (1 << INTEL_OUTPUT_HDMI);
|
||||
crt->base.cloneable = BIT(INTEL_OUTPUT_DVO) | BIT(INTEL_OUTPUT_HDMI);
|
||||
if (IS_I830(dev_priv))
|
||||
crt->base.pipe_mask = BIT(PIPE_A);
|
||||
else
|
||||
crt->base.pipe_mask = ~0;
|
||||
|
||||
if (DISPLAY_VER(dev_priv) == 2)
|
||||
connector->interlace_allowed = 0;
|
||||
else
|
||||
connector->interlace_allowed = 1;
|
||||
connector->doublescan_allowed = 0;
|
||||
if (DISPLAY_VER(dev_priv) != 2)
|
||||
connector->interlace_allowed = true;
|
||||
|
||||
crt->adpa_reg = adpa_reg;
|
||||
|
||||
|
|
|
@ -365,9 +365,8 @@ int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe)
|
|||
BIT(DRM_SCALING_FILTER_DEFAULT) |
|
||||
BIT(DRM_SCALING_FILTER_NEAREST_NEIGHBOR));
|
||||
|
||||
intel_color_init(crtc);
|
||||
|
||||
intel_crtc_drrs_init(crtc);
|
||||
intel_color_crtc_init(crtc);
|
||||
intel_drrs_crtc_init(crtc);
|
||||
intel_crtc_crc_init(crtc);
|
||||
|
||||
cpu_latency_qos_add_request(&crtc->vblank_pm_qos, PM_QOS_DEFAULT_VALUE);
|
||||
|
@ -387,8 +386,7 @@ static bool intel_crtc_needs_vblank_work(const struct intel_crtc_state *crtc_sta
|
|||
return crtc_state->hw.active &&
|
||||
!intel_crtc_needs_modeset(crtc_state) &&
|
||||
!crtc_state->preload_luts &&
|
||||
(crtc_state->uapi.color_mgmt_changed ||
|
||||
crtc_state->update_pipe);
|
||||
intel_crtc_needs_color_update(crtc_state);
|
||||
}
|
||||
|
||||
static void intel_crtc_vblank_work(struct kthread_work *base)
|
||||
|
|
|
@ -298,11 +298,13 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config,
|
|||
pipe_config->csc_mode, pipe_config->gamma_mode,
|
||||
pipe_config->gamma_enable, pipe_config->csc_enable);
|
||||
|
||||
drm_dbg_kms(&i915->drm, "degamma lut: %d entries, gamma lut: %d entries\n",
|
||||
pipe_config->hw.degamma_lut ?
|
||||
drm_color_lut_size(pipe_config->hw.degamma_lut) : 0,
|
||||
pipe_config->hw.gamma_lut ?
|
||||
drm_color_lut_size(pipe_config->hw.gamma_lut) : 0);
|
||||
drm_dbg_kms(&i915->drm, "pre csc lut: %s%d entries, post csc lut: %d entries\n",
|
||||
pipe_config->pre_csc_lut && pipe_config->pre_csc_lut ==
|
||||
i915->display.color.glk_linear_degamma_lut ? "(linear) " : "",
|
||||
pipe_config->pre_csc_lut ?
|
||||
drm_color_lut_size(pipe_config->pre_csc_lut) : 0,
|
||||
pipe_config->post_csc_lut ?
|
||||
drm_color_lut_size(pipe_config->post_csc_lut) : 0);
|
||||
|
||||
dump_planes:
|
||||
if (!state)
|
||||
|
|
|
@ -631,8 +631,10 @@ intel_legacy_cursor_update(struct drm_plane *_plane,
|
|||
*
|
||||
* FIXME bigjoiner fastpath would be good
|
||||
*/
|
||||
if (!crtc_state->hw.active || intel_crtc_needs_modeset(crtc_state) ||
|
||||
crtc_state->update_pipe || crtc_state->bigjoiner_pipes)
|
||||
if (!crtc_state->hw.active ||
|
||||
intel_crtc_needs_modeset(crtc_state) ||
|
||||
intel_crtc_needs_fastset(crtc_state) ||
|
||||
crtc_state->bigjoiner_pipes)
|
||||
goto slow;
|
||||
|
||||
/*
|
||||
|
|
|
@ -43,6 +43,8 @@
|
|||
#include "intel_de.h"
|
||||
#include "intel_display_power.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dkl_phy.h"
|
||||
#include "intel_dkl_phy_regs.h"
|
||||
#include "intel_dp.h"
|
||||
#include "intel_dp_link_training.h"
|
||||
#include "intel_dp_mst.h"
|
||||
|
@ -55,13 +57,13 @@
|
|||
#include "intel_hdmi.h"
|
||||
#include "intel_hotplug.h"
|
||||
#include "intel_lspcon.h"
|
||||
#include "intel_mg_phy_regs.h"
|
||||
#include "intel_pps.h"
|
||||
#include "intel_psr.h"
|
||||
#include "intel_quirks.h"
|
||||
#include "intel_snps_phy.h"
|
||||
#include "intel_sprite.h"
|
||||
#include "intel_tc.h"
|
||||
#include "intel_tc_phy_regs.h"
|
||||
#include "intel_vdsc.h"
|
||||
#include "intel_vrr.h"
|
||||
#include "skl_scaler.h"
|
||||
|
@ -1262,33 +1264,30 @@ static void tgl_dkl_phy_set_signal_levels(struct intel_encoder *encoder,
|
|||
for (ln = 0; ln < 2; ln++) {
|
||||
int level;
|
||||
|
||||
intel_de_write(dev_priv, HIP_INDEX_REG(tc_port),
|
||||
HIP_INDEX_VAL(tc_port, ln));
|
||||
|
||||
intel_de_write(dev_priv, DKL_TX_PMD_LANE_SUS(tc_port), 0);
|
||||
intel_dkl_phy_write(dev_priv, DKL_TX_PMD_LANE_SUS(tc_port, ln), 0);
|
||||
|
||||
level = intel_ddi_level(encoder, crtc_state, 2*ln+0);
|
||||
|
||||
intel_de_rmw(dev_priv, DKL_TX_DPCNTL0(tc_port),
|
||||
DKL_TX_PRESHOOT_COEFF_MASK |
|
||||
DKL_TX_DE_EMPAHSIS_COEFF_MASK |
|
||||
DKL_TX_VSWING_CONTROL_MASK,
|
||||
DKL_TX_PRESHOOT_COEFF(trans->entries[level].dkl.preshoot) |
|
||||
DKL_TX_DE_EMPHASIS_COEFF(trans->entries[level].dkl.de_emphasis) |
|
||||
DKL_TX_VSWING_CONTROL(trans->entries[level].dkl.vswing));
|
||||
intel_dkl_phy_rmw(dev_priv, DKL_TX_DPCNTL0(tc_port, ln),
|
||||
DKL_TX_PRESHOOT_COEFF_MASK |
|
||||
DKL_TX_DE_EMPAHSIS_COEFF_MASK |
|
||||
DKL_TX_VSWING_CONTROL_MASK,
|
||||
DKL_TX_PRESHOOT_COEFF(trans->entries[level].dkl.preshoot) |
|
||||
DKL_TX_DE_EMPHASIS_COEFF(trans->entries[level].dkl.de_emphasis) |
|
||||
DKL_TX_VSWING_CONTROL(trans->entries[level].dkl.vswing));
|
||||
|
||||
level = intel_ddi_level(encoder, crtc_state, 2*ln+1);
|
||||
|
||||
intel_de_rmw(dev_priv, DKL_TX_DPCNTL1(tc_port),
|
||||
DKL_TX_PRESHOOT_COEFF_MASK |
|
||||
DKL_TX_DE_EMPAHSIS_COEFF_MASK |
|
||||
DKL_TX_VSWING_CONTROL_MASK,
|
||||
DKL_TX_PRESHOOT_COEFF(trans->entries[level].dkl.preshoot) |
|
||||
DKL_TX_DE_EMPHASIS_COEFF(trans->entries[level].dkl.de_emphasis) |
|
||||
DKL_TX_VSWING_CONTROL(trans->entries[level].dkl.vswing));
|
||||
intel_dkl_phy_rmw(dev_priv, DKL_TX_DPCNTL1(tc_port, ln),
|
||||
DKL_TX_PRESHOOT_COEFF_MASK |
|
||||
DKL_TX_DE_EMPAHSIS_COEFF_MASK |
|
||||
DKL_TX_VSWING_CONTROL_MASK,
|
||||
DKL_TX_PRESHOOT_COEFF(trans->entries[level].dkl.preshoot) |
|
||||
DKL_TX_DE_EMPHASIS_COEFF(trans->entries[level].dkl.de_emphasis) |
|
||||
DKL_TX_VSWING_CONTROL(trans->entries[level].dkl.vswing));
|
||||
|
||||
intel_de_rmw(dev_priv, DKL_TX_DPCNTL2(tc_port),
|
||||
DKL_TX_DP20BITMODE, 0);
|
||||
intel_dkl_phy_rmw(dev_priv, DKL_TX_DPCNTL2(tc_port, ln),
|
||||
DKL_TX_DP20BITMODE, 0);
|
||||
|
||||
if (IS_ALDERLAKE_P(dev_priv)) {
|
||||
u32 val;
|
||||
|
@ -1306,10 +1305,10 @@ static void tgl_dkl_phy_set_signal_levels(struct intel_encoder *encoder,
|
|||
val |= DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2(0);
|
||||
}
|
||||
|
||||
intel_de_rmw(dev_priv, DKL_TX_DPCNTL2(tc_port),
|
||||
DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX1_MASK |
|
||||
DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2_MASK,
|
||||
val);
|
||||
intel_dkl_phy_rmw(dev_priv, DKL_TX_DPCNTL2(tc_port, ln),
|
||||
DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX1_MASK |
|
||||
DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2_MASK,
|
||||
val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2019,12 +2018,8 @@ icl_program_mg_dp_mode(struct intel_digital_port *dig_port,
|
|||
return;
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 12) {
|
||||
intel_de_write(dev_priv, HIP_INDEX_REG(tc_port),
|
||||
HIP_INDEX_VAL(tc_port, 0x0));
|
||||
ln0 = intel_de_read(dev_priv, DKL_DP_MODE(tc_port));
|
||||
intel_de_write(dev_priv, HIP_INDEX_REG(tc_port),
|
||||
HIP_INDEX_VAL(tc_port, 0x1));
|
||||
ln1 = intel_de_read(dev_priv, DKL_DP_MODE(tc_port));
|
||||
ln0 = intel_dkl_phy_read(dev_priv, DKL_DP_MODE(tc_port, 0));
|
||||
ln1 = intel_dkl_phy_read(dev_priv, DKL_DP_MODE(tc_port, 1));
|
||||
} else {
|
||||
ln0 = intel_de_read(dev_priv, MG_DP_MODE(0, tc_port));
|
||||
ln1 = intel_de_read(dev_priv, MG_DP_MODE(1, tc_port));
|
||||
|
@ -2085,12 +2080,8 @@ icl_program_mg_dp_mode(struct intel_digital_port *dig_port,
|
|||
}
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 12) {
|
||||
intel_de_write(dev_priv, HIP_INDEX_REG(tc_port),
|
||||
HIP_INDEX_VAL(tc_port, 0x0));
|
||||
intel_de_write(dev_priv, DKL_DP_MODE(tc_port), ln0);
|
||||
intel_de_write(dev_priv, HIP_INDEX_REG(tc_port),
|
||||
HIP_INDEX_VAL(tc_port, 0x1));
|
||||
intel_de_write(dev_priv, DKL_DP_MODE(tc_port), ln1);
|
||||
intel_dkl_phy_write(dev_priv, DKL_DP_MODE(tc_port, 0), ln0);
|
||||
intel_dkl_phy_write(dev_priv, DKL_DP_MODE(tc_port, 1), ln1);
|
||||
} else {
|
||||
intel_de_write(dev_priv, MG_DP_MODE(0, tc_port), ln0);
|
||||
intel_de_write(dev_priv, MG_DP_MODE(1, tc_port), ln1);
|
||||
|
@ -3094,10 +3085,8 @@ static void adlp_tbt_to_dp_alt_switch_wa(struct intel_encoder *encoder)
|
|||
enum tc_port tc_port = intel_port_to_tc(i915, encoder->port);
|
||||
int ln;
|
||||
|
||||
for (ln = 0; ln < 2; ln++) {
|
||||
intel_de_write(i915, HIP_INDEX_REG(tc_port), HIP_INDEX_VAL(tc_port, ln));
|
||||
intel_de_rmw(i915, DKL_PCS_DW5(tc_port), DKL_PCS_DW5_CORE_SOFTRESET, 0);
|
||||
}
|
||||
for (ln = 0; ln < 2; ln++)
|
||||
intel_dkl_phy_rmw(i915, DKL_PCS_DW5(tc_port, ln), DKL_PCS_DW5_CORE_SOFTRESET, 0);
|
||||
}
|
||||
|
||||
static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp,
|
||||
|
@ -3536,7 +3525,7 @@ static void icl_ddi_tc_get_clock(struct intel_encoder *encoder,
|
|||
if (drm_WARN_ON(&i915->drm, !pll))
|
||||
return;
|
||||
|
||||
if (intel_get_shared_dpll_id(i915, pll) == DPLL_ID_ICL_TBTPLL)
|
||||
if (pll->info->id == DPLL_ID_ICL_TBTPLL)
|
||||
port_dpll_id = ICL_PORT_DPLL_DEFAULT;
|
||||
else
|
||||
port_dpll_id = ICL_PORT_DPLL_MG_PHY;
|
||||
|
@ -3549,7 +3538,7 @@ static void icl_ddi_tc_get_clock(struct intel_encoder *encoder,
|
|||
|
||||
icl_set_active_port_dpll(crtc_state, port_dpll_id);
|
||||
|
||||
if (intel_get_shared_dpll_id(i915, crtc_state->shared_dpll) == DPLL_ID_ICL_TBTPLL)
|
||||
if (crtc_state->shared_dpll->info->id == DPLL_ID_ICL_TBTPLL)
|
||||
crtc_state->port_clock = icl_calc_tbt_pll_link(i915, encoder->port);
|
||||
else
|
||||
crtc_state->port_clock = intel_dpll_get_freq(i915, crtc_state->shared_dpll,
|
||||
|
@ -3591,7 +3580,7 @@ static void intel_ddi_sync_state(struct intel_encoder *encoder,
|
|||
enum phy phy = intel_port_to_phy(i915, encoder->port);
|
||||
|
||||
if (intel_phy_is_tc(i915, phy))
|
||||
intel_tc_port_sanitize(enc_to_dig_port(encoder));
|
||||
intel_tc_port_sanitize_mode(enc_to_dig_port(encoder));
|
||||
|
||||
if (crtc_state && intel_crtc_has_dp_encoder(crtc_state))
|
||||
intel_dp_sync_state(encoder, crtc_state);
|
||||
|
@ -3801,11 +3790,17 @@ static void intel_ddi_encoder_destroy(struct drm_encoder *encoder)
|
|||
|
||||
static void intel_ddi_encoder_reset(struct drm_encoder *encoder)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(encoder->dev);
|
||||
struct intel_dp *intel_dp = enc_to_intel_dp(to_intel_encoder(encoder));
|
||||
struct intel_digital_port *dig_port = enc_to_dig_port(to_intel_encoder(encoder));
|
||||
enum phy phy = intel_port_to_phy(i915, dig_port->base.port);
|
||||
|
||||
intel_dp->reset_link_params = true;
|
||||
|
||||
intel_pps_encoder_reset(intel_dp);
|
||||
|
||||
if (intel_phy_is_tc(i915, phy))
|
||||
intel_tc_port_init_mode(dig_port);
|
||||
}
|
||||
|
||||
static const struct drm_encoder_funcs intel_ddi_funcs = {
|
||||
|
|
|
@ -830,6 +830,20 @@ intel_plane_fence_y_offset(const struct intel_plane_state *plane_state)
|
|||
return y;
|
||||
}
|
||||
|
||||
static int
|
||||
intel_display_commit_duplicated_state(struct intel_atomic_state *state,
|
||||
struct drm_modeset_acquire_ctx *ctx)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(state->base.dev);
|
||||
int ret;
|
||||
|
||||
ret = drm_atomic_helper_commit_duplicated_state(&state->base, ctx);
|
||||
|
||||
drm_WARN_ON(&i915->drm, ret == -EDEADLK);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
__intel_display_resume(struct drm_i915_private *i915,
|
||||
struct drm_atomic_state *state,
|
||||
|
@ -837,7 +851,7 @@ __intel_display_resume(struct drm_i915_private *i915,
|
|||
{
|
||||
struct drm_crtc_state *crtc_state;
|
||||
struct drm_crtc *crtc;
|
||||
int i, ret;
|
||||
int i;
|
||||
|
||||
intel_modeset_setup_hw_state(i915, ctx);
|
||||
intel_vga_redisable(i915);
|
||||
|
@ -863,11 +877,7 @@ __intel_display_resume(struct drm_i915_private *i915,
|
|||
if (!HAS_GMCH(i915))
|
||||
to_intel_atomic_state(state)->skip_intermediate_wm = true;
|
||||
|
||||
ret = drm_atomic_helper_commit_duplicated_state(state, ctx);
|
||||
|
||||
drm_WARN_ON(&i915->drm, ret == -EDEADLK);
|
||||
|
||||
return ret;
|
||||
return intel_display_commit_duplicated_state(to_intel_atomic_state(state), ctx);
|
||||
}
|
||||
|
||||
static bool gpu_reset_clobbers_display(struct drm_i915_private *dev_priv)
|
||||
|
@ -878,7 +888,6 @@ static bool gpu_reset_clobbers_display(struct drm_i915_private *dev_priv)
|
|||
|
||||
void intel_display_prepare_reset(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
struct drm_modeset_acquire_ctx *ctx = &dev_priv->reset_ctx;
|
||||
struct drm_atomic_state *state;
|
||||
int ret;
|
||||
|
@ -906,10 +915,10 @@ void intel_display_prepare_reset(struct drm_i915_private *dev_priv)
|
|||
* Need mode_config.mutex so that we don't
|
||||
* trample ongoing ->detect() and whatnot.
|
||||
*/
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
mutex_lock(&dev_priv->drm.mode_config.mutex);
|
||||
drm_modeset_acquire_init(ctx, 0);
|
||||
while (1) {
|
||||
ret = drm_modeset_lock_all_ctx(dev, ctx);
|
||||
ret = drm_modeset_lock_all_ctx(&dev_priv->drm, ctx);
|
||||
if (ret != -EDEADLK)
|
||||
break;
|
||||
|
||||
|
@ -919,7 +928,7 @@ void intel_display_prepare_reset(struct drm_i915_private *dev_priv)
|
|||
* Disabling the crtcs gracefully seems nicer. Also the
|
||||
* g33 docs say we should at least disable all the planes.
|
||||
*/
|
||||
state = drm_atomic_helper_duplicate_state(dev, ctx);
|
||||
state = drm_atomic_helper_duplicate_state(&dev_priv->drm, ctx);
|
||||
if (IS_ERR(state)) {
|
||||
ret = PTR_ERR(state);
|
||||
drm_err(&dev_priv->drm, "Duplicating state failed with %i\n",
|
||||
|
@ -927,7 +936,7 @@ void intel_display_prepare_reset(struct drm_i915_private *dev_priv)
|
|||
return;
|
||||
}
|
||||
|
||||
ret = drm_atomic_helper_disable_all(dev, ctx);
|
||||
ret = drm_atomic_helper_disable_all(&dev_priv->drm, ctx);
|
||||
if (ret) {
|
||||
drm_err(&dev_priv->drm, "Suspending crtc's failed with %i\n",
|
||||
ret);
|
||||
|
@ -959,7 +968,7 @@ void intel_display_finish_reset(struct drm_i915_private *i915)
|
|||
/* reset doesn't touch the display */
|
||||
if (!gpu_reset_clobbers_display(i915)) {
|
||||
/* for testing only restore the display */
|
||||
ret = __intel_display_resume(i915, state, ctx);
|
||||
ret = intel_display_commit_duplicated_state(to_intel_atomic_state(state), ctx);
|
||||
if (ret)
|
||||
drm_err(&i915->drm,
|
||||
"Restoring old state failed with %i\n", ret);
|
||||
|
@ -1252,8 +1261,6 @@ static void intel_post_plane_update(struct intel_atomic_state *state,
|
|||
if (needs_cursorclk_wa(old_crtc_state) &&
|
||||
!needs_cursorclk_wa(new_crtc_state))
|
||||
icl_wa_cursorclkgating(dev_priv, pipe, false);
|
||||
|
||||
intel_drrs_activate(new_crtc_state);
|
||||
}
|
||||
|
||||
static void intel_crtc_enable_flip_done(struct intel_atomic_state *state,
|
||||
|
@ -4572,8 +4579,8 @@ static bool encoders_cloneable(const struct intel_encoder *a,
|
|||
const struct intel_encoder *b)
|
||||
{
|
||||
/* masks could be asymmetric, so check both ways */
|
||||
return a == b || (a->cloneable & (1 << b->type) &&
|
||||
b->cloneable & (1 << a->type));
|
||||
return a == b || (a->cloneable & BIT(b->type) &&
|
||||
b->cloneable & BIT(a->type));
|
||||
}
|
||||
|
||||
static bool check_single_encoder_cloning(struct intel_atomic_state *state,
|
||||
|
@ -4824,14 +4831,14 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state,
|
|||
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||
struct intel_crtc_state *crtc_state =
|
||||
intel_atomic_get_new_crtc_state(state, crtc);
|
||||
bool mode_changed = intel_crtc_needs_modeset(crtc_state);
|
||||
int ret;
|
||||
|
||||
if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv) &&
|
||||
mode_changed && !crtc_state->hw.active)
|
||||
intel_crtc_needs_modeset(crtc_state) &&
|
||||
!crtc_state->hw.active)
|
||||
crtc_state->update_wm_post = true;
|
||||
|
||||
if (mode_changed) {
|
||||
if (intel_crtc_needs_modeset(crtc_state)) {
|
||||
ret = intel_dpll_crtc_get_shared_dpll(state, crtc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -4844,8 +4851,7 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state,
|
|||
if (c8_planes_changed(crtc_state))
|
||||
crtc_state->uapi.color_mgmt_changed = true;
|
||||
|
||||
if (mode_changed || crtc_state->update_pipe ||
|
||||
crtc_state->uapi.color_mgmt_changed) {
|
||||
if (intel_crtc_needs_color_update(crtc_state)) {
|
||||
ret = intel_color_check(crtc_state);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -4871,7 +4877,8 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state,
|
|||
}
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 9) {
|
||||
if (mode_changed || crtc_state->update_pipe) {
|
||||
if (intel_crtc_needs_modeset(crtc_state) ||
|
||||
intel_crtc_needs_fastset(crtc_state)) {
|
||||
ret = skl_update_scaler_crtc(crtc_state);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -5637,39 +5644,6 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
|
|||
PIPE_CONF_CHECK_I(name.y2); \
|
||||
} while (0)
|
||||
|
||||
/* This is required for BDW+ where there is only one set of registers for
|
||||
* switching between high and low RR.
|
||||
* This macro can be used whenever a comparison has to be made between one
|
||||
* hw state and multiple sw state variables.
|
||||
*/
|
||||
#define PIPE_CONF_CHECK_M_N_ALT(name, alt_name) do { \
|
||||
if (!intel_compare_link_m_n(¤t_config->name, \
|
||||
&pipe_config->name) && \
|
||||
!intel_compare_link_m_n(¤t_config->alt_name, \
|
||||
&pipe_config->name)) { \
|
||||
pipe_config_mismatch(fastset, crtc, __stringify(name), \
|
||||
"(expected tu %i data %i/%i link %i/%i, " \
|
||||
"or tu %i data %i/%i link %i/%i, " \
|
||||
"found tu %i, data %i/%i link %i/%i)", \
|
||||
current_config->name.tu, \
|
||||
current_config->name.data_m, \
|
||||
current_config->name.data_n, \
|
||||
current_config->name.link_m, \
|
||||
current_config->name.link_n, \
|
||||
current_config->alt_name.tu, \
|
||||
current_config->alt_name.data_m, \
|
||||
current_config->alt_name.data_n, \
|
||||
current_config->alt_name.link_m, \
|
||||
current_config->alt_name.link_n, \
|
||||
pipe_config->name.tu, \
|
||||
pipe_config->name.data_m, \
|
||||
pipe_config->name.data_n, \
|
||||
pipe_config->name.link_m, \
|
||||
pipe_config->name.link_n); \
|
||||
ret = false; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define PIPE_CONF_CHECK_FLAGS(name, mask) do { \
|
||||
if ((current_config->name ^ pipe_config->name) & (mask)) { \
|
||||
pipe_config_mismatch(fastset, crtc, __stringify(name), \
|
||||
|
@ -5738,7 +5712,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
|
|||
|
||||
if (HAS_DOUBLE_BUFFERED_M_N(dev_priv)) {
|
||||
if (!fastset || !pipe_config->seamless_m_n)
|
||||
PIPE_CONF_CHECK_M_N_ALT(dp_m_n, dp_m2_n2);
|
||||
PIPE_CONF_CHECK_M_N(dp_m_n);
|
||||
} else {
|
||||
PIPE_CONF_CHECK_M_N(dp_m_n);
|
||||
PIPE_CONF_CHECK_M_N(dp_m2_n2);
|
||||
|
@ -5815,7 +5789,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
|
|||
|
||||
bp_gamma = intel_color_get_gamma_bit_precision(pipe_config);
|
||||
if (bp_gamma)
|
||||
PIPE_CONF_CHECK_COLOR_LUT(gamma_mode, hw.gamma_lut, bp_gamma);
|
||||
PIPE_CONF_CHECK_COLOR_LUT(gamma_mode, post_csc_lut, bp_gamma);
|
||||
|
||||
if (current_config->active_planes) {
|
||||
PIPE_CONF_CHECK_BOOL(has_psr);
|
||||
|
@ -5937,7 +5911,8 @@ intel_verify_planes(struct intel_atomic_state *state)
|
|||
plane_state->uapi.visible);
|
||||
}
|
||||
|
||||
int intel_modeset_all_pipes(struct intel_atomic_state *state)
|
||||
int intel_modeset_all_pipes(struct intel_atomic_state *state,
|
||||
const char *reason)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
|
||||
struct intel_crtc *crtc;
|
||||
|
@ -5958,7 +5933,11 @@ int intel_modeset_all_pipes(struct intel_atomic_state *state)
|
|||
drm_atomic_crtc_needs_modeset(&crtc_state->uapi))
|
||||
continue;
|
||||
|
||||
drm_dbg_kms(&dev_priv->drm, "[CRTC:%d:%s] Full modeset due to %s\n",
|
||||
crtc->base.base.id, crtc->base.name, reason);
|
||||
|
||||
crtc_state->uapi.mode_changed = true;
|
||||
crtc_state->update_pipe = false;
|
||||
|
||||
ret = drm_atomic_add_affected_connectors(&state->base,
|
||||
&crtc->base);
|
||||
|
@ -6134,7 +6113,8 @@ static void intel_crtc_check_fastset(const struct intel_crtc_state *old_crtc_sta
|
|||
return;
|
||||
|
||||
new_crtc_state->uapi.mode_changed = false;
|
||||
new_crtc_state->update_pipe = true;
|
||||
if (!intel_crtc_needs_modeset(new_crtc_state))
|
||||
new_crtc_state->update_pipe = true;
|
||||
}
|
||||
|
||||
static int intel_crtc_add_planes_to_state(struct intel_atomic_state *state,
|
||||
|
@ -6906,12 +6886,19 @@ static int intel_atomic_check(struct drm_device *dev,
|
|||
|
||||
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
|
||||
new_crtc_state, i) {
|
||||
intel_color_assert_luts(new_crtc_state);
|
||||
|
||||
ret = intel_async_flip_check_hw(state, crtc);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
/* Either full modeset or fastset (or neither), never both */
|
||||
drm_WARN_ON(&dev_priv->drm,
|
||||
intel_crtc_needs_modeset(new_crtc_state) &&
|
||||
intel_crtc_needs_fastset(new_crtc_state));
|
||||
|
||||
if (!intel_crtc_needs_modeset(new_crtc_state) &&
|
||||
!new_crtc_state->update_pipe)
|
||||
!intel_crtc_needs_fastset(new_crtc_state))
|
||||
continue;
|
||||
|
||||
intel_crtc_state_dump(new_crtc_state, state,
|
||||
|
@ -6947,12 +6934,8 @@ static int intel_atomic_prepare_commit(struct intel_atomic_state *state)
|
|||
return ret;
|
||||
|
||||
for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
|
||||
bool mode_changed = intel_crtc_needs_modeset(crtc_state);
|
||||
|
||||
if (mode_changed || crtc_state->update_pipe ||
|
||||
crtc_state->uapi.color_mgmt_changed) {
|
||||
if (intel_crtc_needs_color_update(crtc_state))
|
||||
intel_dsb_prepare(crtc_state);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -7033,14 +7016,13 @@ static void commit_pipe_pre_planes(struct intel_atomic_state *state,
|
|||
* CRTC was enabled.
|
||||
*/
|
||||
if (!modeset) {
|
||||
if (new_crtc_state->uapi.color_mgmt_changed ||
|
||||
new_crtc_state->update_pipe)
|
||||
if (intel_crtc_needs_color_update(new_crtc_state))
|
||||
intel_color_commit_arm(new_crtc_state);
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
|
||||
bdw_set_pipemisc(new_crtc_state);
|
||||
|
||||
if (new_crtc_state->update_pipe)
|
||||
if (intel_crtc_needs_fastset(new_crtc_state))
|
||||
intel_pipe_fastset(old_crtc_state, new_crtc_state);
|
||||
}
|
||||
|
||||
|
@ -7099,25 +7081,23 @@ static void intel_update_crtc(struct intel_atomic_state *state,
|
|||
|
||||
if (!modeset) {
|
||||
if (new_crtc_state->preload_luts &&
|
||||
(new_crtc_state->uapi.color_mgmt_changed ||
|
||||
new_crtc_state->update_pipe))
|
||||
intel_crtc_needs_color_update(new_crtc_state))
|
||||
intel_color_load_luts(new_crtc_state);
|
||||
|
||||
intel_pre_plane_update(state, crtc);
|
||||
|
||||
if (new_crtc_state->update_pipe)
|
||||
if (intel_crtc_needs_fastset(new_crtc_state))
|
||||
intel_encoders_update_pipe(state, crtc);
|
||||
|
||||
if (DISPLAY_VER(i915) >= 11 &&
|
||||
new_crtc_state->update_pipe)
|
||||
intel_crtc_needs_fastset(new_crtc_state))
|
||||
icl_set_pipe_chicken(new_crtc_state);
|
||||
}
|
||||
|
||||
intel_fbc_update(state, crtc);
|
||||
|
||||
if (!modeset &&
|
||||
(new_crtc_state->uapi.color_mgmt_changed ||
|
||||
new_crtc_state->update_pipe))
|
||||
intel_crtc_needs_color_update(new_crtc_state))
|
||||
intel_color_commit_noarm(new_crtc_state);
|
||||
|
||||
intel_crtc_planes_update_noarm(state, crtc);
|
||||
|
@ -7139,7 +7119,7 @@ static void intel_update_crtc(struct intel_atomic_state *state,
|
|||
* valid pipe configuration from the BIOS we need to take care
|
||||
* of enabling them on the CRTC's first fastset.
|
||||
*/
|
||||
if (new_crtc_state->update_pipe && !modeset &&
|
||||
if (intel_crtc_needs_fastset(new_crtc_state) && !modeset &&
|
||||
old_crtc_state->inherited)
|
||||
intel_crtc_arm_fifo_underrun(crtc, new_crtc_state);
|
||||
}
|
||||
|
@ -7162,9 +7142,7 @@ static void intel_old_crtc_state_disables(struct intel_atomic_state *state,
|
|||
intel_fbc_disable(crtc);
|
||||
intel_disable_shared_dpll(old_crtc_state);
|
||||
|
||||
/* FIXME unify this for all platforms */
|
||||
if (!new_crtc_state->hw.active &&
|
||||
!HAS_GMCH(dev_priv))
|
||||
if (!new_crtc_state->hw.active)
|
||||
intel_initial_watermarks(state, crtc);
|
||||
}
|
||||
|
||||
|
@ -7499,9 +7477,8 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
|
|||
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
|
||||
new_crtc_state, i) {
|
||||
if (intel_crtc_needs_modeset(new_crtc_state) ||
|
||||
new_crtc_state->update_pipe) {
|
||||
intel_crtc_needs_fastset(new_crtc_state))
|
||||
intel_modeset_get_crtc_power_domains(new_crtc_state, &put_domains[crtc->pipe]);
|
||||
}
|
||||
}
|
||||
|
||||
intel_commit_modeset_disables(state);
|
||||
|
@ -7604,6 +7581,12 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
|
|||
|
||||
intel_modeset_verify_crtc(crtc, state, old_crtc_state, new_crtc_state);
|
||||
|
||||
/*
|
||||
* Activate DRRS after state readout to avoid
|
||||
* dp_m_n vs. dp_m2_n2 confusion on BDW+.
|
||||
*/
|
||||
intel_drrs_activate(new_crtc_state);
|
||||
|
||||
/*
|
||||
* DSB cleanup is done in cleanup_work aligning with framebuffer
|
||||
* cleanup. So copy and reset the dsb structure to sync with
|
||||
|
@ -8344,6 +8327,7 @@ void intel_init_display_hooks(struct drm_i915_private *dev_priv)
|
|||
if (!HAS_DISPLAY(dev_priv))
|
||||
return;
|
||||
|
||||
intel_color_init_hooks(dev_priv);
|
||||
intel_init_cdclk_hooks(dev_priv);
|
||||
intel_audio_hooks_init(dev_priv);
|
||||
|
||||
|
@ -8674,6 +8658,10 @@ int intel_modeset_init_noirq(struct drm_i915_private *i915)
|
|||
if (ret)
|
||||
goto cleanup_vga_client_pw_domain_dmc;
|
||||
|
||||
ret = intel_color_init(i915);
|
||||
if (ret)
|
||||
goto cleanup_vga_client_pw_domain_dmc;
|
||||
|
||||
ret = intel_dbuf_init(i915);
|
||||
if (ret)
|
||||
goto cleanup_vga_client_pw_domain_dmc;
|
||||
|
|
|
@ -469,10 +469,6 @@ enum hpd_pin {
|
|||
list_for_each_entry((intel_encoder), &(dev)->mode_config.encoder_list, base.head) \
|
||||
for_each_if((intel_encoder)->base.crtc == (__crtc))
|
||||
|
||||
#define for_each_connector_on_encoder(dev, __encoder, intel_connector) \
|
||||
list_for_each_entry((intel_connector), &(dev)->mode_config.connector_list, base.head) \
|
||||
for_each_if((intel_connector)->base.encoder == (__encoder))
|
||||
|
||||
#define for_each_old_intel_plane_in_state(__state, plane, old_plane_state, __i) \
|
||||
for ((__i) = 0; \
|
||||
(__i) < (__state)->base.dev->mode_config.num_total_plane && \
|
||||
|
@ -683,7 +679,8 @@ void intel_modeset_driver_remove(struct drm_i915_private *i915);
|
|||
void intel_modeset_driver_remove_noirq(struct drm_i915_private *i915);
|
||||
void intel_modeset_driver_remove_nogem(struct drm_i915_private *i915);
|
||||
void intel_display_resume(struct drm_device *dev);
|
||||
int intel_modeset_all_pipes(struct intel_atomic_state *state);
|
||||
int intel_modeset_all_pipes(struct intel_atomic_state *state,
|
||||
const char *reason);
|
||||
void intel_modeset_get_crtc_power_domains(struct intel_crtc_state *crtc_state,
|
||||
struct intel_power_domain_mask *old_domains);
|
||||
void intel_modeset_put_crtc_power_domains(struct intel_crtc *crtc,
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
struct drm_i915_private;
|
||||
struct drm_property;
|
||||
struct drm_property_blob;
|
||||
struct i915_audio_component;
|
||||
struct i915_hdcp_comp_master;
|
||||
struct intel_atomic_state;
|
||||
|
@ -308,6 +309,10 @@ struct intel_display {
|
|||
unsigned int max_cdclk_freq;
|
||||
} cdclk;
|
||||
|
||||
struct {
|
||||
struct drm_property_blob *glk_linear_degamma_lut;
|
||||
} color;
|
||||
|
||||
struct {
|
||||
/* The current hardware dbuf configuration */
|
||||
u8 enabled_slices;
|
||||
|
@ -315,6 +320,14 @@ struct intel_display {
|
|||
struct intel_global_obj obj;
|
||||
} dbuf;
|
||||
|
||||
struct {
|
||||
/*
|
||||
* dkl.phy_lock protects against concurrent access of the
|
||||
* Dekel TypeC PHYs.
|
||||
*/
|
||||
spinlock_t phy_lock;
|
||||
} dkl;
|
||||
|
||||
struct {
|
||||
/* VLV/CHV/BXT/GLK DSI MMIO register base address */
|
||||
u32 mmio_base;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "intel_fbdev.h"
|
||||
#include "intel_hdcp.h"
|
||||
#include "intel_hdmi.h"
|
||||
#include "intel_hotplug.h"
|
||||
#include "intel_panel.h"
|
||||
#include "intel_pm.h"
|
||||
#include "intel_psr.h"
|
||||
|
@ -127,7 +128,6 @@ static int i915_vbt(struct seq_file *m, void *unused)
|
|||
static int i915_gem_framebuffer_info(struct seq_file *m, void *data)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = node_to_i915(m->private);
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
struct intel_framebuffer *fbdev_fb = NULL;
|
||||
struct drm_framebuffer *drm_fb;
|
||||
|
||||
|
@ -146,8 +146,8 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data)
|
|||
}
|
||||
#endif
|
||||
|
||||
mutex_lock(&dev->mode_config.fb_lock);
|
||||
drm_for_each_fb(drm_fb, dev) {
|
||||
mutex_lock(&dev_priv->drm.mode_config.fb_lock);
|
||||
drm_for_each_fb(drm_fb, &dev_priv->drm) {
|
||||
struct intel_framebuffer *fb = to_intel_framebuffer(drm_fb);
|
||||
if (fb == fbdev_fb)
|
||||
continue;
|
||||
|
@ -162,7 +162,7 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data)
|
|||
i915_debugfs_describe_obj(m, intel_fb_obj(&fb->base));
|
||||
seq_putc(m, '\n');
|
||||
}
|
||||
mutex_unlock(&dev->mode_config.fb_lock);
|
||||
mutex_unlock(&dev_priv->drm.mode_config.fb_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -897,7 +897,6 @@ static void intel_crtc_info(struct seq_file *m, struct intel_crtc *crtc)
|
|||
static int i915_display_info(struct seq_file *m, void *unused)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = node_to_i915(m->private);
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
struct intel_crtc *crtc;
|
||||
struct drm_connector *connector;
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
|
@ -905,22 +904,22 @@ static int i915_display_info(struct seq_file *m, void *unused)
|
|||
|
||||
wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
|
||||
|
||||
drm_modeset_lock_all(dev);
|
||||
drm_modeset_lock_all(&dev_priv->drm);
|
||||
|
||||
seq_printf(m, "CRTC info\n");
|
||||
seq_printf(m, "---------\n");
|
||||
for_each_intel_crtc(dev, crtc)
|
||||
for_each_intel_crtc(&dev_priv->drm, crtc)
|
||||
intel_crtc_info(m, crtc);
|
||||
|
||||
seq_printf(m, "\n");
|
||||
seq_printf(m, "Connector info\n");
|
||||
seq_printf(m, "--------------\n");
|
||||
drm_connector_list_iter_begin(dev, &conn_iter);
|
||||
drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
|
||||
drm_for_each_connector_iter(connector, &conn_iter)
|
||||
intel_connector_info(m, connector);
|
||||
drm_connector_list_iter_end(&conn_iter);
|
||||
|
||||
drm_modeset_unlock_all(dev);
|
||||
drm_modeset_unlock_all(&dev_priv->drm);
|
||||
|
||||
intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref);
|
||||
|
||||
|
@ -930,10 +929,9 @@ static int i915_display_info(struct seq_file *m, void *unused)
|
|||
static int i915_shared_dplls_info(struct seq_file *m, void *unused)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = node_to_i915(m->private);
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
int i;
|
||||
|
||||
drm_modeset_lock_all(dev);
|
||||
drm_modeset_lock_all(&dev_priv->drm);
|
||||
|
||||
seq_printf(m, "PLL refclks: non-SSC: %d kHz, SSC: %d kHz\n",
|
||||
dev_priv->display.dpll.ref_clks.nssc,
|
||||
|
@ -978,7 +976,7 @@ static int i915_shared_dplls_info(struct seq_file *m, void *unused)
|
|||
seq_printf(m, " mg_pll_tdc_coldst_bias: 0x%08x\n",
|
||||
pll->state.hw_state.mg_pll_tdc_coldst_bias);
|
||||
}
|
||||
drm_modeset_unlock_all(dev);
|
||||
drm_modeset_unlock_all(&dev_priv->drm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -986,14 +984,13 @@ static int i915_shared_dplls_info(struct seq_file *m, void *unused)
|
|||
static int i915_ddb_info(struct seq_file *m, void *unused)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = node_to_i915(m->private);
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
struct skl_ddb_entry *entry;
|
||||
struct intel_crtc *crtc;
|
||||
|
||||
if (DISPLAY_VER(dev_priv) < 9)
|
||||
return -ENODEV;
|
||||
|
||||
drm_modeset_lock_all(dev);
|
||||
drm_modeset_lock_all(&dev_priv->drm);
|
||||
|
||||
seq_printf(m, "%-15s%8s%8s%8s\n", "", "Start", "End", "Size");
|
||||
|
||||
|
@ -1017,53 +1014,7 @@ static int i915_ddb_info(struct seq_file *m, void *unused)
|
|||
entry->end, skl_ddb_entry_size(entry));
|
||||
}
|
||||
|
||||
drm_modeset_unlock_all(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i915_drrs_status(struct seq_file *m, void *unused)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = node_to_i915(m->private);
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
struct intel_connector *connector;
|
||||
struct intel_crtc *crtc;
|
||||
|
||||
drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
|
||||
for_each_intel_connector_iter(connector, &conn_iter) {
|
||||
seq_printf(m, "[CONNECTOR:%d:%s] DRRS type: %s\n",
|
||||
connector->base.base.id, connector->base.name,
|
||||
intel_drrs_type_str(intel_panel_drrs_type(connector)));
|
||||
}
|
||||
drm_connector_list_iter_end(&conn_iter);
|
||||
|
||||
seq_puts(m, "\n");
|
||||
|
||||
for_each_intel_crtc(&dev_priv->drm, crtc) {
|
||||
const struct intel_crtc_state *crtc_state =
|
||||
to_intel_crtc_state(crtc->base.state);
|
||||
|
||||
seq_printf(m, "[CRTC:%d:%s]:\n",
|
||||
crtc->base.base.id, crtc->base.name);
|
||||
|
||||
mutex_lock(&crtc->drrs.mutex);
|
||||
|
||||
/* DRRS Supported */
|
||||
seq_printf(m, "\tDRRS Enabled: %s\n",
|
||||
str_yes_no(crtc_state->has_drrs));
|
||||
|
||||
seq_printf(m, "\tDRRS Active: %s\n",
|
||||
str_yes_no(intel_drrs_is_active(crtc)));
|
||||
|
||||
seq_printf(m, "\tBusy_frontbuffer_bits: 0x%X\n",
|
||||
crtc->drrs.busy_frontbuffer_bits);
|
||||
|
||||
seq_printf(m, "\tDRRS refresh rate: %s\n",
|
||||
crtc->drrs.refresh_rate == DRRS_REFRESH_RATE_LOW ?
|
||||
"low" : "high");
|
||||
|
||||
mutex_unlock(&crtc->drrs.mutex);
|
||||
}
|
||||
drm_modeset_unlock_all(&dev_priv->drm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1107,13 +1058,12 @@ static int i915_lpsp_status(struct seq_file *m, void *unused)
|
|||
static int i915_dp_mst_info(struct seq_file *m, void *unused)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = node_to_i915(m->private);
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
struct intel_encoder *intel_encoder;
|
||||
struct intel_digital_port *dig_port;
|
||||
struct drm_connector *connector;
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
|
||||
drm_connector_list_iter_begin(dev, &conn_iter);
|
||||
drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
|
||||
drm_for_each_connector_iter(connector, &conn_iter) {
|
||||
if (connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort)
|
||||
continue;
|
||||
|
@ -1200,12 +1150,11 @@ static ssize_t i915_displayport_test_active_write(struct file *file,
|
|||
static int i915_displayport_test_active_show(struct seq_file *m, void *data)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = m->private;
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
struct drm_connector *connector;
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
struct intel_dp *intel_dp;
|
||||
|
||||
drm_connector_list_iter_begin(dev, &conn_iter);
|
||||
drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
|
||||
drm_for_each_connector_iter(connector, &conn_iter) {
|
||||
struct intel_encoder *encoder;
|
||||
|
||||
|
@ -1250,12 +1199,11 @@ static const struct file_operations i915_displayport_test_active_fops = {
|
|||
static int i915_displayport_test_data_show(struct seq_file *m, void *data)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = m->private;
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
struct drm_connector *connector;
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
struct intel_dp *intel_dp;
|
||||
|
||||
drm_connector_list_iter_begin(dev, &conn_iter);
|
||||
drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
|
||||
drm_for_each_connector_iter(connector, &conn_iter) {
|
||||
struct intel_encoder *encoder;
|
||||
|
||||
|
@ -1304,12 +1252,11 @@ DEFINE_SHOW_ATTRIBUTE(i915_displayport_test_data);
|
|||
static int i915_displayport_test_type_show(struct seq_file *m, void *data)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = m->private;
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
struct drm_connector *connector;
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
struct intel_dp *intel_dp;
|
||||
|
||||
drm_connector_list_iter_begin(dev, &conn_iter);
|
||||
drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
|
||||
drm_for_each_connector_iter(connector, &conn_iter) {
|
||||
struct intel_encoder *encoder;
|
||||
|
||||
|
@ -1336,7 +1283,6 @@ DEFINE_SHOW_ATTRIBUTE(i915_displayport_test_type);
|
|||
static void wm_latency_show(struct seq_file *m, const u16 wm[8])
|
||||
{
|
||||
struct drm_i915_private *dev_priv = m->private;
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
int level;
|
||||
int num_levels;
|
||||
|
||||
|
@ -1349,7 +1295,7 @@ static void wm_latency_show(struct seq_file *m, const u16 wm[8])
|
|||
else
|
||||
num_levels = ilk_wm_max_level(dev_priv) + 1;
|
||||
|
||||
drm_modeset_lock_all(dev);
|
||||
drm_modeset_lock_all(&dev_priv->drm);
|
||||
|
||||
for (level = 0; level < num_levels; level++) {
|
||||
unsigned int latency = wm[level];
|
||||
|
@ -1370,7 +1316,7 @@ static void wm_latency_show(struct seq_file *m, const u16 wm[8])
|
|||
level, wm[level], latency / 10, latency % 10);
|
||||
}
|
||||
|
||||
drm_modeset_unlock_all(dev);
|
||||
drm_modeset_unlock_all(&dev_priv->drm);
|
||||
}
|
||||
|
||||
static int pri_wm_latency_show(struct seq_file *m, void *data)
|
||||
|
@ -1453,7 +1399,6 @@ static ssize_t wm_latency_write(struct file *file, const char __user *ubuf,
|
|||
{
|
||||
struct seq_file *m = file->private_data;
|
||||
struct drm_i915_private *dev_priv = m->private;
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
u16 new[8] = { 0 };
|
||||
int num_levels;
|
||||
int level;
|
||||
|
@ -1483,12 +1428,12 @@ static ssize_t wm_latency_write(struct file *file, const char __user *ubuf,
|
|||
if (ret != num_levels)
|
||||
return -EINVAL;
|
||||
|
||||
drm_modeset_lock_all(dev);
|
||||
drm_modeset_lock_all(&dev_priv->drm);
|
||||
|
||||
for (level = 0; level < num_levels; level++)
|
||||
wm[level] = new[level];
|
||||
|
||||
drm_modeset_unlock_all(dev);
|
||||
drm_modeset_unlock_all(&dev_priv->drm);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
@ -1566,209 +1511,6 @@ static const struct file_operations i915_cur_wm_latency_fops = {
|
|||
.write = cur_wm_latency_write
|
||||
};
|
||||
|
||||
static int i915_hpd_storm_ctl_show(struct seq_file *m, void *data)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = m->private;
|
||||
struct intel_hotplug *hotplug = &dev_priv->display.hotplug;
|
||||
|
||||
/* Synchronize with everything first in case there's been an HPD
|
||||
* storm, but we haven't finished handling it in the kernel yet
|
||||
*/
|
||||
intel_synchronize_irq(dev_priv);
|
||||
flush_work(&dev_priv->display.hotplug.dig_port_work);
|
||||
flush_delayed_work(&dev_priv->display.hotplug.hotplug_work);
|
||||
|
||||
seq_printf(m, "Threshold: %d\n", hotplug->hpd_storm_threshold);
|
||||
seq_printf(m, "Detected: %s\n",
|
||||
str_yes_no(delayed_work_pending(&hotplug->reenable_work)));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t i915_hpd_storm_ctl_write(struct file *file,
|
||||
const char __user *ubuf, size_t len,
|
||||
loff_t *offp)
|
||||
{
|
||||
struct seq_file *m = file->private_data;
|
||||
struct drm_i915_private *dev_priv = m->private;
|
||||
struct intel_hotplug *hotplug = &dev_priv->display.hotplug;
|
||||
unsigned int new_threshold;
|
||||
int i;
|
||||
char *newline;
|
||||
char tmp[16];
|
||||
|
||||
if (len >= sizeof(tmp))
|
||||
return -EINVAL;
|
||||
|
||||
if (copy_from_user(tmp, ubuf, len))
|
||||
return -EFAULT;
|
||||
|
||||
tmp[len] = '\0';
|
||||
|
||||
/* Strip newline, if any */
|
||||
newline = strchr(tmp, '\n');
|
||||
if (newline)
|
||||
*newline = '\0';
|
||||
|
||||
if (strcmp(tmp, "reset") == 0)
|
||||
new_threshold = HPD_STORM_DEFAULT_THRESHOLD;
|
||||
else if (kstrtouint(tmp, 10, &new_threshold) != 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (new_threshold > 0)
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"Setting HPD storm detection threshold to %d\n",
|
||||
new_threshold);
|
||||
else
|
||||
drm_dbg_kms(&dev_priv->drm, "Disabling HPD storm detection\n");
|
||||
|
||||
spin_lock_irq(&dev_priv->irq_lock);
|
||||
hotplug->hpd_storm_threshold = new_threshold;
|
||||
/* Reset the HPD storm stats so we don't accidentally trigger a storm */
|
||||
for_each_hpd_pin(i)
|
||||
hotplug->stats[i].count = 0;
|
||||
spin_unlock_irq(&dev_priv->irq_lock);
|
||||
|
||||
/* Re-enable hpd immediately if we were in an irq storm */
|
||||
flush_delayed_work(&dev_priv->display.hotplug.reenable_work);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static int i915_hpd_storm_ctl_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, i915_hpd_storm_ctl_show, inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations i915_hpd_storm_ctl_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = i915_hpd_storm_ctl_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
.write = i915_hpd_storm_ctl_write
|
||||
};
|
||||
|
||||
static int i915_hpd_short_storm_ctl_show(struct seq_file *m, void *data)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = m->private;
|
||||
|
||||
seq_printf(m, "Enabled: %s\n",
|
||||
str_yes_no(dev_priv->display.hotplug.hpd_short_storm_enabled));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
i915_hpd_short_storm_ctl_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, i915_hpd_short_storm_ctl_show,
|
||||
inode->i_private);
|
||||
}
|
||||
|
||||
static ssize_t i915_hpd_short_storm_ctl_write(struct file *file,
|
||||
const char __user *ubuf,
|
||||
size_t len, loff_t *offp)
|
||||
{
|
||||
struct seq_file *m = file->private_data;
|
||||
struct drm_i915_private *dev_priv = m->private;
|
||||
struct intel_hotplug *hotplug = &dev_priv->display.hotplug;
|
||||
char *newline;
|
||||
char tmp[16];
|
||||
int i;
|
||||
bool new_state;
|
||||
|
||||
if (len >= sizeof(tmp))
|
||||
return -EINVAL;
|
||||
|
||||
if (copy_from_user(tmp, ubuf, len))
|
||||
return -EFAULT;
|
||||
|
||||
tmp[len] = '\0';
|
||||
|
||||
/* Strip newline, if any */
|
||||
newline = strchr(tmp, '\n');
|
||||
if (newline)
|
||||
*newline = '\0';
|
||||
|
||||
/* Reset to the "default" state for this system */
|
||||
if (strcmp(tmp, "reset") == 0)
|
||||
new_state = !HAS_DP_MST(dev_priv);
|
||||
else if (kstrtobool(tmp, &new_state) != 0)
|
||||
return -EINVAL;
|
||||
|
||||
drm_dbg_kms(&dev_priv->drm, "%sabling HPD short storm detection\n",
|
||||
new_state ? "En" : "Dis");
|
||||
|
||||
spin_lock_irq(&dev_priv->irq_lock);
|
||||
hotplug->hpd_short_storm_enabled = new_state;
|
||||
/* Reset the HPD storm stats so we don't accidentally trigger a storm */
|
||||
for_each_hpd_pin(i)
|
||||
hotplug->stats[i].count = 0;
|
||||
spin_unlock_irq(&dev_priv->irq_lock);
|
||||
|
||||
/* Re-enable hpd immediately if we were in an irq storm */
|
||||
flush_delayed_work(&dev_priv->display.hotplug.reenable_work);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static const struct file_operations i915_hpd_short_storm_ctl_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = i915_hpd_short_storm_ctl_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
.write = i915_hpd_short_storm_ctl_write,
|
||||
};
|
||||
|
||||
static int i915_drrs_ctl_set(void *data, u64 val)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = data;
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
struct intel_crtc *crtc;
|
||||
|
||||
for_each_intel_crtc(dev, crtc) {
|
||||
struct intel_crtc_state *crtc_state;
|
||||
struct drm_crtc_commit *commit;
|
||||
int ret;
|
||||
|
||||
ret = drm_modeset_lock_single_interruptible(&crtc->base.mutex);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
crtc_state = to_intel_crtc_state(crtc->base.state);
|
||||
|
||||
if (!crtc_state->hw.active ||
|
||||
!crtc_state->has_drrs)
|
||||
goto out;
|
||||
|
||||
commit = crtc_state->uapi.commit;
|
||||
if (commit) {
|
||||
ret = wait_for_completion_interruptible(&commit->hw_done);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
drm_dbg(&dev_priv->drm,
|
||||
"Manually %sactivating DRRS\n", val ? "" : "de");
|
||||
|
||||
if (val)
|
||||
intel_drrs_activate(crtc_state);
|
||||
else
|
||||
intel_drrs_deactivate(crtc_state);
|
||||
|
||||
out:
|
||||
drm_modeset_unlock(&crtc->base.mutex);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_SIMPLE_ATTRIBUTE(i915_drrs_ctl_fops, NULL, i915_drrs_ctl_set, "%llu\n");
|
||||
|
||||
static ssize_t
|
||||
i915_fifo_underrun_reset_write(struct file *filp,
|
||||
const char __user *ubuf,
|
||||
|
@ -1776,7 +1518,6 @@ i915_fifo_underrun_reset_write(struct file *filp,
|
|||
{
|
||||
struct drm_i915_private *dev_priv = filp->private_data;
|
||||
struct intel_crtc *crtc;
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
int ret;
|
||||
bool reset;
|
||||
|
||||
|
@ -1787,7 +1528,7 @@ i915_fifo_underrun_reset_write(struct file *filp,
|
|||
if (!reset)
|
||||
return cnt;
|
||||
|
||||
for_each_intel_crtc(dev, crtc) {
|
||||
for_each_intel_crtc(&dev_priv->drm, crtc) {
|
||||
struct drm_crtc_commit *commit;
|
||||
struct intel_crtc_state *crtc_state;
|
||||
|
||||
|
@ -1842,7 +1583,6 @@ static const struct drm_info_list intel_display_debugfs_list[] = {
|
|||
{"i915_shared_dplls_info", i915_shared_dplls_info, 0},
|
||||
{"i915_dp_mst_info", i915_dp_mst_info, 0},
|
||||
{"i915_ddb_info", i915_ddb_info, 0},
|
||||
{"i915_drrs_status", i915_drrs_status, 0},
|
||||
{"i915_lpsp_status", i915_lpsp_status, 0},
|
||||
};
|
||||
|
||||
|
@ -1857,9 +1597,6 @@ static const struct {
|
|||
{"i915_dp_test_data", &i915_displayport_test_data_fops},
|
||||
{"i915_dp_test_type", &i915_displayport_test_type_fops},
|
||||
{"i915_dp_test_active", &i915_displayport_test_active_fops},
|
||||
{"i915_hpd_storm_ctl", &i915_hpd_storm_ctl_fops},
|
||||
{"i915_hpd_short_storm_ctl", &i915_hpd_short_storm_ctl_fops},
|
||||
{"i915_drrs_ctl", &i915_drrs_ctl_fops},
|
||||
{"i915_edp_psr_debug", &i915_edp_psr_debug_fops},
|
||||
};
|
||||
|
||||
|
@ -1882,6 +1619,7 @@ void intel_display_debugfs_register(struct drm_i915_private *i915)
|
|||
|
||||
intel_dmc_debugfs_register(i915);
|
||||
intel_fbc_debugfs_register(i915);
|
||||
intel_hpd_debugfs_register(i915);
|
||||
skl_watermark_ipc_debugfs_register(i915);
|
||||
}
|
||||
|
||||
|
@ -2195,6 +1933,8 @@ void intel_connector_debugfs_add(struct intel_connector *intel_connector)
|
|||
if (!root)
|
||||
return;
|
||||
|
||||
intel_drrs_connector_debugfs_add(intel_connector);
|
||||
|
||||
if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
|
||||
debugfs_create_file("i915_panel_timings", S_IRUGO, root,
|
||||
connector, &i915_panel_fops);
|
||||
|
@ -2247,6 +1987,7 @@ void intel_crtc_debugfs_add(struct drm_crtc *crtc)
|
|||
return;
|
||||
|
||||
crtc_updates_add(crtc);
|
||||
intel_drrs_crtc_debugfs_add(to_intel_crtc(crtc));
|
||||
intel_fbc_crtc_debugfs_add(to_intel_crtc(crtc));
|
||||
|
||||
debugfs_create_file("i915_current_bpc", 0444, crtc->debugfs_entry, crtc,
|
||||
|
|
|
@ -1148,10 +1148,9 @@ static void hsw_assert_cdclk(struct drm_i915_private *dev_priv)
|
|||
|
||||
static void assert_can_disable_lcpll(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
struct intel_crtc *crtc;
|
||||
|
||||
for_each_intel_crtc(dev, crtc)
|
||||
for_each_intel_crtc(&dev_priv->drm, crtc)
|
||||
I915_STATE_WARN(crtc->active, "CRTC for pipe %c enabled\n",
|
||||
pipe_name(crtc->pipe));
|
||||
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#include "intel_de.h"
|
||||
#include "intel_display_power_well.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dkl_phy.h"
|
||||
#include "intel_dkl_phy_regs.h"
|
||||
#include "intel_dmc.h"
|
||||
#include "intel_dpio_phy.h"
|
||||
#include "intel_dpll.h"
|
||||
|
@ -529,11 +531,9 @@ icl_tc_phy_aux_power_well_enable(struct drm_i915_private *dev_priv,
|
|||
enum tc_port tc_port;
|
||||
|
||||
tc_port = TGL_AUX_PW_TO_TC_PORT(i915_power_well_instance(power_well)->hsw.idx);
|
||||
intel_de_write(dev_priv, HIP_INDEX_REG(tc_port),
|
||||
HIP_INDEX_VAL(tc_port, 0x2));
|
||||
|
||||
if (intel_de_wait_for_set(dev_priv, DKL_CMN_UC_DW_27(tc_port),
|
||||
DKL_CMN_UC_DW27_UC_HEALTH, 1))
|
||||
if (wait_for(intel_dkl_phy_read(dev_priv, DKL_CMN_UC_DW_27(tc_port)) &
|
||||
DKL_CMN_UC_DW27_UC_HEALTH, 1))
|
||||
drm_warn(&dev_priv->drm,
|
||||
"Timeout waiting TC uC health\n");
|
||||
}
|
||||
|
|
|
@ -1001,11 +1001,15 @@ struct intel_crtc_state {
|
|||
*/
|
||||
struct {
|
||||
bool active, enable;
|
||||
/* logical state of LUTs */
|
||||
struct drm_property_blob *degamma_lut, *gamma_lut, *ctm;
|
||||
struct drm_display_mode mode, pipe_mode, adjusted_mode;
|
||||
enum drm_scaling_filter scaling_filter;
|
||||
} hw;
|
||||
|
||||
/* actual state of LUTs */
|
||||
struct drm_property_blob *pre_csc_lut, *post_csc_lut;
|
||||
|
||||
/**
|
||||
* quirks - bitfield with hw state readout quirks
|
||||
*
|
||||
|
@ -2040,15 +2044,16 @@ static inline bool
|
|||
intel_crtc_has_type(const struct intel_crtc_state *crtc_state,
|
||||
enum intel_output_type type)
|
||||
{
|
||||
return crtc_state->output_types & (1 << type);
|
||||
return crtc_state->output_types & BIT(type);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
intel_crtc_has_dp_encoder(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
return crtc_state->output_types &
|
||||
((1 << INTEL_OUTPUT_DP) |
|
||||
(1 << INTEL_OUTPUT_DP_MST) |
|
||||
(1 << INTEL_OUTPUT_EDP));
|
||||
(BIT(INTEL_OUTPUT_DP) |
|
||||
BIT(INTEL_OUTPUT_DP_MST) |
|
||||
BIT(INTEL_OUTPUT_EDP));
|
||||
}
|
||||
|
||||
static inline bool
|
||||
|
@ -2057,6 +2062,20 @@ intel_crtc_needs_modeset(const struct intel_crtc_state *crtc_state)
|
|||
return drm_atomic_crtc_needs_modeset(&crtc_state->uapi);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
intel_crtc_needs_fastset(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
return crtc_state->update_pipe;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
intel_crtc_needs_color_update(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
return crtc_state->uapi.color_mgmt_changed ||
|
||||
intel_crtc_needs_fastset(crtc_state) ||
|
||||
intel_crtc_needs_modeset(crtc_state);
|
||||
}
|
||||
|
||||
static inline u32 intel_plane_ggtt_offset(const struct intel_plane_state *plane_state)
|
||||
{
|
||||
return i915_ggtt_offset(plane_state->ggtt_vma);
|
||||
|
|
106
drivers/gpu/drm/i915/display/intel_dkl_phy.c
Normal file
106
drivers/gpu/drm/i915/display/intel_dkl_phy.c
Normal file
|
@ -0,0 +1,106 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* Copyright © 2022 Intel Corporation
|
||||
*/
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
|
||||
#include "intel_de.h"
|
||||
#include "intel_display.h"
|
||||
#include "intel_dkl_phy.h"
|
||||
#include "intel_dkl_phy_regs.h"
|
||||
|
||||
static void
|
||||
dkl_phy_set_hip_idx(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg)
|
||||
{
|
||||
enum tc_port tc_port = DKL_REG_TC_PORT(reg);
|
||||
|
||||
drm_WARN_ON(&i915->drm, tc_port < TC_PORT_1 || tc_port >= I915_MAX_TC_PORTS);
|
||||
|
||||
intel_de_write(i915,
|
||||
HIP_INDEX_REG(tc_port),
|
||||
HIP_INDEX_VAL(tc_port, reg.bank_idx));
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_dkl_phy_read - read a Dekel PHY register
|
||||
* @i915: i915 device instance
|
||||
* @reg: Dekel PHY register
|
||||
*
|
||||
* Read the @reg Dekel PHY register.
|
||||
*
|
||||
* Returns the read value.
|
||||
*/
|
||||
u32
|
||||
intel_dkl_phy_read(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
spin_lock(&i915->display.dkl.phy_lock);
|
||||
|
||||
dkl_phy_set_hip_idx(i915, reg);
|
||||
val = intel_de_read(i915, DKL_REG_MMIO(reg));
|
||||
|
||||
spin_unlock(&i915->display.dkl.phy_lock);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_dkl_phy_write - write a Dekel PHY register
|
||||
* @i915: i915 device instance
|
||||
* @reg: Dekel PHY register
|
||||
* @val: value to write
|
||||
*
|
||||
* Write @val to the @reg Dekel PHY register.
|
||||
*/
|
||||
void
|
||||
intel_dkl_phy_write(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg, u32 val)
|
||||
{
|
||||
spin_lock(&i915->display.dkl.phy_lock);
|
||||
|
||||
dkl_phy_set_hip_idx(i915, reg);
|
||||
intel_de_write(i915, DKL_REG_MMIO(reg), val);
|
||||
|
||||
spin_unlock(&i915->display.dkl.phy_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_dkl_phy_rmw - read-modify-write a Dekel PHY register
|
||||
* @i915: i915 device instance
|
||||
* @reg: Dekel PHY register
|
||||
* @clear: mask to clear
|
||||
* @set: mask to set
|
||||
*
|
||||
* Read the @reg Dekel PHY register, clearing then setting the @clear/@set bits in it, and writing
|
||||
* this value back to the register if the value differs from the read one.
|
||||
*/
|
||||
void
|
||||
intel_dkl_phy_rmw(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg, u32 clear, u32 set)
|
||||
{
|
||||
spin_lock(&i915->display.dkl.phy_lock);
|
||||
|
||||
dkl_phy_set_hip_idx(i915, reg);
|
||||
intel_de_rmw(i915, DKL_REG_MMIO(reg), clear, set);
|
||||
|
||||
spin_unlock(&i915->display.dkl.phy_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_dkl_phy_posting_read - do a posting read from a Dekel PHY register
|
||||
* @i915: i915 device instance
|
||||
* @reg: Dekel PHY register
|
||||
*
|
||||
* Read the @reg Dekel PHY register without returning the read value.
|
||||
*/
|
||||
void
|
||||
intel_dkl_phy_posting_read(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg)
|
||||
{
|
||||
spin_lock(&i915->display.dkl.phy_lock);
|
||||
|
||||
dkl_phy_set_hip_idx(i915, reg);
|
||||
intel_de_posting_read(i915, DKL_REG_MMIO(reg));
|
||||
|
||||
spin_unlock(&i915->display.dkl.phy_lock);
|
||||
}
|
24
drivers/gpu/drm/i915/display/intel_dkl_phy.h
Normal file
24
drivers/gpu/drm/i915/display/intel_dkl_phy.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
/*
|
||||
* Copyright © 2022 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef __INTEL_DKL_PHY_H__
|
||||
#define __INTEL_DKL_PHY_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#include "intel_dkl_phy_regs.h"
|
||||
|
||||
struct drm_i915_private;
|
||||
|
||||
u32
|
||||
intel_dkl_phy_read(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg);
|
||||
void
|
||||
intel_dkl_phy_write(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg, u32 val);
|
||||
void
|
||||
intel_dkl_phy_rmw(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg, u32 clear, u32 set);
|
||||
void
|
||||
intel_dkl_phy_posting_read(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg);
|
||||
|
||||
#endif /* __INTEL_DKL_PHY_H__ */
|
204
drivers/gpu/drm/i915/display/intel_dkl_phy_regs.h
Normal file
204
drivers/gpu/drm/i915/display/intel_dkl_phy_regs.h
Normal file
|
@ -0,0 +1,204 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
/*
|
||||
* Copyright © 2022 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef __INTEL_DKL_PHY_REGS__
|
||||
#define __INTEL_DKL_PHY_REGS__
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct intel_dkl_phy_reg {
|
||||
u32 reg:24;
|
||||
u32 bank_idx:4;
|
||||
};
|
||||
|
||||
#define _DKL_PHY1_BASE 0x168000
|
||||
#define _DKL_PHY2_BASE 0x169000
|
||||
#define _DKL_PHY3_BASE 0x16A000
|
||||
#define _DKL_PHY4_BASE 0x16B000
|
||||
#define _DKL_PHY5_BASE 0x16C000
|
||||
#define _DKL_PHY6_BASE 0x16D000
|
||||
|
||||
#define DKL_REG_TC_PORT(__reg) \
|
||||
(TC_PORT_1 + ((__reg).reg - _DKL_PHY1_BASE) / (_DKL_PHY2_BASE - _DKL_PHY1_BASE))
|
||||
|
||||
/* DEKEL PHY MMIO Address = Phy base + (internal address & ~index_mask) */
|
||||
#define DKL_REG_MMIO(__reg) _MMIO((__reg).reg)
|
||||
|
||||
#define _DKL_REG_PHY_BASE(tc_port) _PORT(tc_port, \
|
||||
_DKL_PHY1_BASE, \
|
||||
_DKL_PHY2_BASE)
|
||||
|
||||
#define _DKL_BANK_SHIFT 12
|
||||
#define _DKL_REG_BANK_OFFSET(phy_offset) \
|
||||
((phy_offset) & ((1 << _DKL_BANK_SHIFT) - 1))
|
||||
#define _DKL_REG_BANK_IDX(phy_offset) \
|
||||
(((phy_offset) >> _DKL_BANK_SHIFT) & 0xf)
|
||||
|
||||
#define _DKL_REG(tc_port, phy_offset) \
|
||||
((const struct intel_dkl_phy_reg) { \
|
||||
.reg = _DKL_REG_PHY_BASE(tc_port) + \
|
||||
_DKL_REG_BANK_OFFSET(phy_offset), \
|
||||
.bank_idx = _DKL_REG_BANK_IDX(phy_offset), \
|
||||
})
|
||||
|
||||
#define _DKL_REG_LN(tc_port, ln_idx, ln0_offs, ln1_offs) \
|
||||
_DKL_REG(tc_port, (ln0_offs) + (ln_idx) * ((ln1_offs) - (ln0_offs)))
|
||||
|
||||
#define _DKL_PCS_DW5_LN0 0x0014
|
||||
#define _DKL_PCS_DW5_LN1 0x1014
|
||||
#define DKL_PCS_DW5(tc_port, ln) _DKL_REG_LN(tc_port, ln, \
|
||||
_DKL_PCS_DW5_LN0, \
|
||||
_DKL_PCS_DW5_LN1)
|
||||
#define DKL_PCS_DW5_CORE_SOFTRESET REG_BIT(11)
|
||||
|
||||
#define _DKL_PLL_DIV0 0x2200
|
||||
#define DKL_PLL_DIV0(tc_port) _DKL_REG(tc_port, \
|
||||
_DKL_PLL_DIV0)
|
||||
#define DKL_PLL_DIV0_AFC_STARTUP_MASK REG_GENMASK(27, 25)
|
||||
#define DKL_PLL_DIV0_AFC_STARTUP(val) REG_FIELD_PREP(DKL_PLL_DIV0_AFC_STARTUP_MASK, (val))
|
||||
#define DKL_PLL_DIV0_INTEG_COEFF(x) ((x) << 16)
|
||||
#define DKL_PLL_DIV0_INTEG_COEFF_MASK (0x1F << 16)
|
||||
#define DKL_PLL_DIV0_PROP_COEFF(x) ((x) << 12)
|
||||
#define DKL_PLL_DIV0_PROP_COEFF_MASK (0xF << 12)
|
||||
#define DKL_PLL_DIV0_FBPREDIV_SHIFT (8)
|
||||
#define DKL_PLL_DIV0_FBPREDIV(x) ((x) << DKL_PLL_DIV0_FBPREDIV_SHIFT)
|
||||
#define DKL_PLL_DIV0_FBPREDIV_MASK (0xF << DKL_PLL_DIV0_FBPREDIV_SHIFT)
|
||||
#define DKL_PLL_DIV0_FBDIV_INT(x) ((x) << 0)
|
||||
#define DKL_PLL_DIV0_FBDIV_INT_MASK (0xFF << 0)
|
||||
#define DKL_PLL_DIV0_MASK (DKL_PLL_DIV0_INTEG_COEFF_MASK | \
|
||||
DKL_PLL_DIV0_PROP_COEFF_MASK | \
|
||||
DKL_PLL_DIV0_FBPREDIV_MASK | \
|
||||
DKL_PLL_DIV0_FBDIV_INT_MASK)
|
||||
|
||||
#define _DKL_PLL_DIV1 0x2204
|
||||
#define DKL_PLL_DIV1(tc_port) _DKL_REG(tc_port, \
|
||||
_DKL_PLL_DIV1)
|
||||
#define DKL_PLL_DIV1_IREF_TRIM(x) ((x) << 16)
|
||||
#define DKL_PLL_DIV1_IREF_TRIM_MASK (0x1F << 16)
|
||||
#define DKL_PLL_DIV1_TDC_TARGET_CNT(x) ((x) << 0)
|
||||
#define DKL_PLL_DIV1_TDC_TARGET_CNT_MASK (0xFF << 0)
|
||||
|
||||
#define _DKL_PLL_SSC 0x2210
|
||||
#define DKL_PLL_SSC(tc_port) _DKL_REG(tc_port, \
|
||||
_DKL_PLL_SSC)
|
||||
#define DKL_PLL_SSC_IREF_NDIV_RATIO(x) ((x) << 29)
|
||||
#define DKL_PLL_SSC_IREF_NDIV_RATIO_MASK (0x7 << 29)
|
||||
#define DKL_PLL_SSC_STEP_LEN(x) ((x) << 16)
|
||||
#define DKL_PLL_SSC_STEP_LEN_MASK (0xFF << 16)
|
||||
#define DKL_PLL_SSC_STEP_NUM(x) ((x) << 11)
|
||||
#define DKL_PLL_SSC_STEP_NUM_MASK (0x7 << 11)
|
||||
#define DKL_PLL_SSC_EN (1 << 9)
|
||||
|
||||
#define _DKL_PLL_BIAS 0x2214
|
||||
#define DKL_PLL_BIAS(tc_port) _DKL_REG(tc_port, \
|
||||
_DKL_PLL_BIAS)
|
||||
#define DKL_PLL_BIAS_FRAC_EN_H (1 << 30)
|
||||
#define DKL_PLL_BIAS_FBDIV_SHIFT (8)
|
||||
#define DKL_PLL_BIAS_FBDIV_FRAC(x) ((x) << DKL_PLL_BIAS_FBDIV_SHIFT)
|
||||
#define DKL_PLL_BIAS_FBDIV_FRAC_MASK (0x3FFFFF << DKL_PLL_BIAS_FBDIV_SHIFT)
|
||||
|
||||
#define _DKL_PLL_TDC_COLDST_BIAS 0x2218
|
||||
#define DKL_PLL_TDC_COLDST_BIAS(tc_port) _DKL_REG(tc_port, \
|
||||
_DKL_PLL_TDC_COLDST_BIAS)
|
||||
#define DKL_PLL_TDC_SSC_STEP_SIZE(x) ((x) << 8)
|
||||
#define DKL_PLL_TDC_SSC_STEP_SIZE_MASK (0xFF << 8)
|
||||
#define DKL_PLL_TDC_FEED_FWD_GAIN(x) ((x) << 0)
|
||||
#define DKL_PLL_TDC_FEED_FWD_GAIN_MASK (0xFF << 0)
|
||||
|
||||
#define _DKL_REFCLKIN_CTL 0x212C
|
||||
#define DKL_REFCLKIN_CTL(tc_port) _DKL_REG(tc_port, \
|
||||
_DKL_REFCLKIN_CTL)
|
||||
/* Bits are the same as MG_REFCLKIN_CTL */
|
||||
|
||||
#define _DKL_CLKTOP2_HSCLKCTL 0x20D4
|
||||
#define DKL_CLKTOP2_HSCLKCTL(rc_port) _DKL_REG(tc_port, \
|
||||
_DKL_CLKTOP2_HSCLKCTL)
|
||||
/* Bits are the same as MG_CLKTOP2_HSCLKCTL */
|
||||
|
||||
#define _DKL_CLKTOP2_CORECLKCTL1 0x20D8
|
||||
#define DKL_CLKTOP2_CORECLKCTL1(tc_port) _DKL_REG(tc_port, \
|
||||
_DKL_CLKTOP2_CORECLKCTL1)
|
||||
/* Bits are the same as MG_CLKTOP2_CORECLKCTL1 */
|
||||
|
||||
#define _DKL_TX_DPCNTL0_LN0 0x02C0
|
||||
#define _DKL_TX_DPCNTL0_LN1 0x12C0
|
||||
#define DKL_TX_DPCNTL0(tc_port, ln) _DKL_REG_LN(tc_port, ln, \
|
||||
_DKL_TX_DPCNTL0_LN0, \
|
||||
_DKL_TX_DPCNTL0_LN1)
|
||||
#define DKL_TX_PRESHOOT_COEFF(x) ((x) << 13)
|
||||
#define DKL_TX_PRESHOOT_COEFF_MASK (0x1f << 13)
|
||||
#define DKL_TX_DE_EMPHASIS_COEFF(x) ((x) << 8)
|
||||
#define DKL_TX_DE_EMPAHSIS_COEFF_MASK (0x1f << 8)
|
||||
#define DKL_TX_VSWING_CONTROL(x) ((x) << 0)
|
||||
#define DKL_TX_VSWING_CONTROL_MASK (0x7 << 0)
|
||||
|
||||
#define _DKL_TX_DPCNTL1_LN0 0x02C4
|
||||
#define _DKL_TX_DPCNTL1_LN1 0x12C4
|
||||
#define DKL_TX_DPCNTL1(tc_port, ln) _DKL_REG_LN(tc_port, ln, \
|
||||
_DKL_TX_DPCNTL1_LN0, \
|
||||
_DKL_TX_DPCNTL1_LN1)
|
||||
/* Bits are the same as DKL_TX_DPCNTRL0 */
|
||||
|
||||
#define _DKL_TX_DPCNTL2_LN0 0x02C8
|
||||
#define _DKL_TX_DPCNTL2_LN1 0x12C8
|
||||
#define DKL_TX_DPCNTL2(tc_port, ln) _DKL_REG_LN(tc_port, ln, \
|
||||
_DKL_TX_DPCNTL2_LN0, \
|
||||
_DKL_TX_DPCNTL2_LN1)
|
||||
#define DKL_TX_DP20BITMODE REG_BIT(2)
|
||||
#define DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX1_MASK REG_GENMASK(4, 3)
|
||||
#define DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX1(val) REG_FIELD_PREP(DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX1_MASK, (val))
|
||||
#define DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2_MASK REG_GENMASK(6, 5)
|
||||
#define DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2(val) REG_FIELD_PREP(DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2_MASK, (val))
|
||||
|
||||
#define _DKL_TX_FW_CALIB_LN0 0x02F8
|
||||
#define _DKL_TX_FW_CALIB_LN1 0x12F8
|
||||
#define DKL_TX_FW_CALIB(tc_port, ln) _DKL_REG_LN(tc_port, ln, \
|
||||
_DKL_TX_FW_CALIB_LN0, \
|
||||
_DKL_TX_FW_CALIB_LN1)
|
||||
#define DKL_TX_CFG_DISABLE_WAIT_INIT (1 << 7)
|
||||
|
||||
#define _DKL_TX_PMD_LANE_SUS_LN0 0x0D00
|
||||
#define _DKL_TX_PMD_LANE_SUS_LN1 0x1D00
|
||||
#define DKL_TX_PMD_LANE_SUS(tc_port, ln) _DKL_REG_LN(tc_port, ln, \
|
||||
_DKL_TX_PMD_LANE_SUS_LN0, \
|
||||
_DKL_TX_PMD_LANE_SUS_LN1)
|
||||
|
||||
#define _DKL_TX_DW17_LN0 0x0DC4
|
||||
#define _DKL_TX_DW17_LN1 0x1DC4
|
||||
#define DKL_TX_DW17(tc_port, ln) _DKL_REG_LN(tc_port, ln, \
|
||||
_DKL_TX_DW17_LN0, \
|
||||
_DKL_TX_DW17_LN1)
|
||||
|
||||
#define _DKL_TX_DW18_LN0 0x0DC8
|
||||
#define _DKL_TX_DW18_LN1 0x1DC8
|
||||
#define DKL_TX_DW18(tc_port, ln) _DKL_REG_LN(tc_port, ln, \
|
||||
_DKL_TX_DW18_LN0, \
|
||||
_DKL_TX_DW18_LN1)
|
||||
|
||||
#define _DKL_DP_MODE_LN0 0x00A0
|
||||
#define _DKL_DP_MODE_LN1 0x10A0
|
||||
#define DKL_DP_MODE(tc_port, ln) _DKL_REG_LN(tc_port, ln, \
|
||||
_DKL_DP_MODE_LN0, \
|
||||
_DKL_DP_MODE_LN1)
|
||||
|
||||
#define _DKL_CMN_UC_DW27 0x236C
|
||||
#define DKL_CMN_UC_DW_27(tc_port) _DKL_REG(tc_port, \
|
||||
_DKL_CMN_UC_DW27)
|
||||
#define DKL_CMN_UC_DW27_UC_HEALTH (0x1 << 15)
|
||||
|
||||
/*
|
||||
* Each Dekel PHY is addressed through a 4KB aperture. Each PHY has more than
|
||||
* 4KB of register space, so a separate index is programmed in HIP_INDEX_REG0
|
||||
* or HIP_INDEX_REG1, based on the port number, to set the upper 2 address
|
||||
* bits that point the 4KB window into the full PHY register space.
|
||||
*/
|
||||
#define _HIP_INDEX_REG0 0x1010A0
|
||||
#define _HIP_INDEX_REG1 0x1010A4
|
||||
#define HIP_INDEX_REG(tc_port) _MMIO((tc_port) < 4 ? _HIP_INDEX_REG0 \
|
||||
: _HIP_INDEX_REG1)
|
||||
#define _HIP_INDEX_SHIFT(tc_port) (8 * ((tc_port) % 4))
|
||||
#define HIP_INDEX_VAL(tc_port, val) ((val) << _HIP_INDEX_SHIFT(tc_port))
|
||||
|
||||
#endif /* __INTEL_DKL_PHY_REGS__ */
|
|
@ -1065,12 +1065,13 @@ static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused)
|
|||
seq_printf(m, "fw loaded: %s\n",
|
||||
str_yes_no(intel_dmc_has_payload(i915)));
|
||||
seq_printf(m, "path: %s\n", dmc->fw_path);
|
||||
seq_printf(m, "Pipe A fw support: %s\n",
|
||||
seq_printf(m, "Pipe A fw needed: %s\n",
|
||||
str_yes_no(GRAPHICS_VER(i915) >= 12));
|
||||
seq_printf(m, "Pipe A fw loaded: %s\n",
|
||||
str_yes_no(dmc->dmc_info[DMC_FW_PIPEA].payload));
|
||||
seq_printf(m, "Pipe B fw support: %s\n",
|
||||
str_yes_no(IS_ALDERLAKE_P(i915)));
|
||||
seq_printf(m, "Pipe B fw needed: %s\n",
|
||||
str_yes_no(IS_ALDERLAKE_P(i915) ||
|
||||
DISPLAY_VER(i915) >= 14));
|
||||
seq_printf(m, "Pipe B fw loaded: %s\n",
|
||||
str_yes_no(dmc->dmc_info[DMC_FW_PIPEB].payload));
|
||||
|
||||
|
@ -1081,22 +1082,19 @@ static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused)
|
|||
DMC_VERSION_MINOR(dmc->version));
|
||||
|
||||
if (DISPLAY_VER(i915) >= 12) {
|
||||
if (IS_DGFX(i915)) {
|
||||
i915_reg_t dc3co_reg;
|
||||
|
||||
if (IS_DGFX(i915) || DISPLAY_VER(i915) >= 14) {
|
||||
dc3co_reg = DG1_DMC_DEBUG3;
|
||||
dc5_reg = DG1_DMC_DEBUG_DC5_COUNT;
|
||||
} else {
|
||||
dc3co_reg = TGL_DMC_DEBUG3;
|
||||
dc5_reg = TGL_DMC_DEBUG_DC5_COUNT;
|
||||
dc6_reg = TGL_DMC_DEBUG_DC6_COUNT;
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE: DMC_DEBUG3 is a general purpose reg.
|
||||
* According to B.Specs:49196 DMC f/w reuses DC5/6 counter
|
||||
* reg for DC3CO debugging and validation,
|
||||
* but TGL DMC f/w is using DMC_DEBUG3 reg for DC3CO counter.
|
||||
*/
|
||||
seq_printf(m, "DC3CO count: %d\n",
|
||||
intel_de_read(i915, IS_DGFX(i915) ?
|
||||
DG1_DMC_DEBUG3 : TGL_DMC_DEBUG3));
|
||||
intel_de_read(i915, dc3co_reg));
|
||||
} else {
|
||||
dc5_reg = IS_BROXTON(i915) ? BXT_DMC_DC3_DC5_COUNT :
|
||||
SKL_DMC_DC3_DC5_COUNT;
|
||||
|
|
|
@ -2306,6 +2306,7 @@ bool intel_dp_initial_fastset_check(struct intel_encoder *encoder,
|
|||
{
|
||||
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
|
||||
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
|
||||
bool fastset = true;
|
||||
|
||||
/*
|
||||
* If BIOS has set an unsupported or non-standard link rate for some
|
||||
|
@ -2313,9 +2314,10 @@ bool intel_dp_initial_fastset_check(struct intel_encoder *encoder,
|
|||
*/
|
||||
if (intel_dp_rate_index(intel_dp->source_rates, intel_dp->num_source_rates,
|
||||
crtc_state->port_clock) < 0) {
|
||||
drm_dbg_kms(&i915->drm, "Forcing full modeset due to unsupported link rate\n");
|
||||
drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s] Forcing full modeset due to unsupported link rate\n",
|
||||
encoder->base.base.id, encoder->base.name);
|
||||
crtc_state->uapi.connectors_changed = true;
|
||||
return false;
|
||||
fastset = false;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2326,18 +2328,20 @@ bool intel_dp_initial_fastset_check(struct intel_encoder *encoder,
|
|||
* Remove once we have readout for DSC.
|
||||
*/
|
||||
if (crtc_state->dsc.compression_enable) {
|
||||
drm_dbg_kms(&i915->drm, "Forcing full modeset due to DSC being enabled\n");
|
||||
drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s] Forcing full modeset due to DSC being enabled\n",
|
||||
encoder->base.base.id, encoder->base.name);
|
||||
crtc_state->uapi.mode_changed = true;
|
||||
return false;
|
||||
fastset = false;
|
||||
}
|
||||
|
||||
if (CAN_PSR(intel_dp)) {
|
||||
drm_dbg_kms(&i915->drm, "Forcing full modeset to compute PSR state\n");
|
||||
drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s] Forcing full modeset to compute PSR state\n",
|
||||
encoder->base.base.id, encoder->base.name);
|
||||
crtc_state->uapi.mode_changed = true;
|
||||
return false;
|
||||
fastset = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return fastset;
|
||||
}
|
||||
|
||||
static void intel_dp_get_pcon_dsc_cap(struct intel_dp *intel_dp)
|
||||
|
@ -2686,7 +2690,6 @@ void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp,
|
|||
str_enable_disable(tmp));
|
||||
}
|
||||
|
||||
|
||||
bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp)
|
||||
{
|
||||
u8 dprx = 0;
|
||||
|
@ -3957,6 +3960,8 @@ intel_dp_handle_hdmi_link_status_change(struct intel_dp *intel_dp)
|
|||
|
||||
drm_dp_pcon_hdmi_frl_link_error_count(&intel_dp->aux, &intel_dp->attached_connector->base);
|
||||
|
||||
intel_dp->frl.is_trained = false;
|
||||
|
||||
/* Restart FRL training or fall back to TMDS mode */
|
||||
intel_dp_check_frl_training(intel_dp);
|
||||
}
|
||||
|
@ -5172,19 +5177,6 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connect
|
|||
if (has_gamut_metadata_dip(dev_priv, port))
|
||||
drm_connector_attach_hdr_output_metadata_property(connector);
|
||||
|
||||
if (intel_dp_is_edp(intel_dp)) {
|
||||
u32 allowed_scalers;
|
||||
|
||||
allowed_scalers = BIT(DRM_MODE_SCALE_ASPECT) | BIT(DRM_MODE_SCALE_FULLSCREEN);
|
||||
if (!HAS_GMCH(dev_priv))
|
||||
allowed_scalers |= BIT(DRM_MODE_SCALE_CENTER);
|
||||
|
||||
drm_connector_attach_scaling_mode_property(connector, allowed_scalers);
|
||||
|
||||
connector->state->scaling_mode = DRM_MODE_SCALE_ASPECT;
|
||||
|
||||
}
|
||||
|
||||
if (HAS_VRR(dev_priv))
|
||||
drm_connector_attach_vrr_capable_property(connector);
|
||||
}
|
||||
|
@ -5197,8 +5189,7 @@ intel_edp_add_properties(struct intel_dp *intel_dp)
|
|||
const struct drm_display_mode *fixed_mode =
|
||||
intel_panel_preferred_fixed_mode(connector);
|
||||
|
||||
if (!fixed_mode)
|
||||
return;
|
||||
intel_attach_scaling_mode_property(&connector->base);
|
||||
|
||||
drm_connector_set_panel_orientation_with_quirk(&connector->base,
|
||||
i915->display.vbt.orientation,
|
||||
|
@ -5206,16 +5197,43 @@ intel_edp_add_properties(struct intel_dp *intel_dp)
|
|||
fixed_mode->vdisplay);
|
||||
}
|
||||
|
||||
static void intel_edp_backlight_setup(struct intel_dp *intel_dp,
|
||||
struct intel_connector *connector)
|
||||
{
|
||||
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
|
||||
enum pipe pipe = INVALID_PIPE;
|
||||
|
||||
if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) {
|
||||
/*
|
||||
* Figure out the current pipe for the initial backlight setup.
|
||||
* If the current pipe isn't valid, try the PPS pipe, and if that
|
||||
* fails just assume pipe A.
|
||||
*/
|
||||
pipe = vlv_active_pipe(intel_dp);
|
||||
|
||||
if (pipe != PIPE_A && pipe != PIPE_B)
|
||||
pipe = intel_dp->pps.pps_pipe;
|
||||
|
||||
if (pipe != PIPE_A && pipe != PIPE_B)
|
||||
pipe = PIPE_A;
|
||||
|
||||
drm_dbg_kms(&i915->drm,
|
||||
"[CONNECTOR:%d:%s] using pipe %c for initial backlight setup\n",
|
||||
connector->base.base.id, connector->base.name,
|
||||
pipe_name(pipe));
|
||||
}
|
||||
|
||||
intel_backlight_setup(connector, pipe);
|
||||
}
|
||||
|
||||
static bool intel_edp_init_connector(struct intel_dp *intel_dp,
|
||||
struct intel_connector *intel_connector)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
struct drm_connector *connector = &intel_connector->base;
|
||||
struct drm_display_mode *fixed_mode;
|
||||
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
|
||||
bool has_dpcd;
|
||||
enum pipe pipe = INVALID_PIPE;
|
||||
struct edid *edid;
|
||||
|
||||
if (!intel_dp_is_edp(intel_dp))
|
||||
|
@ -5228,7 +5246,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
|
|||
* with an already powered-on LVDS power sequencer.
|
||||
*/
|
||||
if (intel_get_lvds_encoder(dev_priv)) {
|
||||
drm_WARN_ON(dev,
|
||||
drm_WARN_ON(&dev_priv->drm,
|
||||
!(HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv)));
|
||||
drm_info(&dev_priv->drm,
|
||||
"LVDS was detected, not registering eDP\n");
|
||||
|
@ -5244,11 +5262,12 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
|
|||
if (!has_dpcd) {
|
||||
/* if this fails, presume the device is a ghost */
|
||||
drm_info(&dev_priv->drm,
|
||||
"failed to retrieve link info, disabling eDP\n");
|
||||
"[ENCODER:%d:%s] failed to retrieve link info, disabling eDP\n",
|
||||
encoder->base.base.id, encoder->base.name);
|
||||
goto out_vdd_off;
|
||||
}
|
||||
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
mutex_lock(&dev_priv->drm.mode_config.mutex);
|
||||
edid = drm_get_edid(connector, &intel_dp->aux.ddc);
|
||||
if (!edid) {
|
||||
/* Fallback to EDID from ACPI OpRegion, if any */
|
||||
|
@ -5273,9 +5292,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
|
|||
intel_bios_init_panel(dev_priv, &intel_connector->panel,
|
||||
encoder->devdata, IS_ERR(edid) ? NULL : edid);
|
||||
|
||||
intel_panel_add_edid_fixed_modes(intel_connector,
|
||||
intel_connector->panel.vbt.drrs_type != DRRS_TYPE_NONE,
|
||||
intel_vrr_is_capable(intel_connector));
|
||||
intel_panel_add_edid_fixed_modes(intel_connector, true);
|
||||
|
||||
/* MSO requires information from the EDID */
|
||||
intel_edp_mso_init(intel_dp);
|
||||
|
@ -5288,30 +5305,18 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
|
|||
if (!intel_panel_preferred_fixed_mode(intel_connector))
|
||||
intel_panel_add_vbt_lfp_fixed_mode(intel_connector);
|
||||
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
mutex_unlock(&dev_priv->drm.mode_config.mutex);
|
||||
|
||||
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
|
||||
/*
|
||||
* Figure out the current pipe for the initial backlight setup.
|
||||
* If the current pipe isn't valid, try the PPS pipe, and if that
|
||||
* fails just assume pipe A.
|
||||
*/
|
||||
pipe = vlv_active_pipe(intel_dp);
|
||||
|
||||
if (pipe != PIPE_A && pipe != PIPE_B)
|
||||
pipe = intel_dp->pps.pps_pipe;
|
||||
|
||||
if (pipe != PIPE_A && pipe != PIPE_B)
|
||||
pipe = PIPE_A;
|
||||
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"using pipe %c for initial backlight setup\n",
|
||||
pipe_name(pipe));
|
||||
if (!intel_panel_preferred_fixed_mode(intel_connector)) {
|
||||
drm_info(&dev_priv->drm,
|
||||
"[ENCODER:%d:%s] failed to find fixed mode for the panel, disabling eDP\n",
|
||||
encoder->base.base.id, encoder->base.name);
|
||||
goto out_vdd_off;
|
||||
}
|
||||
|
||||
intel_panel_init(intel_connector);
|
||||
|
||||
intel_backlight_setup(intel_connector, pipe);
|
||||
intel_edp_backlight_setup(intel_dp, intel_connector);
|
||||
|
||||
intel_edp_add_properties(intel_dp);
|
||||
|
||||
|
@ -5413,7 +5418,6 @@ intel_dp_init_connector(struct intel_digital_port *dig_port,
|
|||
|
||||
if (!HAS_GMCH(dev_priv))
|
||||
connector->interlace_allowed = true;
|
||||
connector->doublescan_allowed = 0;
|
||||
|
||||
intel_connector->polled = DRM_CONNECTOR_POLL_HPD;
|
||||
|
||||
|
|
|
@ -19,28 +19,20 @@
|
|||
#include "intel_hdcp.h"
|
||||
#include "intel_hdcp_regs.h"
|
||||
|
||||
static unsigned int transcoder_to_stream_enc_status(enum transcoder cpu_transcoder)
|
||||
static u32 transcoder_to_stream_enc_status(enum transcoder cpu_transcoder)
|
||||
{
|
||||
u32 stream_enc_mask;
|
||||
|
||||
switch (cpu_transcoder) {
|
||||
case TRANSCODER_A:
|
||||
stream_enc_mask = HDCP_STATUS_STREAM_A_ENC;
|
||||
break;
|
||||
return HDCP_STATUS_STREAM_A_ENC;
|
||||
case TRANSCODER_B:
|
||||
stream_enc_mask = HDCP_STATUS_STREAM_B_ENC;
|
||||
break;
|
||||
return HDCP_STATUS_STREAM_B_ENC;
|
||||
case TRANSCODER_C:
|
||||
stream_enc_mask = HDCP_STATUS_STREAM_C_ENC;
|
||||
break;
|
||||
return HDCP_STATUS_STREAM_C_ENC;
|
||||
case TRANSCODER_D:
|
||||
stream_enc_mask = HDCP_STATUS_STREAM_D_ENC;
|
||||
break;
|
||||
return HDCP_STATUS_STREAM_D_ENC;
|
||||
default:
|
||||
stream_enc_mask = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return stream_enc_mask;
|
||||
}
|
||||
|
||||
static void intel_dp_hdcp_wait_for_cp_irq(struct intel_hdcp *hdcp, int timeout)
|
||||
|
|
|
@ -793,7 +793,35 @@ static bool intel_dp_mst_get_hw_state(struct intel_connector *connector)
|
|||
return false;
|
||||
}
|
||||
|
||||
static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, const char *pathprop)
|
||||
static int intel_dp_mst_add_properties(struct intel_dp *intel_dp,
|
||||
struct drm_connector *connector,
|
||||
const char *pathprop)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(connector->dev);
|
||||
|
||||
drm_object_attach_property(&connector->base,
|
||||
i915->drm.mode_config.path_property, 0);
|
||||
drm_object_attach_property(&connector->base,
|
||||
i915->drm.mode_config.tile_property, 0);
|
||||
|
||||
intel_attach_force_audio_property(connector);
|
||||
intel_attach_broadcast_rgb_property(connector);
|
||||
|
||||
/*
|
||||
* Reuse the prop from the SST connector because we're
|
||||
* not allowed to create new props after device registration.
|
||||
*/
|
||||
connector->max_bpc_property =
|
||||
intel_dp->attached_connector->base.max_bpc_property;
|
||||
if (connector->max_bpc_property)
|
||||
drm_connector_attach_max_bpc_property(connector, 6, 12);
|
||||
|
||||
return drm_connector_set_path_property(connector, pathprop);
|
||||
}
|
||||
|
||||
static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
|
||||
struct drm_dp_mst_port *port,
|
||||
const char *pathprop)
|
||||
{
|
||||
struct intel_dp *intel_dp = container_of(mgr, struct intel_dp, mst_mgr);
|
||||
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
|
||||
|
@ -833,28 +861,14 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
|
|||
goto err;
|
||||
}
|
||||
|
||||
drm_object_attach_property(&connector->base, dev->mode_config.path_property, 0);
|
||||
drm_object_attach_property(&connector->base, dev->mode_config.tile_property, 0);
|
||||
|
||||
ret = drm_connector_set_path_property(connector, pathprop);
|
||||
ret = intel_dp_mst_add_properties(intel_dp, connector, pathprop);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
intel_attach_force_audio_property(connector);
|
||||
intel_attach_broadcast_rgb_property(connector);
|
||||
|
||||
ret = intel_dp_hdcp_init(dig_port, intel_connector);
|
||||
if (ret)
|
||||
drm_dbg_kms(&dev_priv->drm, "[%s:%d] HDCP MST init failed, skipping.\n",
|
||||
connector->name, connector->base.id);
|
||||
/*
|
||||
* Reuse the prop from the SST connector because we're
|
||||
* not allowed to create new props after device registration.
|
||||
*/
|
||||
connector->max_bpc_property =
|
||||
intel_dp->attached_connector->base.max_bpc_property;
|
||||
if (connector->max_bpc_property)
|
||||
drm_connector_attach_max_bpc_property(connector, 6, 12);
|
||||
|
||||
return connector;
|
||||
|
||||
|
|
|
@ -25,12 +25,14 @@
|
|||
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dkl_phy.h"
|
||||
#include "intel_dkl_phy_regs.h"
|
||||
#include "intel_dpio_phy.h"
|
||||
#include "intel_dpll.h"
|
||||
#include "intel_dpll_mgr.h"
|
||||
#include "intel_mg_phy_regs.h"
|
||||
#include "intel_pch_refclk.h"
|
||||
#include "intel_tc.h"
|
||||
#include "intel_tc_phy_regs.h"
|
||||
|
||||
/**
|
||||
* DOC: Display PLLs
|
||||
|
@ -152,28 +154,6 @@ intel_get_shared_dpll_by_id(struct drm_i915_private *dev_priv,
|
|||
return &dev_priv->display.dpll.shared_dplls[id];
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_get_shared_dpll_id - get the id of a DPLL
|
||||
* @dev_priv: i915 device instance
|
||||
* @pll: the DPLL
|
||||
*
|
||||
* Returns:
|
||||
* The id of @pll
|
||||
*/
|
||||
enum intel_dpll_id
|
||||
intel_get_shared_dpll_id(struct drm_i915_private *dev_priv,
|
||||
struct intel_shared_dpll *pll)
|
||||
{
|
||||
long pll_idx = pll - dev_priv->display.dpll.shared_dplls;
|
||||
|
||||
if (drm_WARN_ON(&dev_priv->drm,
|
||||
pll_idx < 0 ||
|
||||
pll_idx >= dev_priv->display.dpll.num_shared_dpll))
|
||||
return -1;
|
||||
|
||||
return pll_idx;
|
||||
}
|
||||
|
||||
/* For ILK+ */
|
||||
void assert_shared_dpll(struct drm_i915_private *dev_priv,
|
||||
struct intel_shared_dpll *pll,
|
||||
|
@ -384,20 +364,30 @@ intel_reference_shared_dpll(struct intel_atomic_state *state,
|
|||
if (shared_dpll[id].pipe_mask == 0)
|
||||
shared_dpll[id].hw_state = *pll_state;
|
||||
|
||||
drm_dbg(&i915->drm, "using %s for pipe %c\n", pll->info->name,
|
||||
pipe_name(crtc->pipe));
|
||||
drm_WARN_ON(&i915->drm, (shared_dpll[id].pipe_mask & BIT(crtc->pipe)) != 0);
|
||||
|
||||
shared_dpll[id].pipe_mask |= BIT(crtc->pipe);
|
||||
|
||||
drm_dbg_kms(&i915->drm, "[CRTC:%d:%s] reserving %s\n",
|
||||
crtc->base.base.id, crtc->base.name, pll->info->name);
|
||||
}
|
||||
|
||||
static void intel_unreference_shared_dpll(struct intel_atomic_state *state,
|
||||
const struct intel_crtc *crtc,
|
||||
const struct intel_shared_dpll *pll)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(state->base.dev);
|
||||
struct intel_shared_dpll_state *shared_dpll;
|
||||
const enum intel_dpll_id id = pll->info->id;
|
||||
|
||||
shared_dpll = intel_atomic_get_shared_dpll_state(&state->base);
|
||||
shared_dpll[pll->info->id].pipe_mask &= ~BIT(crtc->pipe);
|
||||
|
||||
drm_WARN_ON(&i915->drm, (shared_dpll[id].pipe_mask & BIT(crtc->pipe)) == 0);
|
||||
|
||||
shared_dpll[id].pipe_mask &= ~BIT(crtc->pipe);
|
||||
|
||||
drm_dbg_kms(&i915->drm, "[CRTC:%d:%s] releasing %s\n",
|
||||
crtc->base.base.id, crtc->base.name, pll->info->name);
|
||||
}
|
||||
|
||||
static void intel_put_dpll(struct intel_atomic_state *state,
|
||||
|
@ -708,8 +698,6 @@ struct hsw_wrpll_rnp {
|
|||
|
||||
static unsigned hsw_wrpll_get_budget_for_freq(int clock)
|
||||
{
|
||||
unsigned budget;
|
||||
|
||||
switch (clock) {
|
||||
case 25175000:
|
||||
case 25200000:
|
||||
|
@ -742,21 +730,18 @@ static unsigned hsw_wrpll_get_budget_for_freq(int clock)
|
|||
case 222750000:
|
||||
case 296703000:
|
||||
case 297000000:
|
||||
budget = 0;
|
||||
break;
|
||||
return 0;
|
||||
case 233500000:
|
||||
case 245250000:
|
||||
case 247750000:
|
||||
case 253250000:
|
||||
case 298000000:
|
||||
budget = 1500;
|
||||
break;
|
||||
return 1500;
|
||||
case 169128000:
|
||||
case 169500000:
|
||||
case 179500000:
|
||||
case 202000000:
|
||||
budget = 2000;
|
||||
break;
|
||||
return 2000;
|
||||
case 256250000:
|
||||
case 262500000:
|
||||
case 270000000:
|
||||
|
@ -766,18 +751,13 @@ static unsigned hsw_wrpll_get_budget_for_freq(int clock)
|
|||
case 281250000:
|
||||
case 286000000:
|
||||
case 291750000:
|
||||
budget = 4000;
|
||||
break;
|
||||
return 4000;
|
||||
case 267250000:
|
||||
case 268500000:
|
||||
budget = 5000;
|
||||
break;
|
||||
return 5000;
|
||||
default:
|
||||
budget = 1000;
|
||||
break;
|
||||
return 1000;
|
||||
}
|
||||
|
||||
return budget;
|
||||
}
|
||||
|
||||
static void hsw_wrpll_update_rnp(u64 freq2k, unsigned int budget,
|
||||
|
@ -3508,15 +3488,12 @@ static bool dkl_pll_get_hw_state(struct drm_i915_private *dev_priv,
|
|||
* All registers read here have the same HIP_INDEX_REG even though
|
||||
* they are on different building blocks
|
||||
*/
|
||||
intel_de_write(dev_priv, HIP_INDEX_REG(tc_port),
|
||||
HIP_INDEX_VAL(tc_port, 0x2));
|
||||
|
||||
hw_state->mg_refclkin_ctl = intel_de_read(dev_priv,
|
||||
DKL_REFCLKIN_CTL(tc_port));
|
||||
hw_state->mg_refclkin_ctl = intel_dkl_phy_read(dev_priv,
|
||||
DKL_REFCLKIN_CTL(tc_port));
|
||||
hw_state->mg_refclkin_ctl &= MG_REFCLKIN_CTL_OD_2_MUX_MASK;
|
||||
|
||||
hw_state->mg_clktop2_hsclkctl =
|
||||
intel_de_read(dev_priv, DKL_CLKTOP2_HSCLKCTL(tc_port));
|
||||
intel_dkl_phy_read(dev_priv, DKL_CLKTOP2_HSCLKCTL(tc_port));
|
||||
hw_state->mg_clktop2_hsclkctl &=
|
||||
MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL_MASK |
|
||||
MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL_MASK |
|
||||
|
@ -3524,32 +3501,32 @@ static bool dkl_pll_get_hw_state(struct drm_i915_private *dev_priv,
|
|||
MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK;
|
||||
|
||||
hw_state->mg_clktop2_coreclkctl1 =
|
||||
intel_de_read(dev_priv, DKL_CLKTOP2_CORECLKCTL1(tc_port));
|
||||
intel_dkl_phy_read(dev_priv, DKL_CLKTOP2_CORECLKCTL1(tc_port));
|
||||
hw_state->mg_clktop2_coreclkctl1 &=
|
||||
MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO_MASK;
|
||||
|
||||
hw_state->mg_pll_div0 = intel_de_read(dev_priv, DKL_PLL_DIV0(tc_port));
|
||||
hw_state->mg_pll_div0 = intel_dkl_phy_read(dev_priv, DKL_PLL_DIV0(tc_port));
|
||||
val = DKL_PLL_DIV0_MASK;
|
||||
if (dev_priv->display.vbt.override_afc_startup)
|
||||
val |= DKL_PLL_DIV0_AFC_STARTUP_MASK;
|
||||
hw_state->mg_pll_div0 &= val;
|
||||
|
||||
hw_state->mg_pll_div1 = intel_de_read(dev_priv, DKL_PLL_DIV1(tc_port));
|
||||
hw_state->mg_pll_div1 = intel_dkl_phy_read(dev_priv, DKL_PLL_DIV1(tc_port));
|
||||
hw_state->mg_pll_div1 &= (DKL_PLL_DIV1_IREF_TRIM_MASK |
|
||||
DKL_PLL_DIV1_TDC_TARGET_CNT_MASK);
|
||||
|
||||
hw_state->mg_pll_ssc = intel_de_read(dev_priv, DKL_PLL_SSC(tc_port));
|
||||
hw_state->mg_pll_ssc = intel_dkl_phy_read(dev_priv, DKL_PLL_SSC(tc_port));
|
||||
hw_state->mg_pll_ssc &= (DKL_PLL_SSC_IREF_NDIV_RATIO_MASK |
|
||||
DKL_PLL_SSC_STEP_LEN_MASK |
|
||||
DKL_PLL_SSC_STEP_NUM_MASK |
|
||||
DKL_PLL_SSC_EN);
|
||||
|
||||
hw_state->mg_pll_bias = intel_de_read(dev_priv, DKL_PLL_BIAS(tc_port));
|
||||
hw_state->mg_pll_bias = intel_dkl_phy_read(dev_priv, DKL_PLL_BIAS(tc_port));
|
||||
hw_state->mg_pll_bias &= (DKL_PLL_BIAS_FRAC_EN_H |
|
||||
DKL_PLL_BIAS_FBDIV_FRAC_MASK);
|
||||
|
||||
hw_state->mg_pll_tdc_coldst_bias =
|
||||
intel_de_read(dev_priv, DKL_PLL_TDC_COLDST_BIAS(tc_port));
|
||||
intel_dkl_phy_read(dev_priv, DKL_PLL_TDC_COLDST_BIAS(tc_port));
|
||||
hw_state->mg_pll_tdc_coldst_bias &= (DKL_PLL_TDC_SSC_STEP_SIZE_MASK |
|
||||
DKL_PLL_TDC_FEED_FWD_GAIN_MASK);
|
||||
|
||||
|
@ -3737,61 +3714,58 @@ static void dkl_pll_write(struct drm_i915_private *dev_priv,
|
|||
* All registers programmed here have the same HIP_INDEX_REG even
|
||||
* though on different building block
|
||||
*/
|
||||
intel_de_write(dev_priv, HIP_INDEX_REG(tc_port),
|
||||
HIP_INDEX_VAL(tc_port, 0x2));
|
||||
|
||||
/* All the registers are RMW */
|
||||
val = intel_de_read(dev_priv, DKL_REFCLKIN_CTL(tc_port));
|
||||
val = intel_dkl_phy_read(dev_priv, DKL_REFCLKIN_CTL(tc_port));
|
||||
val &= ~MG_REFCLKIN_CTL_OD_2_MUX_MASK;
|
||||
val |= hw_state->mg_refclkin_ctl;
|
||||
intel_de_write(dev_priv, DKL_REFCLKIN_CTL(tc_port), val);
|
||||
intel_dkl_phy_write(dev_priv, DKL_REFCLKIN_CTL(tc_port), val);
|
||||
|
||||
val = intel_de_read(dev_priv, DKL_CLKTOP2_CORECLKCTL1(tc_port));
|
||||
val = intel_dkl_phy_read(dev_priv, DKL_CLKTOP2_CORECLKCTL1(tc_port));
|
||||
val &= ~MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO_MASK;
|
||||
val |= hw_state->mg_clktop2_coreclkctl1;
|
||||
intel_de_write(dev_priv, DKL_CLKTOP2_CORECLKCTL1(tc_port), val);
|
||||
intel_dkl_phy_write(dev_priv, DKL_CLKTOP2_CORECLKCTL1(tc_port), val);
|
||||
|
||||
val = intel_de_read(dev_priv, DKL_CLKTOP2_HSCLKCTL(tc_port));
|
||||
val = intel_dkl_phy_read(dev_priv, DKL_CLKTOP2_HSCLKCTL(tc_port));
|
||||
val &= ~(MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL_MASK |
|
||||
MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL_MASK |
|
||||
MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_MASK |
|
||||
MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK);
|
||||
val |= hw_state->mg_clktop2_hsclkctl;
|
||||
intel_de_write(dev_priv, DKL_CLKTOP2_HSCLKCTL(tc_port), val);
|
||||
intel_dkl_phy_write(dev_priv, DKL_CLKTOP2_HSCLKCTL(tc_port), val);
|
||||
|
||||
val = DKL_PLL_DIV0_MASK;
|
||||
if (dev_priv->display.vbt.override_afc_startup)
|
||||
val |= DKL_PLL_DIV0_AFC_STARTUP_MASK;
|
||||
intel_de_rmw(dev_priv, DKL_PLL_DIV0(tc_port), val,
|
||||
hw_state->mg_pll_div0);
|
||||
intel_dkl_phy_rmw(dev_priv, DKL_PLL_DIV0(tc_port), val,
|
||||
hw_state->mg_pll_div0);
|
||||
|
||||
val = intel_de_read(dev_priv, DKL_PLL_DIV1(tc_port));
|
||||
val = intel_dkl_phy_read(dev_priv, DKL_PLL_DIV1(tc_port));
|
||||
val &= ~(DKL_PLL_DIV1_IREF_TRIM_MASK |
|
||||
DKL_PLL_DIV1_TDC_TARGET_CNT_MASK);
|
||||
val |= hw_state->mg_pll_div1;
|
||||
intel_de_write(dev_priv, DKL_PLL_DIV1(tc_port), val);
|
||||
intel_dkl_phy_write(dev_priv, DKL_PLL_DIV1(tc_port), val);
|
||||
|
||||
val = intel_de_read(dev_priv, DKL_PLL_SSC(tc_port));
|
||||
val = intel_dkl_phy_read(dev_priv, DKL_PLL_SSC(tc_port));
|
||||
val &= ~(DKL_PLL_SSC_IREF_NDIV_RATIO_MASK |
|
||||
DKL_PLL_SSC_STEP_LEN_MASK |
|
||||
DKL_PLL_SSC_STEP_NUM_MASK |
|
||||
DKL_PLL_SSC_EN);
|
||||
val |= hw_state->mg_pll_ssc;
|
||||
intel_de_write(dev_priv, DKL_PLL_SSC(tc_port), val);
|
||||
intel_dkl_phy_write(dev_priv, DKL_PLL_SSC(tc_port), val);
|
||||
|
||||
val = intel_de_read(dev_priv, DKL_PLL_BIAS(tc_port));
|
||||
val = intel_dkl_phy_read(dev_priv, DKL_PLL_BIAS(tc_port));
|
||||
val &= ~(DKL_PLL_BIAS_FRAC_EN_H |
|
||||
DKL_PLL_BIAS_FBDIV_FRAC_MASK);
|
||||
val |= hw_state->mg_pll_bias;
|
||||
intel_de_write(dev_priv, DKL_PLL_BIAS(tc_port), val);
|
||||
intel_dkl_phy_write(dev_priv, DKL_PLL_BIAS(tc_port), val);
|
||||
|
||||
val = intel_de_read(dev_priv, DKL_PLL_TDC_COLDST_BIAS(tc_port));
|
||||
val = intel_dkl_phy_read(dev_priv, DKL_PLL_TDC_COLDST_BIAS(tc_port));
|
||||
val &= ~(DKL_PLL_TDC_SSC_STEP_SIZE_MASK |
|
||||
DKL_PLL_TDC_FEED_FWD_GAIN_MASK);
|
||||
val |= hw_state->mg_pll_tdc_coldst_bias;
|
||||
intel_de_write(dev_priv, DKL_PLL_TDC_COLDST_BIAS(tc_port), val);
|
||||
intel_dkl_phy_write(dev_priv, DKL_PLL_TDC_COLDST_BIAS(tc_port), val);
|
||||
|
||||
intel_de_posting_read(dev_priv, DKL_PLL_TDC_COLDST_BIAS(tc_port));
|
||||
intel_dkl_phy_posting_read(dev_priv, DKL_PLL_TDC_COLDST_BIAS(tc_port));
|
||||
}
|
||||
|
||||
static void icl_pll_power_enable(struct drm_i915_private *dev_priv,
|
||||
|
@ -4193,6 +4167,8 @@ void intel_shared_dpll_init(struct drm_i915_private *dev_priv)
|
|||
const struct dpll_info *dpll_info;
|
||||
int i;
|
||||
|
||||
mutex_init(&dev_priv->display.dpll.lock);
|
||||
|
||||
if (IS_DG2(dev_priv))
|
||||
/* No shared DPLLs on DG2; port PLLs are part of the PHY */
|
||||
dpll_mgr = NULL;
|
||||
|
@ -4237,7 +4213,6 @@ void intel_shared_dpll_init(struct drm_i915_private *dev_priv)
|
|||
|
||||
dev_priv->display.dpll.mgr = dpll_mgr;
|
||||
dev_priv->display.dpll.num_shared_dpll = i;
|
||||
mutex_init(&dev_priv->display.dpll.lock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -328,9 +328,6 @@ struct intel_shared_dpll {
|
|||
struct intel_shared_dpll *
|
||||
intel_get_shared_dpll_by_id(struct drm_i915_private *dev_priv,
|
||||
enum intel_dpll_id id);
|
||||
enum intel_dpll_id
|
||||
intel_get_shared_dpll_id(struct drm_i915_private *dev_priv,
|
||||
struct intel_shared_dpll *pll);
|
||||
void assert_shared_dpll(struct drm_i915_private *dev_priv,
|
||||
struct intel_shared_dpll *pll,
|
||||
bool state);
|
||||
|
|
|
@ -284,16 +284,124 @@ void intel_drrs_flush(struct drm_i915_private *dev_priv,
|
|||
}
|
||||
|
||||
/**
|
||||
* intel_crtc_drrs_init - Init DRRS for CRTC
|
||||
* intel_drrs_crtc_init - Init DRRS for CRTC
|
||||
* @crtc: crtc
|
||||
*
|
||||
* This function is called only once at driver load to initialize basic
|
||||
* DRRS stuff.
|
||||
*
|
||||
*/
|
||||
void intel_crtc_drrs_init(struct intel_crtc *crtc)
|
||||
void intel_drrs_crtc_init(struct intel_crtc *crtc)
|
||||
{
|
||||
INIT_DELAYED_WORK(&crtc->drrs.work, intel_drrs_downclock_work);
|
||||
mutex_init(&crtc->drrs.mutex);
|
||||
crtc->drrs.cpu_transcoder = INVALID_TRANSCODER;
|
||||
}
|
||||
|
||||
static int intel_drrs_debugfs_status_show(struct seq_file *m, void *unused)
|
||||
{
|
||||
struct intel_crtc *crtc = m->private;
|
||||
const struct intel_crtc_state *crtc_state;
|
||||
int ret;
|
||||
|
||||
ret = drm_modeset_lock_single_interruptible(&crtc->base.mutex);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
crtc_state = to_intel_crtc_state(crtc->base.state);
|
||||
|
||||
mutex_lock(&crtc->drrs.mutex);
|
||||
|
||||
seq_printf(m, "DRRS enabled: %s\n",
|
||||
str_yes_no(crtc_state->has_drrs));
|
||||
|
||||
seq_printf(m, "DRRS active: %s\n",
|
||||
str_yes_no(intel_drrs_is_active(crtc)));
|
||||
|
||||
seq_printf(m, "DRRS refresh rate: %s\n",
|
||||
crtc->drrs.refresh_rate == DRRS_REFRESH_RATE_LOW ?
|
||||
"low" : "high");
|
||||
|
||||
seq_printf(m, "DRRS busy frontbuffer bits: 0x%x\n",
|
||||
crtc->drrs.busy_frontbuffer_bits);
|
||||
|
||||
mutex_unlock(&crtc->drrs.mutex);
|
||||
|
||||
drm_modeset_unlock(&crtc->base.mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_SHOW_ATTRIBUTE(intel_drrs_debugfs_status);
|
||||
|
||||
static int intel_drrs_debugfs_ctl_set(void *data, u64 val)
|
||||
{
|
||||
struct intel_crtc *crtc = data;
|
||||
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
|
||||
struct intel_crtc_state *crtc_state;
|
||||
struct drm_crtc_commit *commit;
|
||||
int ret;
|
||||
|
||||
ret = drm_modeset_lock_single_interruptible(&crtc->base.mutex);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
crtc_state = to_intel_crtc_state(crtc->base.state);
|
||||
|
||||
if (!crtc_state->hw.active ||
|
||||
!crtc_state->has_drrs)
|
||||
goto out;
|
||||
|
||||
commit = crtc_state->uapi.commit;
|
||||
if (commit) {
|
||||
ret = wait_for_completion_interruptible(&commit->hw_done);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
drm_dbg(&i915->drm,
|
||||
"Manually %sactivating DRRS\n", val ? "" : "de");
|
||||
|
||||
if (val)
|
||||
intel_drrs_activate(crtc_state);
|
||||
else
|
||||
intel_drrs_deactivate(crtc_state);
|
||||
|
||||
out:
|
||||
drm_modeset_unlock(&crtc->base.mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
DEFINE_SIMPLE_ATTRIBUTE(intel_drrs_debugfs_ctl_fops,
|
||||
NULL, intel_drrs_debugfs_ctl_set, "%llu\n");
|
||||
|
||||
void intel_drrs_crtc_debugfs_add(struct intel_crtc *crtc)
|
||||
{
|
||||
debugfs_create_file("i915_drrs_status", 0444, crtc->base.debugfs_entry,
|
||||
crtc, &intel_drrs_debugfs_status_fops);
|
||||
|
||||
debugfs_create_file("i915_drrs_ctl", 0644, crtc->base.debugfs_entry,
|
||||
crtc, &intel_drrs_debugfs_ctl_fops);
|
||||
}
|
||||
|
||||
static int intel_drrs_debugfs_type_show(struct seq_file *m, void *unused)
|
||||
{
|
||||
struct intel_connector *connector = m->private;
|
||||
|
||||
seq_printf(m, "DRRS type: %s\n",
|
||||
intel_drrs_type_str(intel_panel_drrs_type(connector)));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_SHOW_ATTRIBUTE(intel_drrs_debugfs_type);
|
||||
|
||||
void intel_drrs_connector_debugfs_add(struct intel_connector *connector)
|
||||
{
|
||||
if (intel_panel_drrs_type(connector) == DRRS_TYPE_NONE)
|
||||
return;
|
||||
|
||||
debugfs_create_file("i915_drrs_type", 0444, connector->base.debugfs_entry,
|
||||
connector, &intel_drrs_debugfs_type_fops);
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@ void intel_drrs_invalidate(struct drm_i915_private *dev_priv,
|
|||
unsigned int frontbuffer_bits);
|
||||
void intel_drrs_flush(struct drm_i915_private *dev_priv,
|
||||
unsigned int frontbuffer_bits);
|
||||
void intel_crtc_drrs_init(struct intel_crtc *crtc);
|
||||
void intel_drrs_crtc_init(struct intel_crtc *crtc);
|
||||
void intel_drrs_crtc_debugfs_add(struct intel_crtc *crtc);
|
||||
void intel_drrs_connector_debugfs_add(struct intel_connector *connector);
|
||||
|
||||
#endif /* __INTEL_DRRS_H__ */
|
||||
|
|
|
@ -491,8 +491,8 @@ void intel_dvo_init(struct drm_i915_private *dev_priv)
|
|||
intel_encoder->pipe_mask = ~0;
|
||||
|
||||
if (dvo->type != INTEL_DVO_CHIP_LVDS)
|
||||
intel_encoder->cloneable = (1 << INTEL_OUTPUT_ANALOG) |
|
||||
(1 << INTEL_OUTPUT_DVO);
|
||||
intel_encoder->cloneable = BIT(INTEL_OUTPUT_ANALOG) |
|
||||
BIT(INTEL_OUTPUT_DVO);
|
||||
|
||||
switch (dvo->type) {
|
||||
case INTEL_DVO_CHIP_TMDS:
|
||||
|
@ -515,8 +515,6 @@ void intel_dvo_init(struct drm_i915_private *dev_priv)
|
|||
drm_connector_helper_add(connector,
|
||||
&intel_dvo_connector_helper_funcs);
|
||||
connector->display_info.subpixel_order = SubPixelHorizontalRGB;
|
||||
connector->interlace_allowed = false;
|
||||
connector->doublescan_allowed = false;
|
||||
|
||||
intel_connector_attach_encoder(intel_connector, intel_encoder);
|
||||
if (dvo->type == INTEL_DVO_CHIP_LVDS) {
|
||||
|
|
|
@ -300,6 +300,19 @@ static bool plane_caps_contain_all(u8 caps, u8 mask)
|
|||
return (caps & mask) == mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_fb_is_tiled_modifier: Check if a modifier is a tiled modifier type
|
||||
* @modifier: Modifier to check
|
||||
*
|
||||
* Returns:
|
||||
* Returns %true if @modifier is a tiled modifier.
|
||||
*/
|
||||
bool intel_fb_is_tiled_modifier(u64 modifier)
|
||||
{
|
||||
return plane_caps_contain_any(lookup_modifier(modifier)->plane_caps,
|
||||
INTEL_PLANE_CAP_TILING_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_fb_is_ccs_modifier: Check if a modifier is a CCS modifier type
|
||||
* @modifier: Modifier to check
|
||||
|
|
|
@ -29,6 +29,7 @@ struct intel_plane_state;
|
|||
#define INTEL_PLANE_CAP_TILING_Yf BIT(5)
|
||||
#define INTEL_PLANE_CAP_TILING_4 BIT(6)
|
||||
|
||||
bool intel_fb_is_tiled_modifier(u64 modifier);
|
||||
bool intel_fb_is_ccs_modifier(u64 modifier);
|
||||
bool intel_fb_is_rc_ccs_cc_modifier(u64 modifier);
|
||||
bool intel_fb_is_mc_ccs_modifier(u64 modifier);
|
||||
|
|
|
@ -670,6 +670,7 @@ static void intel_fbc_nuke(struct intel_fbc *fbc)
|
|||
{
|
||||
struct drm_i915_private *i915 = fbc->i915;
|
||||
|
||||
lockdep_assert_held(&fbc->lock);
|
||||
drm_WARN_ON(&i915->drm, fbc->flip_pending);
|
||||
|
||||
trace_intel_fbc_nuke(fbc->state.plane);
|
||||
|
@ -679,6 +680,8 @@ static void intel_fbc_nuke(struct intel_fbc *fbc)
|
|||
|
||||
static void intel_fbc_activate(struct intel_fbc *fbc)
|
||||
{
|
||||
lockdep_assert_held(&fbc->lock);
|
||||
|
||||
intel_fbc_hw_activate(fbc);
|
||||
intel_fbc_nuke(fbc);
|
||||
|
||||
|
@ -687,9 +690,7 @@ static void intel_fbc_activate(struct intel_fbc *fbc)
|
|||
|
||||
static void intel_fbc_deactivate(struct intel_fbc *fbc, const char *reason)
|
||||
{
|
||||
struct drm_i915_private *i915 = fbc->i915;
|
||||
|
||||
drm_WARN_ON(&i915->drm, !mutex_is_locked(&fbc->lock));
|
||||
lockdep_assert_held(&fbc->lock);
|
||||
|
||||
if (fbc->active)
|
||||
intel_fbc_hw_deactivate(fbc);
|
||||
|
@ -1009,7 +1010,8 @@ static bool intel_fbc_is_fence_ok(const struct intel_plane_state *plane_state)
|
|||
{
|
||||
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
|
||||
|
||||
/* The use of a CPU fence is one of two ways to detect writes by the
|
||||
/*
|
||||
* The use of a CPU fence is one of two ways to detect writes by the
|
||||
* CPU to the scanout and trigger updates to the FBC.
|
||||
*
|
||||
* The other method is by software tracking (see
|
||||
|
@ -1019,12 +1021,6 @@ static bool intel_fbc_is_fence_ok(const struct intel_plane_state *plane_state)
|
|||
* Note that is possible for a tiled surface to be unmappable (and
|
||||
* so have no fence associated with it) due to aperture constraints
|
||||
* at the time of pinning.
|
||||
*
|
||||
* FIXME with 90/270 degree rotation we should use the fence on
|
||||
* the normal GTT view (the rotated view doesn't even have a
|
||||
* fence). Would need changes to the FBC fence Y offset as well.
|
||||
* For now this will effectively disable FBC with 90/270 degree
|
||||
* rotation.
|
||||
*/
|
||||
return DISPLAY_VER(i915) >= 9 ||
|
||||
(plane_state->flags & PLANE_HAS_FENCE &&
|
||||
|
@ -1227,6 +1223,8 @@ static bool __intel_fbc_pre_update(struct intel_atomic_state *state,
|
|||
struct intel_fbc *fbc = plane->fbc;
|
||||
bool need_vblank_wait = false;
|
||||
|
||||
lockdep_assert_held(&fbc->lock);
|
||||
|
||||
fbc->flip_pending = true;
|
||||
|
||||
if (intel_fbc_can_flip_nuke(state, crtc, plane))
|
||||
|
@ -1284,7 +1282,7 @@ static void __intel_fbc_disable(struct intel_fbc *fbc)
|
|||
struct drm_i915_private *i915 = fbc->i915;
|
||||
struct intel_plane *plane = fbc->state.plane;
|
||||
|
||||
drm_WARN_ON(&i915->drm, !mutex_is_locked(&fbc->lock));
|
||||
lockdep_assert_held(&fbc->lock);
|
||||
drm_WARN_ON(&i915->drm, fbc->active);
|
||||
|
||||
drm_dbg_kms(&i915->drm, "Disabling FBC on [PLANE:%d:%s]\n",
|
||||
|
@ -1299,9 +1297,9 @@ static void __intel_fbc_disable(struct intel_fbc *fbc)
|
|||
|
||||
static void __intel_fbc_post_update(struct intel_fbc *fbc)
|
||||
{
|
||||
struct drm_i915_private *i915 = fbc->i915;
|
||||
lockdep_assert_held(&fbc->lock);
|
||||
|
||||
drm_WARN_ON(&i915->drm, !mutex_is_locked(&fbc->lock));
|
||||
fbc->flip_pending = false;
|
||||
|
||||
if (!fbc->busy_bits)
|
||||
intel_fbc_activate(fbc);
|
||||
|
@ -1324,10 +1322,8 @@ void intel_fbc_post_update(struct intel_atomic_state *state,
|
|||
|
||||
mutex_lock(&fbc->lock);
|
||||
|
||||
if (fbc->state.plane == plane) {
|
||||
fbc->flip_pending = false;
|
||||
if (fbc->state.plane == plane)
|
||||
__intel_fbc_post_update(fbc);
|
||||
}
|
||||
|
||||
mutex_unlock(&fbc->lock);
|
||||
}
|
||||
|
@ -1437,6 +1433,8 @@ static void __intel_fbc_enable(struct intel_atomic_state *state,
|
|||
intel_atomic_get_new_plane_state(state, plane);
|
||||
struct intel_fbc *fbc = plane->fbc;
|
||||
|
||||
lockdep_assert_held(&fbc->lock);
|
||||
|
||||
if (fbc->state.plane) {
|
||||
if (fbc->state.plane != plane)
|
||||
return;
|
||||
|
@ -1522,7 +1520,8 @@ void intel_fbc_update(struct intel_atomic_state *state,
|
|||
|
||||
mutex_lock(&fbc->lock);
|
||||
|
||||
if (crtc_state->update_pipe && plane_state->no_fbc_reason) {
|
||||
if (intel_crtc_needs_fastset(crtc_state) &&
|
||||
plane_state->no_fbc_reason) {
|
||||
if (fbc->state.plane == plane)
|
||||
__intel_fbc_disable(fbc);
|
||||
} else {
|
||||
|
|
|
@ -175,7 +175,7 @@ static int intelfb_alloc(struct drm_fb_helper *helper,
|
|||
}
|
||||
|
||||
if (IS_ERR(obj)) {
|
||||
drm_err(&dev_priv->drm, "failed to allocate framebuffer\n");
|
||||
drm_err(&dev_priv->drm, "failed to allocate framebuffer (%pe)\n", obj);
|
||||
return PTR_ERR(obj);
|
||||
}
|
||||
|
||||
|
@ -256,7 +256,7 @@ static int intelfb_create(struct drm_fb_helper *helper,
|
|||
|
||||
info = drm_fb_helper_alloc_fbi(helper);
|
||||
if (IS_ERR(info)) {
|
||||
drm_err(&dev_priv->drm, "Failed to allocate fb_info\n");
|
||||
drm_err(&dev_priv->drm, "Failed to allocate fb_info (%pe)\n", info);
|
||||
ret = PTR_ERR(info);
|
||||
goto out_unpin;
|
||||
}
|
||||
|
@ -291,7 +291,7 @@ static int intelfb_create(struct drm_fb_helper *helper,
|
|||
vaddr = i915_vma_pin_iomap(vma);
|
||||
if (IS_ERR(vaddr)) {
|
||||
drm_err(&dev_priv->drm,
|
||||
"Failed to remap framebuffer into virtual memory\n");
|
||||
"Failed to remap framebuffer into virtual memory (%pe)\n", vaddr);
|
||||
ret = PTR_ERR(vaddr);
|
||||
goto out_unpin;
|
||||
}
|
||||
|
|
|
@ -2950,9 +2950,8 @@ void intel_hdmi_init_connector(struct intel_digital_port *dig_port,
|
|||
ddc);
|
||||
drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs);
|
||||
|
||||
connector->interlace_allowed = 1;
|
||||
connector->doublescan_allowed = 0;
|
||||
connector->stereo_allowed = 1;
|
||||
connector->interlace_allowed = true;
|
||||
connector->stereo_allowed = true;
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 10)
|
||||
connector->ycbcr_420_allowed = true;
|
||||
|
|
|
@ -90,6 +90,9 @@ enum hpd_pin intel_hpd_pin_default(struct drm_i915_private *dev_priv,
|
|||
return HPD_PORT_A + port - PORT_A;
|
||||
}
|
||||
|
||||
/* Threshold == 5 for long IRQs, 50 for short */
|
||||
#define HPD_STORM_DEFAULT_THRESHOLD 50
|
||||
|
||||
#define HPD_STORM_DETECT_PERIOD 1000
|
||||
#define HPD_STORM_REENABLE_DELAY (2 * 60 * 1000)
|
||||
#define HPD_RETRY_DELAY 1000
|
||||
|
@ -175,14 +178,13 @@ static bool intel_hpd_irq_storm_detect(struct drm_i915_private *dev_priv,
|
|||
static void
|
||||
intel_hpd_irq_storm_switch_to_polling(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
struct intel_connector *connector;
|
||||
bool hpd_disabled = false;
|
||||
|
||||
lockdep_assert_held(&dev_priv->irq_lock);
|
||||
|
||||
drm_connector_list_iter_begin(dev, &conn_iter);
|
||||
drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
|
||||
for_each_intel_connector_iter(connector, &conn_iter) {
|
||||
enum hpd_pin pin;
|
||||
|
||||
|
@ -208,7 +210,7 @@ intel_hpd_irq_storm_switch_to_polling(struct drm_i915_private *dev_priv)
|
|||
|
||||
/* Enable polling and queue hotplug re-enabling. */
|
||||
if (hpd_disabled) {
|
||||
drm_kms_helper_poll_enable(dev);
|
||||
drm_kms_helper_poll_enable(&dev_priv->drm);
|
||||
mod_delayed_work(system_wq, &dev_priv->display.hotplug.reenable_work,
|
||||
msecs_to_jiffies(HPD_STORM_REENABLE_DELAY));
|
||||
}
|
||||
|
@ -219,7 +221,6 @@ static void intel_hpd_irq_storm_reenable_work(struct work_struct *work)
|
|||
struct drm_i915_private *dev_priv =
|
||||
container_of(work, typeof(*dev_priv),
|
||||
display.hotplug.reenable_work.work);
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
struct intel_connector *connector;
|
||||
intel_wakeref_t wakeref;
|
||||
|
@ -229,7 +230,7 @@ static void intel_hpd_irq_storm_reenable_work(struct work_struct *work)
|
|||
|
||||
spin_lock_irq(&dev_priv->irq_lock);
|
||||
|
||||
drm_connector_list_iter_begin(dev, &conn_iter);
|
||||
drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
|
||||
for_each_intel_connector_iter(connector, &conn_iter) {
|
||||
pin = intel_connector_hpd_pin(connector);
|
||||
if (pin == HPD_NONE ||
|
||||
|
@ -367,14 +368,13 @@ static void i915_hotplug_work_func(struct work_struct *work)
|
|||
struct drm_i915_private *dev_priv =
|
||||
container_of(work, struct drm_i915_private,
|
||||
display.hotplug.hotplug_work.work);
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
struct intel_connector *connector;
|
||||
u32 changed = 0, retry = 0;
|
||||
u32 hpd_event_bits;
|
||||
u32 hpd_retry_bits;
|
||||
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
mutex_lock(&dev_priv->drm.mode_config.mutex);
|
||||
drm_dbg_kms(&dev_priv->drm, "running encoder hotplug functions\n");
|
||||
|
||||
spin_lock_irq(&dev_priv->irq_lock);
|
||||
|
@ -389,7 +389,7 @@ static void i915_hotplug_work_func(struct work_struct *work)
|
|||
|
||||
spin_unlock_irq(&dev_priv->irq_lock);
|
||||
|
||||
drm_connector_list_iter_begin(dev, &conn_iter);
|
||||
drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
|
||||
for_each_intel_connector_iter(connector, &conn_iter) {
|
||||
enum hpd_pin pin;
|
||||
u32 hpd_bit;
|
||||
|
@ -426,10 +426,10 @@ static void i915_hotplug_work_func(struct work_struct *work)
|
|||
}
|
||||
}
|
||||
drm_connector_list_iter_end(&conn_iter);
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
mutex_unlock(&dev_priv->drm.mode_config.mutex);
|
||||
|
||||
if (changed)
|
||||
drm_kms_helper_hotplug_event(dev);
|
||||
drm_kms_helper_hotplug_event(&dev_priv->drm);
|
||||
|
||||
/* Remove shared HPD pins that have changed */
|
||||
retry &= ~changed;
|
||||
|
@ -612,16 +612,15 @@ static void i915_hpd_poll_init_work(struct work_struct *work)
|
|||
struct drm_i915_private *dev_priv =
|
||||
container_of(work, struct drm_i915_private,
|
||||
display.hotplug.poll_init_work);
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
struct intel_connector *connector;
|
||||
bool enabled;
|
||||
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
mutex_lock(&dev_priv->drm.mode_config.mutex);
|
||||
|
||||
enabled = READ_ONCE(dev_priv->display.hotplug.poll_enabled);
|
||||
|
||||
drm_connector_list_iter_begin(dev, &conn_iter);
|
||||
drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
|
||||
for_each_intel_connector_iter(connector, &conn_iter) {
|
||||
enum hpd_pin pin;
|
||||
|
||||
|
@ -638,16 +637,16 @@ static void i915_hpd_poll_init_work(struct work_struct *work)
|
|||
drm_connector_list_iter_end(&conn_iter);
|
||||
|
||||
if (enabled)
|
||||
drm_kms_helper_poll_enable(dev);
|
||||
drm_kms_helper_poll_enable(&dev_priv->drm);
|
||||
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
mutex_unlock(&dev_priv->drm.mode_config.mutex);
|
||||
|
||||
/*
|
||||
* We might have missed any hotplugs that happened while we were
|
||||
* in the middle of disabling polling
|
||||
*/
|
||||
if (!enabled)
|
||||
drm_helper_hpd_irq_event(dev);
|
||||
drm_helper_hpd_irq_event(&dev_priv->drm);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -711,14 +710,23 @@ void intel_hpd_poll_disable(struct drm_i915_private *dev_priv)
|
|||
schedule_work(&dev_priv->display.hotplug.poll_init_work);
|
||||
}
|
||||
|
||||
void intel_hpd_init_work(struct drm_i915_private *dev_priv)
|
||||
void intel_hpd_init_early(struct drm_i915_private *i915)
|
||||
{
|
||||
INIT_DELAYED_WORK(&dev_priv->display.hotplug.hotplug_work,
|
||||
INIT_DELAYED_WORK(&i915->display.hotplug.hotplug_work,
|
||||
i915_hotplug_work_func);
|
||||
INIT_WORK(&dev_priv->display.hotplug.dig_port_work, i915_digport_work_func);
|
||||
INIT_WORK(&dev_priv->display.hotplug.poll_init_work, i915_hpd_poll_init_work);
|
||||
INIT_DELAYED_WORK(&dev_priv->display.hotplug.reenable_work,
|
||||
INIT_WORK(&i915->display.hotplug.dig_port_work, i915_digport_work_func);
|
||||
INIT_WORK(&i915->display.hotplug.poll_init_work, i915_hpd_poll_init_work);
|
||||
INIT_DELAYED_WORK(&i915->display.hotplug.reenable_work,
|
||||
intel_hpd_irq_storm_reenable_work);
|
||||
|
||||
i915->display.hotplug.hpd_storm_threshold = HPD_STORM_DEFAULT_THRESHOLD;
|
||||
/* If we have MST support, we want to avoid doing short HPD IRQ storm
|
||||
* detection, as short HPD storms will occur as a natural part of
|
||||
* sideband messaging with MST.
|
||||
* On older platforms however, IRQ storms can occur with both long and
|
||||
* short pulses, as seen on some G4x systems.
|
||||
*/
|
||||
i915->display.hotplug.hpd_short_storm_enabled = !HAS_DP_MST(i915);
|
||||
}
|
||||
|
||||
void intel_hpd_cancel_work(struct drm_i915_private *dev_priv)
|
||||
|
@ -767,3 +775,169 @@ void intel_hpd_enable(struct drm_i915_private *dev_priv, enum hpd_pin pin)
|
|||
dev_priv->display.hotplug.stats[pin].state = HPD_ENABLED;
|
||||
spin_unlock_irq(&dev_priv->irq_lock);
|
||||
}
|
||||
|
||||
static int i915_hpd_storm_ctl_show(struct seq_file *m, void *data)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = m->private;
|
||||
struct intel_hotplug *hotplug = &dev_priv->display.hotplug;
|
||||
|
||||
/* Synchronize with everything first in case there's been an HPD
|
||||
* storm, but we haven't finished handling it in the kernel yet
|
||||
*/
|
||||
intel_synchronize_irq(dev_priv);
|
||||
flush_work(&dev_priv->display.hotplug.dig_port_work);
|
||||
flush_delayed_work(&dev_priv->display.hotplug.hotplug_work);
|
||||
|
||||
seq_printf(m, "Threshold: %d\n", hotplug->hpd_storm_threshold);
|
||||
seq_printf(m, "Detected: %s\n",
|
||||
str_yes_no(delayed_work_pending(&hotplug->reenable_work)));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t i915_hpd_storm_ctl_write(struct file *file,
|
||||
const char __user *ubuf, size_t len,
|
||||
loff_t *offp)
|
||||
{
|
||||
struct seq_file *m = file->private_data;
|
||||
struct drm_i915_private *dev_priv = m->private;
|
||||
struct intel_hotplug *hotplug = &dev_priv->display.hotplug;
|
||||
unsigned int new_threshold;
|
||||
int i;
|
||||
char *newline;
|
||||
char tmp[16];
|
||||
|
||||
if (len >= sizeof(tmp))
|
||||
return -EINVAL;
|
||||
|
||||
if (copy_from_user(tmp, ubuf, len))
|
||||
return -EFAULT;
|
||||
|
||||
tmp[len] = '\0';
|
||||
|
||||
/* Strip newline, if any */
|
||||
newline = strchr(tmp, '\n');
|
||||
if (newline)
|
||||
*newline = '\0';
|
||||
|
||||
if (strcmp(tmp, "reset") == 0)
|
||||
new_threshold = HPD_STORM_DEFAULT_THRESHOLD;
|
||||
else if (kstrtouint(tmp, 10, &new_threshold) != 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (new_threshold > 0)
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"Setting HPD storm detection threshold to %d\n",
|
||||
new_threshold);
|
||||
else
|
||||
drm_dbg_kms(&dev_priv->drm, "Disabling HPD storm detection\n");
|
||||
|
||||
spin_lock_irq(&dev_priv->irq_lock);
|
||||
hotplug->hpd_storm_threshold = new_threshold;
|
||||
/* Reset the HPD storm stats so we don't accidentally trigger a storm */
|
||||
for_each_hpd_pin(i)
|
||||
hotplug->stats[i].count = 0;
|
||||
spin_unlock_irq(&dev_priv->irq_lock);
|
||||
|
||||
/* Re-enable hpd immediately if we were in an irq storm */
|
||||
flush_delayed_work(&dev_priv->display.hotplug.reenable_work);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static int i915_hpd_storm_ctl_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, i915_hpd_storm_ctl_show, inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations i915_hpd_storm_ctl_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = i915_hpd_storm_ctl_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
.write = i915_hpd_storm_ctl_write
|
||||
};
|
||||
|
||||
static int i915_hpd_short_storm_ctl_show(struct seq_file *m, void *data)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = m->private;
|
||||
|
||||
seq_printf(m, "Enabled: %s\n",
|
||||
str_yes_no(dev_priv->display.hotplug.hpd_short_storm_enabled));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
i915_hpd_short_storm_ctl_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, i915_hpd_short_storm_ctl_show,
|
||||
inode->i_private);
|
||||
}
|
||||
|
||||
static ssize_t i915_hpd_short_storm_ctl_write(struct file *file,
|
||||
const char __user *ubuf,
|
||||
size_t len, loff_t *offp)
|
||||
{
|
||||
struct seq_file *m = file->private_data;
|
||||
struct drm_i915_private *dev_priv = m->private;
|
||||
struct intel_hotplug *hotplug = &dev_priv->display.hotplug;
|
||||
char *newline;
|
||||
char tmp[16];
|
||||
int i;
|
||||
bool new_state;
|
||||
|
||||
if (len >= sizeof(tmp))
|
||||
return -EINVAL;
|
||||
|
||||
if (copy_from_user(tmp, ubuf, len))
|
||||
return -EFAULT;
|
||||
|
||||
tmp[len] = '\0';
|
||||
|
||||
/* Strip newline, if any */
|
||||
newline = strchr(tmp, '\n');
|
||||
if (newline)
|
||||
*newline = '\0';
|
||||
|
||||
/* Reset to the "default" state for this system */
|
||||
if (strcmp(tmp, "reset") == 0)
|
||||
new_state = !HAS_DP_MST(dev_priv);
|
||||
else if (kstrtobool(tmp, &new_state) != 0)
|
||||
return -EINVAL;
|
||||
|
||||
drm_dbg_kms(&dev_priv->drm, "%sabling HPD short storm detection\n",
|
||||
new_state ? "En" : "Dis");
|
||||
|
||||
spin_lock_irq(&dev_priv->irq_lock);
|
||||
hotplug->hpd_short_storm_enabled = new_state;
|
||||
/* Reset the HPD storm stats so we don't accidentally trigger a storm */
|
||||
for_each_hpd_pin(i)
|
||||
hotplug->stats[i].count = 0;
|
||||
spin_unlock_irq(&dev_priv->irq_lock);
|
||||
|
||||
/* Re-enable hpd immediately if we were in an irq storm */
|
||||
flush_delayed_work(&dev_priv->display.hotplug.reenable_work);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static const struct file_operations i915_hpd_short_storm_ctl_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = i915_hpd_short_storm_ctl_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
.write = i915_hpd_short_storm_ctl_write,
|
||||
};
|
||||
|
||||
void intel_hpd_debugfs_register(struct drm_i915_private *i915)
|
||||
{
|
||||
struct drm_minor *minor = i915->drm.primary;
|
||||
|
||||
debugfs_create_file("i915_hpd_storm_ctl", 0644, minor->debugfs_root,
|
||||
i915, &i915_hpd_storm_ctl_fops);
|
||||
debugfs_create_file("i915_hpd_short_storm_ctl", 0644, minor->debugfs_root,
|
||||
i915, &i915_hpd_short_storm_ctl_fops);
|
||||
}
|
||||
|
|
|
@ -22,11 +22,12 @@ void intel_hpd_irq_handler(struct drm_i915_private *dev_priv,
|
|||
u32 pin_mask, u32 long_mask);
|
||||
void intel_hpd_trigger_irq(struct intel_digital_port *dig_port);
|
||||
void intel_hpd_init(struct drm_i915_private *dev_priv);
|
||||
void intel_hpd_init_work(struct drm_i915_private *dev_priv);
|
||||
void intel_hpd_init_early(struct drm_i915_private *i915);
|
||||
void intel_hpd_cancel_work(struct drm_i915_private *dev_priv);
|
||||
enum hpd_pin intel_hpd_pin_default(struct drm_i915_private *dev_priv,
|
||||
enum port port);
|
||||
bool intel_hpd_disable(struct drm_i915_private *dev_priv, enum hpd_pin pin);
|
||||
void intel_hpd_enable(struct drm_i915_private *dev_priv, enum hpd_pin pin);
|
||||
void intel_hpd_debugfs_register(struct drm_i915_private *i915);
|
||||
|
||||
#endif /* __INTEL_HOTPLUG_H__ */
|
||||
|
|
|
@ -80,8 +80,7 @@
|
|||
static struct platform_device *
|
||||
lpe_audio_platdev_create(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
struct pci_dev *pdev = to_pci_dev(dev->dev);
|
||||
struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
|
||||
struct platform_device_info pinfo = {};
|
||||
struct resource *rsc;
|
||||
struct platform_device *platdev;
|
||||
|
@ -108,7 +107,7 @@ lpe_audio_platdev_create(struct drm_i915_private *dev_priv)
|
|||
rsc[1].flags = IORESOURCE_MEM;
|
||||
rsc[1].name = "hdmi-lpe-audio-mmio";
|
||||
|
||||
pinfo.parent = dev->dev;
|
||||
pinfo.parent = dev_priv->drm.dev;
|
||||
pinfo.name = "hdmi-lpe-audio";
|
||||
pinfo.id = -1;
|
||||
pinfo.res = rsc;
|
||||
|
|
|
@ -78,9 +78,9 @@ struct intel_lvds_encoder {
|
|||
struct intel_connector *attached_connector;
|
||||
};
|
||||
|
||||
static struct intel_lvds_encoder *to_lvds_encoder(struct drm_encoder *encoder)
|
||||
static struct intel_lvds_encoder *to_lvds_encoder(struct intel_encoder *encoder)
|
||||
{
|
||||
return container_of(encoder, struct intel_lvds_encoder, base.base);
|
||||
return container_of(encoder, struct intel_lvds_encoder, base);
|
||||
}
|
||||
|
||||
bool intel_lvds_port_enabled(struct drm_i915_private *dev_priv,
|
||||
|
@ -103,7 +103,7 @@ static bool intel_lvds_get_hw_state(struct intel_encoder *encoder,
|
|||
enum pipe *pipe)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
|
||||
struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(encoder);
|
||||
intel_wakeref_t wakeref;
|
||||
bool ret;
|
||||
|
||||
|
@ -123,7 +123,7 @@ static void intel_lvds_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_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
|
||||
struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(encoder);
|
||||
u32 tmp, flags = 0;
|
||||
|
||||
pipe_config->output_types |= BIT(INTEL_OUTPUT_LVDS);
|
||||
|
@ -229,7 +229,7 @@ static void intel_pre_enable_lvds(struct intel_atomic_state *state,
|
|||
const struct intel_crtc_state *pipe_config,
|
||||
const struct drm_connector_state *conn_state)
|
||||
{
|
||||
struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
|
||||
struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(encoder);
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
|
||||
const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
|
||||
|
@ -312,7 +312,7 @@ static void intel_enable_lvds(struct intel_atomic_state *state,
|
|||
const struct drm_connector_state *conn_state)
|
||||
{
|
||||
struct drm_device *dev = encoder->base.dev;
|
||||
struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
|
||||
struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(encoder);
|
||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
|
||||
intel_de_write(dev_priv, lvds_encoder->reg,
|
||||
|
@ -334,7 +334,7 @@ static void intel_disable_lvds(struct intel_atomic_state *state,
|
|||
const struct intel_crtc_state *old_crtc_state,
|
||||
const struct drm_connector_state *old_conn_state)
|
||||
{
|
||||
struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
|
||||
struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(encoder);
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
|
||||
intel_de_write(dev_priv, PP_CONTROL(0),
|
||||
|
@ -413,7 +413,7 @@ static int intel_lvds_compute_config(struct intel_encoder *intel_encoder,
|
|||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev);
|
||||
struct intel_lvds_encoder *lvds_encoder =
|
||||
to_lvds_encoder(&intel_encoder->base);
|
||||
to_lvds_encoder(intel_encoder);
|
||||
struct intel_connector *intel_connector =
|
||||
lvds_encoder->attached_connector;
|
||||
struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
|
||||
|
@ -775,7 +775,7 @@ bool intel_is_dual_link_lvds(struct drm_i915_private *dev_priv)
|
|||
{
|
||||
struct intel_encoder *encoder = intel_get_lvds_encoder(dev_priv);
|
||||
|
||||
return encoder && to_lvds_encoder(&encoder->base)->is_dual_link;
|
||||
return encoder && to_lvds_encoder(encoder)->is_dual_link;
|
||||
}
|
||||
|
||||
static bool compute_is_dual_link_lvds(struct intel_lvds_encoder *lvds_encoder)
|
||||
|
@ -814,6 +814,11 @@ static bool compute_is_dual_link_lvds(struct intel_lvds_encoder *lvds_encoder)
|
|||
return (val & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP;
|
||||
}
|
||||
|
||||
static void intel_lvds_add_properties(struct drm_connector *connector)
|
||||
{
|
||||
intel_attach_scaling_mode_property(connector);
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_lvds_init - setup LVDS connectors on this device
|
||||
* @dev_priv: i915 device
|
||||
|
@ -823,7 +828,6 @@ static bool compute_is_dual_link_lvds(struct intel_lvds_encoder *lvds_encoder)
|
|||
*/
|
||||
void intel_lvds_init(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
struct intel_lvds_encoder *lvds_encoder;
|
||||
struct intel_encoder *intel_encoder;
|
||||
struct intel_connector *intel_connector;
|
||||
|
@ -833,11 +837,10 @@ void intel_lvds_init(struct drm_i915_private *dev_priv)
|
|||
i915_reg_t lvds_reg;
|
||||
u32 lvds;
|
||||
u8 pin;
|
||||
u32 allowed_scalers;
|
||||
|
||||
/* Skip init on machines we know falsely report LVDS */
|
||||
if (dmi_check_system(intel_no_lvds)) {
|
||||
drm_WARN(dev, !dev_priv->display.vbt.int_lvds_support,
|
||||
drm_WARN(&dev_priv->drm, !dev_priv->display.vbt.int_lvds_support,
|
||||
"Useless DMI match. Internal LVDS support disabled by VBT\n");
|
||||
return;
|
||||
}
|
||||
|
@ -886,10 +889,10 @@ void intel_lvds_init(struct drm_i915_private *dev_priv)
|
|||
intel_encoder = &lvds_encoder->base;
|
||||
encoder = &intel_encoder->base;
|
||||
connector = &intel_connector->base;
|
||||
drm_connector_init(dev, &intel_connector->base, &intel_lvds_connector_funcs,
|
||||
drm_connector_init(&dev_priv->drm, &intel_connector->base, &intel_lvds_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_LVDS);
|
||||
|
||||
drm_encoder_init(dev, &intel_encoder->base, &intel_lvds_enc_funcs,
|
||||
drm_encoder_init(&dev_priv->drm, &intel_encoder->base, &intel_lvds_enc_funcs,
|
||||
DRM_MODE_ENCODER_LVDS, "LVDS");
|
||||
|
||||
intel_encoder->enable = intel_enable_lvds;
|
||||
|
@ -920,17 +923,10 @@ void intel_lvds_init(struct drm_i915_private *dev_priv)
|
|||
|
||||
drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs);
|
||||
connector->display_info.subpixel_order = SubPixelHorizontalRGB;
|
||||
connector->interlace_allowed = false;
|
||||
connector->doublescan_allowed = false;
|
||||
|
||||
lvds_encoder->reg = lvds_reg;
|
||||
|
||||
/* create the scaling mode property */
|
||||
allowed_scalers = BIT(DRM_MODE_SCALE_ASPECT);
|
||||
allowed_scalers |= BIT(DRM_MODE_SCALE_FULLSCREEN);
|
||||
allowed_scalers |= BIT(DRM_MODE_SCALE_CENTER);
|
||||
drm_connector_attach_scaling_mode_property(connector, allowed_scalers);
|
||||
connector->state->scaling_mode = DRM_MODE_SCALE_ASPECT;
|
||||
intel_lvds_add_properties(connector);
|
||||
|
||||
intel_lvds_pps_get_hw_state(dev_priv, &lvds_encoder->init_pps);
|
||||
lvds_encoder->init_lvds_val = lvds;
|
||||
|
@ -947,7 +943,7 @@ void intel_lvds_init(struct drm_i915_private *dev_priv)
|
|||
* Attempt to get the fixed panel mode from DDC. Assume that the
|
||||
* preferred mode is the right one.
|
||||
*/
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
mutex_lock(&dev_priv->drm.mode_config.mutex);
|
||||
if (vga_switcheroo_handler_flags() & VGA_SWITCHEROO_CAN_SWITCH_DDC)
|
||||
edid = drm_get_edid_switcheroo(connector,
|
||||
intel_gmbus_get_adapter(dev_priv, pin));
|
||||
|
@ -971,9 +967,7 @@ void intel_lvds_init(struct drm_i915_private *dev_priv)
|
|||
IS_ERR(edid) ? NULL : edid);
|
||||
|
||||
/* Try EDID first */
|
||||
intel_panel_add_edid_fixed_modes(intel_connector,
|
||||
intel_connector->panel.vbt.drrs_type != DRRS_TYPE_NONE,
|
||||
false);
|
||||
intel_panel_add_edid_fixed_modes(intel_connector, true);
|
||||
|
||||
/* Failed to get EDID, what about VBT? */
|
||||
if (!intel_panel_preferred_fixed_mode(intel_connector))
|
||||
|
@ -987,7 +981,7 @@ void intel_lvds_init(struct drm_i915_private *dev_priv)
|
|||
if (!intel_panel_preferred_fixed_mode(intel_connector))
|
||||
intel_panel_add_encoder_fixed_mode(intel_connector, intel_encoder);
|
||||
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
mutex_unlock(&dev_priv->drm.mode_config.mutex);
|
||||
|
||||
/* If we still don't have a mode after all that, give up. */
|
||||
if (!intel_panel_preferred_fixed_mode(intel_connector))
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
* Copyright © 2022 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef __INTEL_TC_PHY_REGS__
|
||||
#define __INTEL_TC_PHY_REGS__
|
||||
#ifndef __INTEL_MG_PHY_REGS__
|
||||
#define __INTEL_MG_PHY_REGS__
|
||||
|
||||
#include "i915_reg_defs.h"
|
||||
|
||||
|
@ -277,4 +277,4 @@
|
|||
_MG_PLL_TDC_COLDST_BIAS_PORT1, \
|
||||
_MG_PLL_TDC_COLDST_BIAS_PORT2)
|
||||
|
||||
#endif /* __INTEL_TC_PHY_REGS__ */
|
||||
#endif /* __INTEL_MG_PHY_REGS__ */
|
|
@ -155,6 +155,12 @@ static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state
|
|||
crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
|
||||
crtc_state->uapi.scaling_filter = crtc_state->hw.scaling_filter;
|
||||
|
||||
/* assume 1:1 mapping */
|
||||
drm_property_replace_blob(&crtc_state->hw.degamma_lut,
|
||||
crtc_state->pre_csc_lut);
|
||||
drm_property_replace_blob(&crtc_state->hw.gamma_lut,
|
||||
crtc_state->post_csc_lut);
|
||||
|
||||
drm_property_replace_blob(&crtc_state->uapi.degamma_lut,
|
||||
crtc_state->hw.degamma_lut);
|
||||
drm_property_replace_blob(&crtc_state->uapi.gamma_lut,
|
||||
|
@ -205,13 +211,21 @@ static bool intel_crtc_has_encoders(struct intel_crtc *crtc)
|
|||
|
||||
static struct intel_connector *intel_encoder_find_connector(struct intel_encoder *encoder)
|
||||
{
|
||||
struct drm_device *dev = encoder->base.dev;
|
||||
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
struct intel_connector *connector;
|
||||
struct intel_connector *found_connector = NULL;
|
||||
|
||||
for_each_connector_on_encoder(dev, &encoder->base, connector)
|
||||
return connector;
|
||||
drm_connector_list_iter_begin(&i915->drm, &conn_iter);
|
||||
for_each_intel_connector_iter(connector, &conn_iter) {
|
||||
if (&encoder->base == connector->base.encoder) {
|
||||
found_connector = connector;
|
||||
break;
|
||||
}
|
||||
}
|
||||
drm_connector_list_iter_end(&conn_iter);
|
||||
|
||||
return NULL;
|
||||
return found_connector;
|
||||
}
|
||||
|
||||
static void intel_sanitize_fifo_underrun_reporting(const struct intel_crtc_state *crtc_state)
|
||||
|
|
|
@ -227,7 +227,8 @@ void intel_modeset_verify_crtc(struct intel_crtc *crtc,
|
|||
struct intel_crtc_state *old_crtc_state,
|
||||
struct intel_crtc_state *new_crtc_state)
|
||||
{
|
||||
if (!intel_crtc_needs_modeset(new_crtc_state) && !new_crtc_state->update_pipe)
|
||||
if (!intel_crtc_needs_modeset(new_crtc_state) &&
|
||||
!intel_crtc_needs_fastset(new_crtc_state))
|
||||
return;
|
||||
|
||||
intel_wm_state_verify(crtc, new_crtc_state);
|
||||
|
|
|
@ -463,7 +463,6 @@ static u32 asle_set_backlight(struct drm_i915_private *dev_priv, u32 bclp)
|
|||
struct intel_connector *connector;
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
struct opregion_asle *asle = dev_priv->display.opregion.asle;
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
|
||||
drm_dbg(&dev_priv->drm, "bclp = 0x%08x\n", bclp);
|
||||
|
||||
|
@ -480,7 +479,7 @@ static u32 asle_set_backlight(struct drm_i915_private *dev_priv, u32 bclp)
|
|||
if (bclp > 255)
|
||||
return ASLC_BACKLIGHT_FAILED;
|
||||
|
||||
drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
|
||||
drm_modeset_lock(&dev_priv->drm.mode_config.connection_mutex, NULL);
|
||||
|
||||
/*
|
||||
* Update backlight on all connectors that support backlight (usually
|
||||
|
@ -488,13 +487,13 @@ static u32 asle_set_backlight(struct drm_i915_private *dev_priv, u32 bclp)
|
|||
*/
|
||||
drm_dbg_kms(&dev_priv->drm, "updating opregion backlight %d/255\n",
|
||||
bclp);
|
||||
drm_connector_list_iter_begin(dev, &conn_iter);
|
||||
drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
|
||||
for_each_intel_connector_iter(connector, &conn_iter)
|
||||
intel_backlight_set_acpi(connector->base.state, bclp, 255);
|
||||
drm_connector_list_iter_end(&conn_iter);
|
||||
asle->cblv = DIV_ROUND_UP(bclp * 100, 255) | ASLE_CBLV_VALID;
|
||||
|
||||
drm_modeset_unlock(&dev->mode_config.connection_mutex);
|
||||
drm_modeset_unlock(&dev_priv->drm.mode_config.connection_mutex);
|
||||
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -85,9 +85,10 @@ static bool is_alt_drrs_mode(const struct drm_display_mode *mode,
|
|||
static bool is_alt_fixed_mode(const struct drm_display_mode *mode,
|
||||
const struct drm_display_mode *preferred_mode)
|
||||
{
|
||||
return drm_mode_match(mode, preferred_mode,
|
||||
DRM_MODE_MATCH_FLAGS |
|
||||
DRM_MODE_MATCH_3D_FLAGS) &&
|
||||
u32 sync_flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NHSYNC |
|
||||
DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC;
|
||||
|
||||
return (mode->flags & ~sync_flags) == (preferred_mode->flags & ~sync_flags) &&
|
||||
mode->hdisplay == preferred_mode->hdisplay &&
|
||||
mode->vdisplay == preferred_mode->vdisplay;
|
||||
}
|
||||
|
@ -147,12 +148,24 @@ int intel_panel_get_modes(struct intel_connector *connector)
|
|||
return num_modes;
|
||||
}
|
||||
|
||||
static bool has_drrs_modes(struct intel_connector *connector)
|
||||
{
|
||||
const struct drm_display_mode *mode1;
|
||||
|
||||
list_for_each_entry(mode1, &connector->panel.fixed_modes, head) {
|
||||
const struct drm_display_mode *mode2 = mode1;
|
||||
|
||||
list_for_each_entry_continue(mode2, &connector->panel.fixed_modes, head) {
|
||||
if (is_alt_drrs_mode(mode1, mode2))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
enum drrs_type intel_panel_drrs_type(struct intel_connector *connector)
|
||||
{
|
||||
if (list_empty(&connector->panel.fixed_modes) ||
|
||||
list_is_singular(&connector->panel.fixed_modes))
|
||||
return DRRS_TYPE_NONE;
|
||||
|
||||
return connector->panel.vbt.drrs_type;
|
||||
}
|
||||
|
||||
|
@ -254,10 +267,10 @@ static void intel_panel_destroy_probed_modes(struct intel_connector *connector)
|
|||
}
|
||||
|
||||
void intel_panel_add_edid_fixed_modes(struct intel_connector *connector,
|
||||
bool has_drrs, bool has_vrr)
|
||||
bool use_alt_fixed_modes)
|
||||
{
|
||||
intel_panel_add_edid_preferred_mode(connector);
|
||||
if (intel_panel_preferred_fixed_mode(connector) && (has_drrs || has_vrr))
|
||||
if (intel_panel_preferred_fixed_mode(connector) && use_alt_fixed_modes)
|
||||
intel_panel_add_edid_alt_fixed_modes(connector);
|
||||
intel_panel_destroy_probed_modes(connector);
|
||||
}
|
||||
|
@ -653,6 +666,9 @@ int intel_panel_init(struct intel_connector *connector)
|
|||
|
||||
intel_backlight_init_funcs(panel);
|
||||
|
||||
if (!has_drrs_modes(connector))
|
||||
connector->panel.vbt.drrs_type = DRRS_TYPE_NONE;
|
||||
|
||||
drm_dbg_kms(connector->base.dev,
|
||||
"[CONNECTOR:%d:%s] DRRS type: %s\n",
|
||||
connector->base.base.id, connector->base.name,
|
||||
|
|
|
@ -44,7 +44,7 @@ int intel_panel_fitting(struct intel_crtc_state *crtc_state,
|
|||
int intel_panel_compute_config(struct intel_connector *connector,
|
||||
struct drm_display_mode *adjusted_mode);
|
||||
void intel_panel_add_edid_fixed_modes(struct intel_connector *connector,
|
||||
bool has_drrs, bool has_vrr);
|
||||
bool use_alt_fixed_modes);
|
||||
void intel_panel_add_vbt_lfp_fixed_mode(struct intel_connector *connector);
|
||||
void intel_panel_add_vbt_sdvo_fixed_mode(struct intel_connector *connector);
|
||||
void intel_panel_add_encoder_fixed_mode(struct intel_connector *connector,
|
||||
|
|
|
@ -75,7 +75,6 @@ static int i9xx_pipe_crc_auto_source(struct drm_i915_private *dev_priv,
|
|||
enum pipe pipe,
|
||||
enum intel_pipe_crc_source *source)
|
||||
{
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
struct intel_encoder *encoder;
|
||||
struct intel_crtc *crtc;
|
||||
struct intel_digital_port *dig_port;
|
||||
|
@ -83,8 +82,8 @@ static int i9xx_pipe_crc_auto_source(struct drm_i915_private *dev_priv,
|
|||
|
||||
*source = INTEL_PIPE_CRC_SOURCE_PIPE;
|
||||
|
||||
drm_modeset_lock_all(dev);
|
||||
for_each_intel_encoder(dev, encoder) {
|
||||
drm_modeset_lock_all(&dev_priv->drm);
|
||||
for_each_intel_encoder(&dev_priv->drm, encoder) {
|
||||
if (!encoder->base.crtc)
|
||||
continue;
|
||||
|
||||
|
@ -111,7 +110,7 @@ static int i9xx_pipe_crc_auto_source(struct drm_i915_private *dev_priv,
|
|||
*source = INTEL_PIPE_CRC_SOURCE_DP_D;
|
||||
break;
|
||||
default:
|
||||
drm_WARN(dev, 1, "nonexisting DP port %c\n",
|
||||
drm_WARN(&dev_priv->drm, 1, "nonexisting DP port %c\n",
|
||||
port_name(dig_port->base.port));
|
||||
break;
|
||||
}
|
||||
|
@ -120,7 +119,7 @@ static int i9xx_pipe_crc_auto_source(struct drm_i915_private *dev_priv,
|
|||
break;
|
||||
}
|
||||
}
|
||||
drm_modeset_unlock_all(dev);
|
||||
drm_modeset_unlock_all(&dev_priv->drm);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -533,7 +533,7 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
|
|||
|
||||
val |= psr_compute_idle_frames(intel_dp) << EDP_PSR2_IDLE_FRAME_SHIFT;
|
||||
|
||||
if (!IS_ALDERLAKE_P(dev_priv))
|
||||
if (DISPLAY_VER(dev_priv) <= 13 && !IS_ALDERLAKE_P(dev_priv))
|
||||
val |= EDP_SU_TRACK_ENABLE;
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 10 && DISPLAY_VER(dev_priv) <= 12)
|
||||
|
@ -616,7 +616,7 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
|
|||
static bool
|
||||
transcoder_has_psr2(struct drm_i915_private *dev_priv, enum transcoder trans)
|
||||
{
|
||||
if (IS_ALDERLAKE_P(dev_priv))
|
||||
if (IS_ALDERLAKE_P(dev_priv) || DISPLAY_VER(dev_priv) >= 14)
|
||||
return trans == TRANSCODER_A || trans == TRANSCODER_B;
|
||||
else if (DISPLAY_VER(dev_priv) >= 12)
|
||||
return trans == TRANSCODER_A;
|
||||
|
@ -696,7 +696,7 @@ dc3co_is_pipe_port_compatible(struct intel_dp *intel_dp,
|
|||
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
|
||||
enum port port = dig_port->base.port;
|
||||
|
||||
if (IS_ALDERLAKE_P(dev_priv))
|
||||
if (IS_ALDERLAKE_P(dev_priv) || DISPLAY_VER(dev_priv) >= 14)
|
||||
return pipe <= PIPE_B && port <= PORT_B;
|
||||
else
|
||||
return pipe == PIPE_A && port == PORT_A;
|
||||
|
@ -795,11 +795,11 @@ static bool psr2_granularity_check(struct intel_dp *intel_dp,
|
|||
return intel_dp->psr.su_y_granularity == 4;
|
||||
|
||||
/*
|
||||
* adl_p has 1 line granularity. For other platforms with SW tracking we
|
||||
* can adjust the y coordinates to match sink requirement if multiple of
|
||||
* 4.
|
||||
* adl_p and display 14+ platforms has 1 line granularity.
|
||||
* For other platforms with SW tracking we can adjust the y coordinates
|
||||
* to match sink requirement if multiple of 4.
|
||||
*/
|
||||
if (IS_ALDERLAKE_P(dev_priv))
|
||||
if (IS_ALDERLAKE_P(dev_priv) || DISPLAY_VER(dev_priv) >= 14)
|
||||
y_granularity = intel_dp->psr.su_y_granularity;
|
||||
else if (intel_dp->psr.su_y_granularity <= 2)
|
||||
y_granularity = 4;
|
||||
|
@ -883,7 +883,8 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
|
|||
* resolution requires DSC to be enabled, priority is given to DSC
|
||||
* over PSR2.
|
||||
*/
|
||||
if (crtc_state->dsc.compression_enable) {
|
||||
if (crtc_state->dsc.compression_enable &&
|
||||
(DISPLAY_VER(dev_priv) <= 13 && !IS_ALDERLAKE_P(dev_priv))) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"PSR2 cannot be enabled since DSC is enabled\n");
|
||||
return false;
|
||||
|
@ -1474,7 +1475,7 @@ static u32 man_trk_ctl_enable_bit_get(struct drm_i915_private *dev_priv)
|
|||
|
||||
static u32 man_trk_ctl_single_full_frame_bit_get(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
return IS_ALDERLAKE_P(dev_priv) ?
|
||||
return IS_ALDERLAKE_P(dev_priv) || DISPLAY_VER(dev_priv) >= 14 ?
|
||||
ADLP_PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME :
|
||||
PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME;
|
||||
}
|
||||
|
@ -1627,7 +1628,7 @@ static void psr2_man_trk_ctl_calc(struct intel_crtc_state *crtc_state,
|
|||
if (clip->y1 == -1)
|
||||
goto exit;
|
||||
|
||||
if (IS_ALDERLAKE_P(dev_priv)) {
|
||||
if (IS_ALDERLAKE_P(dev_priv) || DISPLAY_VER(dev_priv) >= 14) {
|
||||
val |= ADLP_PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR(clip->y1);
|
||||
val |= ADLP_PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR(clip->y2 - 1);
|
||||
} else {
|
||||
|
@ -1664,7 +1665,15 @@ static void intel_psr2_sel_fetch_pipe_alignment(const struct intel_crtc_state *c
|
|||
struct drm_rect *pipe_clip)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
|
||||
const u16 y_alignment = crtc_state->su_y_granularity;
|
||||
const struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
|
||||
u16 y_alignment;
|
||||
|
||||
/* ADLP aligns the SU region to vdsc slice height in case dsc is enabled */
|
||||
if (crtc_state->dsc.compression_enable &&
|
||||
(IS_ALDERLAKE_P(dev_priv) || DISPLAY_VER(dev_priv) >= 14))
|
||||
y_alignment = vdsc_cfg->slice_height;
|
||||
else
|
||||
y_alignment = crtc_state->su_y_granularity;
|
||||
|
||||
pipe_clip->y1 -= pipe_clip->y1 % y_alignment;
|
||||
if (pipe_clip->y2 % y_alignment)
|
||||
|
@ -2054,13 +2063,12 @@ static bool __psr_wait_for_idle_locked(struct intel_dp *intel_dp)
|
|||
static int intel_psr_fastset_force(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
struct drm_modeset_acquire_ctx ctx;
|
||||
struct drm_atomic_state *state;
|
||||
struct drm_connector *conn;
|
||||
int err = 0;
|
||||
|
||||
state = drm_atomic_state_alloc(dev);
|
||||
state = drm_atomic_state_alloc(&dev_priv->drm);
|
||||
if (!state)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -2069,7 +2077,7 @@ static int intel_psr_fastset_force(struct drm_i915_private *dev_priv)
|
|||
|
||||
retry:
|
||||
|
||||
drm_connector_list_iter_begin(dev, &conn_iter);
|
||||
drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
|
||||
drm_for_each_connector_iter(conn, &conn_iter) {
|
||||
struct drm_connector_state *conn_state;
|
||||
struct drm_crtc_state *crtc_state;
|
||||
|
|
|
@ -199,7 +199,7 @@ to_intel_sdvo_connector(struct drm_connector *connector)
|
|||
container_of((conn_state), struct intel_sdvo_connector_state, base.base)
|
||||
|
||||
static bool
|
||||
intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, u16 flags);
|
||||
intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo);
|
||||
static bool
|
||||
intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo,
|
||||
struct intel_sdvo_connector *intel_sdvo_connector,
|
||||
|
@ -1297,13 +1297,28 @@ static bool intel_sdvo_limited_color_range(struct intel_encoder *encoder,
|
|||
return intel_hdmi_limited_color_range(crtc_state, conn_state);
|
||||
}
|
||||
|
||||
static bool intel_sdvo_has_audio(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
const struct drm_connector_state *conn_state)
|
||||
{
|
||||
struct intel_sdvo *intel_sdvo = to_sdvo(encoder);
|
||||
const struct intel_digital_connector_state *intel_conn_state =
|
||||
to_intel_digital_connector_state(conn_state);
|
||||
|
||||
if (!crtc_state->has_hdmi_sink)
|
||||
return false;
|
||||
|
||||
if (intel_conn_state->force_audio == HDMI_AUDIO_AUTO)
|
||||
return intel_sdvo->has_hdmi_audio;
|
||||
else
|
||||
return intel_conn_state->force_audio == HDMI_AUDIO_ON;
|
||||
}
|
||||
|
||||
static int intel_sdvo_compute_config(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *pipe_config,
|
||||
struct drm_connector_state *conn_state)
|
||||
{
|
||||
struct intel_sdvo *intel_sdvo = to_sdvo(encoder);
|
||||
struct intel_sdvo_connector_state *intel_sdvo_state =
|
||||
to_intel_sdvo_connector_state(conn_state);
|
||||
struct intel_sdvo_connector *intel_sdvo_connector =
|
||||
to_intel_sdvo_connector(conn_state->connector);
|
||||
struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
|
||||
|
@ -1362,13 +1377,7 @@ static int intel_sdvo_compute_config(struct intel_encoder *encoder,
|
|||
|
||||
pipe_config->has_hdmi_sink = intel_has_hdmi_sink(intel_sdvo, conn_state);
|
||||
|
||||
if (pipe_config->has_hdmi_sink) {
|
||||
if (intel_sdvo_state->base.force_audio == HDMI_AUDIO_AUTO)
|
||||
pipe_config->has_audio = intel_sdvo->has_hdmi_audio;
|
||||
else
|
||||
pipe_config->has_audio =
|
||||
intel_sdvo_state->base.force_audio == HDMI_AUDIO_ON;
|
||||
}
|
||||
pipe_config->has_audio = intel_sdvo_has_audio(encoder, pipe_config, conn_state);
|
||||
|
||||
pipe_config->limited_color_range =
|
||||
intel_sdvo_limited_color_range(encoder, pipe_config,
|
||||
|
@ -2290,17 +2299,12 @@ static int intel_sdvo_get_tv_modes(struct drm_connector *connector)
|
|||
|
||||
static int intel_sdvo_get_lvds_modes(struct drm_connector *connector)
|
||||
{
|
||||
struct intel_sdvo *intel_sdvo = intel_attached_sdvo(to_intel_connector(connector));
|
||||
struct drm_i915_private *dev_priv = to_i915(connector->dev);
|
||||
int num_modes = 0;
|
||||
|
||||
drm_dbg_kms(&dev_priv->drm, "[CONNECTOR:%d:%s]\n",
|
||||
connector->base.id, connector->name);
|
||||
|
||||
num_modes += intel_panel_get_modes(to_intel_connector(connector));
|
||||
num_modes += intel_ddc_get_modes(connector, &intel_sdvo->ddc);
|
||||
|
||||
return num_modes;
|
||||
return intel_panel_get_modes(to_intel_connector(connector));
|
||||
}
|
||||
|
||||
static int intel_sdvo_get_modes(struct drm_connector *connector)
|
||||
|
@ -2627,7 +2631,7 @@ intel_sdvo_unselect_i2c_bus(struct intel_sdvo *sdvo)
|
|||
}
|
||||
|
||||
static bool
|
||||
intel_sdvo_is_hdmi_connector(struct intel_sdvo *intel_sdvo, int device)
|
||||
intel_sdvo_is_hdmi_connector(struct intel_sdvo *intel_sdvo)
|
||||
{
|
||||
return intel_sdvo_check_supp_encode(intel_sdvo);
|
||||
}
|
||||
|
@ -2689,9 +2693,8 @@ intel_sdvo_connector_init(struct intel_sdvo_connector *connector,
|
|||
drm_connector_helper_add(drm_connector,
|
||||
&intel_sdvo_connector_helper_funcs);
|
||||
|
||||
connector->base.base.interlace_allowed = 1;
|
||||
connector->base.base.doublescan_allowed = 0;
|
||||
connector->base.base.display_info.subpixel_order = SubPixelHorizontalRGB;
|
||||
connector->base.base.interlace_allowed = true;
|
||||
connector->base.get_hw_state = intel_sdvo_connector_get_hw_state;
|
||||
|
||||
intel_connector_attach_encoder(&connector->base, &encoder->base);
|
||||
|
@ -2733,7 +2736,7 @@ static struct intel_sdvo_connector *intel_sdvo_connector_alloc(void)
|
|||
}
|
||||
|
||||
static bool
|
||||
intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
|
||||
intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, u16 type)
|
||||
{
|
||||
struct drm_encoder *encoder = &intel_sdvo->base.base;
|
||||
struct drm_connector *connector;
|
||||
|
@ -2741,19 +2744,13 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
|
|||
struct intel_connector *intel_connector;
|
||||
struct intel_sdvo_connector *intel_sdvo_connector;
|
||||
|
||||
DRM_DEBUG_KMS("initialising DVI device %d\n", device);
|
||||
DRM_DEBUG_KMS("initialising DVI type 0x%x\n", type);
|
||||
|
||||
intel_sdvo_connector = intel_sdvo_connector_alloc();
|
||||
if (!intel_sdvo_connector)
|
||||
return false;
|
||||
|
||||
if (device == 0) {
|
||||
intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS0;
|
||||
intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS0;
|
||||
} else if (device == 1) {
|
||||
intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS1;
|
||||
intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS1;
|
||||
}
|
||||
intel_sdvo_connector->output_flag = type;
|
||||
|
||||
intel_connector = &intel_sdvo_connector->base;
|
||||
connector = &intel_connector->base;
|
||||
|
@ -2773,7 +2770,7 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
|
|||
encoder->encoder_type = DRM_MODE_ENCODER_TMDS;
|
||||
connector->connector_type = DRM_MODE_CONNECTOR_DVID;
|
||||
|
||||
if (intel_sdvo_is_hdmi_connector(intel_sdvo, device)) {
|
||||
if (intel_sdvo_is_hdmi_connector(intel_sdvo)) {
|
||||
connector->connector_type = DRM_MODE_CONNECTOR_HDMIA;
|
||||
intel_sdvo_connector->is_hdmi = true;
|
||||
}
|
||||
|
@ -2790,14 +2787,14 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
|
|||
}
|
||||
|
||||
static bool
|
||||
intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type)
|
||||
intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, u16 type)
|
||||
{
|
||||
struct drm_encoder *encoder = &intel_sdvo->base.base;
|
||||
struct drm_connector *connector;
|
||||
struct intel_connector *intel_connector;
|
||||
struct intel_sdvo_connector *intel_sdvo_connector;
|
||||
|
||||
DRM_DEBUG_KMS("initialising TV type %d\n", type);
|
||||
DRM_DEBUG_KMS("initialising TV type 0x%x\n", type);
|
||||
|
||||
intel_sdvo_connector = intel_sdvo_connector_alloc();
|
||||
if (!intel_sdvo_connector)
|
||||
|
@ -2808,7 +2805,6 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type)
|
|||
encoder->encoder_type = DRM_MODE_ENCODER_TVDAC;
|
||||
connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO;
|
||||
|
||||
intel_sdvo->controlled_output |= type;
|
||||
intel_sdvo_connector->output_flag = type;
|
||||
|
||||
if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) {
|
||||
|
@ -2830,14 +2826,14 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type)
|
|||
}
|
||||
|
||||
static bool
|
||||
intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device)
|
||||
intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, u16 type)
|
||||
{
|
||||
struct drm_encoder *encoder = &intel_sdvo->base.base;
|
||||
struct drm_connector *connector;
|
||||
struct intel_connector *intel_connector;
|
||||
struct intel_sdvo_connector *intel_sdvo_connector;
|
||||
|
||||
DRM_DEBUG_KMS("initialising analog device %d\n", device);
|
||||
DRM_DEBUG_KMS("initialising analog type 0x%x\n", type);
|
||||
|
||||
intel_sdvo_connector = intel_sdvo_connector_alloc();
|
||||
if (!intel_sdvo_connector)
|
||||
|
@ -2849,13 +2845,7 @@ intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device)
|
|||
encoder->encoder_type = DRM_MODE_ENCODER_DAC;
|
||||
connector->connector_type = DRM_MODE_CONNECTOR_VGA;
|
||||
|
||||
if (device == 0) {
|
||||
intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB0;
|
||||
intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB0;
|
||||
} else if (device == 1) {
|
||||
intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB1;
|
||||
intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1;
|
||||
}
|
||||
intel_sdvo_connector->output_flag = type;
|
||||
|
||||
if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) {
|
||||
kfree(intel_sdvo_connector);
|
||||
|
@ -2866,7 +2856,7 @@ intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device)
|
|||
}
|
||||
|
||||
static bool
|
||||
intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
|
||||
intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, u16 type)
|
||||
{
|
||||
struct drm_encoder *encoder = &intel_sdvo->base.base;
|
||||
struct drm_i915_private *i915 = to_i915(encoder->dev);
|
||||
|
@ -2874,7 +2864,7 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
|
|||
struct intel_connector *intel_connector;
|
||||
struct intel_sdvo_connector *intel_sdvo_connector;
|
||||
|
||||
DRM_DEBUG_KMS("initialising LVDS device %d\n", device);
|
||||
DRM_DEBUG_KMS("initialising LVDS type 0x%x\n", type);
|
||||
|
||||
intel_sdvo_connector = intel_sdvo_connector_alloc();
|
||||
if (!intel_sdvo_connector)
|
||||
|
@ -2885,13 +2875,7 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
|
|||
encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
|
||||
connector->connector_type = DRM_MODE_CONNECTOR_LVDS;
|
||||
|
||||
if (device == 0) {
|
||||
intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS0;
|
||||
intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS0;
|
||||
} else if (device == 1) {
|
||||
intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS1;
|
||||
intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1;
|
||||
}
|
||||
intel_sdvo_connector->output_flag = type;
|
||||
|
||||
if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) {
|
||||
kfree(intel_sdvo_connector);
|
||||
|
@ -2910,8 +2894,12 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
|
|||
intel_panel_add_vbt_sdvo_fixed_mode(intel_connector);
|
||||
|
||||
if (!intel_panel_preferred_fixed_mode(intel_connector)) {
|
||||
mutex_lock(&i915->drm.mode_config.mutex);
|
||||
|
||||
intel_ddc_get_modes(connector, &intel_sdvo->ddc);
|
||||
intel_panel_add_edid_fixed_modes(intel_connector, false, false);
|
||||
intel_panel_add_edid_fixed_modes(intel_connector, false);
|
||||
|
||||
mutex_unlock(&i915->drm.mode_config.mutex);
|
||||
}
|
||||
|
||||
intel_panel_init(intel_connector);
|
||||
|
@ -2926,58 +2914,78 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, u16 flags)
|
||||
static u16 intel_sdvo_filter_output_flags(u16 flags)
|
||||
{
|
||||
flags &= SDVO_OUTPUT_MASK;
|
||||
|
||||
/* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/
|
||||
if (!(flags & SDVO_OUTPUT_TMDS0))
|
||||
flags &= ~SDVO_OUTPUT_TMDS1;
|
||||
|
||||
if (flags & SDVO_OUTPUT_TMDS0)
|
||||
if (!intel_sdvo_dvi_init(intel_sdvo, 0))
|
||||
return false;
|
||||
if (!(flags & SDVO_OUTPUT_RGB0))
|
||||
flags &= ~SDVO_OUTPUT_RGB1;
|
||||
|
||||
if ((flags & SDVO_TMDS_MASK) == SDVO_TMDS_MASK)
|
||||
if (!intel_sdvo_dvi_init(intel_sdvo, 1))
|
||||
return false;
|
||||
if (!(flags & SDVO_OUTPUT_LVDS0))
|
||||
flags &= ~SDVO_OUTPUT_LVDS1;
|
||||
|
||||
/* TV has no XXX1 function block */
|
||||
if (flags & SDVO_OUTPUT_SVID0)
|
||||
if (!intel_sdvo_tv_init(intel_sdvo, SDVO_OUTPUT_SVID0))
|
||||
return false;
|
||||
return flags;
|
||||
}
|
||||
|
||||
if (flags & SDVO_OUTPUT_CVBS0)
|
||||
if (!intel_sdvo_tv_init(intel_sdvo, SDVO_OUTPUT_CVBS0))
|
||||
return false;
|
||||
static bool intel_sdvo_output_init(struct intel_sdvo *sdvo, u16 type)
|
||||
{
|
||||
if (type & SDVO_TMDS_MASK)
|
||||
return intel_sdvo_dvi_init(sdvo, type);
|
||||
else if (type & SDVO_TV_MASK)
|
||||
return intel_sdvo_tv_init(sdvo, type);
|
||||
else if (type & SDVO_RGB_MASK)
|
||||
return intel_sdvo_analog_init(sdvo, type);
|
||||
else if (type & SDVO_LVDS_MASK)
|
||||
return intel_sdvo_lvds_init(sdvo, type);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
if (flags & SDVO_OUTPUT_YPRPB0)
|
||||
if (!intel_sdvo_tv_init(intel_sdvo, SDVO_OUTPUT_YPRPB0))
|
||||
return false;
|
||||
static bool
|
||||
intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo)
|
||||
{
|
||||
static const u16 probe_order[] = {
|
||||
SDVO_OUTPUT_TMDS0,
|
||||
SDVO_OUTPUT_TMDS1,
|
||||
/* TV has no XXX1 function block */
|
||||
SDVO_OUTPUT_SVID0,
|
||||
SDVO_OUTPUT_CVBS0,
|
||||
SDVO_OUTPUT_YPRPB0,
|
||||
SDVO_OUTPUT_RGB0,
|
||||
SDVO_OUTPUT_RGB1,
|
||||
SDVO_OUTPUT_LVDS0,
|
||||
SDVO_OUTPUT_LVDS1,
|
||||
};
|
||||
struct drm_i915_private *i915 = to_i915(intel_sdvo->base.base.dev);
|
||||
u16 flags;
|
||||
int i;
|
||||
|
||||
if (flags & SDVO_OUTPUT_RGB0)
|
||||
if (!intel_sdvo_analog_init(intel_sdvo, 0))
|
||||
return false;
|
||||
flags = intel_sdvo_filter_output_flags(intel_sdvo->caps.output_flags);
|
||||
|
||||
if ((flags & SDVO_RGB_MASK) == SDVO_RGB_MASK)
|
||||
if (!intel_sdvo_analog_init(intel_sdvo, 1))
|
||||
return false;
|
||||
|
||||
if (flags & SDVO_OUTPUT_LVDS0)
|
||||
if (!intel_sdvo_lvds_init(intel_sdvo, 0))
|
||||
return false;
|
||||
|
||||
if ((flags & SDVO_LVDS_MASK) == SDVO_LVDS_MASK)
|
||||
if (!intel_sdvo_lvds_init(intel_sdvo, 1))
|
||||
return false;
|
||||
|
||||
if ((flags & SDVO_OUTPUT_MASK) == 0) {
|
||||
unsigned char bytes[2];
|
||||
|
||||
intel_sdvo->controlled_output = 0;
|
||||
memcpy(bytes, &intel_sdvo->caps.output_flags, 2);
|
||||
DRM_DEBUG_KMS("%s: Unknown SDVO output type (0x%02x%02x)\n",
|
||||
SDVO_NAME(intel_sdvo),
|
||||
bytes[0], bytes[1]);
|
||||
if (flags == 0) {
|
||||
DRM_DEBUG_KMS("%s: Unknown SDVO output type (0x%04x)\n",
|
||||
SDVO_NAME(intel_sdvo), intel_sdvo->caps.output_flags);
|
||||
return false;
|
||||
}
|
||||
|
||||
intel_sdvo->controlled_output = flags;
|
||||
|
||||
intel_sdvo_select_ddc_bus(i915, intel_sdvo);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(probe_order); i++) {
|
||||
u16 type = flags & probe_order[i];
|
||||
|
||||
if (!type)
|
||||
continue;
|
||||
|
||||
if (!intel_sdvo_output_init(intel_sdvo, type))
|
||||
return false;
|
||||
}
|
||||
|
||||
intel_sdvo->base.pipe_mask = ~0;
|
||||
|
||||
return true;
|
||||
|
@ -3353,8 +3361,7 @@ bool intel_sdvo_init(struct drm_i915_private *dev_priv,
|
|||
intel_sdvo->colorimetry_cap =
|
||||
intel_sdvo_get_colorimetry_cap(intel_sdvo);
|
||||
|
||||
if (intel_sdvo_output_setup(intel_sdvo,
|
||||
intel_sdvo->caps.output_flags) != true) {
|
||||
if (!intel_sdvo_output_setup(intel_sdvo)) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"SDVO output failed to setup on %s\n",
|
||||
SDVO_NAME(intel_sdvo));
|
||||
|
@ -3383,8 +3390,6 @@ bool intel_sdvo_init(struct drm_i915_private *dev_priv,
|
|||
*/
|
||||
intel_sdvo->base.cloneable = 0;
|
||||
|
||||
intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo);
|
||||
|
||||
/* Set the input timing to the screen. Assume always input 0. */
|
||||
if (!intel_sdvo_set_target_input(intel_sdvo))
|
||||
goto err_output;
|
||||
|
@ -3407,9 +3412,12 @@ bool intel_sdvo_init(struct drm_i915_private *dev_priv,
|
|||
(intel_sdvo->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N',
|
||||
/* check currently supported outputs */
|
||||
intel_sdvo->caps.output_flags &
|
||||
(SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0) ? 'Y' : 'N',
|
||||
(SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0 |
|
||||
SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_SVID0 |
|
||||
SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_YPRPB0) ? 'Y' : 'N',
|
||||
intel_sdvo->caps.output_flags &
|
||||
(SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N');
|
||||
(SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1 |
|
||||
SDVO_OUTPUT_LVDS1) ? 'Y' : 'N');
|
||||
return true;
|
||||
|
||||
err_output:
|
||||
|
|
|
@ -8,9 +8,10 @@
|
|||
#include "intel_display.h"
|
||||
#include "intel_display_power_map.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dkl_phy_regs.h"
|
||||
#include "intel_dp_mst.h"
|
||||
#include "intel_mg_phy_regs.h"
|
||||
#include "intel_tc.h"
|
||||
#include "intel_tc_phy_regs.h"
|
||||
|
||||
static const char *tc_port_mode_name(enum tc_port_mode mode)
|
||||
{
|
||||
|
@ -408,14 +409,9 @@ static bool adl_tc_phy_take_ownership(struct intel_digital_port *dig_port,
|
|||
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
|
||||
struct intel_uncore *uncore = &i915->uncore;
|
||||
enum port port = dig_port->base.port;
|
||||
u32 val;
|
||||
|
||||
val = intel_uncore_read(uncore, DDI_BUF_CTL(port));
|
||||
if (take)
|
||||
val |= DDI_BUF_CTL_TC_PHY_OWNERSHIP;
|
||||
else
|
||||
val &= ~DDI_BUF_CTL_TC_PHY_OWNERSHIP;
|
||||
intel_uncore_write(uncore, DDI_BUF_CTL(port), val);
|
||||
intel_uncore_rmw(uncore, DDI_BUF_CTL(port), DDI_BUF_CTL_TC_PHY_OWNERSHIP,
|
||||
take ? DDI_BUF_CTL_TC_PHY_OWNERSHIP : 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -687,18 +683,58 @@ static void
|
|||
intel_tc_port_link_init_refcount(struct intel_digital_port *dig_port,
|
||||
int refcount)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
|
||||
|
||||
drm_WARN_ON(&i915->drm, dig_port->tc_link_refcount);
|
||||
dig_port->tc_link_refcount = refcount;
|
||||
}
|
||||
|
||||
void intel_tc_port_sanitize(struct intel_digital_port *dig_port)
|
||||
/**
|
||||
* intel_tc_port_init_mode: Read out HW state and init the given port's TypeC mode
|
||||
* @dig_port: digital port
|
||||
*
|
||||
* Read out the HW state and initialize the TypeC mode of @dig_port. The mode
|
||||
* will be locked until intel_tc_port_sanitize_mode() is called.
|
||||
*/
|
||||
void intel_tc_port_init_mode(struct intel_digital_port *dig_port)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
|
||||
intel_wakeref_t tc_cold_wref;
|
||||
enum intel_display_power_domain domain;
|
||||
|
||||
mutex_lock(&dig_port->tc_lock);
|
||||
|
||||
drm_WARN_ON(&i915->drm, dig_port->tc_mode != TC_PORT_DISCONNECTED);
|
||||
drm_WARN_ON(&i915->drm, dig_port->tc_lock_wakeref);
|
||||
drm_WARN_ON(&i915->drm, dig_port->tc_link_refcount);
|
||||
|
||||
tc_cold_wref = tc_cold_block(dig_port, &domain);
|
||||
|
||||
dig_port->tc_mode = intel_tc_port_get_current_mode(dig_port);
|
||||
/* Prevent changing dig_port->tc_mode until intel_tc_port_sanitize_mode() is called. */
|
||||
intel_tc_port_link_init_refcount(dig_port, 1);
|
||||
dig_port->tc_lock_wakeref = tc_cold_block(dig_port, &dig_port->tc_lock_power_domain);
|
||||
|
||||
tc_cold_unblock(dig_port, domain, tc_cold_wref);
|
||||
|
||||
drm_dbg_kms(&i915->drm, "Port %s: init mode (%s)\n",
|
||||
dig_port->tc_port_name,
|
||||
tc_port_mode_name(dig_port->tc_mode));
|
||||
|
||||
mutex_unlock(&dig_port->tc_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_tc_port_sanitize_mode: Sanitize the given port's TypeC mode
|
||||
* @dig_port: digital port
|
||||
*
|
||||
* Sanitize @dig_port's TypeC mode wrt. the encoder's state right after driver
|
||||
* loading and system resume:
|
||||
* If the encoder is enabled keep the TypeC mode/PHY connected state locked until
|
||||
* the encoder is disabled.
|
||||
* If the encoder is disabled make sure the PHY is disconnected.
|
||||
*/
|
||||
void intel_tc_port_sanitize_mode(struct intel_digital_port *dig_port)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
|
||||
struct intel_encoder *encoder = &dig_port->base;
|
||||
intel_wakeref_t tc_cold_wref;
|
||||
enum intel_display_power_domain domain;
|
||||
int active_links = 0;
|
||||
|
||||
mutex_lock(&dig_port->tc_lock);
|
||||
|
@ -708,21 +744,14 @@ void intel_tc_port_sanitize(struct intel_digital_port *dig_port)
|
|||
else if (encoder->base.crtc)
|
||||
active_links = to_intel_crtc(encoder->base.crtc)->active;
|
||||
|
||||
drm_WARN_ON(&i915->drm, dig_port->tc_mode != TC_PORT_DISCONNECTED);
|
||||
drm_WARN_ON(&i915->drm, dig_port->tc_lock_wakeref);
|
||||
drm_WARN_ON(&i915->drm, dig_port->tc_link_refcount != 1);
|
||||
intel_tc_port_link_init_refcount(dig_port, active_links);
|
||||
|
||||
tc_cold_wref = tc_cold_block(dig_port, &domain);
|
||||
|
||||
dig_port->tc_mode = intel_tc_port_get_current_mode(dig_port);
|
||||
if (active_links) {
|
||||
if (!icl_tc_phy_is_connected(dig_port))
|
||||
drm_dbg_kms(&i915->drm,
|
||||
"Port %s: PHY disconnected with %d active link(s)\n",
|
||||
dig_port->tc_port_name, active_links);
|
||||
intel_tc_port_link_init_refcount(dig_port, active_links);
|
||||
|
||||
dig_port->tc_lock_wakeref = tc_cold_block(dig_port,
|
||||
&dig_port->tc_lock_power_domain);
|
||||
} else {
|
||||
/*
|
||||
* TBT-alt is the default mode in any case the PHY ownership is not
|
||||
|
@ -736,9 +765,10 @@ void intel_tc_port_sanitize(struct intel_digital_port *dig_port)
|
|||
dig_port->tc_port_name,
|
||||
tc_port_mode_name(dig_port->tc_mode));
|
||||
icl_tc_phy_disconnect(dig_port);
|
||||
}
|
||||
|
||||
tc_cold_unblock(dig_port, domain, tc_cold_wref);
|
||||
tc_cold_unblock(dig_port, dig_port->tc_lock_power_domain,
|
||||
fetch_and_zero(&dig_port->tc_lock_wakeref));
|
||||
}
|
||||
|
||||
drm_dbg_kms(&i915->drm, "Port %s: sanitize mode (%s)\n",
|
||||
dig_port->tc_port_name,
|
||||
|
@ -923,4 +953,6 @@ void intel_tc_port_init(struct intel_digital_port *dig_port, bool is_legacy)
|
|||
dig_port->tc_mode = TC_PORT_DISCONNECTED;
|
||||
dig_port->tc_link_refcount = 0;
|
||||
tc_port_load_fia_params(i915, dig_port);
|
||||
|
||||
intel_tc_port_init_mode(dig_port);
|
||||
}
|
||||
|
|
|
@ -24,7 +24,8 @@ int intel_tc_port_fia_max_lane_count(struct intel_digital_port *dig_port);
|
|||
void intel_tc_port_set_fia_lane_count(struct intel_digital_port *dig_port,
|
||||
int required_lanes);
|
||||
|
||||
void intel_tc_port_sanitize(struct intel_digital_port *dig_port);
|
||||
void intel_tc_port_init_mode(struct intel_digital_port *dig_port);
|
||||
void intel_tc_port_sanitize_mode(struct intel_digital_port *dig_port);
|
||||
void intel_tc_port_lock(struct intel_digital_port *dig_port);
|
||||
void intel_tc_port_unlock(struct intel_digital_port *dig_port);
|
||||
void intel_tc_port_flush_work(struct intel_digital_port *dig_port);
|
||||
|
|
|
@ -1880,18 +1880,56 @@ static const struct drm_encoder_funcs intel_tv_enc_funcs = {
|
|||
.destroy = intel_encoder_destroy,
|
||||
};
|
||||
|
||||
static void intel_tv_add_properties(struct drm_connector *connector)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(connector->dev);
|
||||
struct drm_connector_state *conn_state = connector->state;
|
||||
const char *tv_format_names[ARRAY_SIZE(tv_modes)];
|
||||
int i;
|
||||
|
||||
/* BIOS margin values */
|
||||
conn_state->tv.margins.left = 54;
|
||||
conn_state->tv.margins.top = 36;
|
||||
conn_state->tv.margins.right = 46;
|
||||
conn_state->tv.margins.bottom = 37;
|
||||
|
||||
conn_state->tv.mode = 0;
|
||||
|
||||
/* Create TV properties then attach current values */
|
||||
for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
|
||||
/* 1080p50/1080p60 not supported on gen3 */
|
||||
if (DISPLAY_VER(i915) == 3 && tv_modes[i].oversample == 1)
|
||||
break;
|
||||
|
||||
tv_format_names[i] = tv_modes[i].name;
|
||||
}
|
||||
drm_mode_create_tv_properties(&i915->drm, i, tv_format_names);
|
||||
|
||||
drm_object_attach_property(&connector->base,
|
||||
i915->drm.mode_config.tv_mode_property,
|
||||
conn_state->tv.mode);
|
||||
drm_object_attach_property(&connector->base,
|
||||
i915->drm.mode_config.tv_left_margin_property,
|
||||
conn_state->tv.margins.left);
|
||||
drm_object_attach_property(&connector->base,
|
||||
i915->drm.mode_config.tv_top_margin_property,
|
||||
conn_state->tv.margins.top);
|
||||
drm_object_attach_property(&connector->base,
|
||||
i915->drm.mode_config.tv_right_margin_property,
|
||||
conn_state->tv.margins.right);
|
||||
drm_object_attach_property(&connector->base,
|
||||
i915->drm.mode_config.tv_bottom_margin_property,
|
||||
conn_state->tv.margins.bottom);
|
||||
}
|
||||
|
||||
void
|
||||
intel_tv_init(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
struct drm_connector *connector;
|
||||
struct intel_tv *intel_tv;
|
||||
struct intel_encoder *intel_encoder;
|
||||
struct intel_connector *intel_connector;
|
||||
u32 tv_dac_on, tv_dac_off, save_tv_dac;
|
||||
const char *tv_format_names[ARRAY_SIZE(tv_modes)];
|
||||
int i, initial_mode = 0;
|
||||
struct drm_connector_state *state;
|
||||
|
||||
if ((intel_de_read(dev_priv, TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED)
|
||||
return;
|
||||
|
@ -1937,7 +1975,6 @@ intel_tv_init(struct drm_i915_private *dev_priv)
|
|||
|
||||
intel_encoder = &intel_tv->base;
|
||||
connector = &intel_connector->base;
|
||||
state = connector->state;
|
||||
|
||||
/*
|
||||
* The documentation, for the older chipsets at least, recommend
|
||||
|
@ -1951,10 +1988,10 @@ intel_tv_init(struct drm_i915_private *dev_priv)
|
|||
*/
|
||||
intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT;
|
||||
|
||||
drm_connector_init(dev, connector, &intel_tv_connector_funcs,
|
||||
drm_connector_init(&dev_priv->drm, connector, &intel_tv_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_SVIDEO);
|
||||
|
||||
drm_encoder_init(dev, &intel_encoder->base, &intel_tv_enc_funcs,
|
||||
drm_encoder_init(&dev_priv->drm, &intel_encoder->base, &intel_tv_enc_funcs,
|
||||
DRM_MODE_ENCODER_TVDAC, "TV");
|
||||
|
||||
intel_encoder->compute_config = intel_tv_compute_config;
|
||||
|
@ -1974,41 +2011,7 @@ intel_tv_init(struct drm_i915_private *dev_priv)
|
|||
intel_encoder->cloneable = 0;
|
||||
intel_tv->type = DRM_MODE_CONNECTOR_Unknown;
|
||||
|
||||
/* BIOS margin values */
|
||||
state->tv.margins.left = 54;
|
||||
state->tv.margins.top = 36;
|
||||
state->tv.margins.right = 46;
|
||||
state->tv.margins.bottom = 37;
|
||||
|
||||
state->tv.mode = initial_mode;
|
||||
|
||||
drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs);
|
||||
connector->interlace_allowed = false;
|
||||
connector->doublescan_allowed = false;
|
||||
|
||||
/* Create TV properties then attach current values */
|
||||
for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
|
||||
/* 1080p50/1080p60 not supported on gen3 */
|
||||
if (DISPLAY_VER(dev_priv) == 3 &&
|
||||
tv_modes[i].oversample == 1)
|
||||
break;
|
||||
|
||||
tv_format_names[i] = tv_modes[i].name;
|
||||
}
|
||||
drm_mode_create_tv_properties(dev, i, tv_format_names);
|
||||
|
||||
drm_object_attach_property(&connector->base, dev->mode_config.tv_mode_property,
|
||||
state->tv.mode);
|
||||
drm_object_attach_property(&connector->base,
|
||||
dev->mode_config.tv_left_margin_property,
|
||||
state->tv.margins.left);
|
||||
drm_object_attach_property(&connector->base,
|
||||
dev->mode_config.tv_top_margin_property,
|
||||
state->tv.margins.top);
|
||||
drm_object_attach_property(&connector->base,
|
||||
dev->mode_config.tv_right_margin_property,
|
||||
state->tv.margins.right);
|
||||
drm_object_attach_property(&connector->base,
|
||||
dev->mode_config.tv_bottom_margin_property,
|
||||
state->tv.margins.bottom);
|
||||
intel_tv_add_properties(connector);
|
||||
}
|
||||
|
|
|
@ -1706,26 +1706,10 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
wp->y_tiled = modifier == I915_FORMAT_MOD_Y_TILED ||
|
||||
modifier == I915_FORMAT_MOD_4_TILED ||
|
||||
modifier == I915_FORMAT_MOD_Yf_TILED ||
|
||||
modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
|
||||
modifier == I915_FORMAT_MOD_Yf_TILED_CCS ||
|
||||
modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS ||
|
||||
modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS ||
|
||||
modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC ||
|
||||
modifier == I915_FORMAT_MOD_4_TILED_DG2_RC_CCS ||
|
||||
modifier == I915_FORMAT_MOD_4_TILED_DG2_MC_CCS ||
|
||||
modifier == I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC;
|
||||
wp->x_tiled = modifier == I915_FORMAT_MOD_X_TILED;
|
||||
wp->rc_surface = modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
|
||||
modifier == I915_FORMAT_MOD_Yf_TILED_CCS ||
|
||||
modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS ||
|
||||
modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS ||
|
||||
modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC ||
|
||||
modifier == I915_FORMAT_MOD_4_TILED_DG2_RC_CCS ||
|
||||
modifier == I915_FORMAT_MOD_4_TILED_DG2_MC_CCS ||
|
||||
modifier == I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC;
|
||||
wp->y_tiled = modifier != I915_FORMAT_MOD_X_TILED &&
|
||||
intel_fb_is_tiled_modifier(modifier);
|
||||
wp->rc_surface = intel_fb_is_ccs_modifier(modifier);
|
||||
wp->is_planar = intel_format_info_is_yuv_semiplanar(format, modifier);
|
||||
|
||||
wp->width = width;
|
||||
|
@ -2498,7 +2482,7 @@ skl_compute_ddb(struct intel_atomic_state *state)
|
|||
|
||||
if (old_dbuf_state->joined_mbus != new_dbuf_state->joined_mbus) {
|
||||
/* TODO: Implement vblank synchronized MBUS joining changes */
|
||||
ret = intel_modeset_all_pipes(state);
|
||||
ret = intel_modeset_all_pipes(state, "MBUS joining change");
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1659,19 +1659,10 @@ static const struct drm_connector_funcs intel_dsi_connector_funcs = {
|
|||
|
||||
static void vlv_dsi_add_properties(struct intel_connector *connector)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
|
||||
const struct drm_display_mode *fixed_mode =
|
||||
intel_panel_preferred_fixed_mode(connector);
|
||||
u32 allowed_scalers;
|
||||
|
||||
allowed_scalers = BIT(DRM_MODE_SCALE_ASPECT) | BIT(DRM_MODE_SCALE_FULLSCREEN);
|
||||
if (!HAS_GMCH(dev_priv))
|
||||
allowed_scalers |= BIT(DRM_MODE_SCALE_CENTER);
|
||||
|
||||
drm_connector_attach_scaling_mode_property(&connector->base,
|
||||
allowed_scalers);
|
||||
|
||||
connector->base.state->scaling_mode = DRM_MODE_SCALE_ASPECT;
|
||||
intel_attach_scaling_mode_property(&connector->base);
|
||||
|
||||
drm_connector_set_panel_orientation_with_quirk(&connector->base,
|
||||
intel_dsi_get_panel_orientation(connector),
|
||||
|
@ -1854,7 +1845,6 @@ static void vlv_dphy_param_init(struct intel_dsi *intel_dsi)
|
|||
|
||||
void vlv_dsi_init(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
struct intel_dsi *intel_dsi;
|
||||
struct intel_encoder *intel_encoder;
|
||||
struct drm_encoder *encoder;
|
||||
|
@ -1891,7 +1881,7 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv)
|
|||
|
||||
connector = &intel_connector->base;
|
||||
|
||||
drm_encoder_init(dev, encoder, &intel_dsi_funcs, DRM_MODE_ENCODER_DSI,
|
||||
drm_encoder_init(&dev_priv->drm, encoder, &intel_dsi_funcs, DRM_MODE_ENCODER_DSI,
|
||||
"DSI %c", port_name(port));
|
||||
|
||||
intel_encoder->compute_config = intel_dsi_compute_config;
|
||||
|
@ -1974,20 +1964,18 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv)
|
|||
intel_dsi_vbt_gpio_init(intel_dsi,
|
||||
intel_dsi_get_hw_state(intel_encoder, &pipe));
|
||||
|
||||
drm_connector_init(dev, connector, &intel_dsi_connector_funcs,
|
||||
drm_connector_init(&dev_priv->drm, connector, &intel_dsi_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_DSI);
|
||||
|
||||
drm_connector_helper_add(connector, &intel_dsi_connector_helper_funcs);
|
||||
|
||||
connector->display_info.subpixel_order = SubPixelHorizontalRGB; /*XXX*/
|
||||
connector->interlace_allowed = false;
|
||||
connector->doublescan_allowed = false;
|
||||
|
||||
intel_connector_attach_encoder(intel_connector, intel_encoder);
|
||||
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
mutex_lock(&dev_priv->drm.mode_config.mutex);
|
||||
intel_panel_add_vbt_lfp_fixed_mode(intel_connector);
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
mutex_unlock(&dev_priv->drm.mode_config.mutex);
|
||||
|
||||
if (!intel_panel_preferred_fixed_mode(intel_connector)) {
|
||||
drm_dbg_kms(&dev_priv->drm, "no fixed mode\n");
|
||||
|
|
|
@ -113,7 +113,7 @@ bool i915_gem_clflush_object(struct drm_i915_gem_object *obj,
|
|||
clflush = clflush_work_create(obj);
|
||||
if (clflush) {
|
||||
i915_sw_fence_await_reservation(&clflush->base.chain,
|
||||
obj->base.resv, NULL, true,
|
||||
obj->base.resv, true,
|
||||
i915_fence_timeout(i915),
|
||||
I915_FENCE_GFP);
|
||||
dma_resv_add_fence(obj->base.resv, &clflush->base.dma,
|
||||
|
|
|
@ -39,6 +39,9 @@
|
|||
#define FORCEWAKE_ACK_RENDER_GEN9 _MMIO(0xd84)
|
||||
#define FORCEWAKE_ACK_MEDIA_GEN9 _MMIO(0xd88)
|
||||
|
||||
#define GMD_ID_GRAPHICS _MMIO(0xd8c)
|
||||
#define GMD_ID_MEDIA _MMIO(MTL_MEDIA_GSI_BASE + 0xd8c)
|
||||
|
||||
#define MCFG_MCR_SELECTOR _MMIO(0xfd0)
|
||||
#define SF_MCR_SELECTOR _MMIO(0xfd8)
|
||||
#define GEN8_MCR_SELECTOR _MMIO(0xfdc)
|
||||
|
|
|
@ -2293,11 +2293,11 @@ rcs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal)
|
|||
}
|
||||
|
||||
if (IS_DG1_GRAPHICS_STEP(i915, STEP_A0, STEP_B0) ||
|
||||
IS_ROCKETLAKE(i915) || IS_TIGERLAKE(i915)) {
|
||||
IS_ROCKETLAKE(i915) || IS_TIGERLAKE(i915) || IS_ALDERLAKE_P(i915)) {
|
||||
/*
|
||||
* Wa_1607030317:tgl
|
||||
* Wa_1607186500:tgl
|
||||
* Wa_1607297627:tgl,rkl,dg1[a0]
|
||||
* Wa_1607297627:tgl,rkl,dg1[a0],adlp
|
||||
*
|
||||
* On TGL and RKL there are multiple entries for this WA in the
|
||||
* BSpec; some indicate this is an A0-only WA, others indicate
|
||||
|
|
|
@ -337,7 +337,8 @@ static int i915_driver_early_probe(struct drm_i915_private *dev_priv)
|
|||
if (i915_inject_probe_failure(dev_priv))
|
||||
return -ENODEV;
|
||||
|
||||
intel_device_info_subplatform_init(dev_priv);
|
||||
intel_device_info_runtime_init_early(dev_priv);
|
||||
|
||||
intel_step_init(dev_priv);
|
||||
|
||||
intel_uncore_mmio_debug_init_early(dev_priv);
|
||||
|
@ -353,6 +354,7 @@ static int i915_driver_early_probe(struct drm_i915_private *dev_priv)
|
|||
mutex_init(&dev_priv->display.wm.wm_mutex);
|
||||
mutex_init(&dev_priv->display.pps.mutex);
|
||||
mutex_init(&dev_priv->display.hdcp.comp_mutex);
|
||||
spin_lock_init(&dev_priv->display.dkl.phy_lock);
|
||||
|
||||
i915_memcpy_init_early(dev_priv);
|
||||
intel_runtime_pm_init_early(&dev_priv->runtime_pm);
|
||||
|
@ -738,7 +740,6 @@ static void i915_driver_hw_remove(struct drm_i915_private *dev_priv)
|
|||
*/
|
||||
static void i915_driver_register(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
struct intel_gt *gt;
|
||||
unsigned int i;
|
||||
|
||||
|
@ -748,7 +749,7 @@ static void i915_driver_register(struct drm_i915_private *dev_priv)
|
|||
intel_vgpu_register(dev_priv);
|
||||
|
||||
/* Reveal our presence to userspace */
|
||||
if (drm_dev_register(dev, 0)) {
|
||||
if (drm_dev_register(&dev_priv->drm, 0)) {
|
||||
drm_err(&dev_priv->drm,
|
||||
"Failed to register driver for userspace access!\n");
|
||||
return;
|
||||
|
@ -893,10 +894,6 @@ int i915_driver_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
if (IS_ERR(i915))
|
||||
return PTR_ERR(i915);
|
||||
|
||||
/* Disable nuclear pageflip by default on pre-ILK */
|
||||
if (!i915->params.nuclear_pageflip && DISPLAY_VER(i915) < 5)
|
||||
i915->drm.driver_features &= ~DRIVER_ATOMIC;
|
||||
|
||||
ret = pci_enable_device(pdev);
|
||||
if (ret)
|
||||
goto out_fini;
|
||||
|
@ -1092,32 +1089,30 @@ static void i915_driver_postclose(struct drm_device *dev, struct drm_file *file)
|
|||
|
||||
static void intel_suspend_encoders(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
struct intel_encoder *encoder;
|
||||
|
||||
if (!HAS_DISPLAY(dev_priv))
|
||||
return;
|
||||
|
||||
drm_modeset_lock_all(dev);
|
||||
for_each_intel_encoder(dev, encoder)
|
||||
drm_modeset_lock_all(&dev_priv->drm);
|
||||
for_each_intel_encoder(&dev_priv->drm, encoder)
|
||||
if (encoder->suspend)
|
||||
encoder->suspend(encoder);
|
||||
drm_modeset_unlock_all(dev);
|
||||
drm_modeset_unlock_all(&dev_priv->drm);
|
||||
}
|
||||
|
||||
static void intel_shutdown_encoders(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
struct intel_encoder *encoder;
|
||||
|
||||
if (!HAS_DISPLAY(dev_priv))
|
||||
return;
|
||||
|
||||
drm_modeset_lock_all(dev);
|
||||
for_each_intel_encoder(dev, encoder)
|
||||
drm_modeset_lock_all(&dev_priv->drm);
|
||||
for_each_intel_encoder(&dev_priv->drm, encoder)
|
||||
if (encoder->shutdown)
|
||||
encoder->shutdown(encoder);
|
||||
drm_modeset_unlock_all(dev);
|
||||
drm_modeset_unlock_all(&dev_priv->drm);
|
||||
}
|
||||
|
||||
void i915_driver_shutdown(struct drm_i915_private *i915)
|
||||
|
|
|
@ -75,9 +75,6 @@ struct intel_limit;
|
|||
struct intel_overlay_error_state;
|
||||
struct vlv_s0ix_state;
|
||||
|
||||
/* Threshold == 5 for long IRQs, 50 for short */
|
||||
#define HPD_STORM_DEFAULT_THRESHOLD 50
|
||||
|
||||
#define I915_GEM_GPU_DOMAINS \
|
||||
(I915_GEM_DOMAIN_RENDER | \
|
||||
I915_GEM_DOMAIN_SAMPLER | \
|
||||
|
@ -871,6 +868,7 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
|
|||
#define HAS_DOUBLE_BUFFERED_M_N(dev_priv) (DISPLAY_VER(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
|
||||
|
||||
#define HAS_CDCLK_CRAWL(dev_priv) (INTEL_INFO(dev_priv)->display.has_cdclk_crawl)
|
||||
#define HAS_CDCLK_SQUASH(dev_priv) (INTEL_INFO(dev_priv)->display.has_cdclk_squash)
|
||||
#define HAS_DDI(dev_priv) (INTEL_INFO(dev_priv)->display.has_ddi)
|
||||
#define HAS_FPGA_DBG_UNCLAIMED(dev_priv) (INTEL_INFO(dev_priv)->display.has_fpga_dbg)
|
||||
#define HAS_PSR(dev_priv) (INTEL_INFO(dev_priv)->display.has_psr)
|
||||
|
@ -938,6 +936,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
|
|||
|
||||
#define HAS_GMCH(dev_priv) (INTEL_INFO(dev_priv)->display.has_gmch)
|
||||
|
||||
#define HAS_GMD_ID(i915) (INTEL_INFO(i915)->has_gmd_id)
|
||||
|
||||
#define HAS_LSPCON(dev_priv) (IS_DISPLAY_VER(dev_priv, 9, 10))
|
||||
|
||||
#define HAS_L3_CCS_READ(i915) (INTEL_INFO(i915)->has_l3_ccs_read)
|
||||
|
|
|
@ -325,15 +325,10 @@ i915_hotplug_interrupt_update_locked(struct drm_i915_private *dev_priv,
|
|||
u32 mask,
|
||||
u32 bits)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
lockdep_assert_held(&dev_priv->irq_lock);
|
||||
drm_WARN_ON(&dev_priv->drm, bits & ~mask);
|
||||
|
||||
val = intel_uncore_read(&dev_priv->uncore, PORT_HOTPLUG_EN);
|
||||
val &= ~mask;
|
||||
val |= bits;
|
||||
intel_uncore_write(&dev_priv->uncore, PORT_HOTPLUG_EN, val);
|
||||
intel_uncore_rmw(&dev_priv->uncore, PORT_HOTPLUG_EN, mask, bits);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1057,8 +1052,8 @@ static void ivb_parity_work(struct work_struct *work)
|
|||
if (drm_WARN_ON(&dev_priv->drm, !dev_priv->l3_parity.which_slice))
|
||||
goto out;
|
||||
|
||||
misccpctl = intel_uncore_read(&dev_priv->uncore, GEN7_MISCCPCTL);
|
||||
intel_uncore_write(&dev_priv->uncore, GEN7_MISCCPCTL, misccpctl & ~GEN7_DOP_CLOCK_GATE_ENABLE);
|
||||
misccpctl = intel_uncore_rmw(&dev_priv->uncore, GEN7_MISCCPCTL,
|
||||
GEN7_DOP_CLOCK_GATE_ENABLE, 0);
|
||||
intel_uncore_posting_read(&dev_priv->uncore, GEN7_MISCCPCTL);
|
||||
|
||||
while ((slice = ffs(dev_priv->l3_parity.which_slice)) != 0) {
|
||||
|
@ -1689,8 +1684,7 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg)
|
|||
* bits this time around.
|
||||
*/
|
||||
intel_uncore_write(&dev_priv->uncore, VLV_MASTER_IER, 0);
|
||||
ier = intel_uncore_read(&dev_priv->uncore, VLV_IER);
|
||||
intel_uncore_write(&dev_priv->uncore, VLV_IER, 0);
|
||||
ier = intel_uncore_rmw(&dev_priv->uncore, VLV_IER, ~0, 0);
|
||||
|
||||
if (gt_iir)
|
||||
intel_uncore_write(&dev_priv->uncore, GTIIR, gt_iir);
|
||||
|
@ -1775,8 +1769,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
|
|||
* bits this time around.
|
||||
*/
|
||||
intel_uncore_write(&dev_priv->uncore, GEN8_MASTER_IRQ, 0);
|
||||
ier = intel_uncore_read(&dev_priv->uncore, VLV_IER);
|
||||
intel_uncore_write(&dev_priv->uncore, VLV_IER, 0);
|
||||
ier = intel_uncore_rmw(&dev_priv->uncore, VLV_IER, ~0, 0);
|
||||
|
||||
gen8_gt_irq_handler(to_gt(dev_priv), master_ctl);
|
||||
|
||||
|
@ -1981,8 +1974,7 @@ static void icp_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir)
|
|||
if (ddi_hotplug_trigger) {
|
||||
u32 dig_hotplug_reg;
|
||||
|
||||
dig_hotplug_reg = intel_uncore_read(&dev_priv->uncore, SHOTPLUG_CTL_DDI);
|
||||
intel_uncore_write(&dev_priv->uncore, SHOTPLUG_CTL_DDI, dig_hotplug_reg);
|
||||
dig_hotplug_reg = intel_uncore_rmw(&dev_priv->uncore, SHOTPLUG_CTL_DDI, 0, 0);
|
||||
|
||||
intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask,
|
||||
ddi_hotplug_trigger, dig_hotplug_reg,
|
||||
|
@ -1993,8 +1985,7 @@ static void icp_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir)
|
|||
if (tc_hotplug_trigger) {
|
||||
u32 dig_hotplug_reg;
|
||||
|
||||
dig_hotplug_reg = intel_uncore_read(&dev_priv->uncore, SHOTPLUG_CTL_TC);
|
||||
intel_uncore_write(&dev_priv->uncore, SHOTPLUG_CTL_TC, dig_hotplug_reg);
|
||||
dig_hotplug_reg = intel_uncore_rmw(&dev_priv->uncore, SHOTPLUG_CTL_TC, 0, 0);
|
||||
|
||||
intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask,
|
||||
tc_hotplug_trigger, dig_hotplug_reg,
|
||||
|
@ -2019,8 +2010,7 @@ static void spt_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir)
|
|||
if (hotplug_trigger) {
|
||||
u32 dig_hotplug_reg;
|
||||
|
||||
dig_hotplug_reg = intel_uncore_read(&dev_priv->uncore, PCH_PORT_HOTPLUG);
|
||||
intel_uncore_write(&dev_priv->uncore, PCH_PORT_HOTPLUG, dig_hotplug_reg);
|
||||
dig_hotplug_reg = intel_uncore_rmw(&dev_priv->uncore, PCH_PORT_HOTPLUG, 0, 0);
|
||||
|
||||
intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask,
|
||||
hotplug_trigger, dig_hotplug_reg,
|
||||
|
@ -2031,8 +2021,7 @@ static void spt_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir)
|
|||
if (hotplug2_trigger) {
|
||||
u32 dig_hotplug_reg;
|
||||
|
||||
dig_hotplug_reg = intel_uncore_read(&dev_priv->uncore, PCH_PORT_HOTPLUG2);
|
||||
intel_uncore_write(&dev_priv->uncore, PCH_PORT_HOTPLUG2, dig_hotplug_reg);
|
||||
dig_hotplug_reg = intel_uncore_rmw(&dev_priv->uncore, PCH_PORT_HOTPLUG2, 0, 0);
|
||||
|
||||
intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask,
|
||||
hotplug2_trigger, dig_hotplug_reg,
|
||||
|
@ -2052,8 +2041,7 @@ static void ilk_hpd_irq_handler(struct drm_i915_private *dev_priv,
|
|||
{
|
||||
u32 dig_hotplug_reg, pin_mask = 0, long_mask = 0;
|
||||
|
||||
dig_hotplug_reg = intel_uncore_read(&dev_priv->uncore, DIGITAL_PORT_HOTPLUG_CNTRL);
|
||||
intel_uncore_write(&dev_priv->uncore, DIGITAL_PORT_HOTPLUG_CNTRL, dig_hotplug_reg);
|
||||
dig_hotplug_reg = intel_uncore_rmw(&dev_priv->uncore, DIGITAL_PORT_HOTPLUG_CNTRL, 0, 0);
|
||||
|
||||
intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask,
|
||||
hotplug_trigger, dig_hotplug_reg,
|
||||
|
@ -2232,8 +2220,7 @@ static void bxt_hpd_irq_handler(struct drm_i915_private *dev_priv,
|
|||
{
|
||||
u32 dig_hotplug_reg, pin_mask = 0, long_mask = 0;
|
||||
|
||||
dig_hotplug_reg = intel_uncore_read(&dev_priv->uncore, PCH_PORT_HOTPLUG);
|
||||
intel_uncore_write(&dev_priv->uncore, PCH_PORT_HOTPLUG, dig_hotplug_reg);
|
||||
dig_hotplug_reg = intel_uncore_rmw(&dev_priv->uncore, PCH_PORT_HOTPLUG, 0, 0);
|
||||
|
||||
intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask,
|
||||
hotplug_trigger, dig_hotplug_reg,
|
||||
|
@ -2252,8 +2239,7 @@ static void gen11_hpd_irq_handler(struct drm_i915_private *dev_priv, u32 iir)
|
|||
if (trigger_tc) {
|
||||
u32 dig_hotplug_reg;
|
||||
|
||||
dig_hotplug_reg = intel_uncore_read(&dev_priv->uncore, GEN11_TC_HOTPLUG_CTL);
|
||||
intel_uncore_write(&dev_priv->uncore, GEN11_TC_HOTPLUG_CTL, dig_hotplug_reg);
|
||||
dig_hotplug_reg = intel_uncore_rmw(&dev_priv->uncore, GEN11_TC_HOTPLUG_CTL, 0, 0);
|
||||
|
||||
intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask,
|
||||
trigger_tc, dig_hotplug_reg,
|
||||
|
@ -2264,8 +2250,7 @@ static void gen11_hpd_irq_handler(struct drm_i915_private *dev_priv, u32 iir)
|
|||
if (trigger_tbt) {
|
||||
u32 dig_hotplug_reg;
|
||||
|
||||
dig_hotplug_reg = intel_uncore_read(&dev_priv->uncore, GEN11_TBT_HOTPLUG_CTL);
|
||||
intel_uncore_write(&dev_priv->uncore, GEN11_TBT_HOTPLUG_CTL, dig_hotplug_reg);
|
||||
dig_hotplug_reg = intel_uncore_rmw(&dev_priv->uncore, GEN11_TBT_HOTPLUG_CTL, 0, 0);
|
||||
|
||||
intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask,
|
||||
trigger_tbt, dig_hotplug_reg,
|
||||
|
@ -2355,8 +2340,7 @@ gen8_de_misc_irq_handler(struct drm_i915_private *dev_priv, u32 iir)
|
|||
else
|
||||
iir_reg = EDP_PSR_IIR;
|
||||
|
||||
psr_iir = intel_uncore_read(&dev_priv->uncore, iir_reg);
|
||||
intel_uncore_write(&dev_priv->uncore, iir_reg, psr_iir);
|
||||
psr_iir = intel_uncore_rmw(&dev_priv->uncore, iir_reg, 0, 0);
|
||||
|
||||
if (psr_iir)
|
||||
found = true;
|
||||
|
@ -2426,8 +2410,7 @@ static void gen11_dsi_te_interrupt_handler(struct drm_i915_private *dev_priv,
|
|||
|
||||
/* clear TE in dsi IIR */
|
||||
port = (te_trigger & DSI1_TE) ? PORT_B : PORT_A;
|
||||
tmp = intel_uncore_read(&dev_priv->uncore, DSI_INTR_IDENT_REG(port));
|
||||
intel_uncore_write(&dev_priv->uncore, DSI_INTR_IDENT_REG(port), tmp);
|
||||
tmp = intel_uncore_rmw(&dev_priv->uncore, DSI_INTR_IDENT_REG(port), 0, 0);
|
||||
}
|
||||
|
||||
static u32 gen8_de_pipe_flip_done_mask(struct drm_i915_private *i915)
|
||||
|
@ -2884,7 +2867,6 @@ static bool gen11_dsi_configure_te(struct intel_crtc *intel_crtc,
|
|||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
|
||||
enum port port;
|
||||
u32 tmp;
|
||||
|
||||
if (!(intel_crtc->mode_flags &
|
||||
(I915_MODE_FLAG_DSI_USE_TE1 | I915_MODE_FLAG_DSI_USE_TE0)))
|
||||
|
@ -2896,16 +2878,10 @@ static bool gen11_dsi_configure_te(struct intel_crtc *intel_crtc,
|
|||
else
|
||||
port = PORT_A;
|
||||
|
||||
tmp = intel_uncore_read(&dev_priv->uncore, DSI_INTR_MASK_REG(port));
|
||||
if (enable)
|
||||
tmp &= ~DSI_TE_EVENT;
|
||||
else
|
||||
tmp |= DSI_TE_EVENT;
|
||||
intel_uncore_rmw(&dev_priv->uncore, DSI_INTR_MASK_REG(port), DSI_TE_EVENT,
|
||||
enable ? 0 : DSI_TE_EVENT);
|
||||
|
||||
intel_uncore_write(&dev_priv->uncore, DSI_INTR_MASK_REG(port), tmp);
|
||||
|
||||
tmp = intel_uncore_read(&dev_priv->uncore, DSI_INTR_IDENT_REG(port));
|
||||
intel_uncore_write(&dev_priv->uncore, DSI_INTR_IDENT_REG(port), tmp);
|
||||
intel_uncore_rmw(&dev_priv->uncore, DSI_INTR_IDENT_REG(port), 0, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -3020,7 +2996,7 @@ static void vlv_display_irq_reset(struct drm_i915_private *dev_priv)
|
|||
intel_uncore_write(uncore, DPINVGTT, DPINVGTT_STATUS_MASK_VLV);
|
||||
|
||||
i915_hotplug_interrupt_update_locked(dev_priv, 0xffffffff, 0);
|
||||
intel_uncore_write(uncore, PORT_HOTPLUG_STAT, intel_uncore_read(&dev_priv->uncore, PORT_HOTPLUG_STAT));
|
||||
intel_uncore_rmw(uncore, PORT_HOTPLUG_STAT, 0, 0);
|
||||
|
||||
i9xx_pipestat_irq_reset(dev_priv);
|
||||
|
||||
|
@ -3118,7 +3094,7 @@ 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_master_intr_disable(uncore->regs);
|
||||
|
||||
gen8_gt_irq_reset(to_gt(dev_priv));
|
||||
gen8_display_irq_reset(dev_priv);
|
||||
|
@ -3250,7 +3226,7 @@ static void cherryview_irq_reset(struct drm_i915_private *dev_priv)
|
|||
{
|
||||
struct intel_uncore *uncore = &dev_priv->uncore;
|
||||
|
||||
intel_uncore_write(&dev_priv->uncore, GEN8_MASTER_IRQ, 0);
|
||||
intel_uncore_write(uncore, GEN8_MASTER_IRQ, 0);
|
||||
intel_uncore_posting_read(&dev_priv->uncore, GEN8_MASTER_IRQ);
|
||||
|
||||
gen8_gt_irq_reset(to_gt(dev_priv));
|
||||
|
@ -3290,23 +3266,20 @@ static u32 ibx_hotplug_enables(struct drm_i915_private *i915,
|
|||
|
||||
static void ibx_hpd_detection_setup(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
u32 hotplug;
|
||||
|
||||
/*
|
||||
* Enable digital hotplug on the PCH, and configure the DP short pulse
|
||||
* duration to 2ms (which is the minimum in the Display Port spec).
|
||||
* The pulse duration bits are reserved on LPT+.
|
||||
*/
|
||||
hotplug = intel_uncore_read(&dev_priv->uncore, PCH_PORT_HOTPLUG);
|
||||
hotplug &= ~(PORTA_HOTPLUG_ENABLE |
|
||||
PORTB_HOTPLUG_ENABLE |
|
||||
PORTC_HOTPLUG_ENABLE |
|
||||
PORTD_HOTPLUG_ENABLE |
|
||||
PORTB_PULSE_DURATION_MASK |
|
||||
PORTC_PULSE_DURATION_MASK |
|
||||
PORTD_PULSE_DURATION_MASK);
|
||||
hotplug |= intel_hpd_hotplug_enables(dev_priv, ibx_hotplug_enables);
|
||||
intel_uncore_write(&dev_priv->uncore, PCH_PORT_HOTPLUG, hotplug);
|
||||
intel_uncore_rmw(&dev_priv->uncore, PCH_PORT_HOTPLUG,
|
||||
PORTA_HOTPLUG_ENABLE |
|
||||
PORTB_HOTPLUG_ENABLE |
|
||||
PORTC_HOTPLUG_ENABLE |
|
||||
PORTD_HOTPLUG_ENABLE |
|
||||
PORTB_PULSE_DURATION_MASK |
|
||||
PORTC_PULSE_DURATION_MASK |
|
||||
PORTD_PULSE_DURATION_MASK,
|
||||
intel_hpd_hotplug_enables(dev_priv, ibx_hotplug_enables));
|
||||
}
|
||||
|
||||
static void ibx_hpd_irq_setup(struct drm_i915_private *dev_priv)
|
||||
|
@ -3353,30 +3326,24 @@ static u32 icp_tc_hotplug_enables(struct drm_i915_private *i915,
|
|||
|
||||
static void icp_ddi_hpd_detection_setup(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
u32 hotplug;
|
||||
|
||||
hotplug = intel_uncore_read(&dev_priv->uncore, SHOTPLUG_CTL_DDI);
|
||||
hotplug &= ~(SHOTPLUG_CTL_DDI_HPD_ENABLE(HPD_PORT_A) |
|
||||
SHOTPLUG_CTL_DDI_HPD_ENABLE(HPD_PORT_B) |
|
||||
SHOTPLUG_CTL_DDI_HPD_ENABLE(HPD_PORT_C) |
|
||||
SHOTPLUG_CTL_DDI_HPD_ENABLE(HPD_PORT_D));
|
||||
hotplug |= intel_hpd_hotplug_enables(dev_priv, icp_ddi_hotplug_enables);
|
||||
intel_uncore_write(&dev_priv->uncore, SHOTPLUG_CTL_DDI, hotplug);
|
||||
intel_uncore_rmw(&dev_priv->uncore, SHOTPLUG_CTL_DDI,
|
||||
SHOTPLUG_CTL_DDI_HPD_ENABLE(HPD_PORT_A) |
|
||||
SHOTPLUG_CTL_DDI_HPD_ENABLE(HPD_PORT_B) |
|
||||
SHOTPLUG_CTL_DDI_HPD_ENABLE(HPD_PORT_C) |
|
||||
SHOTPLUG_CTL_DDI_HPD_ENABLE(HPD_PORT_D),
|
||||
intel_hpd_hotplug_enables(dev_priv, icp_ddi_hotplug_enables));
|
||||
}
|
||||
|
||||
static void icp_tc_hpd_detection_setup(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
u32 hotplug;
|
||||
|
||||
hotplug = intel_uncore_read(&dev_priv->uncore, SHOTPLUG_CTL_TC);
|
||||
hotplug &= ~(ICP_TC_HPD_ENABLE(HPD_PORT_TC1) |
|
||||
ICP_TC_HPD_ENABLE(HPD_PORT_TC2) |
|
||||
ICP_TC_HPD_ENABLE(HPD_PORT_TC3) |
|
||||
ICP_TC_HPD_ENABLE(HPD_PORT_TC4) |
|
||||
ICP_TC_HPD_ENABLE(HPD_PORT_TC5) |
|
||||
ICP_TC_HPD_ENABLE(HPD_PORT_TC6));
|
||||
hotplug |= intel_hpd_hotplug_enables(dev_priv, icp_tc_hotplug_enables);
|
||||
intel_uncore_write(&dev_priv->uncore, SHOTPLUG_CTL_TC, hotplug);
|
||||
intel_uncore_rmw(&dev_priv->uncore, SHOTPLUG_CTL_TC,
|
||||
ICP_TC_HPD_ENABLE(HPD_PORT_TC1) |
|
||||
ICP_TC_HPD_ENABLE(HPD_PORT_TC2) |
|
||||
ICP_TC_HPD_ENABLE(HPD_PORT_TC3) |
|
||||
ICP_TC_HPD_ENABLE(HPD_PORT_TC4) |
|
||||
ICP_TC_HPD_ENABLE(HPD_PORT_TC5) |
|
||||
ICP_TC_HPD_ENABLE(HPD_PORT_TC6),
|
||||
intel_hpd_hotplug_enables(dev_priv, icp_tc_hotplug_enables));
|
||||
}
|
||||
|
||||
static void icp_hpd_irq_setup(struct drm_i915_private *dev_priv)
|
||||
|
@ -3411,62 +3378,54 @@ static u32 gen11_hotplug_enables(struct drm_i915_private *i915,
|
|||
}
|
||||
}
|
||||
|
||||
static void dg1_hpd_invert(struct drm_i915_private *i915)
|
||||
{
|
||||
u32 val = (INVERT_DDIA_HPD |
|
||||
INVERT_DDIB_HPD |
|
||||
INVERT_DDIC_HPD |
|
||||
INVERT_DDID_HPD);
|
||||
intel_uncore_rmw(&i915->uncore, SOUTH_CHICKEN1, 0, val);
|
||||
}
|
||||
|
||||
static void dg1_hpd_irq_setup(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = intel_uncore_read(&dev_priv->uncore, SOUTH_CHICKEN1);
|
||||
val |= (INVERT_DDIA_HPD |
|
||||
INVERT_DDIB_HPD |
|
||||
INVERT_DDIC_HPD |
|
||||
INVERT_DDID_HPD);
|
||||
intel_uncore_write(&dev_priv->uncore, SOUTH_CHICKEN1, val);
|
||||
|
||||
dg1_hpd_invert(dev_priv);
|
||||
icp_hpd_irq_setup(dev_priv);
|
||||
}
|
||||
|
||||
static void gen11_tc_hpd_detection_setup(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
u32 hotplug;
|
||||
|
||||
hotplug = intel_uncore_read(&dev_priv->uncore, GEN11_TC_HOTPLUG_CTL);
|
||||
hotplug &= ~(GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC1) |
|
||||
GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC2) |
|
||||
GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC3) |
|
||||
GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC4) |
|
||||
GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC5) |
|
||||
GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC6));
|
||||
hotplug |= intel_hpd_hotplug_enables(dev_priv, gen11_hotplug_enables);
|
||||
intel_uncore_write(&dev_priv->uncore, GEN11_TC_HOTPLUG_CTL, hotplug);
|
||||
intel_uncore_rmw(&dev_priv->uncore, GEN11_TC_HOTPLUG_CTL,
|
||||
GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC1) |
|
||||
GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC2) |
|
||||
GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC3) |
|
||||
GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC4) |
|
||||
GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC5) |
|
||||
GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC6),
|
||||
intel_hpd_hotplug_enables(dev_priv, gen11_hotplug_enables));
|
||||
}
|
||||
|
||||
static void gen11_tbt_hpd_detection_setup(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
u32 hotplug;
|
||||
|
||||
hotplug = intel_uncore_read(&dev_priv->uncore, GEN11_TBT_HOTPLUG_CTL);
|
||||
hotplug &= ~(GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC1) |
|
||||
GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC2) |
|
||||
GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC3) |
|
||||
GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC4) |
|
||||
GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC5) |
|
||||
GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC6));
|
||||
hotplug |= intel_hpd_hotplug_enables(dev_priv, gen11_hotplug_enables);
|
||||
intel_uncore_write(&dev_priv->uncore, GEN11_TBT_HOTPLUG_CTL, hotplug);
|
||||
intel_uncore_rmw(&dev_priv->uncore, GEN11_TBT_HOTPLUG_CTL,
|
||||
GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC1) |
|
||||
GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC2) |
|
||||
GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC3) |
|
||||
GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC4) |
|
||||
GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC5) |
|
||||
GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC6),
|
||||
intel_hpd_hotplug_enables(dev_priv, gen11_hotplug_enables));
|
||||
}
|
||||
|
||||
static void gen11_hpd_irq_setup(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
u32 hotplug_irqs, enabled_irqs;
|
||||
u32 val;
|
||||
|
||||
enabled_irqs = intel_hpd_enabled_irqs(dev_priv, dev_priv->display.hotplug.hpd);
|
||||
hotplug_irqs = intel_hpd_hotplug_irqs(dev_priv, dev_priv->display.hotplug.hpd);
|
||||
|
||||
val = intel_uncore_read(&dev_priv->uncore, GEN11_DE_HPD_IMR);
|
||||
val &= ~hotplug_irqs;
|
||||
val |= ~enabled_irqs & hotplug_irqs;
|
||||
intel_uncore_write(&dev_priv->uncore, GEN11_DE_HPD_IMR, val);
|
||||
intel_uncore_rmw(&dev_priv->uncore, GEN11_DE_HPD_IMR, hotplug_irqs,
|
||||
~enabled_irqs & hotplug_irqs);
|
||||
intel_uncore_posting_read(&dev_priv->uncore, GEN11_DE_HPD_IMR);
|
||||
|
||||
gen11_tc_hpd_detection_setup(dev_priv);
|
||||
|
@ -3506,29 +3465,22 @@ static u32 spt_hotplug2_enables(struct drm_i915_private *i915,
|
|||
|
||||
static void spt_hpd_detection_setup(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
u32 val, hotplug;
|
||||
|
||||
/* Display WA #1179 WaHardHangonHotPlug: cnp */
|
||||
if (HAS_PCH_CNP(dev_priv)) {
|
||||
val = intel_uncore_read(&dev_priv->uncore, SOUTH_CHICKEN1);
|
||||
val &= ~CHASSIS_CLK_REQ_DURATION_MASK;
|
||||
val |= CHASSIS_CLK_REQ_DURATION(0xf);
|
||||
intel_uncore_write(&dev_priv->uncore, SOUTH_CHICKEN1, val);
|
||||
intel_uncore_rmw(&dev_priv->uncore, SOUTH_CHICKEN1, CHASSIS_CLK_REQ_DURATION_MASK,
|
||||
CHASSIS_CLK_REQ_DURATION(0xf));
|
||||
}
|
||||
|
||||
/* Enable digital hotplug on the PCH */
|
||||
hotplug = intel_uncore_read(&dev_priv->uncore, PCH_PORT_HOTPLUG);
|
||||
hotplug &= ~(PORTA_HOTPLUG_ENABLE |
|
||||
PORTB_HOTPLUG_ENABLE |
|
||||
PORTC_HOTPLUG_ENABLE |
|
||||
PORTD_HOTPLUG_ENABLE);
|
||||
hotplug |= intel_hpd_hotplug_enables(dev_priv, spt_hotplug_enables);
|
||||
intel_uncore_write(&dev_priv->uncore, PCH_PORT_HOTPLUG, hotplug);
|
||||
intel_uncore_rmw(&dev_priv->uncore, PCH_PORT_HOTPLUG,
|
||||
PORTA_HOTPLUG_ENABLE |
|
||||
PORTB_HOTPLUG_ENABLE |
|
||||
PORTC_HOTPLUG_ENABLE |
|
||||
PORTD_HOTPLUG_ENABLE,
|
||||
intel_hpd_hotplug_enables(dev_priv, spt_hotplug_enables));
|
||||
|
||||
hotplug = intel_uncore_read(&dev_priv->uncore, PCH_PORT_HOTPLUG2);
|
||||
hotplug &= ~PORTE_HOTPLUG_ENABLE;
|
||||
hotplug |= intel_hpd_hotplug_enables(dev_priv, spt_hotplug2_enables);
|
||||
intel_uncore_write(&dev_priv->uncore, PCH_PORT_HOTPLUG2, hotplug);
|
||||
intel_uncore_rmw(&dev_priv->uncore, PCH_PORT_HOTPLUG2, PORTE_HOTPLUG_ENABLE,
|
||||
intel_hpd_hotplug_enables(dev_priv, spt_hotplug2_enables));
|
||||
}
|
||||
|
||||
static void spt_hpd_irq_setup(struct drm_i915_private *dev_priv)
|
||||
|
@ -3560,18 +3512,14 @@ static u32 ilk_hotplug_enables(struct drm_i915_private *i915,
|
|||
|
||||
static void ilk_hpd_detection_setup(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
u32 hotplug;
|
||||
|
||||
/*
|
||||
* Enable digital hotplug on the CPU, and configure the DP short pulse
|
||||
* duration to 2ms (which is the minimum in the Display Port spec)
|
||||
* The pulse duration bits are reserved on HSW+.
|
||||
*/
|
||||
hotplug = intel_uncore_read(&dev_priv->uncore, DIGITAL_PORT_HOTPLUG_CNTRL);
|
||||
hotplug &= ~(DIGITAL_PORTA_HOTPLUG_ENABLE |
|
||||
DIGITAL_PORTA_PULSE_DURATION_MASK);
|
||||
hotplug |= intel_hpd_hotplug_enables(dev_priv, ilk_hotplug_enables);
|
||||
intel_uncore_write(&dev_priv->uncore, DIGITAL_PORT_HOTPLUG_CNTRL, hotplug);
|
||||
intel_uncore_rmw(&dev_priv->uncore, DIGITAL_PORT_HOTPLUG_CNTRL,
|
||||
DIGITAL_PORTA_HOTPLUG_ENABLE | DIGITAL_PORTA_PULSE_DURATION_MASK,
|
||||
intel_hpd_hotplug_enables(dev_priv, ilk_hotplug_enables));
|
||||
}
|
||||
|
||||
static void ilk_hpd_irq_setup(struct drm_i915_private *dev_priv)
|
||||
|
@ -3619,17 +3567,12 @@ static u32 bxt_hotplug_enables(struct drm_i915_private *i915,
|
|||
|
||||
static void bxt_hpd_detection_setup(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
u32 hotplug;
|
||||
|
||||
hotplug = intel_uncore_read(&dev_priv->uncore, PCH_PORT_HOTPLUG);
|
||||
hotplug &= ~(PORTA_HOTPLUG_ENABLE |
|
||||
PORTB_HOTPLUG_ENABLE |
|
||||
PORTC_HOTPLUG_ENABLE |
|
||||
BXT_DDIA_HPD_INVERT |
|
||||
BXT_DDIB_HPD_INVERT |
|
||||
BXT_DDIC_HPD_INVERT);
|
||||
hotplug |= intel_hpd_hotplug_enables(dev_priv, bxt_hotplug_enables);
|
||||
intel_uncore_write(&dev_priv->uncore, PCH_PORT_HOTPLUG, hotplug);
|
||||
intel_uncore_rmw(&dev_priv->uncore, PCH_PORT_HOTPLUG,
|
||||
PORTA_HOTPLUG_ENABLE |
|
||||
PORTB_HOTPLUG_ENABLE |
|
||||
PORTC_HOTPLUG_ENABLE |
|
||||
BXT_DDI_HPD_INVERT_MASK,
|
||||
intel_hpd_hotplug_enables(dev_priv, bxt_hotplug_enables));
|
||||
}
|
||||
|
||||
static void bxt_hpd_irq_setup(struct drm_i915_private *dev_priv)
|
||||
|
@ -4009,9 +3952,7 @@ static void i9xx_error_irq_ack(struct drm_i915_private *dev_priv,
|
|||
{
|
||||
u32 emr;
|
||||
|
||||
*eir = intel_uncore_read(&dev_priv->uncore, EIR);
|
||||
|
||||
intel_uncore_write(&dev_priv->uncore, EIR, *eir);
|
||||
*eir = intel_uncore_rmw(&dev_priv->uncore, EIR, 0, 0);
|
||||
|
||||
*eir_stuck = intel_uncore_read(&dev_priv->uncore, EIR);
|
||||
if (*eir_stuck == 0)
|
||||
|
@ -4027,8 +3968,7 @@ static void i9xx_error_irq_ack(struct drm_i915_private *dev_priv,
|
|||
* (or by a GPU reset) so we mask any bit that
|
||||
* remains set.
|
||||
*/
|
||||
emr = intel_uncore_read(&dev_priv->uncore, EMR);
|
||||
intel_uncore_write(&dev_priv->uncore, EMR, 0xffffffff);
|
||||
emr = intel_uncore_rmw(&dev_priv->uncore, EMR, ~0, 0xffffffff);
|
||||
intel_uncore_write(&dev_priv->uncore, EMR, emr | *eir_stuck);
|
||||
}
|
||||
|
||||
|
@ -4095,7 +4035,7 @@ static void i915_irq_reset(struct drm_i915_private *dev_priv)
|
|||
|
||||
if (I915_HAS_HOTPLUG(dev_priv)) {
|
||||
i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0);
|
||||
intel_uncore_write(&dev_priv->uncore, PORT_HOTPLUG_STAT, intel_uncore_read(&dev_priv->uncore, PORT_HOTPLUG_STAT));
|
||||
intel_uncore_rmw(&dev_priv->uncore, PORT_HOTPLUG_STAT, 0, 0);
|
||||
}
|
||||
|
||||
i9xx_pipestat_irq_reset(dev_priv);
|
||||
|
@ -4109,8 +4049,8 @@ static void i915_irq_postinstall(struct drm_i915_private *dev_priv)
|
|||
struct intel_uncore *uncore = &dev_priv->uncore;
|
||||
u32 enable_mask;
|
||||
|
||||
intel_uncore_write(&dev_priv->uncore, EMR, ~(I915_ERROR_PAGE_TABLE |
|
||||
I915_ERROR_MEMORY_REFRESH));
|
||||
intel_uncore_write(uncore, EMR, ~(I915_ERROR_PAGE_TABLE |
|
||||
I915_ERROR_MEMORY_REFRESH));
|
||||
|
||||
/* Unmask the interrupts that we always want on. */
|
||||
dev_priv->irq_mask =
|
||||
|
@ -4205,7 +4145,7 @@ static void i965_irq_reset(struct drm_i915_private *dev_priv)
|
|||
struct intel_uncore *uncore = &dev_priv->uncore;
|
||||
|
||||
i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0);
|
||||
intel_uncore_write(&dev_priv->uncore, PORT_HOTPLUG_STAT, intel_uncore_read(&dev_priv->uncore, PORT_HOTPLUG_STAT));
|
||||
intel_uncore_rmw(uncore, PORT_HOTPLUG_STAT, 0, 0);
|
||||
|
||||
i9xx_pipestat_irq_reset(dev_priv);
|
||||
|
||||
|
@ -4232,7 +4172,7 @@ static void i965_irq_postinstall(struct drm_i915_private *dev_priv)
|
|||
error_mask = ~(I915_ERROR_PAGE_TABLE |
|
||||
I915_ERROR_MEMORY_REFRESH);
|
||||
}
|
||||
intel_uncore_write(&dev_priv->uncore, EMR, error_mask);
|
||||
intel_uncore_write(uncore, EMR, error_mask);
|
||||
|
||||
/* Unmask the interrupts that we always want on. */
|
||||
dev_priv->irq_mask =
|
||||
|
@ -4383,7 +4323,6 @@ void intel_hpd_irq_setup(struct drm_i915_private *i915)
|
|||
*/
|
||||
void intel_irq_init(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct drm_device *dev = &dev_priv->drm;
|
||||
int i;
|
||||
|
||||
INIT_WORK(&dev_priv->l3_parity.error_work, ivb_parity_work);
|
||||
|
@ -4399,9 +4338,9 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
|
|||
|
||||
intel_hpd_init_pins(dev_priv);
|
||||
|
||||
intel_hpd_init_work(dev_priv);
|
||||
intel_hpd_init_early(dev_priv);
|
||||
|
||||
dev->vblank_disable_immediate = true;
|
||||
dev_priv->drm.vblank_disable_immediate = true;
|
||||
|
||||
/* Most platforms treat the display irq block as an always-on
|
||||
* power domain. vlv/chv can disable it at runtime and need
|
||||
|
@ -4413,15 +4352,6 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
|
|||
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
|
||||
dev_priv->display_irqs_enabled = false;
|
||||
|
||||
dev_priv->display.hotplug.hpd_storm_threshold = HPD_STORM_DEFAULT_THRESHOLD;
|
||||
/* If we have MST support, we want to avoid doing short HPD IRQ storm
|
||||
* detection, as short HPD storms will occur as a natural part of
|
||||
* sideband messaging with MST.
|
||||
* On older platforms however, IRQ storms can occur with both long and
|
||||
* short pulses, as seen on some G4x systems.
|
||||
*/
|
||||
dev_priv->display.hotplug.hpd_short_storm_enabled = !HAS_DP_MST(dev_priv);
|
||||
|
||||
if (HAS_GMCH(dev_priv)) {
|
||||
if (I915_HAS_HOTPLUG(dev_priv))
|
||||
dev_priv->display.funcs.hotplug = &i915_hpd_funcs;
|
||||
|
|
|
@ -1066,6 +1066,7 @@ static const struct intel_device_info xehpsdv_info = {
|
|||
.has_heci_pxp = 1, \
|
||||
.needs_compact_pt = 1, \
|
||||
.has_media_ratio_mode = 1, \
|
||||
.display.has_cdclk_squash = 1, \
|
||||
.__runtime.platform_engine_mask = \
|
||||
BIT(RCS0) | BIT(BCS0) | \
|
||||
BIT(VECS0) | BIT(VECS1) | \
|
||||
|
@ -1144,6 +1145,7 @@ static const struct intel_device_info mtl_info = {
|
|||
.display.has_modular_fia = 1,
|
||||
.extra_gt_list = xelpmp_extra_gt,
|
||||
.has_flat_ccs = 0,
|
||||
.has_gmd_id = 1,
|
||||
.has_snoop = 1,
|
||||
.__runtime.memory_regions = REGION_SMEM | REGION_STOLEN_LMEM,
|
||||
.__runtime.platform_engine_mask = BIT(RCS0) | BIT(BCS0) | BIT(CCS0),
|
||||
|
|
|
@ -5847,6 +5847,11 @@
|
|||
#define ICL_DSSM_CDCLK_PLL_REFCLK_19_2MHz (1 << 29)
|
||||
#define ICL_DSSM_CDCLK_PLL_REFCLK_38_4MHz (2 << 29)
|
||||
|
||||
#define GMD_ID_DISPLAY _MMIO(0x510a0)
|
||||
#define GMD_ID_ARCH_MASK REG_GENMASK(31, 22)
|
||||
#define GMD_ID_RELEASE_MASK REG_GENMASK(21, 14)
|
||||
#define GMD_ID_STEP REG_GENMASK(5, 0)
|
||||
|
||||
/*GEN11 chicken */
|
||||
#define _PIPEA_CHICKEN 0x70038
|
||||
#define _PIPEB_CHICKEN 0x71038
|
||||
|
@ -7413,182 +7418,6 @@ enum skl_power_gate {
|
|||
_ADLS_DPLL4_CFGCR1, \
|
||||
_ADLS_DPLL3_CFGCR1)
|
||||
|
||||
#define _DKL_PHY1_BASE 0x168000
|
||||
#define _DKL_PHY2_BASE 0x169000
|
||||
#define _DKL_PHY3_BASE 0x16A000
|
||||
#define _DKL_PHY4_BASE 0x16B000
|
||||
#define _DKL_PHY5_BASE 0x16C000
|
||||
#define _DKL_PHY6_BASE 0x16D000
|
||||
|
||||
/* DEKEL PHY MMIO Address = Phy base + (internal address & ~index_mask) */
|
||||
#define _DKL_PCS_DW5 0x14
|
||||
#define DKL_PCS_DW5(tc_port) _MMIO(_PORT(tc_port, _DKL_PHY1_BASE, \
|
||||
_DKL_PHY2_BASE) + \
|
||||
_DKL_PCS_DW5)
|
||||
#define DKL_PCS_DW5_CORE_SOFTRESET REG_BIT(11)
|
||||
|
||||
#define _DKL_PLL_DIV0 0x200
|
||||
#define DKL_PLL_DIV0_AFC_STARTUP_MASK REG_GENMASK(27, 25)
|
||||
#define DKL_PLL_DIV0_AFC_STARTUP(val) REG_FIELD_PREP(DKL_PLL_DIV0_AFC_STARTUP_MASK, (val))
|
||||
#define DKL_PLL_DIV0_INTEG_COEFF(x) ((x) << 16)
|
||||
#define DKL_PLL_DIV0_INTEG_COEFF_MASK (0x1F << 16)
|
||||
#define DKL_PLL_DIV0_PROP_COEFF(x) ((x) << 12)
|
||||
#define DKL_PLL_DIV0_PROP_COEFF_MASK (0xF << 12)
|
||||
#define DKL_PLL_DIV0_FBPREDIV_SHIFT (8)
|
||||
#define DKL_PLL_DIV0_FBPREDIV(x) ((x) << DKL_PLL_DIV0_FBPREDIV_SHIFT)
|
||||
#define DKL_PLL_DIV0_FBPREDIV_MASK (0xF << DKL_PLL_DIV0_FBPREDIV_SHIFT)
|
||||
#define DKL_PLL_DIV0_FBDIV_INT(x) ((x) << 0)
|
||||
#define DKL_PLL_DIV0_FBDIV_INT_MASK (0xFF << 0)
|
||||
#define DKL_PLL_DIV0_MASK (DKL_PLL_DIV0_INTEG_COEFF_MASK | \
|
||||
DKL_PLL_DIV0_PROP_COEFF_MASK | \
|
||||
DKL_PLL_DIV0_FBPREDIV_MASK | \
|
||||
DKL_PLL_DIV0_FBDIV_INT_MASK)
|
||||
#define DKL_PLL_DIV0(tc_port) _MMIO(_PORT(tc_port, _DKL_PHY1_BASE, \
|
||||
_DKL_PHY2_BASE) + \
|
||||
_DKL_PLL_DIV0)
|
||||
|
||||
#define _DKL_PLL_DIV1 0x204
|
||||
#define DKL_PLL_DIV1_IREF_TRIM(x) ((x) << 16)
|
||||
#define DKL_PLL_DIV1_IREF_TRIM_MASK (0x1F << 16)
|
||||
#define DKL_PLL_DIV1_TDC_TARGET_CNT(x) ((x) << 0)
|
||||
#define DKL_PLL_DIV1_TDC_TARGET_CNT_MASK (0xFF << 0)
|
||||
#define DKL_PLL_DIV1(tc_port) _MMIO(_PORT(tc_port, _DKL_PHY1_BASE, \
|
||||
_DKL_PHY2_BASE) + \
|
||||
_DKL_PLL_DIV1)
|
||||
|
||||
#define _DKL_PLL_SSC 0x210
|
||||
#define DKL_PLL_SSC_IREF_NDIV_RATIO(x) ((x) << 29)
|
||||
#define DKL_PLL_SSC_IREF_NDIV_RATIO_MASK (0x7 << 29)
|
||||
#define DKL_PLL_SSC_STEP_LEN(x) ((x) << 16)
|
||||
#define DKL_PLL_SSC_STEP_LEN_MASK (0xFF << 16)
|
||||
#define DKL_PLL_SSC_STEP_NUM(x) ((x) << 11)
|
||||
#define DKL_PLL_SSC_STEP_NUM_MASK (0x7 << 11)
|
||||
#define DKL_PLL_SSC_EN (1 << 9)
|
||||
#define DKL_PLL_SSC(tc_port) _MMIO(_PORT(tc_port, _DKL_PHY1_BASE, \
|
||||
_DKL_PHY2_BASE) + \
|
||||
_DKL_PLL_SSC)
|
||||
|
||||
#define _DKL_PLL_BIAS 0x214
|
||||
#define DKL_PLL_BIAS_FRAC_EN_H (1 << 30)
|
||||
#define DKL_PLL_BIAS_FBDIV_SHIFT (8)
|
||||
#define DKL_PLL_BIAS_FBDIV_FRAC(x) ((x) << DKL_PLL_BIAS_FBDIV_SHIFT)
|
||||
#define DKL_PLL_BIAS_FBDIV_FRAC_MASK (0x3FFFFF << DKL_PLL_BIAS_FBDIV_SHIFT)
|
||||
#define DKL_PLL_BIAS(tc_port) _MMIO(_PORT(tc_port, _DKL_PHY1_BASE, \
|
||||
_DKL_PHY2_BASE) + \
|
||||
_DKL_PLL_BIAS)
|
||||
|
||||
#define _DKL_PLL_TDC_COLDST_BIAS 0x218
|
||||
#define DKL_PLL_TDC_SSC_STEP_SIZE(x) ((x) << 8)
|
||||
#define DKL_PLL_TDC_SSC_STEP_SIZE_MASK (0xFF << 8)
|
||||
#define DKL_PLL_TDC_FEED_FWD_GAIN(x) ((x) << 0)
|
||||
#define DKL_PLL_TDC_FEED_FWD_GAIN_MASK (0xFF << 0)
|
||||
#define DKL_PLL_TDC_COLDST_BIAS(tc_port) _MMIO(_PORT(tc_port, \
|
||||
_DKL_PHY1_BASE, \
|
||||
_DKL_PHY2_BASE) + \
|
||||
_DKL_PLL_TDC_COLDST_BIAS)
|
||||
|
||||
#define _DKL_REFCLKIN_CTL 0x12C
|
||||
/* Bits are the same as MG_REFCLKIN_CTL */
|
||||
#define DKL_REFCLKIN_CTL(tc_port) _MMIO(_PORT(tc_port, \
|
||||
_DKL_PHY1_BASE, \
|
||||
_DKL_PHY2_BASE) + \
|
||||
_DKL_REFCLKIN_CTL)
|
||||
|
||||
#define _DKL_CLKTOP2_HSCLKCTL 0xD4
|
||||
/* Bits are the same as MG_CLKTOP2_HSCLKCTL */
|
||||
#define DKL_CLKTOP2_HSCLKCTL(tc_port) _MMIO(_PORT(tc_port, \
|
||||
_DKL_PHY1_BASE, \
|
||||
_DKL_PHY2_BASE) + \
|
||||
_DKL_CLKTOP2_HSCLKCTL)
|
||||
|
||||
#define _DKL_CLKTOP2_CORECLKCTL1 0xD8
|
||||
/* Bits are the same as MG_CLKTOP2_CORECLKCTL1 */
|
||||
#define DKL_CLKTOP2_CORECLKCTL1(tc_port) _MMIO(_PORT(tc_port, \
|
||||
_DKL_PHY1_BASE, \
|
||||
_DKL_PHY2_BASE) + \
|
||||
_DKL_CLKTOP2_CORECLKCTL1)
|
||||
|
||||
#define _DKL_TX_DPCNTL0 0x2C0
|
||||
#define DKL_TX_PRESHOOT_COEFF(x) ((x) << 13)
|
||||
#define DKL_TX_PRESHOOT_COEFF_MASK (0x1f << 13)
|
||||
#define DKL_TX_DE_EMPHASIS_COEFF(x) ((x) << 8)
|
||||
#define DKL_TX_DE_EMPAHSIS_COEFF_MASK (0x1f << 8)
|
||||
#define DKL_TX_VSWING_CONTROL(x) ((x) << 0)
|
||||
#define DKL_TX_VSWING_CONTROL_MASK (0x7 << 0)
|
||||
#define DKL_TX_DPCNTL0(tc_port) _MMIO(_PORT(tc_port, \
|
||||
_DKL_PHY1_BASE, \
|
||||
_DKL_PHY2_BASE) + \
|
||||
_DKL_TX_DPCNTL0)
|
||||
|
||||
#define _DKL_TX_DPCNTL1 0x2C4
|
||||
/* Bits are the same as DKL_TX_DPCNTRL0 */
|
||||
#define DKL_TX_DPCNTL1(tc_port) _MMIO(_PORT(tc_port, \
|
||||
_DKL_PHY1_BASE, \
|
||||
_DKL_PHY2_BASE) + \
|
||||
_DKL_TX_DPCNTL1)
|
||||
|
||||
#define _DKL_TX_DPCNTL2 0x2C8
|
||||
#define DKL_TX_DP20BITMODE REG_BIT(2)
|
||||
#define DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX1_MASK REG_GENMASK(4, 3)
|
||||
#define DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX1(val) REG_FIELD_PREP(DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX1_MASK, (val))
|
||||
#define DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2_MASK REG_GENMASK(6, 5)
|
||||
#define DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2(val) REG_FIELD_PREP(DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2_MASK, (val))
|
||||
#define DKL_TX_DPCNTL2(tc_port) _MMIO(_PORT(tc_port, \
|
||||
_DKL_PHY1_BASE, \
|
||||
_DKL_PHY2_BASE) + \
|
||||
_DKL_TX_DPCNTL2)
|
||||
|
||||
#define _DKL_TX_FW_CALIB 0x2F8
|
||||
#define DKL_TX_CFG_DISABLE_WAIT_INIT (1 << 7)
|
||||
#define DKL_TX_FW_CALIB(tc_port) _MMIO(_PORT(tc_port, \
|
||||
_DKL_PHY1_BASE, \
|
||||
_DKL_PHY2_BASE) + \
|
||||
_DKL_TX_FW_CALIB)
|
||||
|
||||
#define _DKL_TX_PMD_LANE_SUS 0xD00
|
||||
#define DKL_TX_PMD_LANE_SUS(tc_port) _MMIO(_PORT(tc_port, \
|
||||
_DKL_PHY1_BASE, \
|
||||
_DKL_PHY2_BASE) + \
|
||||
_DKL_TX_PMD_LANE_SUS)
|
||||
|
||||
#define _DKL_TX_DW17 0xDC4
|
||||
#define DKL_TX_DW17(tc_port) _MMIO(_PORT(tc_port, \
|
||||
_DKL_PHY1_BASE, \
|
||||
_DKL_PHY2_BASE) + \
|
||||
_DKL_TX_DW17)
|
||||
|
||||
#define _DKL_TX_DW18 0xDC8
|
||||
#define DKL_TX_DW18(tc_port) _MMIO(_PORT(tc_port, \
|
||||
_DKL_PHY1_BASE, \
|
||||
_DKL_PHY2_BASE) + \
|
||||
_DKL_TX_DW18)
|
||||
|
||||
#define _DKL_DP_MODE 0xA0
|
||||
#define DKL_DP_MODE(tc_port) _MMIO(_PORT(tc_port, \
|
||||
_DKL_PHY1_BASE, \
|
||||
_DKL_PHY2_BASE) + \
|
||||
_DKL_DP_MODE)
|
||||
|
||||
#define _DKL_CMN_UC_DW27 0x36C
|
||||
#define DKL_CMN_UC_DW27_UC_HEALTH (0x1 << 15)
|
||||
#define DKL_CMN_UC_DW_27(tc_port) _MMIO(_PORT(tc_port, \
|
||||
_DKL_PHY1_BASE, \
|
||||
_DKL_PHY2_BASE) + \
|
||||
_DKL_CMN_UC_DW27)
|
||||
|
||||
/*
|
||||
* Each Dekel PHY is addressed through a 4KB aperture. Each PHY has more than
|
||||
* 4KB of register space, so a separate index is programmed in HIP_INDEX_REG0
|
||||
* or HIP_INDEX_REG1, based on the port number, to set the upper 2 address
|
||||
* bits that point the 4KB window into the full PHY register space.
|
||||
*/
|
||||
#define _HIP_INDEX_REG0 0x1010A0
|
||||
#define _HIP_INDEX_REG1 0x1010A4
|
||||
#define HIP_INDEX_REG(tc_port) _MMIO((tc_port) < 4 ? _HIP_INDEX_REG0 \
|
||||
: _HIP_INDEX_REG1)
|
||||
#define _HIP_INDEX_SHIFT(tc_port) (8 * ((tc_port) % 4))
|
||||
#define HIP_INDEX_VAL(tc_port, val) ((val) << _HIP_INDEX_SHIFT(tc_port))
|
||||
|
||||
/* BXT display engine PLL */
|
||||
#define BXT_DE_PLL_CTL _MMIO(0x6d000)
|
||||
#define BXT_DE_PLL_RATIO(x) (x) /* {60,65,100} * 19.2MHz */
|
||||
|
@ -8341,6 +8170,11 @@ enum skl_power_gate {
|
|||
#define GEN12_CULLBIT2 _MMIO(0x7030)
|
||||
#define GEN12_STATE_ACK_DEBUG _MMIO(0x20BC)
|
||||
|
||||
#define _MTL_CLKGATE_DIS_TRANS_A 0x604E8
|
||||
#define _MTL_CLKGATE_DIS_TRANS_B 0x614E8
|
||||
#define MTL_CLKGATE_DIS_TRANS(trans) _MMIO_TRANS2(trans, _MTL_CLKGATE_DIS_TRANS_A)
|
||||
#define MTL_CLKGATE_DIS_TRANS_DMASC_GATING_DIS REG_BIT(7)
|
||||
|
||||
#define MTL_LATENCY_LP0_LP1 _MMIO(0x45780)
|
||||
#define MTL_LATENCY_LP2_LP3 _MMIO(0x45784)
|
||||
#define MTL_LATENCY_LP4_LP5 _MMIO(0x45788)
|
||||
|
@ -8364,4 +8198,6 @@ enum skl_power_gate {
|
|||
#define MTL_TRAS_MASK REG_GENMASK(16, 8)
|
||||
#define MTL_TRDPRE_MASK REG_GENMASK(7, 0)
|
||||
|
||||
#define MTL_MEDIA_GSI_BASE 0x380000
|
||||
|
||||
#endif /* _I915_REG_H_ */
|
||||
|
|
|
@ -571,7 +571,6 @@ int __i915_sw_fence_await_dma_fence(struct i915_sw_fence *fence,
|
|||
|
||||
int i915_sw_fence_await_reservation(struct i915_sw_fence *fence,
|
||||
struct dma_resv *resv,
|
||||
const struct dma_fence_ops *exclude,
|
||||
bool write,
|
||||
unsigned long timeout,
|
||||
gfp_t gfp)
|
||||
|
|
|
@ -91,7 +91,6 @@ int i915_sw_fence_await_dma_fence(struct i915_sw_fence *fence,
|
|||
|
||||
int i915_sw_fence_await_reservation(struct i915_sw_fence *fence,
|
||||
struct dma_resv *resv,
|
||||
const struct dma_fence_ops *exclude,
|
||||
bool write,
|
||||
unsigned long timeout,
|
||||
gfp_t gfp);
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include "display/intel_cdclk.h"
|
||||
#include "display/intel_de.h"
|
||||
#include "gt/intel_gt_regs.h"
|
||||
#include "intel_device_info.h"
|
||||
#include "i915_drv.h"
|
||||
#include "i915_utils.h"
|
||||
|
@ -231,7 +232,7 @@ static bool find_devid(u16 id, const u16 *p, unsigned int num)
|
|||
return false;
|
||||
}
|
||||
|
||||
void intel_device_info_subplatform_init(struct drm_i915_private *i915)
|
||||
static void intel_device_info_subplatform_init(struct drm_i915_private *i915)
|
||||
{
|
||||
const struct intel_device_info *info = INTEL_INFO(i915);
|
||||
const struct intel_runtime_info *rinfo = RUNTIME_INFO(i915);
|
||||
|
@ -288,6 +289,78 @@ void intel_device_info_subplatform_init(struct drm_i915_private *i915)
|
|||
RUNTIME_INFO(i915)->platform_mask[pi] |= mask;
|
||||
}
|
||||
|
||||
static void ip_ver_read(struct drm_i915_private *i915, u32 offset, struct intel_ip_version *ip)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
|
||||
void __iomem *addr;
|
||||
u32 val;
|
||||
u8 expected_ver = ip->ver;
|
||||
u8 expected_rel = ip->rel;
|
||||
|
||||
addr = pci_iomap_range(pdev, 0, offset, sizeof(u32));
|
||||
if (drm_WARN_ON(&i915->drm, !addr))
|
||||
return;
|
||||
|
||||
val = ioread32(addr);
|
||||
pci_iounmap(pdev, addr);
|
||||
|
||||
ip->ver = REG_FIELD_GET(GMD_ID_ARCH_MASK, val);
|
||||
ip->rel = REG_FIELD_GET(GMD_ID_RELEASE_MASK, val);
|
||||
ip->step = REG_FIELD_GET(GMD_ID_STEP, val);
|
||||
|
||||
/* Sanity check against expected versions from device info */
|
||||
if (IP_VER(ip->ver, ip->rel) < IP_VER(expected_ver, expected_rel))
|
||||
drm_dbg(&i915->drm,
|
||||
"Hardware reports GMD IP version %u.%u (REG[0x%x] = 0x%08x) but minimum expected is %u.%u\n",
|
||||
ip->ver, ip->rel, offset, val, expected_ver, expected_rel);
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the graphics version for the current device. This must be done before
|
||||
* any code that performs checks on GRAPHICS_VER or DISPLAY_VER, so this
|
||||
* function should be called very early in the driver initialization sequence.
|
||||
*
|
||||
* Regular MMIO access is not yet setup at the point this function is called so
|
||||
* we peek at the appropriate MMIO offset directly. The GMD_ID register is
|
||||
* part of an 'always on' power well by design, so we don't need to worry about
|
||||
* forcewake while reading it.
|
||||
*/
|
||||
static void intel_ipver_early_init(struct drm_i915_private *i915)
|
||||
{
|
||||
struct intel_runtime_info *runtime = RUNTIME_INFO(i915);
|
||||
|
||||
if (!HAS_GMD_ID(i915)) {
|
||||
drm_WARN_ON(&i915->drm, RUNTIME_INFO(i915)->graphics.ip.ver > 12);
|
||||
/*
|
||||
* On older platforms, graphics and media share the same ip
|
||||
* version and release.
|
||||
*/
|
||||
RUNTIME_INFO(i915)->media.ip =
|
||||
RUNTIME_INFO(i915)->graphics.ip;
|
||||
return;
|
||||
}
|
||||
|
||||
ip_ver_read(i915, i915_mmio_reg_offset(GMD_ID_GRAPHICS),
|
||||
&runtime->graphics.ip);
|
||||
ip_ver_read(i915, i915_mmio_reg_offset(GMD_ID_DISPLAY),
|
||||
&runtime->display.ip);
|
||||
ip_ver_read(i915, i915_mmio_reg_offset(GMD_ID_MEDIA),
|
||||
&runtime->media.ip);
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_device_info_runtime_init_early - initialize early runtime info
|
||||
* @i915: the i915 device
|
||||
*
|
||||
* Determine early intel_device_info fields at runtime. This function needs
|
||||
* to be called before the MMIO has been setup.
|
||||
*/
|
||||
void intel_device_info_runtime_init_early(struct drm_i915_private *i915)
|
||||
{
|
||||
intel_ipver_early_init(i915);
|
||||
intel_device_info_subplatform_init(i915);
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_device_info_runtime_init - initialize runtime info
|
||||
* @dev_priv: the i915 device
|
||||
|
@ -442,6 +515,11 @@ void intel_device_info_runtime_init(struct drm_i915_private *dev_priv)
|
|||
runtime->has_dmc = false;
|
||||
runtime->has_dsc = false;
|
||||
}
|
||||
|
||||
/* Disable nuclear pageflip by default on pre-g4x */
|
||||
if (!dev_priv->params.nuclear_pageflip &&
|
||||
DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv))
|
||||
dev_priv->drm.driver_features &= ~DRIVER_ATOMIC;
|
||||
}
|
||||
|
||||
void intel_driver_caps_print(const struct intel_driver_caps *caps,
|
||||
|
|
|
@ -153,6 +153,7 @@ enum intel_ppgtt_type {
|
|||
func(has_4tile); \
|
||||
func(has_flat_ccs); \
|
||||
func(has_global_mocs); \
|
||||
func(has_gmd_id); \
|
||||
func(has_gt_uc); \
|
||||
func(has_heci_pxp); \
|
||||
func(has_heci_gscfi); \
|
||||
|
@ -180,6 +181,7 @@ enum intel_ppgtt_type {
|
|||
/* Keep in alphabetical order */ \
|
||||
func(cursor_needs_physical); \
|
||||
func(has_cdclk_crawl); \
|
||||
func(has_cdclk_squash); \
|
||||
func(has_ddi); \
|
||||
func(has_dp_mst); \
|
||||
func(has_dsb); \
|
||||
|
@ -195,20 +197,25 @@ enum intel_ppgtt_type {
|
|||
func(overlay_needs_physical); \
|
||||
func(supports_tv);
|
||||
|
||||
struct ip_version {
|
||||
struct intel_ip_version {
|
||||
u8 ver;
|
||||
u8 rel;
|
||||
u8 step;
|
||||
};
|
||||
|
||||
struct intel_runtime_info {
|
||||
/*
|
||||
* Single "graphics" IP version that represents
|
||||
* render, compute and copy behavior.
|
||||
*/
|
||||
struct {
|
||||
struct ip_version ip;
|
||||
struct intel_ip_version ip;
|
||||
} graphics;
|
||||
struct {
|
||||
struct ip_version ip;
|
||||
struct intel_ip_version ip;
|
||||
} media;
|
||||
struct {
|
||||
struct ip_version ip;
|
||||
struct intel_ip_version ip;
|
||||
} display;
|
||||
|
||||
/*
|
||||
|
@ -308,7 +315,7 @@ struct intel_driver_caps {
|
|||
|
||||
const char *intel_platform_name(enum intel_platform platform);
|
||||
|
||||
void intel_device_info_subplatform_init(struct drm_i915_private *dev_priv);
|
||||
void intel_device_info_runtime_init_early(struct drm_i915_private *dev_priv);
|
||||
void intel_device_info_runtime_init(struct drm_i915_private *dev_priv);
|
||||
|
||||
void intel_device_info_print(const struct intel_device_info *info,
|
||||
|
|
|
@ -895,19 +895,14 @@ static void pnv_update_wm(struct drm_i915_private *dev_priv)
|
|||
wm = intel_calculate_wm(pixel_rate, &pnv_cursor_wm,
|
||||
pnv_display_wm.fifo_size,
|
||||
4, latency->cursor_sr);
|
||||
reg = intel_uncore_read(&dev_priv->uncore, DSPFW3);
|
||||
reg &= ~DSPFW_CURSOR_SR_MASK;
|
||||
reg |= FW_WM(wm, CURSOR_SR);
|
||||
intel_uncore_write(&dev_priv->uncore, DSPFW3, reg);
|
||||
intel_uncore_rmw(&dev_priv->uncore, DSPFW3, DSPFW_CURSOR_SR_MASK,
|
||||
FW_WM(wm, CURSOR_SR));
|
||||
|
||||
/* Display HPLL off SR */
|
||||
wm = intel_calculate_wm(pixel_rate, &pnv_display_hplloff_wm,
|
||||
pnv_display_hplloff_wm.fifo_size,
|
||||
cpp, latency->display_hpll_disable);
|
||||
reg = intel_uncore_read(&dev_priv->uncore, DSPFW3);
|
||||
reg &= ~DSPFW_HPLL_SR_MASK;
|
||||
reg |= FW_WM(wm, HPLL_SR);
|
||||
intel_uncore_write(&dev_priv->uncore, DSPFW3, reg);
|
||||
intel_uncore_rmw(&dev_priv->uncore, DSPFW3, DSPFW_HPLL_SR_MASK, FW_WM(wm, HPLL_SR));
|
||||
|
||||
/* cursor HPLL off SR */
|
||||
wm = intel_calculate_wm(pixel_rate, &pnv_cursor_hplloff_wm,
|
||||
|
@ -1337,34 +1332,14 @@ static bool g4x_compute_fbc_en(const struct g4x_wm_state *wm_state,
|
|||
return true;
|
||||
}
|
||||
|
||||
static int g4x_compute_pipe_wm(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
static int _g4x_compute_pipe_wm(struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_crtc_state *crtc_state =
|
||||
intel_atomic_get_new_crtc_state(state, crtc);
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
struct g4x_wm_state *wm_state = &crtc_state->wm.g4x.optimal;
|
||||
u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR);
|
||||
const struct g4x_pipe_wm *raw;
|
||||
const struct intel_plane_state *old_plane_state;
|
||||
const struct intel_plane_state *new_plane_state;
|
||||
struct intel_plane *plane;
|
||||
enum plane_id plane_id;
|
||||
int i, level;
|
||||
unsigned int dirty = 0;
|
||||
|
||||
for_each_oldnew_intel_plane_in_state(state, plane,
|
||||
old_plane_state,
|
||||
new_plane_state, i) {
|
||||
if (new_plane_state->hw.crtc != &crtc->base &&
|
||||
old_plane_state->hw.crtc != &crtc->base)
|
||||
continue;
|
||||
|
||||
if (g4x_raw_plane_wm_compute(crtc_state, new_plane_state))
|
||||
dirty |= BIT(plane->id);
|
||||
}
|
||||
|
||||
if (!dirty)
|
||||
return 0;
|
||||
int level;
|
||||
|
||||
level = G4X_WM_LEVEL_NORMAL;
|
||||
if (!g4x_raw_crtc_wm_is_valid(crtc_state, level))
|
||||
|
@ -1417,6 +1392,34 @@ static int g4x_compute_pipe_wm(struct intel_atomic_state *state,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int g4x_compute_pipe_wm(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
struct intel_crtc_state *crtc_state =
|
||||
intel_atomic_get_new_crtc_state(state, crtc);
|
||||
const struct intel_plane_state *old_plane_state;
|
||||
const struct intel_plane_state *new_plane_state;
|
||||
struct intel_plane *plane;
|
||||
unsigned int dirty = 0;
|
||||
int i;
|
||||
|
||||
for_each_oldnew_intel_plane_in_state(state, plane,
|
||||
old_plane_state,
|
||||
new_plane_state, i) {
|
||||
if (new_plane_state->hw.crtc != &crtc->base &&
|
||||
old_plane_state->hw.crtc != &crtc->base)
|
||||
continue;
|
||||
|
||||
if (g4x_raw_plane_wm_compute(crtc_state, new_plane_state))
|
||||
dirty |= BIT(plane->id);
|
||||
}
|
||||
|
||||
if (!dirty)
|
||||
return 0;
|
||||
|
||||
return _g4x_compute_pipe_wm(crtc_state);
|
||||
}
|
||||
|
||||
static int g4x_compute_intermediate_wm(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
|
@ -1857,64 +1860,17 @@ static bool vlv_raw_crtc_wm_is_valid(const struct intel_crtc_state *crtc_state,
|
|||
vlv_raw_plane_wm_is_valid(crtc_state, PLANE_CURSOR, level);
|
||||
}
|
||||
|
||||
static int vlv_compute_pipe_wm(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
static int _vlv_compute_pipe_wm(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);
|
||||
struct intel_crtc_state *crtc_state =
|
||||
intel_atomic_get_new_crtc_state(state, crtc);
|
||||
struct vlv_wm_state *wm_state = &crtc_state->wm.vlv.optimal;
|
||||
const struct vlv_fifo_state *fifo_state =
|
||||
&crtc_state->wm.vlv.fifo_state;
|
||||
u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR);
|
||||
int num_active_planes = hweight8(active_planes);
|
||||
bool needs_modeset = drm_atomic_crtc_needs_modeset(&crtc_state->uapi);
|
||||
const struct intel_plane_state *old_plane_state;
|
||||
const struct intel_plane_state *new_plane_state;
|
||||
struct intel_plane *plane;
|
||||
enum plane_id plane_id;
|
||||
int level, ret, i;
|
||||
unsigned int dirty = 0;
|
||||
|
||||
for_each_oldnew_intel_plane_in_state(state, plane,
|
||||
old_plane_state,
|
||||
new_plane_state, i) {
|
||||
if (new_plane_state->hw.crtc != &crtc->base &&
|
||||
old_plane_state->hw.crtc != &crtc->base)
|
||||
continue;
|
||||
|
||||
if (vlv_raw_plane_wm_compute(crtc_state, new_plane_state))
|
||||
dirty |= BIT(plane->id);
|
||||
}
|
||||
|
||||
/*
|
||||
* DSPARB registers may have been reset due to the
|
||||
* power well being turned off. Make sure we restore
|
||||
* them to a consistent state even if no primary/sprite
|
||||
* planes are initially active.
|
||||
*/
|
||||
if (needs_modeset)
|
||||
crtc_state->fifo_changed = true;
|
||||
|
||||
if (!dirty)
|
||||
return 0;
|
||||
|
||||
/* cursor changes don't warrant a FIFO recompute */
|
||||
if (dirty & ~BIT(PLANE_CURSOR)) {
|
||||
const struct intel_crtc_state *old_crtc_state =
|
||||
intel_atomic_get_old_crtc_state(state, crtc);
|
||||
const struct vlv_fifo_state *old_fifo_state =
|
||||
&old_crtc_state->wm.vlv.fifo_state;
|
||||
|
||||
ret = vlv_compute_fifo(crtc_state);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (needs_modeset ||
|
||||
memcmp(old_fifo_state, fifo_state,
|
||||
sizeof(*fifo_state)) != 0)
|
||||
crtc_state->fifo_changed = true;
|
||||
}
|
||||
int level;
|
||||
|
||||
/* initially allow all levels */
|
||||
wm_state->num_levels = intel_wm_num_levels(dev_priv);
|
||||
|
@ -1961,6 +1917,67 @@ static int vlv_compute_pipe_wm(struct intel_atomic_state *state,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int vlv_compute_pipe_wm(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
struct intel_crtc_state *crtc_state =
|
||||
intel_atomic_get_new_crtc_state(state, crtc);
|
||||
bool needs_modeset = drm_atomic_crtc_needs_modeset(&crtc_state->uapi);
|
||||
const struct intel_plane_state *old_plane_state;
|
||||
const struct intel_plane_state *new_plane_state;
|
||||
struct intel_plane *plane;
|
||||
unsigned int dirty = 0;
|
||||
int i;
|
||||
|
||||
for_each_oldnew_intel_plane_in_state(state, plane,
|
||||
old_plane_state,
|
||||
new_plane_state, i) {
|
||||
if (new_plane_state->hw.crtc != &crtc->base &&
|
||||
old_plane_state->hw.crtc != &crtc->base)
|
||||
continue;
|
||||
|
||||
if (vlv_raw_plane_wm_compute(crtc_state, new_plane_state))
|
||||
dirty |= BIT(plane->id);
|
||||
}
|
||||
|
||||
/*
|
||||
* DSPARB registers may have been reset due to the
|
||||
* power well being turned off. Make sure we restore
|
||||
* them to a consistent state even if no primary/sprite
|
||||
* planes are initially active. We also force a FIFO
|
||||
* recomputation so that we are sure to sanitize the
|
||||
* FIFO setting we took over from the BIOS even if there
|
||||
* are no active planes on the crtc.
|
||||
*/
|
||||
if (needs_modeset)
|
||||
dirty = ~0;
|
||||
|
||||
if (!dirty)
|
||||
return 0;
|
||||
|
||||
/* cursor changes don't warrant a FIFO recompute */
|
||||
if (dirty & ~BIT(PLANE_CURSOR)) {
|
||||
const struct intel_crtc_state *old_crtc_state =
|
||||
intel_atomic_get_old_crtc_state(state, crtc);
|
||||
const struct vlv_fifo_state *old_fifo_state =
|
||||
&old_crtc_state->wm.vlv.fifo_state;
|
||||
const struct vlv_fifo_state *new_fifo_state =
|
||||
&crtc_state->wm.vlv.fifo_state;
|
||||
int ret;
|
||||
|
||||
ret = vlv_compute_fifo(crtc_state);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (needs_modeset ||
|
||||
memcmp(old_fifo_state, new_fifo_state,
|
||||
sizeof(*new_fifo_state)) != 0)
|
||||
crtc_state->fifo_changed = true;
|
||||
}
|
||||
|
||||
return _vlv_compute_pipe_wm(crtc_state);
|
||||
}
|
||||
|
||||
#define VLV_FIFO(plane, value) \
|
||||
(((value) << DSPARB_ ## plane ## _SHIFT_VLV) & DSPARB_ ## plane ## _MASK_VLV)
|
||||
|
||||
|
@ -3458,7 +3475,6 @@ static void ilk_write_wm_values(struct drm_i915_private *dev_priv,
|
|||
{
|
||||
struct ilk_wm_values *previous = &dev_priv->display.wm.hw;
|
||||
unsigned int dirty;
|
||||
u32 val;
|
||||
|
||||
dirty = ilk_compute_wm_dirty(dev_priv, previous, results);
|
||||
if (!dirty)
|
||||
|
@ -3474,31 +3490,19 @@ static void ilk_write_wm_values(struct drm_i915_private *dev_priv,
|
|||
intel_uncore_write(&dev_priv->uncore, WM0_PIPE_ILK(PIPE_C), results->wm_pipe[2]);
|
||||
|
||||
if (dirty & WM_DIRTY_DDB) {
|
||||
if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
|
||||
val = intel_uncore_read(&dev_priv->uncore, WM_MISC);
|
||||
if (results->partitioning == INTEL_DDB_PART_1_2)
|
||||
val &= ~WM_MISC_DATA_PARTITION_5_6;
|
||||
else
|
||||
val |= WM_MISC_DATA_PARTITION_5_6;
|
||||
intel_uncore_write(&dev_priv->uncore, WM_MISC, val);
|
||||
} else {
|
||||
val = intel_uncore_read(&dev_priv->uncore, DISP_ARB_CTL2);
|
||||
if (results->partitioning == INTEL_DDB_PART_1_2)
|
||||
val &= ~DISP_DATA_PARTITION_5_6;
|
||||
else
|
||||
val |= DISP_DATA_PARTITION_5_6;
|
||||
intel_uncore_write(&dev_priv->uncore, DISP_ARB_CTL2, val);
|
||||
}
|
||||
if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
|
||||
intel_uncore_rmw(&dev_priv->uncore, WM_MISC, WM_MISC_DATA_PARTITION_5_6,
|
||||
results->partitioning == INTEL_DDB_PART_1_2 ? 0 :
|
||||
WM_MISC_DATA_PARTITION_5_6);
|
||||
else
|
||||
intel_uncore_rmw(&dev_priv->uncore, DISP_ARB_CTL2, DISP_DATA_PARTITION_5_6,
|
||||
results->partitioning == INTEL_DDB_PART_1_2 ? 0 :
|
||||
DISP_DATA_PARTITION_5_6);
|
||||
}
|
||||
|
||||
if (dirty & WM_DIRTY_FBC) {
|
||||
val = intel_uncore_read(&dev_priv->uncore, DISP_ARB_CTL);
|
||||
if (results->enable_fbc_wm)
|
||||
val &= ~DISP_FBC_WM_DIS;
|
||||
else
|
||||
val |= DISP_FBC_WM_DIS;
|
||||
intel_uncore_write(&dev_priv->uncore, DISP_ARB_CTL, val);
|
||||
}
|
||||
if (dirty & WM_DIRTY_FBC)
|
||||
intel_uncore_rmw(&dev_priv->uncore, DISP_ARB_CTL, DISP_FBC_WM_DIS,
|
||||
results->enable_fbc_wm ? 0 : DISP_FBC_WM_DIS);
|
||||
|
||||
if (dirty & WM_DIRTY_LP(1) &&
|
||||
previous->wm_lp_spr[0] != results->wm_lp_spr[0])
|
||||
|
@ -3824,6 +3828,8 @@ void g4x_wm_get_hw_state(struct drm_i915_private *dev_priv)
|
|||
plane_id, USHRT_MAX);
|
||||
g4x_raw_fbc_wm_set(crtc_state, level, USHRT_MAX);
|
||||
|
||||
g4x_invalidate_wms(crtc, active, level);
|
||||
|
||||
crtc_state->wm.g4x.optimal = *active;
|
||||
crtc_state->wm.g4x.intermediate = *active;
|
||||
|
||||
|
@ -3860,37 +3866,30 @@ void g4x_wm_sanitize(struct drm_i915_private *dev_priv)
|
|||
to_intel_crtc_state(crtc->base.state);
|
||||
struct intel_plane_state *plane_state =
|
||||
to_intel_plane_state(plane->base.state);
|
||||
struct g4x_wm_state *wm_state = &crtc_state->wm.g4x.optimal;
|
||||
enum plane_id plane_id = plane->id;
|
||||
int level;
|
||||
int level, num_levels = intel_wm_num_levels(dev_priv);
|
||||
|
||||
if (plane_state->uapi.visible)
|
||||
continue;
|
||||
|
||||
for (level = 0; level < 3; level++) {
|
||||
for (level = 0; level < num_levels; level++) {
|
||||
struct g4x_pipe_wm *raw =
|
||||
&crtc_state->wm.g4x.raw[level];
|
||||
|
||||
raw->plane[plane_id] = 0;
|
||||
wm_state->wm.plane[plane_id] = 0;
|
||||
}
|
||||
|
||||
if (plane_id == PLANE_PRIMARY) {
|
||||
for (level = 0; level < 3; level++) {
|
||||
struct g4x_pipe_wm *raw =
|
||||
&crtc_state->wm.g4x.raw[level];
|
||||
if (plane_id == PLANE_PRIMARY)
|
||||
raw->fbc = 0;
|
||||
}
|
||||
|
||||
wm_state->sr.fbc = 0;
|
||||
wm_state->hpll.fbc = 0;
|
||||
wm_state->fbc_en = false;
|
||||
}
|
||||
}
|
||||
|
||||
for_each_intel_crtc(&dev_priv->drm, crtc) {
|
||||
struct intel_crtc_state *crtc_state =
|
||||
to_intel_crtc_state(crtc->base.state);
|
||||
int ret;
|
||||
|
||||
ret = _g4x_compute_pipe_wm(crtc_state);
|
||||
drm_WARN_ON(&dev_priv->drm, ret);
|
||||
|
||||
crtc_state->wm.g4x.intermediate =
|
||||
crtc_state->wm.g4x.optimal;
|
||||
|
@ -4016,30 +4015,27 @@ void vlv_wm_sanitize(struct drm_i915_private *dev_priv)
|
|||
to_intel_crtc_state(crtc->base.state);
|
||||
struct intel_plane_state *plane_state =
|
||||
to_intel_plane_state(plane->base.state);
|
||||
struct vlv_wm_state *wm_state = &crtc_state->wm.vlv.optimal;
|
||||
const struct vlv_fifo_state *fifo_state =
|
||||
&crtc_state->wm.vlv.fifo_state;
|
||||
enum plane_id plane_id = plane->id;
|
||||
int level;
|
||||
int level, num_levels = intel_wm_num_levels(dev_priv);
|
||||
|
||||
if (plane_state->uapi.visible)
|
||||
continue;
|
||||
|
||||
for (level = 0; level < wm_state->num_levels; level++) {
|
||||
for (level = 0; level < num_levels; level++) {
|
||||
struct g4x_pipe_wm *raw =
|
||||
&crtc_state->wm.vlv.raw[level];
|
||||
|
||||
raw->plane[plane_id] = 0;
|
||||
|
||||
wm_state->wm[level].plane[plane_id] =
|
||||
vlv_invert_wm_value(raw->plane[plane_id],
|
||||
fifo_state->plane[plane_id]);
|
||||
}
|
||||
}
|
||||
|
||||
for_each_intel_crtc(&dev_priv->drm, crtc) {
|
||||
struct intel_crtc_state *crtc_state =
|
||||
to_intel_crtc_state(crtc->base.state);
|
||||
int ret;
|
||||
|
||||
ret = _vlv_compute_pipe_wm(crtc_state);
|
||||
drm_WARN_ON(&dev_priv->drm, ret);
|
||||
|
||||
crtc_state->wm.vlv.intermediate =
|
||||
crtc_state->wm.vlv.optimal;
|
||||
|
@ -4117,7 +4113,7 @@ static void g4x_disable_trickle_feed(struct drm_i915_private *dev_priv)
|
|||
intel_uncore_read(&dev_priv->uncore, DSPCNTR(pipe)) |
|
||||
DISP_TRICKLE_FEED_DISABLE);
|
||||
|
||||
intel_uncore_write(&dev_priv->uncore, DSPSURF(pipe), intel_uncore_read(&dev_priv->uncore, DSPSURF(pipe)));
|
||||
intel_uncore_rmw(&dev_priv->uncore, DSPSURF(pipe), 0, 0);
|
||||
intel_uncore_posting_read(&dev_priv->uncore, DSPSURF(pipe));
|
||||
}
|
||||
}
|
||||
|
@ -4325,8 +4321,8 @@ static void gen8_set_l3sqc_credits(struct drm_i915_private *dev_priv,
|
|||
u32 val;
|
||||
|
||||
/* WaTempDisableDOPClkGating:bdw */
|
||||
misccpctl = intel_uncore_read(&dev_priv->uncore, GEN7_MISCCPCTL);
|
||||
intel_uncore_write(&dev_priv->uncore, GEN7_MISCCPCTL, misccpctl & ~GEN7_DOP_CLOCK_GATE_ENABLE);
|
||||
misccpctl = intel_uncore_rmw(&dev_priv->uncore, GEN7_MISCCPCTL,
|
||||
GEN7_DOP_CLOCK_GATE_ENABLE, 0);
|
||||
|
||||
val = intel_uncore_read(&dev_priv->uncore, GEN8_L3SQCREG1);
|
||||
val &= ~L3_PRIO_CREDITS_MASK;
|
||||
|
@ -4605,8 +4601,6 @@ static void hsw_init_clock_gating(struct drm_i915_private *dev_priv)
|
|||
|
||||
static void ivb_init_clock_gating(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
u32 snpcr;
|
||||
|
||||
intel_uncore_write(&dev_priv->uncore, ILK_DSPCLK_GATE_D, ILK_VRHUNIT_CLOCK_GATE_DISABLE);
|
||||
|
||||
/* WaFbcAsynchFlipDisableFbcQueue:ivb */
|
||||
|
@ -4644,10 +4638,8 @@ static void ivb_init_clock_gating(struct drm_i915_private *dev_priv)
|
|||
|
||||
g4x_disable_trickle_feed(dev_priv);
|
||||
|
||||
snpcr = intel_uncore_read(&dev_priv->uncore, GEN6_MBCUNIT_SNPCR);
|
||||
snpcr &= ~GEN6_MBC_SNPCR_MASK;
|
||||
snpcr |= GEN6_MBC_SNPCR_MED;
|
||||
intel_uncore_write(&dev_priv->uncore, GEN6_MBCUNIT_SNPCR, snpcr);
|
||||
intel_uncore_rmw(&dev_priv->uncore, GEN6_MBCUNIT_SNPCR, GEN6_MBC_SNPCR_MASK,
|
||||
GEN6_MBC_SNPCR_MED);
|
||||
|
||||
if (!HAS_PCH_NOP(dev_priv))
|
||||
cpt_init_clock_gating(dev_priv);
|
||||
|
|
|
@ -591,8 +591,15 @@ void intel_runtime_pm_enable(struct intel_runtime_pm *rpm)
|
|||
pm_runtime_use_autosuspend(kdev);
|
||||
}
|
||||
|
||||
/* Enable by default */
|
||||
pm_runtime_allow(kdev);
|
||||
/*
|
||||
* FIXME: Temp hammer to keep autosupend disable on lmem supported platforms.
|
||||
* As per PCIe specs 5.3.1.4.1, all iomem read write request over a PCIe
|
||||
* function will be unsupported in case PCIe endpoint function is in D3.
|
||||
* Let's keep i915 autosuspend control 'on' till we fix all known issue
|
||||
* with lmem access in D3.
|
||||
*/
|
||||
if (!IS_DGFX(i915))
|
||||
pm_runtime_allow(kdev);
|
||||
|
||||
/*
|
||||
* The core calls the driver load handler with an RPM reference held.
|
||||
|
|
|
@ -135,6 +135,19 @@ static const struct intel_step_info adlp_n_revids[] = {
|
|||
[0x0] = { COMMON_GT_MEDIA_STEP(A0), .display_step = STEP_D0 },
|
||||
};
|
||||
|
||||
static u8 gmd_to_intel_step(struct drm_i915_private *i915,
|
||||
struct intel_ip_version *gmd)
|
||||
{
|
||||
u8 step = gmd->step + STEP_A0;
|
||||
|
||||
if (step >= STEP_FUTURE) {
|
||||
drm_dbg(&i915->drm, "Using future steppings\n");
|
||||
return STEP_FUTURE;
|
||||
}
|
||||
|
||||
return step;
|
||||
}
|
||||
|
||||
static void pvc_step_init(struct drm_i915_private *i915, int pci_revid);
|
||||
|
||||
void intel_step_init(struct drm_i915_private *i915)
|
||||
|
@ -144,6 +157,18 @@ void intel_step_init(struct drm_i915_private *i915)
|
|||
int revid = INTEL_REVID(i915);
|
||||
struct intel_step_info step = {};
|
||||
|
||||
if (HAS_GMD_ID(i915)) {
|
||||
step.graphics_step = gmd_to_intel_step(i915,
|
||||
&RUNTIME_INFO(i915)->graphics.ip);
|
||||
step.media_step = gmd_to_intel_step(i915,
|
||||
&RUNTIME_INFO(i915)->media.ip);
|
||||
step.display_step = gmd_to_intel_step(i915,
|
||||
&RUNTIME_INFO(i915)->display.ip);
|
||||
RUNTIME_INFO(i915)->step = step;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (IS_PONTEVECCHIO(i915)) {
|
||||
pvc_step_init(i915, revid);
|
||||
return;
|
||||
|
|
|
@ -11,6 +11,10 @@
|
|||
struct drm_i915_private;
|
||||
|
||||
struct intel_step_info {
|
||||
/*
|
||||
* It is expected to have 4 number steps per letter. Deviation from
|
||||
* the expectation breaks gmd_to_intel_step().
|
||||
*/
|
||||
u8 graphics_step; /* Represents the compute tile on Xe_HPC */
|
||||
u8 display_step;
|
||||
u8 media_step;
|
||||
|
@ -23,21 +27,43 @@ struct intel_step_info {
|
|||
func(A0) \
|
||||
func(A1) \
|
||||
func(A2) \
|
||||
func(A3) \
|
||||
func(B0) \
|
||||
func(B1) \
|
||||
func(B2) \
|
||||
func(B3) \
|
||||
func(C0) \
|
||||
func(C1) \
|
||||
func(C2) \
|
||||
func(C3) \
|
||||
func(D0) \
|
||||
func(D1) \
|
||||
func(D2) \
|
||||
func(D3) \
|
||||
func(E0) \
|
||||
func(E1) \
|
||||
func(E2) \
|
||||
func(E3) \
|
||||
func(F0) \
|
||||
func(F1) \
|
||||
func(F2) \
|
||||
func(F3) \
|
||||
func(G0) \
|
||||
func(G1) \
|
||||
func(G2) \
|
||||
func(G3) \
|
||||
func(H0) \
|
||||
func(H1) \
|
||||
func(H2) \
|
||||
func(H3) \
|
||||
func(I0) \
|
||||
func(I1) \
|
||||
func(J0)
|
||||
func(I2) \
|
||||
func(I3) \
|
||||
func(J0) \
|
||||
func(J1) \
|
||||
func(J2) \
|
||||
func(J3)
|
||||
|
||||
/*
|
||||
* Symbolic steppings that do not match the hardware. These are valid both as gt
|
||||
|
|
|
@ -431,15 +431,15 @@ intel_uncore_read64_2x32(struct intel_uncore *uncore,
|
|||
#define intel_uncore_write64_fw(...) __raw_uncore_write64(__VA_ARGS__)
|
||||
#define intel_uncore_posting_read_fw(...) ((void)intel_uncore_read_fw(__VA_ARGS__))
|
||||
|
||||
static inline void intel_uncore_rmw(struct intel_uncore *uncore,
|
||||
i915_reg_t reg, u32 clear, u32 set)
|
||||
static inline u32 intel_uncore_rmw(struct intel_uncore *uncore,
|
||||
i915_reg_t reg, u32 clear, u32 set)
|
||||
{
|
||||
u32 old, val;
|
||||
|
||||
old = intel_uncore_read(uncore, reg);
|
||||
val = (old & ~clear) | set;
|
||||
if (val != old)
|
||||
intel_uncore_write(uncore, reg, val);
|
||||
intel_uncore_write(uncore, reg, val);
|
||||
return old;
|
||||
}
|
||||
|
||||
static inline void intel_uncore_rmw_fw(struct intel_uncore *uncore,
|
||||
|
|
|
@ -77,6 +77,7 @@ static int pxp_create_arb_session(struct intel_pxp *pxp)
|
|||
drm_err(>->i915->drm, "arb session failed to go in play\n");
|
||||
return ret;
|
||||
}
|
||||
drm_dbg(>->i915->drm, "PXP ARB session is alive\n");
|
||||
|
||||
if (!++pxp->key_instance)
|
||||
++pxp->key_instance;
|
||||
|
|
|
@ -174,6 +174,9 @@ int intel_pxp_tee_cmd_create_arb_session(struct intel_pxp *pxp,
|
|||
|
||||
if (ret)
|
||||
drm_err(&i915->drm, "Failed to send tee msg ret=[%d]\n", ret);
|
||||
else if (msg_out.header.status != 0x0)
|
||||
drm_warn(&i915->drm, "PXP firmware failed arb session init request ret=[0x%08x]\n",
|
||||
msg_out.header.status);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -194,7 +194,6 @@ static void vlv_restore_gunit_s0ix_state(struct drm_i915_private *i915)
|
|||
{
|
||||
struct vlv_s0ix_state *s = i915->vlv_s0ix_state;
|
||||
struct intel_uncore *uncore = &i915->uncore;
|
||||
u32 val;
|
||||
int i;
|
||||
|
||||
if (!s)
|
||||
|
@ -262,15 +261,11 @@ static void vlv_restore_gunit_s0ix_state(struct drm_i915_private *i915)
|
|||
* be restored, as they are used to control the s0ix suspend/resume
|
||||
* sequence by the caller.
|
||||
*/
|
||||
val = intel_uncore_read(uncore, VLV_GTLC_WAKE_CTRL);
|
||||
val &= VLV_GTLC_ALLOWWAKEREQ;
|
||||
val |= s->gtlc_wake_ctrl & ~VLV_GTLC_ALLOWWAKEREQ;
|
||||
intel_uncore_write(uncore, VLV_GTLC_WAKE_CTRL, val);
|
||||
intel_uncore_rmw(uncore, VLV_GTLC_WAKE_CTRL, ~VLV_GTLC_ALLOWWAKEREQ,
|
||||
s->gtlc_wake_ctrl & ~VLV_GTLC_ALLOWWAKEREQ);
|
||||
|
||||
val = intel_uncore_read(uncore, VLV_GTLC_SURVIVABILITY_REG);
|
||||
val &= VLV_GFX_CLK_FORCE_ON_BIT;
|
||||
val |= s->gtlc_survive & ~VLV_GFX_CLK_FORCE_ON_BIT;
|
||||
intel_uncore_write(uncore, VLV_GTLC_SURVIVABILITY_REG, val);
|
||||
intel_uncore_rmw(uncore, VLV_GTLC_SURVIVABILITY_REG, ~VLV_GFX_CLK_FORCE_ON_BIT,
|
||||
s->gtlc_survive & ~VLV_GFX_CLK_FORCE_ON_BIT);
|
||||
|
||||
intel_uncore_write(uncore, VLV_PMWGICZ, s->pmwgicz);
|
||||
|
||||
|
@ -308,14 +303,10 @@ static int vlv_wait_for_pw_status(struct drm_i915_private *i915,
|
|||
static int vlv_force_gfx_clock(struct drm_i915_private *i915, bool force_on)
|
||||
{
|
||||
struct intel_uncore *uncore = &i915->uncore;
|
||||
u32 val;
|
||||
int err;
|
||||
|
||||
val = intel_uncore_read(uncore, VLV_GTLC_SURVIVABILITY_REG);
|
||||
val &= ~VLV_GFX_CLK_FORCE_ON_BIT;
|
||||
if (force_on)
|
||||
val |= VLV_GFX_CLK_FORCE_ON_BIT;
|
||||
intel_uncore_write(uncore, VLV_GTLC_SURVIVABILITY_REG, val);
|
||||
intel_uncore_rmw(uncore, VLV_GTLC_SURVIVABILITY_REG, VLV_GFX_CLK_FORCE_ON_BIT,
|
||||
force_on ? VLV_GFX_CLK_FORCE_ON_BIT : 0);
|
||||
|
||||
if (!force_on)
|
||||
return 0;
|
||||
|
@ -340,11 +331,8 @@ static int vlv_allow_gt_wake(struct drm_i915_private *i915, bool allow)
|
|||
u32 val;
|
||||
int err;
|
||||
|
||||
val = intel_uncore_read(uncore, VLV_GTLC_WAKE_CTRL);
|
||||
val &= ~VLV_GTLC_ALLOWWAKEREQ;
|
||||
if (allow)
|
||||
val |= VLV_GTLC_ALLOWWAKEREQ;
|
||||
intel_uncore_write(uncore, VLV_GTLC_WAKE_CTRL, val);
|
||||
intel_uncore_rmw(uncore, VLV_GTLC_WAKE_CTRL, VLV_GTLC_ALLOWWAKEREQ,
|
||||
allow ? VLV_GTLC_ALLOWWAKEREQ : 0);
|
||||
intel_uncore_posting_read(uncore, VLV_GTLC_WAKE_CTRL);
|
||||
|
||||
mask = VLV_GTLC_ALLOWWAKEACK;
|
||||
|
|
Loading…
Reference in a new issue