diff options
Diffstat (limited to 'drivers/gpu')
64 files changed, 3108 insertions, 1474 deletions
diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig index c6e3792622f2..9c0990c0ec87 100644 --- a/drivers/gpu/drm/i915/Kconfig +++ b/drivers/gpu/drm/i915/Kconfig @@ -56,24 +56,33 @@ config DRM_I915 If "M" is selected, the module will be called i915. config DRM_I915_FORCE_PROBE - string "Force probe driver for selected new Intel hardware" + string "Force probe i915 for selected Intel hardware IDs" depends on DRM_I915 help This is the default value for the i915.force_probe module parameter. Using the module parameter overrides this option. - Force probe the driver for new Intel graphics devices that are + Force probe the i915 for Intel graphics devices that are recognized but not properly supported by this kernel version. It is recommended to upgrade to a kernel version with proper support as soon as it is available. + It can also be used to block the probe of recognized and fully + supported devices. + Use "" to disable force probe. If in doubt, use this. - Use "<pci-id>[,<pci-id>,...]" to force probe the driver for listed + Use "<pci-id>[,<pci-id>,...]" to force probe the i915 for listed devices. For example, "4500" or "4500,4571". Use "*" to force probe the driver for all known devices. + Use "!" right before the ID to block the probe of the device. For + example, "4500,!4571" forces the probe of 4500 and blocks the probe of + 4571. + + Use "!*" to block the probe of the driver for all known devices. + config DRM_I915_CAPTURE_ERROR bool "Enable capturing GPU state following a hang" depends on DRM_I915 diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 01974b82d205..7046e435a155 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -48,9 +48,7 @@ i915-y += i915_driver.o \ i915_sysfs.o \ i915_utils.o \ intel_device_info.o \ - intel_dram.o \ intel_memory_region.o \ - intel_pch.o \ intel_pcode.o \ intel_pm.o \ intel_region_ttm.o \ @@ -62,6 +60,11 @@ i915-y += i915_driver.o \ vlv_sideband.o \ vlv_suspend.o +# core peripheral code +i915-y += \ + soc/intel_dram.o \ + soc/intel_pch.o + # core library code i915-y += \ i915_memcpy.o \ diff --git a/drivers/gpu/drm/i915/display/dvo_ch7xxx.c b/drivers/gpu/drm/i915/display/dvo_ch7xxx.c index 54f58ba44b9f..6d948520e9a6 100644 --- a/drivers/gpu/drm/i915/display/dvo_ch7xxx.c +++ b/drivers/gpu/drm/i915/display/dvo_ch7xxx.c @@ -50,15 +50,26 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define CH7xxx_INPUT_CLOCK 0x1d #define CH7xxx_GPIO 0x1e #define CH7xxx_GPIO_HPIR (1<<3) -#define CH7xxx_IDF 0x1f +#define CH7xxx_IDF 0x1f +#define CH7xxx_IDF_IBS (1<<7) +#define CH7xxx_IDF_DES (1<<6) #define CH7xxx_IDF_HSP (1<<3) #define CH7xxx_IDF_VSP (1<<4) #define CH7xxx_CONNECTION_DETECT 0x20 #define CH7xxx_CDET_DVI (1<<5) -#define CH7301_DAC_CNTL 0x21 +#define CH7xxx_DAC_CNTL 0x21 +#define CH7xxx_SYNCO_MASK (3 << 3) +#define CH7xxx_SYNCO_VGA_HSYNC (1 << 3) + +#define CH7xxx_CLOCK_OUTPUT 0x22 +#define CH7xxx_BCOEN (1 << 4) +#define CH7xxx_BCOP (1 << 3) +#define CH7xxx_BCO_MASK (7 << 0) +#define CH7xxx_BCO_VGA_VSYNC (6 << 0) + #define CH7301_HOTPLUG 0x23 #define CH7xxx_TCTL 0x31 #define CH7xxx_TVCO 0x32 @@ -301,6 +312,8 @@ static void ch7xxx_mode_set(struct intel_dvo_device *dvo, ch7xxx_readb(dvo, CH7xxx_IDF, &idf); + idf |= CH7xxx_IDF_IBS; + idf &= ~(CH7xxx_IDF_HSP | CH7xxx_IDF_VSP); if (mode->flags & DRM_MODE_FLAG_PHSYNC) idf |= CH7xxx_IDF_HSP; @@ -309,6 +322,11 @@ static void ch7xxx_mode_set(struct intel_dvo_device *dvo, idf |= CH7xxx_IDF_VSP; ch7xxx_writeb(dvo, CH7xxx_IDF, idf); + + ch7xxx_writeb(dvo, CH7xxx_DAC_CNTL, + CH7xxx_SYNCO_VGA_HSYNC); + ch7xxx_writeb(dvo, CH7xxx_CLOCK_OUTPUT, + CH7xxx_BCOEN | CH7xxx_BCO_VGA_VSYNC); } /* set the CH7xxx power state */ diff --git a/drivers/gpu/drm/i915/display/dvo_sil164.c b/drivers/gpu/drm/i915/display/dvo_sil164.c index 0dfa0a0209ff..4acc8ce29c0b 100644 --- a/drivers/gpu/drm/i915/display/dvo_sil164.c +++ b/drivers/gpu/drm/i915/display/dvo_sil164.c @@ -58,6 +58,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define SIL164_9_MDI (1<<0) #define SIL164_REGC 0x0c +#define SIL164_C_SCNT (1<<7) +#define SIL164_C_PLLF_MASK (0xf<<1) +#define SIL164_C_PLLF_REC (4<<1) +#define SIL164_C_PFEN (1<<0) struct sil164_priv { //I2CDevRec d; @@ -205,7 +209,13 @@ static void sil164_mode_set(struct intel_dvo_device *dvo, sil164_writeb(sil, 0x0c, 0x89); sil164_writeb(sil, 0x08, 0x31);*/ /* don't do much */ - return; + + sil164_writeb(dvo, SIL164_REG8, + SIL164_8_VEN | SIL164_8_HEN); + sil164_writeb(dvo, SIL164_REG9, + SIL164_9_TSEL); + sil164_writeb(dvo, SIL164_REGC, + SIL164_C_PLLF_REC | SIL164_C_PFEN); } /* set the SIL164 power state */ @@ -224,7 +234,6 @@ static void sil164_dpms(struct intel_dvo_device *dvo, bool enable) ch &= ~SIL164_8_PD; sil164_writeb(dvo, SIL164_REG8, ch); - return; } static bool sil164_get_hw_state(struct intel_dvo_device *dvo) diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c index d16b30a2dded..ae14c794c4bc 100644 --- a/drivers/gpu/drm/i915/display/icl_dsi.c +++ b/drivers/gpu/drm/i915/display/icl_dsi.c @@ -2043,7 +2043,7 @@ void icl_dsi_init(struct drm_i915_private *dev_priv) /* attach connector to encoder */ intel_connector_attach_encoder(intel_connector, encoder); - intel_bios_init_panel(dev_priv, &intel_connector->panel, NULL, NULL); + intel_bios_init_panel_late(dev_priv, &intel_connector->panel, NULL, NULL); mutex_lock(&dev_priv->drm.mode_config.mutex); intel_panel_add_vbt_lfp_fixed_mode(intel_connector); diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c index 6621aa245caf..a9a3f3715279 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic.c +++ b/drivers/gpu/drm/i915/display/intel_atomic.c @@ -41,6 +41,7 @@ #include "intel_global_state.h" #include "intel_hdcp.h" #include "intel_psr.h" +#include "intel_fb.h" #include "skl_universal_plane.h" /** @@ -310,11 +311,11 @@ intel_crtc_destroy_state(struct drm_crtc *crtc, kfree(crtc_state); } -static void intel_atomic_setup_scaler(struct intel_crtc_scaler_state *scaler_state, - int num_scalers_need, struct intel_crtc *intel_crtc, - const char *name, int idx, - struct intel_plane_state *plane_state, - int *scaler_id) +static int intel_atomic_setup_scaler(struct intel_crtc_scaler_state *scaler_state, + int num_scalers_need, struct intel_crtc *intel_crtc, + const char *name, int idx, + struct intel_plane_state *plane_state, + int *scaler_id) { struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev); int j; @@ -334,7 +335,7 @@ static void intel_atomic_setup_scaler(struct intel_crtc_scaler_state *scaler_sta if (drm_WARN(&dev_priv->drm, *scaler_id < 0, "Cannot find scaler for %s:%d\n", name, idx)) - return; + return -EINVAL; /* set scaler mode */ if (plane_state && plane_state->hw.fb && @@ -375,9 +376,71 @@ static void intel_atomic_setup_scaler(struct intel_crtc_scaler_state *scaler_sta mode = SKL_PS_SCALER_MODE_DYN; } + /* + * FIXME: we should also check the scaler factors for pfit, so + * this shouldn't be tied directly to planes. + */ + if (plane_state && plane_state->hw.fb) { + const struct drm_framebuffer *fb = plane_state->hw.fb; + const struct drm_rect *src = &plane_state->uapi.src; + const struct drm_rect *dst = &plane_state->uapi.dst; + int hscale, vscale, max_vscale, max_hscale; + + /* + * FIXME: When two scalers are needed, but only one of + * them needs to downscale, we should make sure that + * the one that needs downscaling support is assigned + * as the first scaler, so we don't reject downscaling + * unnecessarily. + */ + + if (DISPLAY_VER(dev_priv) >= 14) { + /* + * On versions 14 and up, only the first + * scaler supports a vertical scaling factor + * of more than 1.0, while a horizontal + * scaling factor of 3.0 is supported. + */ + max_hscale = 0x30000 - 1; + if (*scaler_id == 0) + max_vscale = 0x30000 - 1; + else + max_vscale = 0x10000; + + } else if (DISPLAY_VER(dev_priv) >= 10 || + !intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier)) { + max_hscale = 0x30000 - 1; + max_vscale = 0x30000 - 1; + } else { + max_hscale = 0x20000 - 1; + max_vscale = 0x20000 - 1; + } + + /* + * FIXME: We should change the if-else block above to + * support HQ vs dynamic scaler properly. + */ + + /* Check if required scaling is within limits */ + hscale = drm_rect_calc_hscale(src, dst, 1, max_hscale); + vscale = drm_rect_calc_vscale(src, dst, 1, max_vscale); + + if (hscale < 0 || vscale < 0) { + drm_dbg_kms(&dev_priv->drm, + "Scaler %d doesn't support required plane scaling\n", + *scaler_id); + drm_rect_debug_print("src: ", src, true); + drm_rect_debug_print("dst: ", dst, false); + + return -EINVAL; + } + } + drm_dbg_kms(&dev_priv->drm, "Attached scaler id %u.%u to %s:%d\n", intel_crtc->pipe, *scaler_id, name, idx); scaler_state->scalers[*scaler_id].mode = mode; + + return 0; } /** @@ -437,7 +500,7 @@ int intel_atomic_setup_scalers(struct drm_i915_private *dev_priv, for (i = 0; i < sizeof(scaler_state->scaler_users) * 8; i++) { int *scaler_id; const char *name; - int idx; + int idx, ret; /* skip if scaler not required */ if (!(scaler_state->scaler_users & (1 << i))) @@ -494,9 +557,11 @@ int intel_atomic_setup_scalers(struct drm_i915_private *dev_priv, scaler_id = &plane_state->scaler_id; } - intel_atomic_setup_scaler(scaler_state, num_scalers_need, - intel_crtc, name, idx, - plane_state, scaler_id); + ret = intel_atomic_setup_scaler(scaler_state, num_scalers_need, + intel_crtc, name, idx, + plane_state, scaler_id); + if (ret < 0) + return ret; } return 0; diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c index 98c3322b4549..626c47e96a6d 100644 --- a/drivers/gpu/drm/i915/display/intel_audio.c +++ b/drivers/gpu/drm/i915/display/intel_audio.c @@ -798,6 +798,17 @@ static void ilk_audio_codec_enable(struct intel_encoder *encoder, mutex_unlock(&i915->display.audio.mutex); } +void intel_audio_sdp_split_update(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state) +{ + struct drm_i915_private *i915 = to_i915(encoder->base.dev); + enum transcoder trans = crtc_state->cpu_transcoder; + + if (HAS_DP20(i915)) + intel_de_rmw(i915, AUD_DP_2DOT0_CTRL(trans), AUD_ENABLE_SDP_SPLIT, + crtc_state->sdp_split_enable ? AUD_ENABLE_SDP_SPLIT : 0); +} + /** * intel_audio_codec_enable - Enable the audio codec for HD audio * @encoder: encoder on which to enable audio diff --git a/drivers/gpu/drm/i915/display/intel_audio.h b/drivers/gpu/drm/i915/display/intel_audio.h index 63b22131dc45..1b87257c6a17 100644 --- a/drivers/gpu/drm/i915/display/intel_audio.h +++ b/drivers/gpu/drm/i915/display/intel_audio.h @@ -22,5 +22,7 @@ void intel_audio_cdclk_change_pre(struct drm_i915_private *dev_priv); void intel_audio_cdclk_change_post(struct drm_i915_private *dev_priv); void intel_audio_init(struct drm_i915_private *dev_priv); void intel_audio_deinit(struct drm_i915_private *dev_priv); +void intel_audio_sdp_split_update(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state); #endif /* __INTEL_AUDIO_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_backlight.c b/drivers/gpu/drm/i915/display/intel_backlight.c index 71af88a70461..5b7da72c95b8 100644 --- a/drivers/gpu/drm/i915/display/intel_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_backlight.c @@ -83,16 +83,16 @@ static u32 scale_hw_to_user(struct intel_connector *connector, u32 intel_backlight_invert_pwm_level(struct intel_connector *connector, u32 val) { - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct drm_i915_private *i915 = to_i915(connector->base.dev); struct intel_panel *panel = &connector->panel; - drm_WARN_ON(&dev_priv->drm, panel->backlight.pwm_level_max == 0); + drm_WARN_ON(&i915->drm, panel->backlight.pwm_level_max == 0); - if (dev_priv->params.invert_brightness < 0) + if (i915->params.invert_brightness < 0) return val; - if (dev_priv->params.invert_brightness > 0 || - intel_has_quirk(dev_priv, QUIRK_INVERT_BRIGHTNESS)) { + if (i915->params.invert_brightness > 0 || + intel_has_quirk(i915, QUIRK_INVERT_BRIGHTNESS)) { return panel->backlight.pwm_level_max - val + panel->backlight.pwm_level_min; } @@ -111,10 +111,10 @@ void intel_backlight_set_pwm_level(const struct drm_connector_state *conn_state, u32 intel_backlight_level_to_pwm(struct intel_connector *connector, u32 val) { - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct drm_i915_private *i915 = to_i915(connector->base.dev); struct intel_panel *panel = &connector->panel; - drm_WARN_ON_ONCE(&dev_priv->drm, + drm_WARN_ON_ONCE(&i915->drm, panel->backlight.max == 0 || panel->backlight.pwm_level_max == 0); val = scale(val, panel->backlight.min, panel->backlight.max, @@ -125,14 +125,14 @@ u32 intel_backlight_level_to_pwm(struct intel_connector *connector, u32 val) u32 intel_backlight_level_from_pwm(struct intel_connector *connector, u32 val) { - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct drm_i915_private *i915 = to_i915(connector->base.dev); struct intel_panel *panel = &connector->panel; - drm_WARN_ON_ONCE(&dev_priv->drm, + drm_WARN_ON_ONCE(&i915->drm, panel->backlight.max == 0 || panel->backlight.pwm_level_max == 0); - if (dev_priv->params.invert_brightness > 0 || - (dev_priv->params.invert_brightness == 0 && intel_has_quirk(dev_priv, QUIRK_INVERT_BRIGHTNESS))) + if (i915->params.invert_brightness > 0 || + (i915->params.invert_brightness == 0 && intel_has_quirk(i915, QUIRK_INVERT_BRIGHTNESS))) val = panel->backlight.pwm_level_max - (val - panel->backlight.pwm_level_min); return scale(val, panel->backlight.pwm_level_min, panel->backlight.pwm_level_max, @@ -141,32 +141,32 @@ u32 intel_backlight_level_from_pwm(struct intel_connector *connector, u32 val) static u32 lpt_get_backlight(struct intel_connector *connector, enum pipe unused) { - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct drm_i915_private *i915 = to_i915(connector->base.dev); - return intel_de_read(dev_priv, BLC_PWM_PCH_CTL2) & BACKLIGHT_DUTY_CYCLE_MASK; + return intel_de_read(i915, BLC_PWM_PCH_CTL2) & BACKLIGHT_DUTY_CYCLE_MASK; } static u32 pch_get_backlight(struct intel_connector *connector, enum pipe unused) { - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct drm_i915_private *i915 = to_i915(connector->base.dev); - return intel_de_read(dev_priv, BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; + return intel_de_read(i915, BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; } static u32 i9xx_get_backlight(struct intel_connector *connector, enum pipe unused) { - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct drm_i915_private *i915 = to_i915(connector->base.dev); struct intel_panel *panel = &connector->panel; u32 val; - val = intel_de_read(dev_priv, BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; - if (DISPLAY_VER(dev_priv) < 4) + val = intel_de_read(i915, BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; + if (DISPLAY_VER(i915) < 4) val >>= 1; if (panel->backlight.combination_mode) { u8 lbpc; - pci_read_config_byte(to_pci_dev(dev_priv->drm.dev), LBPC, &lbpc); + pci_read_config_byte(to_pci_dev(i915->drm.dev), LBPC, &lbpc); val *= lbpc; } @@ -175,21 +175,20 @@ static u32 i9xx_get_backlight(struct intel_connector *connector, enum pipe unuse static u32 vlv_get_backlight(struct intel_connector *connector, enum pipe pipe) { - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct drm_i915_private *i915 = to_i915(connector->base.dev); - if (drm_WARN_ON(&dev_priv->drm, pipe != PIPE_A && pipe != PIPE_B)) + if (drm_WARN_ON(&i915->drm, pipe != PIPE_A && pipe != PIPE_B)) return 0; - return intel_de_read(dev_priv, VLV_BLC_PWM_CTL(pipe)) & BACKLIGHT_DUTY_CYCLE_MASK; + return intel_de_read(i915, VLV_BLC_PWM_CTL(pipe)) & BACKLIGHT_DUTY_CYCLE_MASK; } static u32 bxt_get_backlight(struct intel_connector *connector, enum pipe unused) { - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct drm_i915_private *i915 = to_i915(connector->base.dev); struct intel_panel *panel = &connector->panel; - return intel_de_read(dev_priv, - BXT_BLC_PWM_DUTY(panel->backlight.controller)); + return intel_de_read(i915, BXT_BLC_PWM_DUTY(panel->backlight.controller)); } static u32 ext_pwm_get_backlight(struct intel_connector *connector, enum pipe unused) @@ -204,69 +203,69 @@ static u32 ext_pwm_get_backlight(struct intel_connector *connector, enum pipe un static void lpt_set_backlight(const struct drm_connector_state *conn_state, u32 level) { struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct drm_i915_private *i915 = to_i915(connector->base.dev); + u32 val; - u32 val = intel_de_read(dev_priv, BLC_PWM_PCH_CTL2) & ~BACKLIGHT_DUTY_CYCLE_MASK; - intel_de_write(dev_priv, BLC_PWM_PCH_CTL2, val | level); + val = intel_de_read(i915, BLC_PWM_PCH_CTL2) & ~BACKLIGHT_DUTY_CYCLE_MASK; + intel_de_write(i915, BLC_PWM_PCH_CTL2, val | level); } static void pch_set_backlight(const struct drm_connector_state *conn_state, u32 level) { struct intel_connector *connector = to_intel_connector(conn_state->connector); - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct drm_i915_private *i915 = to_i915(connector->base.dev); u32 tmp; - tmp = intel_de_read(dev_priv, BLC_PWM_CPU_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK; |
