diff --git a/drivers/gpu/drm/display/drm_dp_tunnel.c b/drivers/gpu/drm/display/drm_dp_tunnel.c index bb67f1b83626..76c6bc84a806 100644 --- a/drivers/gpu/drm/display/drm_dp_tunnel.c +++ b/drivers/gpu/drm/display/drm_dp_tunnel.c @@ -149,6 +149,7 @@ struct drm_dp_tunnel { bool bw_alloc_enabled:1; bool has_io_error:1; bool destroyed:1; + bool pr_optimization_support:1; }; struct drm_dp_tunnel_group_state; @@ -508,6 +509,8 @@ create_tunnel(struct drm_dp_tunnel_mgr *mgr, tunnel->bw_alloc_supported = tunnel_reg_bw_alloc_supported(regs); tunnel->bw_alloc_enabled = tunnel_reg_bw_alloc_enabled(regs); + tunnel->pr_optimization_support = tunnel_reg(regs, DP_TUNNELING_CAPABILITIES) & + DP_PANEL_REPLAY_OPTIMIZATION_SUPPORT; if (!add_tunnel_to_group(mgr, drv_group_id, tunnel)) { kfree(tunnel); @@ -1036,6 +1039,20 @@ bool drm_dp_tunnel_bw_alloc_is_enabled(const struct drm_dp_tunnel *tunnel) } EXPORT_SYMBOL(drm_dp_tunnel_bw_alloc_is_enabled); +/** + * drm_dp_tunnel_pr_optimization_supported - Query the PR BW optimization support + * @tunnel: Tunnel object + * + * Query if the PR BW optimization is supported for @tunnel. + * + * Returns %true if the PR BW optimiation is supported for @tunnel. + */ +bool drm_dp_tunnel_pr_optimization_supported(const struct drm_dp_tunnel *tunnel) +{ + return tunnel && tunnel->pr_optimization_support; +} +EXPORT_SYMBOL(drm_dp_tunnel_pr_optimization_supported); + static int clear_bw_req_state(struct drm_dp_aux *aux) { u8 bw_req_mask = DP_BW_REQUEST_SUCCEEDED | DP_BW_REQUEST_FAILED; diff --git a/drivers/gpu/drm/i915/Kconfig.debug b/drivers/gpu/drm/i915/Kconfig.debug index 52a3a59b4ba2..028a2c97361d 100644 --- a/drivers/gpu/drm/i915/Kconfig.debug +++ b/drivers/gpu/drm/i915/Kconfig.debug @@ -153,7 +153,7 @@ config DRM_I915_TRACE_GTT config DRM_I915_SW_FENCE_DEBUG_OBJECTS bool "Enable additional driver debugging for fence objects" depends on DRM_I915 - select DEBUG_OBJECTS + depends on DEBUG_OBJECTS default n help Choose this option to turn on extra driver debugging that may affect diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index b677720a1c2d..07802a7f4ce5 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -80,6 +80,7 @@ i915-y += \ i915_display_pc8.o \ i915_dpt.o \ i915_dsb_buffer.o \ + i915_fb_pin.o \ i915_hdcp_gsc.o \ i915_initial_plane.o \ i915_overlay.o \ @@ -255,6 +256,7 @@ i915-y += \ display/intel_cursor.o \ display/intel_dbuf_bw.o \ display/intel_de.o \ + display/intel_display_clock_gating.o \ display/intel_display.o \ display/intel_display_conversion.o \ display/intel_display_driver.o \ @@ -279,7 +281,6 @@ i915-y += \ display/intel_drrs.o \ display/intel_dsb.o \ display/intel_fb.o \ - display/intel_fb_pin.o \ display/intel_fbc.o \ display/intel_fdi.o \ display/intel_fifo_underrun.o \ @@ -295,6 +296,7 @@ i915-y += \ display/intel_link_bw.o \ display/intel_load_detect.o \ display/intel_lpe_audio.o \ + display/intel_mchbar.o \ display/intel_modeset_lock.o \ display/intel_modeset_setup.o \ display/intel_modeset_verify.o \ @@ -325,8 +327,7 @@ i915-$(CONFIG_ACPI) += \ display/intel_acpi.o \ display/intel_opregion.o i915-$(CONFIG_DRM_FBDEV_EMULATION) += \ - display/intel_fbdev.o \ - display/intel_fbdev_fb.o + display/intel_fbdev.o i915-$(CONFIG_DEBUG_FS) += \ display/intel_display_debugfs.o \ display/intel_display_debugfs_params.o \ diff --git a/drivers/gpu/drm/i915/display/i9xx_display_sr.c b/drivers/gpu/drm/i915/display/i9xx_display_sr.c index 935419441709..1eb2f636cc65 100644 --- a/drivers/gpu/drm/i915/display/i9xx_display_sr.c +++ b/drivers/gpu/drm/i915/display/i9xx_display_sr.c @@ -4,13 +4,13 @@ */ #include +#include #include "i9xx_display_sr.h" #include "i9xx_wm_regs.h" #include "intel_de.h" #include "intel_display_regs.h" #include "intel_gmbus.h" -#include "intel_pci_config.h" static void i9xx_display_save_swf(struct intel_display *display) { diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c index 9c16753a1f3b..70734d32a409 100644 --- a/drivers/gpu/drm/i915/display/i9xx_plane.c +++ b/drivers/gpu/drm/i915/display/i9xx_plane.c @@ -1240,7 +1240,7 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc, fb->width, fb->height, fb->format->cpp[0] * 8, base, fb->pitches[0], plane_config->size); - plane_config->fb = intel_fb; + plane_config->fb = &intel_fb->base; } bool i9xx_fixup_initial_plane_config(struct intel_crtc *crtc, diff --git a/drivers/gpu/drm/i915/display/i9xx_wm.c b/drivers/gpu/drm/i915/display/i9xx_wm.c index ca7010da9419..33d8f6b6afea 100644 --- a/drivers/gpu/drm/i915/display/i9xx_wm.c +++ b/drivers/gpu/drm/i915/display/i9xx_wm.c @@ -19,7 +19,7 @@ #include "intel_display_utils.h" #include "intel_dram.h" #include "intel_fb.h" -#include "intel_mchbar_regs.h" +#include "intel_mchbar.h" #include "intel_wm.h" #include "skl_watermark.h" #include "vlv_sideband.h" @@ -118,41 +118,41 @@ static void chv_set_memory_dvfs(struct intel_display *display, bool enable) u32 val; int ret; - vlv_punit_get(display->drm); + vlv_punit_get(display); - val = vlv_punit_read(display->drm, PUNIT_REG_DDR_SETUP2); + val = vlv_punit_read(display, PUNIT_REG_DDR_SETUP2); if (enable) val &= ~FORCE_DDR_HIGH_FREQ; else val |= FORCE_DDR_HIGH_FREQ; val &= ~FORCE_DDR_LOW_FREQ; val |= FORCE_DDR_FREQ_REQ_ACK; - vlv_punit_write(display->drm, PUNIT_REG_DDR_SETUP2, val); + vlv_punit_write(display, PUNIT_REG_DDR_SETUP2, val); - ret = poll_timeout_us(val = vlv_punit_read(display->drm, PUNIT_REG_DDR_SETUP2), + ret = poll_timeout_us(val = vlv_punit_read(display, PUNIT_REG_DDR_SETUP2), (val & FORCE_DDR_FREQ_REQ_ACK) == 0, 500, 3000, false); if (ret) drm_err(display->drm, "timed out waiting for Punit DDR DVFS request\n"); - vlv_punit_put(display->drm); + vlv_punit_put(display); } static void chv_set_memory_pm5(struct intel_display *display, bool enable) { u32 val; - vlv_punit_get(display->drm); + vlv_punit_get(display); - val = vlv_punit_read(display->drm, PUNIT_REG_DSPSSPM); + val = vlv_punit_read(display, PUNIT_REG_DSPSSPM); if (enable) val |= DSP_MAXFIFO_PM5_ENABLE; else val &= ~DSP_MAXFIFO_PM5_ENABLE; - vlv_punit_write(display->drm, PUNIT_REG_DSPSSPM, val); + vlv_punit_write(display, PUNIT_REG_DSPSSPM, val); - vlv_punit_put(display->drm); + vlv_punit_put(display); } #define FW_WM(value, plane) \ @@ -2742,12 +2742,11 @@ static void ilk_compute_wm_level(struct intel_display *display, static void hsw_read_wm_latency(struct intel_display *display, u16 wm[]) { - struct intel_uncore *uncore = to_intel_uncore(display->drm); u64 sskpd; display->wm.num_levels = 5; - sskpd = intel_uncore_read64(uncore, MCH_SSKPD); + sskpd = intel_mchbar_read64_2x32(display, MCH_SSKPD); wm[0] = REG_FIELD_GET64(SSKPD_NEW_WM0_MASK_HSW, sskpd); if (wm[0] == 0) @@ -2760,12 +2759,11 @@ static void hsw_read_wm_latency(struct intel_display *display, u16 wm[]) static void snb_read_wm_latency(struct intel_display *display, u16 wm[]) { - struct intel_uncore *uncore = to_intel_uncore(display->drm); u32 sskpd; display->wm.num_levels = 4; - sskpd = intel_uncore_read(uncore, MCH_SSKPD); + sskpd = intel_mchbar_read(display, MCH_SSKPD); wm[0] = REG_FIELD_GET(SSKPD_WM0_MASK_SNB, sskpd); wm[1] = REG_FIELD_GET(SSKPD_WM1_MASK_SNB, sskpd); @@ -2775,12 +2773,11 @@ static void snb_read_wm_latency(struct intel_display *display, u16 wm[]) static void ilk_read_wm_latency(struct intel_display *display, u16 wm[]) { - struct intel_uncore *uncore = to_intel_uncore(display->drm); u32 mltr; display->wm.num_levels = 3; - mltr = intel_uncore_read(uncore, MLTR_ILK); + mltr = intel_mchbar_read(display, MLTR_ILK); /* ILK primary LP0 latency is 700 ns */ wm[0] = 7; @@ -3587,7 +3584,7 @@ void ilk_wm_sanitize(struct intel_display *display) int i; /* Only supported on platforms that use atomic watermark design */ - if (!display->funcs.wm->optimize_watermarks) + if (!display->wm.funcs->optimize_watermarks) return; if (drm_WARN_ON(display->drm, DISPLAY_VER(display) >= 9)) @@ -3918,9 +3915,9 @@ static void vlv_wm_get_hw_state(struct intel_display *display) wm->level = VLV_WM_LEVEL_PM2; if (display->platform.cherryview) { - vlv_punit_get(display->drm); + vlv_punit_get(display); - val = vlv_punit_read(display->drm, PUNIT_REG_DSPSSPM); + val = vlv_punit_read(display, PUNIT_REG_DSPSSPM); if (val & DSP_MAXFIFO_PM5_ENABLE) wm->level = VLV_WM_LEVEL_PM5; @@ -3933,11 +3930,11 @@ static void vlv_wm_get_hw_state(struct intel_display *display) * HIGH/LOW bits so that we don't actually change * the current state. */ - val = vlv_punit_read(display->drm, PUNIT_REG_DDR_SETUP2); + val = vlv_punit_read(display, PUNIT_REG_DDR_SETUP2); val |= FORCE_DDR_FREQ_REQ_ACK; - vlv_punit_write(display->drm, PUNIT_REG_DDR_SETUP2, val); + vlv_punit_write(display, PUNIT_REG_DDR_SETUP2, val); - ret = poll_timeout_us(val = vlv_punit_read(display->drm, PUNIT_REG_DDR_SETUP2), + ret = poll_timeout_us(val = vlv_punit_read(display, PUNIT_REG_DDR_SETUP2), (val & FORCE_DDR_FREQ_REQ_ACK) == 0, 500, 3000, false); if (ret) { @@ -3946,12 +3943,12 @@ static void vlv_wm_get_hw_state(struct intel_display *display) "assuming DDR DVFS is disabled\n"); display->wm.num_levels = VLV_WM_LEVEL_PM5 + 1; } else { - val = vlv_punit_read(display->drm, PUNIT_REG_DDR_SETUP2); + val = vlv_punit_read(display, PUNIT_REG_DDR_SETUP2); if ((val & FORCE_DDR_HIGH_FREQ) == 0) wm->level = VLV_WM_LEVEL_DDR_DVFS; } - vlv_punit_put(display->drm); + vlv_punit_put(display); } for_each_intel_crtc(display->drm, crtc) { @@ -4155,34 +4152,34 @@ void i9xx_wm_init(struct intel_display *display) /* For FIFO watermark updates */ if (HAS_PCH_SPLIT(display)) { ilk_setup_wm_latency(display); - display->funcs.wm = &ilk_wm_funcs; + display->wm.funcs = &ilk_wm_funcs; } else if (display->platform.valleyview || display->platform.cherryview) { vlv_setup_wm_latency(display); - display->funcs.wm = &vlv_wm_funcs; + display->wm.funcs = &vlv_wm_funcs; } else if (display->platform.g4x) { g4x_setup_wm_latency(display); - display->funcs.wm = &g4x_wm_funcs; + display->wm.funcs = &g4x_wm_funcs; } else if (display->platform.pineview) { if (!pnv_get_cxsr_latency(display)) { drm_info(display->drm, "Unknown FSB/MEM, disabling CxSR\n"); /* Disable CxSR and never update its watermark again */ intel_set_memory_cxsr(display, false); - display->funcs.wm = &nop_funcs; + display->wm.funcs = &nop_funcs; } else { - display->funcs.wm = &pnv_wm_funcs; + display->wm.funcs = &pnv_wm_funcs; } } else if (DISPLAY_VER(display) == 4) { - display->funcs.wm = &i965_wm_funcs; + display->wm.funcs = &i965_wm_funcs; } else if (DISPLAY_VER(display) == 3) { - display->funcs.wm = &i9xx_wm_funcs; + display->wm.funcs = &i9xx_wm_funcs; } else if (DISPLAY_VER(display) == 2) { if (INTEL_NUM_PIPES(display) == 1) - display->funcs.wm = &i845_wm_funcs; + display->wm.funcs = &i845_wm_funcs; else - display->funcs.wm = &i9xx_wm_funcs; + display->wm.funcs = &i9xx_wm_funcs; } else { drm_err(display->drm, "unexpected fall-through in %s\n", __func__); - display->funcs.wm = &nop_funcs; + display->wm.funcs = &nop_funcs; } } diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c index 8ff128fde7ea..0810facb80e1 100644 --- a/drivers/gpu/drm/i915/display/intel_audio.c +++ b/drivers/gpu/drm/i915/display/intel_audio.c @@ -754,10 +754,8 @@ void intel_audio_codec_enable(struct intel_encoder *encoder, crtc->base.base.id, crtc->base.name, drm_eld_size(crtc_state->eld)); - if (display->funcs.audio) - display->funcs.audio->audio_codec_enable(encoder, - crtc_state, - conn_state); + if (display->audio.funcs) + display->audio.funcs->audio_codec_enable(encoder, crtc_state, conn_state); mutex_lock(&display->audio.mutex); @@ -813,10 +811,8 @@ void intel_audio_codec_disable(struct intel_encoder *encoder, encoder->base.base.id, encoder->base.name, crtc->base.base.id, crtc->base.name); - if (display->funcs.audio) - display->funcs.audio->audio_codec_disable(encoder, - old_crtc_state, - old_conn_state); + if (display->audio.funcs) + display->audio.funcs->audio_codec_disable(encoder, old_crtc_state, old_conn_state); mutex_lock(&display->audio.mutex); @@ -864,8 +860,8 @@ void intel_audio_codec_get_config(struct intel_encoder *encoder, if (!crtc_state->has_audio) return; - if (display->funcs.audio) - display->funcs.audio->audio_codec_get_config(encoder, crtc_state); + if (display->audio.funcs) + display->audio.funcs->audio_codec_get_config(encoder, crtc_state); } static const struct intel_audio_funcs g4x_audio_funcs = { @@ -893,12 +889,12 @@ static const struct intel_audio_funcs hsw_audio_funcs = { void intel_audio_hooks_init(struct intel_display *display) { if (display->platform.g4x) - display->funcs.audio = &g4x_audio_funcs; + display->audio.funcs = &g4x_audio_funcs; else if (display->platform.valleyview || display->platform.cherryview || HAS_PCH_CPT(display) || HAS_PCH_IBX(display)) - display->funcs.audio = &ibx_audio_funcs; + display->audio.funcs = &ibx_audio_funcs; else if (display->platform.haswell || DISPLAY_VER(display) >= 8) - display->funcs.audio = &hsw_audio_funcs; + display->audio.funcs = &hsw_audio_funcs; } struct aud_ts_cdclk_m_n { diff --git a/drivers/gpu/drm/i915/display/intel_backlight.c b/drivers/gpu/drm/i915/display/intel_backlight.c index 34e95f05936e..b128896cb1c2 100644 --- a/drivers/gpu/drm/i915/display/intel_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_backlight.c @@ -11,6 +11,7 @@ #include #include +#include #include "intel_backlight.h" #include "intel_backlight_regs.h" @@ -23,7 +24,6 @@ #include "intel_dp_aux_backlight.h" #include "intel_dsi_dcs_backlight.h" #include "intel_panel.h" -#include "intel_pci_config.h" #include "intel_pps.h" #include "intel_quirks.h" diff --git a/drivers/gpu/drm/i915/display/intel_bo.c b/drivers/gpu/drm/i915/display/intel_bo.c index 3b82d38a0504..8ecdbb7e39f3 100644 --- a/drivers/gpu/drm/i915/display/intel_bo.c +++ b/drivers/gpu/drm/i915/display/intel_bo.c @@ -85,3 +85,30 @@ struct drm_gem_object *intel_bo_framebuffer_lookup(struct intel_display *display { return display->parent->bo->framebuffer_lookup(display->drm, filp, user_mode_cmd); } + +#if IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION) +u32 intel_bo_fbdev_pitch_align(struct intel_display *display, u32 stride) +{ + return display->parent->bo->fbdev_pitch_align(stride); +} + +struct drm_gem_object *intel_bo_fbdev_create(struct intel_display *display, int size) +{ + return display->parent->bo->fbdev_create(display->drm, size); +} + +void intel_bo_fbdev_destroy(struct drm_gem_object *obj) +{ + struct intel_display *display = to_intel_display(obj->dev); + + display->parent->bo->fbdev_destroy(obj); +} + +int intel_bo_fbdev_fill_info(struct drm_gem_object *obj, struct fb_info *info, + struct i915_vma *vma) +{ + struct intel_display *display = to_intel_display(obj->dev); + + return display->parent->bo->fbdev_fill_info(obj, info, vma); +} +#endif diff --git a/drivers/gpu/drm/i915/display/intel_bo.h b/drivers/gpu/drm/i915/display/intel_bo.h index aec188c706c2..348f7fa66960 100644 --- a/drivers/gpu/drm/i915/display/intel_bo.h +++ b/drivers/gpu/drm/i915/display/intel_bo.h @@ -10,6 +10,8 @@ struct drm_file; struct drm_gem_object; struct drm_mode_fb_cmd2; struct drm_scanout_buffer; +struct fb_info; +struct i915_vma; struct intel_display; struct intel_framebuffer; struct seq_file; @@ -31,4 +33,10 @@ struct drm_gem_object *intel_bo_framebuffer_lookup(struct intel_display *display struct drm_file *filp, const struct drm_mode_fb_cmd2 *user_mode_cmd); +u32 intel_bo_fbdev_pitch_align(struct intel_display *display, u32 stride); +struct drm_gem_object *intel_bo_fbdev_create(struct intel_display *display, int size); +void intel_bo_fbdev_destroy(struct drm_gem_object *obj); +int intel_bo_fbdev_fill_info(struct drm_gem_object *obj, struct fb_info *info, + struct i915_vma *vma); + #endif /* __INTEL_BO__ */ diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index 07b4531a4376..9c3a9bbb49f6 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -9,14 +9,14 @@ #include "intel_bw.h" #include "intel_crtc.h" +#include "intel_de.h" #include "intel_display_core.h" #include "intel_display_regs.h" #include "intel_display_types.h" #include "intel_display_utils.h" #include "intel_dram.h" -#include "intel_mchbar_regs.h" +#include "intel_mchbar.h" #include "intel_parent.h" -#include "intel_uncore.h" #include "skl_watermark.h" struct intel_bw_state { @@ -28,9 +28,6 @@ struct intel_bw_state { */ u8 pipe_sagv_reject; - /* bitmask of active pipes */ - u8 active_pipes; - /* * From MTL onwards, to lock a QGV point, punit expects the peak BW of * the selected QGV point as the parameter in multiples of 100MB/s @@ -74,11 +71,10 @@ static int dg1_mchbar_read_qgv_point_info(struct intel_display *display, struct intel_qgv_point *sp, int point) { - struct intel_uncore *uncore = to_intel_uncore(display->drm); u32 dclk_ratio, dclk_reference; u32 val; - val = intel_uncore_read(uncore, SA_PERF_STATUS_0_0_0_MCHBAR_PC); + val = intel_mchbar_read(display, SA_PERF_STATUS_0_0_0_MCHBAR_PC); dclk_ratio = REG_FIELD_GET(DG1_QCLK_RATIO_MASK, val); if (val & DG1_QCLK_REFERENCE) dclk_reference = 6; /* 6 * 16.666 MHz = 100 MHz */ @@ -86,18 +82,18 @@ static int dg1_mchbar_read_qgv_point_info(struct intel_display *display, dclk_reference = 8; /* 8 * 16.666 MHz = 133 MHz */ sp->dclk = DIV_ROUND_UP((16667 * dclk_ratio * dclk_reference) + 500, 1000); - val = intel_uncore_read(uncore, SKL_MC_BIOS_DATA_0_0_0_MCHBAR_PCU); + val = intel_mchbar_read(display, SKL_MC_BIOS_DATA_0_0_0_MCHBAR_PCU); if (val & DG1_GEAR_TYPE) sp->dclk *= 2; if (sp->dclk == 0) return -EINVAL; - val = intel_uncore_read(uncore, MCHBAR_CH0_CR_TC_PRE_0_0_0_MCHBAR); + val = intel_mchbar_read(display, MCHBAR_CH0_CR_TC_PRE_0_0_0_MCHBAR); sp->t_rp = REG_FIELD_GET(DG1_DRAM_T_RP_MASK, val); sp->t_rdpre = REG_FIELD_GET(DG1_DRAM_T_RDPRE_MASK, val); - val = intel_uncore_read(uncore, MCHBAR_CH0_CR_TC_PRE_0_0_0_MCHBAR_HIGH); + val = intel_mchbar_read(display, MCHBAR_CH0_CR_TC_PRE_0_0_0_MCHBAR_HIGH); sp->t_rcd = REG_FIELD_GET(DG1_DRAM_T_RCD_MASK, val); sp->t_ras = REG_FIELD_GET(DG1_DRAM_T_RAS_MASK, val); @@ -211,12 +207,11 @@ static int icl_pcode_restrict_qgv_points(struct intel_display *display, static int mtl_read_qgv_point_info(struct intel_display *display, struct intel_qgv_point *sp, int point) { - struct intel_uncore *uncore = to_intel_uncore(display->drm); u32 val, val2; u16 dclk; - val = intel_uncore_read(uncore, MTL_MEM_SS_INFO_QGV_POINT_LOW(point)); - val2 = intel_uncore_read(uncore, MTL_MEM_SS_INFO_QGV_POINT_HIGH(point)); + val = intel_de_read(display, MTL_MEM_SS_INFO_QGV_POINT_LOW(point)); + val2 = intel_de_read(display, MTL_MEM_SS_INFO_QGV_POINT_HIGH(point)); dclk = REG_FIELD_GET(MTL_DCLK_MASK, val); sp->dclk = DIV_ROUND_CLOSEST(16667 * dclk, 1000); sp->t_rp = REG_FIELD_GET(MTL_TRP_MASK, val); @@ -1265,31 +1260,6 @@ static int intel_bw_check_data_rate(struct intel_atomic_state *state, bool *chan return 0; } -static int intel_bw_modeset_checks(struct intel_atomic_state *state) -{ - const struct intel_bw_state *old_bw_state; - struct intel_bw_state *new_bw_state; - int ret; - - if (!intel_any_crtc_active_changed(state)) - return 0; - - new_bw_state = intel_atomic_get_bw_state(state); - if (IS_ERR(new_bw_state)) - return PTR_ERR(new_bw_state); - - old_bw_state = intel_atomic_get_old_bw_state(state); - - new_bw_state->active_pipes = - intel_calc_active_pipes(state, old_bw_state->active_pipes); - - ret = intel_atomic_lock_global_state(&new_bw_state->base); - if (ret) - return ret; - - return 0; -} - static int intel_bw_check_sagv_mask(struct intel_atomic_state *state) { struct intel_display *display = to_intel_display(state); @@ -1346,10 +1316,6 @@ int intel_bw_atomic_check(struct intel_atomic_state *state) if (DISPLAY_VER(display) < 9) return 0; - ret = intel_bw_modeset_checks(state); - if (ret) - return ret; - ret = intel_bw_check_sagv_mask(state); if (ret) return ret; @@ -1410,7 +1376,6 @@ void intel_bw_update_hw_state(struct intel_display *display) if (DISPLAY_VER(display) < 9) return; - bw_state->active_pipes = 0; bw_state->pipe_sagv_reject = 0; for_each_intel_crtc(display->drm, crtc) { @@ -1418,9 +1383,6 @@ void intel_bw_update_hw_state(struct intel_display *display) to_intel_crtc_state(crtc->base.state); enum pipe pipe = crtc->pipe; - if (crtc_state->hw.active) - bw_state->active_pipes |= BIT(pipe); - if (DISPLAY_VER(display) >= 11) intel_bw_crtc_update(bw_state, crtc_state); @@ -1504,10 +1466,6 @@ bool intel_bw_pmdemand_needs_update(struct intel_atomic_state *state) bool intel_bw_can_enable_sagv(struct intel_display *display, const struct intel_bw_state *bw_state) { - if (DISPLAY_VER(display) < 11 && - bw_state->active_pipes && !is_power_of_2(bw_state->active_pipes)) - return false; - return bw_state->pipe_sagv_reject == 0; } diff --git a/drivers/gpu/drm/i915/display/intel_casf.c b/drivers/gpu/drm/i915/display/intel_casf.c index b167af31de5b..c2d2746c5f04 100644 --- a/drivers/gpu/drm/i915/display/intel_casf.c +++ b/drivers/gpu/drm/i915/display/intel_casf.c @@ -61,10 +61,10 @@ const u16 filtercoeff_3[] = { FILTER_COEFF_0_125, }; -static void intel_casf_filter_lut_load(struct intel_crtc *crtc, - const struct intel_crtc_state *crtc_state) +static void intel_casf_filter_lut_load(const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); int i; intel_de_write(display, SHRPLUT_INDEX(crtc->pipe), @@ -75,53 +75,35 @@ static void intel_casf_filter_lut_load(struct intel_crtc *crtc, sharpness_lut[i]); } -void intel_casf_update_strength(struct intel_crtc_state *crtc_state) -{ - struct intel_display *display = to_intel_display(crtc_state); - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - int win_size; - - intel_de_rmw(display, SHARPNESS_CTL(crtc->pipe), FILTER_STRENGTH_MASK, - FILTER_STRENGTH(crtc_state->hw.casf_params.strength)); - - win_size = intel_de_read(display, SKL_PS_WIN_SZ(crtc->pipe, 1)); - - intel_de_write_fw(display, SKL_PS_WIN_SZ(crtc->pipe, 1), win_size); -} - static void intel_casf_compute_win_size(struct intel_crtc_state *crtc_state) { const struct drm_display_mode *mode = &crtc_state->hw.adjusted_mode; u32 total_pixels = mode->hdisplay * mode->vdisplay; if (total_pixels <= MAX_PIXELS_FOR_3_TAP_FILTER) - crtc_state->hw.casf_params.win_size = SHARPNESS_FILTER_SIZE_3X3; + crtc_state->pch_pfit.casf.win_size = SHARPNESS_FILTER_SIZE_3X3; else if (total_pixels <= MAX_PIXELS_FOR_5_TAP_FILTER) - crtc_state->hw.casf_params.win_size = SHARPNESS_FILTER_SIZE_5X5; + crtc_state->pch_pfit.casf.win_size = SHARPNESS_FILTER_SIZE_5X5; else - crtc_state->hw.casf_params.win_size = SHARPNESS_FILTER_SIZE_7X7; + crtc_state->pch_pfit.casf.win_size = SHARPNESS_FILTER_SIZE_7X7; } +static void intel_casf_scaler_compute_coef(struct intel_crtc_state *crtc_state); + int intel_casf_compute_config(struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); - if (!HAS_CASF(display)) + if (crtc_state->hw.sharpness_strength == 0) return 0; - if (crtc_state->uapi.sharpness_strength == 0) { - crtc_state->hw.casf_params.casf_enable = false; - crtc_state->hw.casf_params.strength = 0; - return 0; - } - /* CASF with joiner not supported in hardware */ if (crtc_state->joiner_pipes) { drm_dbg_kms(display->drm, "CASF not supported with joiner\n"); return -EINVAL; } - crtc_state->hw.casf_params.casf_enable = true; + crtc_state->pch_pfit.casf.enable = true; /* * HW takes a value in form (1.0 + strength) in 4.4 fixed format. @@ -131,12 +113,12 @@ int intel_casf_compute_config(struct intel_crtc_state *crtc_state) * 6.3125 in 4.4 format is b01100101 which is equal to 101. * Also 85 + 16 = 101. */ - crtc_state->hw.casf_params.strength = - min(crtc_state->uapi.sharpness_strength, 0xEF) + 0x10; + crtc_state->pch_pfit.casf.strength = + min(crtc_state->hw.sharpness_strength, 0xEF) + 0x10; intel_casf_compute_win_size(crtc_state); - intel_casf_scaler_compute_config(crtc_state); + intel_casf_scaler_compute_coef(crtc_state); return 0; } @@ -151,35 +133,27 @@ void intel_casf_sharpness_get_config(struct intel_crtc_state *crtc_state) if (sharp & FILTER_EN) { if (drm_WARN_ON(display->drm, REG_FIELD_GET(FILTER_STRENGTH_MASK, sharp) < 16)) - crtc_state->hw.casf_params.strength = 0; + crtc_state->pch_pfit.casf.strength = 0; else - crtc_state->hw.casf_params.strength = + crtc_state->pch_pfit.casf.strength = REG_FIELD_GET(FILTER_STRENGTH_MASK, sharp); - crtc_state->hw.casf_params.casf_enable = true; - crtc_state->hw.casf_params.win_size = + crtc_state->pch_pfit.casf.enable = true; + crtc_state->pch_pfit.casf.win_size = REG_FIELD_GET(FILTER_SIZE_MASK, sharp); } } -bool intel_casf_needs_scaler(const struct intel_crtc_state *crtc_state) -{ - if (crtc_state->hw.casf_params.casf_enable) - return true; - - return false; -} - static int casf_coeff_tap(int i) { return i % SCALER_FILTER_NUM_TAPS; } -static u32 casf_coeff(struct intel_crtc_state *crtc_state, int t) +static u32 casf_coeff(const struct intel_crtc_state *crtc_state, int t) { struct scaler_filter_coeff value; u32 coeff; - value = crtc_state->hw.casf_params.coeff[t]; + value = crtc_state->pch_pfit.casf.coeff[t]; value.sign = 0; coeff = value.sign << 15 | value.exp << 12 | value.mantissa << 3; @@ -189,10 +163,10 @@ static u32 casf_coeff(struct intel_crtc_state *crtc_state, int t) /* * 17 phase of 7 taps requires 119 coefficients in 60 dwords per set. * To enable casf: program scaler coefficients with the coeffients - * that are calculated and stored in hw.casf_params.coeff as per + * that are calculated and stored in pch_pfit.casf.coeff as per * SCALER_COEFFICIENT_FORMAT */ -static void intel_casf_write_coeff(struct intel_crtc_state *crtc_state) +static void intel_casf_write_coeff(const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); @@ -240,16 +214,16 @@ static void convert_sharpness_coef_binary(struct scaler_filter_coeff *coeff, } } -void intel_casf_scaler_compute_config(struct intel_crtc_state *crtc_state) +static void intel_casf_scaler_compute_coef(struct intel_crtc_state *crtc_state) { const u16 *filtercoeff; u16 filter_coeff[SCALER_FILTER_NUM_TAPS]; u16 sumcoeff = 0; int i; - if (crtc_state->hw.casf_params.win_size == 0) + if (crtc_state->pch_pfit.casf.win_size == 0) filtercoeff = filtercoeff_1; - else if (crtc_state->hw.casf_params.win_size == 1) + else if (crtc_state->pch_pfit.casf.win_size == 1) filtercoeff = filtercoeff_2; else filtercoeff = filtercoeff_3; @@ -259,37 +233,13 @@ void intel_casf_scaler_compute_config(struct intel_crtc_state *crtc_state) for (i = 0; i < SCALER_FILTER_NUM_TAPS; i++) { filter_coeff[i] = (*(filtercoeff + i) * 100 / sumcoeff); - convert_sharpness_coef_binary(&crtc_state->hw.casf_params.coeff[i], + convert_sharpness_coef_binary(&crtc_state->pch_pfit.casf.coeff[i], filter_coeff[i]); } } -void intel_casf_enable(struct intel_crtc_state *crtc_state) +void intel_casf_setup(const struct intel_crtc_state *crtc_state) { - struct intel_display *display = to_intel_display(crtc_state); - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - u32 sharpness_ctl; - - intel_casf_filter_lut_load(crtc, crtc_state); - + intel_casf_filter_lut_load(crtc_state); intel_casf_write_coeff(crtc_state); - - sharpness_ctl = FILTER_EN | FILTER_STRENGTH(crtc_state->hw.casf_params.strength); - - sharpness_ctl |= crtc_state->hw.casf_params.win_size; - - intel_de_write(display, SHARPNESS_CTL(crtc->pipe), sharpness_ctl); - - skl_scaler_setup_casf(crtc_state); -} - -void intel_casf_disable(const struct intel_crtc_state *crtc_state) -{ - struct intel_display *display = to_intel_display(crtc_state); - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - - intel_de_write(display, SKL_PS_CTRL(crtc->pipe, 1), 0); - intel_de_write(display, SKL_PS_WIN_POS(crtc->pipe, 1), 0); - intel_de_write(display, SHARPNESS_CTL(crtc->pipe), 0); - intel_de_write(display, SKL_PS_WIN_SZ(crtc->pipe, 1), 0); } diff --git a/drivers/gpu/drm/i915/display/intel_casf.h b/drivers/gpu/drm/i915/display/intel_casf.h index b3fb0bcb3f5b..3ebb7522af0a 100644 --- a/drivers/gpu/drm/i915/display/intel_casf.h +++ b/drivers/gpu/drm/i915/display/intel_casf.h @@ -11,11 +11,7 @@ struct intel_crtc_state; int intel_casf_compute_config(struct intel_crtc_state *crtc_state); -void intel_casf_update_strength(struct intel_crtc_state *new_crtc_state); void intel_casf_sharpness_get_config(struct intel_crtc_state *crtc_state); -void intel_casf_enable(struct intel_crtc_state *crtc_state); -void intel_casf_disable(const struct intel_crtc_state *crtc_state); -void intel_casf_scaler_compute_config(struct intel_crtc_state *crtc_state); -bool intel_casf_needs_scaler(const struct intel_crtc_state *crtc_state); +void intel_casf_setup(const struct intel_crtc_state *crtc_state); #endif /* __INTEL_CASF_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index e3b044ee3e16..a1bf01021d65 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include "hsw_ips.h" @@ -42,9 +43,8 @@ #include "intel_display_utils.h" #include "intel_display_wa.h" #include "intel_dram.h" -#include "intel_mchbar_regs.h" +#include "intel_mchbar.h" #include "intel_parent.h" -#include "intel_pci_config.h" #include "intel_plane.h" #include "intel_psr.h" #include "intel_vdsc.h" @@ -170,27 +170,27 @@ struct intel_cdclk_funcs { void intel_cdclk_get_cdclk(struct intel_display *display, struct intel_cdclk_config *cdclk_config) { - display->funcs.cdclk->get_cdclk(display, cdclk_config); + display->cdclk.funcs->get_cdclk(display, cdclk_config); } static void intel_cdclk_set_cdclk(struct intel_display *display, const struct intel_cdclk_config *cdclk_config, enum pipe pipe) { - display->funcs.cdclk->set_cdclk(display, cdclk_config, pipe); + display->cdclk.funcs->set_cdclk(display, cdclk_config, pipe); } static int intel_cdclk_modeset_calc_cdclk(struct intel_atomic_state *state) { struct intel_display *display = to_intel_display(state); - return display->funcs.cdclk->modeset_calc_cdclk(state); + return display->cdclk.funcs->modeset_calc_cdclk(state); } static u8 intel_cdclk_calc_voltage_level(struct intel_display *display, int cdclk) { - return display->funcs.cdclk->calc_voltage_level(cdclk); + return display->cdclk.funcs->calc_voltage_level(cdclk); } static void fixed_133mhz_get_cdclk(struct intel_display *display, @@ -376,8 +376,8 @@ static unsigned int intel_hpll_vco(struct intel_display *display) else return 0; - tmp = intel_de_read(display, display->platform.pineview || - display->platform.mobile ? HPLLVCO_MOBILE : HPLLVCO); + tmp = intel_mchbar_read(display, display->platform.pineview || + display->platform.mobile ? HPLLVCO_MOBILE : HPLLVCO); vco = vco_table[tmp & 0x7]; if (vco == 0) @@ -613,9 +613,9 @@ static void vlv_get_cdclk(struct intel_display *display, cdclk_config->vco = vlv_clock_get_hpll_vco(display->drm); cdclk_config->cdclk = vlv_clock_get_cdclk(display->drm); - vlv_punit_get(display->drm); - val = vlv_punit_read(display->drm, PUNIT_REG_DSPSSPM); - vlv_punit_put(display->drm); + vlv_punit_get(display); + val = vlv_punit_read(display, PUNIT_REG_DSPSSPM); + vlv_punit_put(display); if (display->platform.valleyview) cdclk_config->voltage_level = (val & DSPFREQGUAR_MASK) >> @@ -691,17 +691,17 @@ static void vlv_set_cdclk(struct intel_display *display, */ wakeref = intel_display_power_get(display, POWER_DOMAIN_DISPLAY_CORE); - vlv_iosf_sb_get(display->drm, - BIT(VLV_IOSF_SB_CCK) | - BIT(VLV_IOSF_SB_BUNIT) | - BIT(VLV_IOSF_SB_PUNIT)); + intel_parent_vlv_iosf_get(display, + BIT(VLV_IOSF_SB_CCK) | + BIT(VLV_IOSF_SB_BUNIT) | + BIT(VLV_IOSF_SB_PUNIT)); - val = vlv_punit_read(display->drm, PUNIT_REG_DSPSSPM); + val = vlv_punit_read(display, PUNIT_REG_DSPSSPM); val &= ~DSPFREQGUAR_MASK; val |= (cmd << DSPFREQGUAR_SHIFT); - vlv_punit_write(display->drm, PUNIT_REG_DSPSSPM, val); + vlv_punit_write(display, PUNIT_REG_DSPSSPM, val); - ret = poll_timeout_us(val = vlv_punit_read(display->drm, PUNIT_REG_DSPSSPM), + ret = poll_timeout_us(val = vlv_punit_read(display, PUNIT_REG_DSPSSPM), (val & DSPFREQSTAT_MASK) == (cmd << DSPFREQSTAT_SHIFT), 500, 50 * 1000, false); if (ret) @@ -714,12 +714,12 @@ static void vlv_set_cdclk(struct intel_display *display, cdclk) - 1; /* adjust cdclk divider */ - val = vlv_cck_read(display->drm, CCK_DISPLAY_CLOCK_CONTROL); + val = vlv_cck_read(display, CCK_DISPLAY_CLOCK_CONTROL); val &= ~CCK_FREQUENCY_VALUES; val |= divider; - vlv_cck_write(display->drm, CCK_DISPLAY_CLOCK_CONTROL, val); + vlv_cck_write(display, CCK_DISPLAY_CLOCK_CONTROL, val); - ret = poll_timeout_us(val = vlv_cck_read(display->drm, CCK_DISPLAY_CLOCK_CONTROL), + ret = poll_timeout_us(val = vlv_cck_read(display, CCK_DISPLAY_CLOCK_CONTROL), (val & CCK_FREQUENCY_STATUS) == (divider << CCK_FREQUENCY_STATUS_SHIFT), 500, 50 * 1000, false); if (ret) @@ -727,7 +727,7 @@ static void vlv_set_cdclk(struct intel_display *display, } /* adjust self-refresh exit latency value */ - val = vlv_bunit_read(display->drm, BUNIT_REG_BISOC); + val = vlv_bunit_read(display, BUNIT_REG_BISOC); val &= ~0x7f; /* @@ -738,12 +738,12 @@ static void vlv_set_cdclk(struct intel_display *display, val |= 4500 / 250; /* 4.5 usec */ else val |= 3000 / 250; /* 3.0 usec */ - vlv_bunit_write(display->drm, BUNIT_REG_BISOC, val); + vlv_bunit_write(display, BUNIT_REG_BISOC, val); - vlv_iosf_sb_put(display->drm, - BIT(VLV_IOSF_SB_CCK) | - BIT(VLV_IOSF_SB_BUNIT) | - BIT(VLV_IOSF_SB_PUNIT)); + intel_parent_vlv_iosf_put(display, + BIT(VLV_IOSF_SB_CCK) | + BIT(VLV_IOSF_SB_BUNIT) | + BIT(VLV_IOSF_SB_PUNIT)); intel_update_cdclk(display); @@ -780,19 +780,19 @@ static void chv_set_cdclk(struct intel_display *display, */ wakeref = intel_display_power_get(display, POWER_DOMAIN_DISPLAY_CORE); - vlv_punit_get(display->drm); - val = vlv_punit_read(display->drm, PUNIT_REG_DSPSSPM); + vlv_punit_get(display); + val = vlv_punit_read(display, PUNIT_REG_DSPSSPM); val &= ~DSPFREQGUAR_MASK_CHV; val |= (cmd << DSPFREQGUAR_SHIFT_CHV); - vlv_punit_write(display->drm, PUNIT_REG_DSPSSPM, val); + vlv_punit_write(display, PUNIT_REG_DSPSSPM, val); - ret = poll_timeout_us(val = vlv_punit_read(display->drm, PUNIT_REG_DSPSSPM), + ret = poll_timeout_us(val = vlv_punit_read(display, PUNIT_REG_DSPSSPM), (val & DSPFREQSTAT_MASK_CHV) == (cmd << DSPFREQSTAT_SHIFT_CHV), 500, 50 * 1000, false); if (ret) drm_err(display->drm, "timed out waiting for CDCLK change\n"); - vlv_punit_put(display->drm); + vlv_punit_put(display); intel_update_cdclk(display); @@ -2619,7 +2619,7 @@ static void intel_set_cdclk(struct intel_display *display, if (!intel_cdclk_changed(&display->cdclk.hw, cdclk_config)) return; - if (drm_WARN_ON_ONCE(display->drm, !display->funcs.cdclk->set_cdclk)) + if (drm_WARN_ON_ONCE(display->drm, !display->cdclk.funcs->set_cdclk)) return; intel_cdclk_dump_config(display, cdclk_config, context); @@ -4042,100 +4042,100 @@ static const struct intel_cdclk_funcs i830_cdclk_funcs = { void intel_init_cdclk_hooks(struct intel_display *display) { if (DISPLAY_VER(display) >= 35) { - display->funcs.cdclk = &xe3lpd_cdclk_funcs; + display->cdclk.funcs = &xe3lpd_cdclk_funcs; display->cdclk.table = xe3p_lpd_cdclk_table; } else if (DISPLAY_VER(display) >= 30) { - display->funcs.cdclk = &xe3lpd_cdclk_funcs; + display->cdclk.funcs = &xe3lpd_cdclk_funcs; display->cdclk.table = xe3lpd_cdclk_table; } else if (DISPLAY_VER(display) >= 20) { - display->funcs.cdclk = &rplu_cdclk_funcs; + display->cdclk.funcs = &rplu_cdclk_funcs; display->cdclk.table = xe2lpd_cdclk_table; } else if (DISPLAY_VERx100(display) >= 1401) { - display->funcs.cdclk = &rplu_cdclk_funcs; + display->cdclk.funcs = &rplu_cdclk_funcs; display->cdclk.table = xe2hpd_cdclk_table; } else if (DISPLAY_VER(display) >= 14) { - display->funcs.cdclk = &rplu_cdclk_funcs; + display->cdclk.funcs = &rplu_cdclk_funcs; display->cdclk.table = mtl_cdclk_table; } else if (display->platform.dg2) { - display->funcs.cdclk = &tgl_cdclk_funcs; + display->cdclk.funcs = &tgl_cdclk_funcs; display->cdclk.table = dg2_cdclk_table; } else if (display->platform.alderlake_p) { /* Wa_22011320316:adl-p[a0] */ if (intel_display_wa(display, INTEL_DISPLAY_WA_22011320316)) { display->cdclk.table = adlp_a_step_cdclk_table; - display->funcs.cdclk = &tgl_cdclk_funcs; + display->cdclk.funcs = &tgl_cdclk_funcs; } else if (display->platform.alderlake_p_raptorlake_u) { display->cdclk.table = rplu_cdclk_table; - display->funcs.cdclk = &rplu_cdclk_funcs; + display->cdclk.funcs = &rplu_cdclk_funcs; } else { display->cdclk.table = adlp_cdclk_table; - display->funcs.cdclk = &tgl_cdclk_funcs; + display->cdclk.funcs = &tgl_cdclk_funcs; } } else if (display->platform.rocketlake) { - display->funcs.cdclk = &tgl_cdclk_funcs; + display->cdclk.funcs = &tgl_cdclk_funcs; display->cdclk.table = rkl_cdclk_table; } else if (DISPLAY_VER(display) >= 12) { - display->funcs.cdclk = &tgl_cdclk_funcs; + display->cdclk.funcs = &tgl_cdclk_funcs; display->cdclk.table = icl_cdclk_table; } else if (display->platform.jasperlake || display->platform.elkhartlake) { - display->funcs.cdclk = &ehl_cdclk_funcs; + display->cdclk.funcs = &ehl_cdclk_funcs; display->cdclk.table = icl_cdclk_table; } else if (DISPLAY_VER(display) >= 11) { - display->funcs.cdclk = &icl_cdclk_funcs; + display->cdclk.funcs = &icl_cdclk_funcs; display->cdclk.table = icl_cdclk_table; } else if (display->platform.geminilake || display->platform.broxton) { - display->funcs.cdclk = &bxt_cdclk_funcs; + display->cdclk.funcs = &bxt_cdclk_funcs; if (display->platform.geminilake) display->cdclk.table = glk_cdclk_table; else display->cdclk.table = bxt_cdclk_table; } else if (DISPLAY_VER(display) == 9) { - display->funcs.cdclk = &skl_cdclk_funcs; + display->cdclk.funcs = &skl_cdclk_funcs; } else if (display->platform.broadwell) { - display->funcs.cdclk = &bdw_cdclk_funcs; + display->cdclk.funcs = &bdw_cdclk_funcs; } else if (display->platform.haswell) { - display->funcs.cdclk = &hsw_cdclk_funcs; + display->cdclk.funcs = &hsw_cdclk_funcs; } else if (display->platform.cherryview) { - display->funcs.cdclk = &chv_cdclk_funcs; + display->cdclk.funcs = &chv_cdclk_funcs; } else if (display->platform.valleyview) { - display->funcs.cdclk = &vlv_cdclk_funcs; + display->cdclk.funcs = &vlv_cdclk_funcs; } else if (display->platform.sandybridge || display->platform.ivybridge) { - display->funcs.cdclk = &fixed_400mhz_cdclk_funcs; + display->cdclk.funcs = &fixed_400mhz_cdclk_funcs; } else if (display->platform.ironlake) { - display->funcs.cdclk = &ilk_cdclk_funcs; + display->cdclk.funcs = &ilk_cdclk_funcs; } else if (display->platform.gm45) { - display->funcs.cdclk = &gm45_cdclk_funcs; + display->cdclk.funcs = &gm45_cdclk_funcs; } else if (display->platform.g45) { - display->funcs.cdclk = &g33_cdclk_funcs; + display->cdclk.funcs = &g33_cdclk_funcs; } else if (display->platform.i965gm) { - display->funcs.cdclk = &i965gm_cdclk_funcs; + display->cdclk.funcs = &i965gm_cdclk_funcs; } else if (display->platform.i965g) { - display->funcs.cdclk = &fixed_400mhz_cdclk_funcs; + display->cdclk.funcs = &fixed_400mhz_cdclk_funcs; } else if (display->platform.pineview) { - display->funcs.cdclk = &pnv_cdclk_funcs; + display->cdclk.funcs = &pnv_cdclk_funcs; } else if (display->platform.g33) { - display->funcs.cdclk = &g33_cdclk_funcs; + display->cdclk.funcs = &g33_cdclk_funcs; } else if (display->platform.i945gm) { - display->funcs.cdclk = &i945gm_cdclk_funcs; + display->cdclk.funcs = &i945gm_cdclk_funcs; } else if (display->platform.i945g) { - display->funcs.cdclk = &fixed_400mhz_cdclk_funcs; + display->cdclk.funcs = &fixed_400mhz_cdclk_funcs; } else if (display->platform.i915gm) { - display->funcs.cdclk = &i915gm_cdclk_funcs; + display->cdclk.funcs = &i915gm_cdclk_funcs; } else if (display->platform.i915g) { - display->funcs.cdclk = &i915g_cdclk_funcs; + display->cdclk.funcs = &i915g_cdclk_funcs; } else if (display->platform.i865g) { - display->funcs.cdclk = &i865g_cdclk_funcs; + display->cdclk.funcs = &i865g_cdclk_funcs; } else if (display->platform.i85x) { - display->funcs.cdclk = &i85x_cdclk_funcs; + display->cdclk.funcs = &i85x_cdclk_funcs; } else if (display->platform.i845g) { - display->funcs.cdclk = &i845g_cdclk_funcs; + display->cdclk.funcs = &i845g_cdclk_funcs; } else if (display->platform.i830) { - display->funcs.cdclk = &i830_cdclk_funcs; + display->cdclk.funcs = &i830_cdclk_funcs; } - if (drm_WARN(display->drm, !display->funcs.cdclk, + if (drm_WARN(display->drm, !display->cdclk.funcs, "Unknown platform. Assuming i830\n")) - display->funcs.cdclk = &i830_cdclk_funcs; + display->cdclk.funcs = &i830_cdclk_funcs; } int intel_cdclk_logical(const struct intel_cdclk_state *cdclk_state) diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c index e7950655434b..0531c60e5e5d 100644 --- a/drivers/gpu/drm/i915/display/intel_color.c +++ b/drivers/gpu/drm/i915/display/intel_color.c @@ -1933,7 +1933,7 @@ void intel_color_load_luts(const struct intel_crtc_state *crtc_state) if (crtc_state->dsb_color) return; - display->funcs.color->load_luts(crtc_state); + display->color.funcs->load_luts(crtc_state); } void intel_color_commit_noarm(struct intel_dsb *dsb, @@ -1941,8 +1941,8 @@ void intel_color_commit_noarm(struct intel_dsb *dsb, { struct intel_display *display = to_intel_display(crtc_state); - if (display->funcs.color->color_commit_noarm) - display->funcs.color->color_commit_noarm(dsb, crtc_state); + if (display->color.funcs->color_commit_noarm) + display->color.funcs->color_commit_noarm(dsb, crtc_state); } void intel_color_commit_arm(struct intel_dsb *dsb, @@ -1950,15 +1950,15 @@ void intel_color_commit_arm(struct intel_dsb *dsb, { struct intel_display *display = to_intel_display(crtc_state); - display->funcs.color->color_commit_arm(dsb, crtc_state); + display->color.funcs->color_commit_arm(dsb, crtc_state); } void intel_color_post_update(const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); - if (display->funcs.color->color_post_update) - display->funcs.color->color_post_update(crtc_state); + if (display->color.funcs->color_post_update) + display->color.funcs->color_post_update(crtc_state); } void intel_color_modeset(const struct intel_crtc_state *crtc_state) @@ -2022,7 +2022,7 @@ void intel_color_prepare_commit(struct intel_atomic_state *state, if (!intel_color_uses_dsb(crtc_state)) return; - display->funcs.color->load_luts(crtc_state); + display->color.funcs->load_luts(crtc_state); if (crtc_state->use_dsb && intel_color_uses_chained_dsb(crtc_state)) { intel_vrr_send_push(crtc_state->dsb_color, crtc_state); @@ -2113,19 +2113,19 @@ int intel_color_check(struct intel_atomic_state *state, if (!intel_crtc_needs_color_update(new_crtc_state)) return 0; - return display->funcs.color->color_check(state, crtc); + return display->color.funcs->color_check(state, crtc); } void intel_color_get_config(struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); - display->funcs.color->get_config(crtc_state); + display->color.funcs->get_config(crtc_state); - display->funcs.color->read_luts(crtc_state); + display->color.funcs->read_luts(crtc_state); - if (display->funcs.color->read_csc) - display->funcs.color->read_csc(crtc_state); + if (display->color.funcs->read_csc) + display->color.funcs->read_csc(crtc_state); } bool intel_color_lut_equal(const struct intel_crtc_state *crtc_state, @@ -2142,7 +2142,7 @@ bool intel_color_lut_equal(const struct intel_crtc_state *crtc_state, if (!is_pre_csc_lut && crtc_state->c8_planes) return true; - return display->funcs.color->lut_equal(crtc_state, blob1, blob2, + return display->color.funcs->lut_equal(crtc_state, blob1, blob2, is_pre_csc_lut); } @@ -4253,8 +4253,8 @@ intel_color_load_plane_csc_matrix(struct intel_dsb *dsb, { struct intel_display *display = to_intel_display(plane_state); - if (display->funcs.color->load_plane_csc_matrix) - display->funcs.color->load_plane_csc_matrix(dsb, plane_state); + if (display->color.funcs->load_plane_csc_matrix) + display->color.funcs->load_plane_csc_matrix(dsb, plane_state); } static void @@ -4263,8 +4263,8 @@ intel_color_load_plane_luts(struct intel_dsb *dsb, { struct intel_display *display = to_intel_display(plane_state); - if (display->funcs.color->load_plane_luts) - display->funcs.color->load_plane_luts(dsb, plane_state); + if (display->color.funcs->load_plane_luts) + display->color.funcs->load_plane_luts(dsb, plane_state); } bool @@ -4346,29 +4346,29 @@ void intel_color_init_hooks(struct intel_display *display) { if (HAS_GMCH(display)) { if (display->platform.cherryview) - display->funcs.color = &chv_color_funcs; + display->color.funcs = &chv_color_funcs; else if (display->platform.valleyview) - display->funcs.color = &vlv_color_funcs; + display->color.funcs = &vlv_color_funcs; else if (DISPLAY_VER(display) >= 4) - display->funcs.color = &i965_color_funcs; + display->color.funcs = &i965_color_funcs; else - display->funcs.color = &i9xx_color_funcs; + display->color.funcs = &i9xx_color_funcs; } else { if (DISPLAY_VER(display) >= 12) - display->funcs.color = &tgl_color_funcs; + display->color.funcs = &tgl_color_funcs; else if (DISPLAY_VER(display) == 11) - display->funcs.color = &icl_color_funcs; + display->color.funcs = &icl_color_funcs; else if (DISPLAY_VER(display) == 10) - display->funcs.color = &glk_color_funcs; + display->color.funcs = &glk_color_funcs; else if (DISPLAY_VER(display) == 9) - display->funcs.color = &skl_color_funcs; + display->color.funcs = &skl_color_funcs; else if (DISPLAY_VER(display) == 8) - display->funcs.color = &bdw_color_funcs; + display->color.funcs = &bdw_color_funcs; else if (display->platform.haswell) - display->funcs.color = &hsw_color_funcs; + display->color.funcs = &hsw_color_funcs; else if (DISPLAY_VER(display) == 7) - display->funcs.color = &ivb_color_funcs; + display->color.funcs = &ivb_color_funcs; else - display->funcs.color = &ilk_color_funcs; + display->color.funcs = &ilk_color_funcs; } } diff --git a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c index 234843b8f83a..4493483f10a9 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c +++ b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c @@ -250,7 +250,7 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config, str_enabled_disabled(pipe_config->has_sel_update), str_enabled_disabled(pipe_config->has_panel_replay), str_enabled_disabled(pipe_config->enable_psr2_sel_fetch)); - drm_printf(&p, "minimum HBlank: %d\n", pipe_config->min_hblank); + drm_printf(&p, "minimum hblank: %d\n", pipe_config->min_hblank); } drm_printf(&p, "audio: %i, infoframes: %i, infoframes enabled: 0x%x\n", @@ -320,19 +320,23 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config, drm_printf(&p, "pipe mode: " DRM_MODE_FMT "\n", DRM_MODE_ARG(&pipe_config->hw.pipe_mode)); intel_dump_crtc_timings(&p, &pipe_config->hw.pipe_mode); - drm_printf(&p, "port clock: %d, pipe src: " DRM_RECT_FMT ", pixel rate %d, min cdclk %d\n", - pipe_config->port_clock, DRM_RECT_ARG(&pipe_config->pipe_src), - pipe_config->pixel_rate, pipe_config->min_cdclk); + drm_printf(&p, "port clock: %d, pixel rate %d, min cdclk %d, min voltage level %d\n", + pipe_config->port_clock, pipe_config->pixel_rate, + pipe_config->min_cdclk, pipe_config->min_voltage_level); drm_printf(&p, "linetime: %d, ips linetime: %d\n", pipe_config->linetime, pipe_config->ips_linetime); if (DISPLAY_VER(display) >= 9) - drm_printf(&p, "num_scalers: %d, scaler_users: 0x%x, scaler_id: %d, scaling_filter: %d\n", + drm_printf(&p, "num_scalers: %d, scaler_users: 0x%x, scaler_id: %d, scaling_filter: %d, sharpness_strength: %d\n", crtc->num_scalers, pipe_config->scaler_state.scaler_users, pipe_config->scaler_state.scaler_id, - pipe_config->hw.scaling_filter); + pipe_config->hw.scaling_filter, + pipe_config->hw.sharpness_strength); + + drm_printf(&p, "pipe src: " DRM_RECT_FMT "\n", + DRM_RECT_ARG(&pipe_config->pipe_src)); if (HAS_GMCH(display)) drm_printf(&p, "gmch pfit: control: 0x%08x, ratios: 0x%08x, lvds border: 0x%08x\n", @@ -345,6 +349,11 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config, str_enabled_disabled(pipe_config->pch_pfit.enabled), str_yes_no(pipe_config->pch_pfit.force_thru)); + drm_printf(&p, "sharpness strength: %d, sharpness tap size: %d, sharpness enable: %d\n", + pipe_config->pch_pfit.casf.strength, + pipe_config->pch_pfit.casf.win_size, + pipe_config->pch_pfit.casf.enable); + drm_printf(&p, "ips: %i, double wide: %i, drrs: %i\n", pipe_config->ips_enabled, pipe_config->double_wide, pipe_config->has_drrs); @@ -380,11 +389,6 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config, intel_vdsc_state_dump(&p, 0, pipe_config); - drm_printf(&p, "sharpness strength: %d, sharpness tap size: %d, sharpness enable: %d\n", - pipe_config->hw.casf_params.strength, - pipe_config->hw.casf_params.win_size, - pipe_config->hw.casf_params.casf_enable); - dump_planes: if (!state) return; diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.c b/drivers/gpu/drm/i915/display/intel_cx0_phy.c index 7e59409bbf01..d832e44ef62a 100644 --- a/drivers/gpu/drm/i915/display/intel_cx0_phy.c +++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.c @@ -492,7 +492,7 @@ void intel_cx0_phy_set_signal_levels(struct intel_encoder *encoder, wakeref = intel_cx0_phy_transaction_begin(encoder); - trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); + trans = intel_ddi_buf_trans_get(encoder, crtc_state, &n_entries); if (drm_WARN_ON_ONCE(display->drm, !trans)) { intel_cx0_phy_transaction_end(encoder, wakeref); return; diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 178074316a2c..2681940a5cfe 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -140,7 +140,7 @@ void hsw_prepare_dp_ddi_buffers(struct intel_encoder *encoder, enum port port = encoder->port; const struct intel_ddi_buf_trans *trans; - trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); + trans = intel_ddi_buf_trans_get(encoder, crtc_state, &n_entries); if (drm_WARN_ON_ONCE(display->drm, !trans)) return; @@ -172,7 +172,7 @@ static void hsw_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder, enum port port = encoder->port; const struct intel_ddi_buf_trans *trans; - trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); + trans = intel_ddi_buf_trans_get(encoder, crtc_state, &n_entries); if (drm_WARN_ON_ONCE(display->drm, !trans)) return; @@ -1106,7 +1106,7 @@ static void skl_ddi_set_iboost(struct intel_encoder *encoder, const struct intel_ddi_buf_trans *trans; int n_entries; - trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); + trans = intel_ddi_buf_trans_get(encoder, crtc_state, &n_entries); if (drm_WARN_ON_ONCE(display->drm, !trans)) return; @@ -1132,7 +1132,7 @@ static u8 intel_ddi_dp_voltage_max(struct intel_dp *intel_dp, struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; int n_entries; - encoder->get_buf_trans(encoder, crtc_state, &n_entries); + intel_ddi_buf_trans_get(encoder, crtc_state, &n_entries); if (drm_WARN_ON(display->drm, n_entries < 1)) n_entries = 1; @@ -1175,7 +1175,7 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder, int n_entries, ln; u32 val; - trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); + trans = intel_ddi_buf_trans_get(encoder, crtc_state, &n_entries); if (drm_WARN_ON_ONCE(display->drm, !trans)) return; @@ -1293,7 +1293,7 @@ static void icl_mg_phy_set_signal_levels(struct intel_encoder *encoder, if (intel_tc_port_in_tbt_alt_mode(enc_to_dig_port(encoder))) return; - trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); + trans = intel_ddi_buf_trans_get(encoder, crtc_state, &n_entries); if (drm_WARN_ON_ONCE(display->drm, !trans)) return; @@ -1394,7 +1394,7 @@ static void tgl_dkl_phy_set_signal_levels(struct intel_encoder *encoder, if (intel_tc_port_in_tbt_alt_mode(enc_to_dig_port(encoder))) return; - trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); + trans = intel_ddi_buf_trans_get(encoder, crtc_state, &n_entries); if (drm_WARN_ON_ONCE(display->drm, !trans)) return; @@ -1511,7 +1511,7 @@ int intel_ddi_level(struct intel_encoder *encoder, const struct intel_ddi_buf_trans *trans; int level, n_entries; - trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); + trans = intel_ddi_buf_trans_get(encoder, crtc_state, &n_entries); if (drm_WARN_ON_ONCE(display->drm, !trans)) return 0; diff --git a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c index 395dba8c9e4d..4cd1e4d76c7a 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c +++ b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c @@ -1123,8 +1123,8 @@ static const union intel_ddi_buf_trans_entry _xe3plpd_lt_trans_dp14[] = { { .lt = { 1, 2, 0, 28, 7 } }, { .lt = { 0, 3, 0, 35, 13 } }, { .lt = { 1, 1, 0, 27, 0 } }, - { .lt = { 1, 2, 0, 31, 4 } }, - { .lt = { 0, 3, 0, 39, 9 } }, + { .lt = { 1, 2, 0, 31, 5 } }, + { .lt = { 0, 3, 0, 37, 11 } }, { .lt = { 1, 2, 0, 35, 0 } }, { .lt = { 0, 3, 0, 41, 7 } }, { .lt = { 0, 3, 0, 48, 0 } }, @@ -1852,3 +1852,10 @@ void intel_ddi_buf_trans_init(struct intel_encoder *encoder) MISSING_CASE(pdev->device); } } + +const struct intel_ddi_buf_trans *intel_ddi_buf_trans_get(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, + int *n_entries) +{ + return encoder->get_buf_trans(encoder, crtc_state, n_entries); +} diff --git a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.h b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.h index cec332090a20..9698697f3917 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.h +++ b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.h @@ -77,5 +77,8 @@ struct intel_ddi_buf_trans { bool is_hobl_buf_trans(const struct intel_ddi_buf_trans *table); void intel_ddi_buf_trans_init(struct intel_encoder *encoder); +const struct intel_ddi_buf_trans * +intel_ddi_buf_trans_get(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, int *n_entries); #endif diff --git a/drivers/gpu/drm/i915/display/intel_de.c b/drivers/gpu/drm/i915/display/intel_de.c index d2a418da2d54..a96e83d76eaa 100644 --- a/drivers/gpu/drm/i915/display/intel_de.c +++ b/drivers/gpu/drm/i915/display/intel_de.c @@ -176,3 +176,11 @@ void intel_de_write8(struct intel_display *display, i915_reg_t reg, u8 val) intel_uncore_write8(__to_uncore(display), reg, val); } + +u16 intel_de_read16(struct intel_display *display, i915_reg_t reg) +{ + /* this is only used on MCHBAR registers on pre-SNB */ + drm_WARN_ON(display->drm, DISPLAY_VER(display) >= 6); + + return intel_uncore_read16(__to_uncore(display), reg); +} diff --git a/drivers/gpu/drm/i915/display/intel_de.h b/drivers/gpu/drm/i915/display/intel_de.h index f87b84ab9d6d..14f9dc7b6dfd 100644 --- a/drivers/gpu/drm/i915/display/intel_de.h +++ b/drivers/gpu/drm/i915/display/intel_de.h @@ -19,6 +19,7 @@ static inline struct intel_uncore *__to_uncore(struct intel_display *display) u8 intel_de_read8(struct intel_display *display, i915_reg_t reg); void intel_de_write8(struct intel_display *display, i915_reg_t reg, u8 val); +u16 intel_de_read16(struct intel_display *display, i915_reg_t reg); static inline u32 intel_de_read(struct intel_display *display, i915_reg_t reg) @@ -35,8 +36,8 @@ intel_de_read(struct intel_display *display, i915_reg_t reg) } static inline u64 -intel_de_read64_2x32(struct intel_display *display, - i915_reg_t lower_reg, i915_reg_t upper_reg) +intel_de_read64_2x32_volatile(struct intel_display *display, + i915_reg_t lower_reg, i915_reg_t upper_reg) { u64 val; @@ -52,6 +53,18 @@ intel_de_read64_2x32(struct intel_display *display, return val; } +static inline u64 +intel_de_read64_2x32(struct intel_display *display, i915_reg_t reg) +{ + i915_reg_t upper_reg = _MMIO(i915_mmio_reg_offset(reg) + 4); + u32 lower, upper; + + lower = intel_de_read(display, reg); + upper = intel_de_read(display, upper_reg); + + return (u64)upper << 32 | lower; +} + static inline void intel_de_posting_read(struct intel_display *display, i915_reg_t reg) { diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index efbdd507ac28..d5cf1476c7b9 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -58,7 +58,6 @@ #include "intel_audio.h" #include "intel_bo.h" #include "intel_bw.h" -#include "intel_casf.h" #include "intel_cdclk.h" #include "intel_clock_gating.h" #include "intel_color.h" @@ -988,24 +987,6 @@ static bool audio_disabling(const struct intel_crtc_state *old_crtc_state, memcmp(old_crtc_state->eld, new_crtc_state->eld, MAX_ELD_BYTES) != 0); } -static bool intel_casf_enabling(const struct intel_crtc_state *new_crtc_state, - const struct intel_crtc_state *old_crtc_state) -{ - if (!new_crtc_state->hw.active) - return false; - - return is_enabling(hw.casf_params.casf_enable, old_crtc_state, new_crtc_state); -} - -static bool intel_casf_disabling(const struct intel_crtc_state *old_crtc_state, - const struct intel_crtc_state *new_crtc_state) -{ - if (!new_crtc_state->hw.active) - return false; - - return is_disabling(hw.casf_params.casf_enable, old_crtc_state, new_crtc_state); -} - static bool intel_crtc_lobf_enabling(const struct intel_crtc_state *old_crtc_state, const struct intel_crtc_state *new_crtc_state) { @@ -1187,9 +1168,6 @@ static void intel_pre_plane_update(struct intel_atomic_state *state, if (audio_disabling(old_crtc_state, new_crtc_state)) intel_encoders_audio_disable(state, crtc); - if (intel_casf_disabling(old_crtc_state, new_crtc_state)) - intel_casf_disable(new_crtc_state); - intel_drrs_deactivate(old_crtc_state); if (hsw_ips_pre_update(state, crtc)) @@ -2184,7 +2162,7 @@ static void i9xx_crtc_disable(struct intel_atomic_state *state, if (DISPLAY_VER(display) != 2) intel_set_cpu_fifo_underrun_reporting(display, pipe, false); - if (!display->funcs.wm->initial_watermarks) + if (!display->wm.funcs->initial_watermarks) intel_update_watermarks(display); /* clock the pipe down to 640x480@60 to potentially save power */ @@ -4073,7 +4051,7 @@ bool intel_crtc_get_pipe_config(struct intel_crtc_state *crtc_state) struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - if (!display->funcs.display->get_pipe_config(crtc, crtc_state)) + if (!display->modeset.funcs->get_pipe_config(crtc, crtc_state)) return false; crtc_state->hw.active = true; @@ -4308,14 +4286,9 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state, return ret; } - ret = intel_casf_compute_config(crtc_state); - if (ret) - return ret; - if (DISPLAY_VER(display) >= 9) { if (intel_crtc_needs_modeset(crtc_state) || - intel_crtc_needs_fastset(crtc_state) || - intel_casf_needs_scaler(crtc_state)) { + intel_crtc_needs_fastset(crtc_state)) { ret = skl_update_scaler_crtc(crtc_state); if (ret) return ret; @@ -4550,6 +4523,7 @@ intel_crtc_copy_uapi_to_hw_state_modeset(struct intel_atomic_state *state, drm_mode_copy(&crtc_state->hw.adjusted_mode, &crtc_state->uapi.adjusted_mode); crtc_state->hw.scaling_filter = crtc_state->uapi.scaling_filter; + crtc_state->hw.sharpness_strength = crtc_state->uapi.sharpness_strength; intel_crtc_copy_uapi_to_hw_state_nomodeset(state, crtc); } @@ -4615,6 +4589,7 @@ copy_joiner_crtc_state_modeset(struct intel_atomic_state *state, drm_mode_copy(&secondary_crtc_state->hw.adjusted_mode, &primary_crtc_state->hw.adjusted_mode); secondary_crtc_state->hw.scaling_filter = primary_crtc_state->hw.scaling_filter; + secondary_crtc_state->hw.sharpness_strength = primary_crtc_state->hw.sharpness_strength; if (primary_crtc_state->dp_tunnel_ref.tunnel) drm_dp_tunnel_ref_get(primary_crtc_state->dp_tunnel_ref.tunnel, @@ -5368,12 +5343,12 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, PIPE_CONF_CHECK_BOOL(pch_pfit.enabled); PIPE_CONF_CHECK_RECT(pch_pfit.dst); + PIPE_CONF_CHECK_BOOL(pch_pfit.casf.enable); + PIPE_CONF_CHECK_I(pch_pfit.casf.win_size); + PIPE_CONF_CHECK_I(pch_pfit.casf.strength); PIPE_CONF_CHECK_I(scaler_state.scaler_id); PIPE_CONF_CHECK_I(pixel_rate); - PIPE_CONF_CHECK_BOOL(hw.casf_params.casf_enable); - PIPE_CONF_CHECK_I(hw.casf_params.win_size); - PIPE_CONF_CHECK_I(hw.casf_params.strength); PIPE_CONF_CHECK_X(gamma_mode); if (display->platform.cherryview) @@ -6428,6 +6403,10 @@ int intel_atomic_check(struct drm_device *dev, if (new_crtc_state->uapi.scaling_filter != old_crtc_state->uapi.scaling_filter) new_crtc_state->uapi.mode_changed = true; + + if (new_crtc_state->uapi.sharpness_strength != + old_crtc_state->uapi.sharpness_strength) + new_crtc_state->uapi.mode_changed = true; } intel_vrr_check_modeset(state); @@ -6760,7 +6739,9 @@ static void intel_enable_crtc(struct intel_atomic_state *state, intel_psr_notify_pipe_change(state, crtc, true); - display->funcs.display->crtc_enable(state, crtc); + display->modeset.funcs->crtc_enable(state, crtc); + + intel_crtc_wait_for_next_vblank(crtc); /* vblanks work again, re-enable pipe CRC. */ intel_crtc_enable_pipe_crc(crtc); @@ -6801,11 +6782,6 @@ static void intel_pre_update_crtc(struct intel_atomic_state *state, intel_vrr_set_transcoder_timings(new_crtc_state); } - if (intel_casf_enabling(new_crtc_state, old_crtc_state)) - intel_casf_enable(new_crtc_state); - else if (new_crtc_state->hw.casf_params.strength != old_crtc_state->hw.casf_params.strength) - intel_casf_update_strength(new_crtc_state); - intel_fbc_update(state, crtc); drm_WARN_ON(display->drm, !intel_display_power_is_enabled(display, POWER_DOMAIN_DC_OFF)); @@ -6896,7 +6872,7 @@ static void intel_old_crtc_state_disables(struct intel_atomic_state *state, intel_psr_notify_pipe_change(state, crtc, false); - display->funcs.display->crtc_disable(state, crtc); + display->modeset.funcs->crtc_disable(state, crtc); for_each_intel_crtc_in_pipe_mask(display->drm, pipe_crtc, intel_crtc_joined_pipe_mask(old_crtc_state)) { @@ -7548,7 +7524,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) } /* Now enable the clocks, plane, pipe, and connectors that we set up. */ - display->funcs.display->commit_modeset_enables(state); + display->modeset.funcs->commit_modeset_enables(state); /* FIXME probably need to sequence this properly */ intel_program_dpkgc_latency(state); @@ -8221,7 +8197,7 @@ intel_mode_valid_max_plane_size(struct intel_display *display, return MODE_OK; } -static const struct intel_display_funcs skl_display_funcs = { +static const struct intel_modeset_funcs skl_display_funcs = { .get_pipe_config = hsw_get_pipe_config, .crtc_enable = hsw_crtc_enable, .crtc_disable = hsw_crtc_disable, @@ -8230,7 +8206,7 @@ static const struct intel_display_funcs skl_display_funcs = { .fixup_initial_plane_config = skl_fixup_initial_plane_config, }; -static const struct intel_display_funcs ddi_display_funcs = { +static const struct intel_modeset_funcs ddi_display_funcs = { .get_pipe_config = hsw_get_pipe_config, .crtc_enable = hsw_crtc_enable, .crtc_disable = hsw_crtc_disable, @@ -8239,7 +8215,7 @@ static const struct intel_display_funcs ddi_display_funcs = { .fixup_initial_plane_config = i9xx_fixup_initial_plane_config, }; -static const struct intel_display_funcs pch_split_display_funcs = { +static const struct intel_modeset_funcs pch_split_display_funcs = { .get_pipe_config = ilk_get_pipe_config, .crtc_enable = ilk_crtc_enable, .crtc_disable = ilk_crtc_disable, @@ -8248,7 +8224,7 @@ static const struct intel_display_funcs pch_split_display_funcs = { .fixup_initial_plane_config = i9xx_fixup_initial_plane_config, }; -static const struct intel_display_funcs vlv_display_funcs = { +static const struct intel_modeset_funcs vlv_display_funcs = { .get_pipe_config = i9xx_get_pipe_config, .crtc_enable = valleyview_crtc_enable, .crtc_disable = i9xx_crtc_disable, @@ -8257,7 +8233,7 @@ static const struct intel_display_funcs vlv_display_funcs = { .fixup_initial_plane_config = i9xx_fixup_initial_plane_config, }; -static const struct intel_display_funcs i9xx_display_funcs = { +static const struct intel_modeset_funcs i9xx_display_funcs = { .get_pipe_config = i9xx_get_pipe_config, .crtc_enable = i9xx_crtc_enable, .crtc_disable = i9xx_crtc_disable, @@ -8273,16 +8249,16 @@ static const struct intel_display_funcs i9xx_display_funcs = { void intel_init_display_hooks(struct intel_display *display) { if (DISPLAY_VER(display) >= 9) { - display->funcs.display = &skl_display_funcs; + display->modeset.funcs = &skl_display_funcs; } else if (HAS_DDI(display)) { - display->funcs.display = &ddi_display_funcs; + display->modeset.funcs = &ddi_display_funcs; } else if (HAS_PCH_SPLIT(display)) { - display->funcs.display = &pch_split_display_funcs; + display->modeset.funcs = &pch_split_display_funcs; } else if (display->platform.cherryview || display->platform.valleyview) { - display->funcs.display = &vlv_display_funcs; + display->modeset.funcs = &vlv_display_funcs; } else { - display->funcs.display = &i9xx_display_funcs; + display->modeset.funcs = &i9xx_display_funcs; } } diff --git a/drivers/gpu/drm/i915/display/intel_display_clock_gating.c b/drivers/gpu/drm/i915/display/intel_display_clock_gating.c new file mode 100644 index 000000000000..d036c7e5863d --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_display_clock_gating.c @@ -0,0 +1,270 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright 2026 Intel Corporation + */ + +#include + +#include "intel_de.h" +#include "i9xx_plane_regs.h" +#include "intel_display.h" +#include "intel_display_clock_gating.h" +#include "intel_display_core.h" +#include "intel_display_regs.h" + +static void intel_display_gen9_init_clock_gating(struct intel_display *display) +{ + /* See Bspec note for PSR2_CTL bit 31, Wa#828:skl,bxt,kbl,cfl */ + intel_de_rmw(display, CHICKEN_PAR1_1, 0, SKL_EDP_PSR_FIX_RDWRAP); + + /* WaEnableChickenDCPR:skl,bxt,kbl,glk,cfl */ + intel_de_rmw(display, GEN8_CHICKEN_DCPR_1, 0, MASK_WAKEMEM); + + /* + * WaFbcWakeMemOn:skl,bxt,kbl,glk,cfl + * Display WA #0859: skl,bxt,kbl,glk,cfl + */ + intel_de_rmw(display, DISP_ARB_CTL, 0, DISP_FBC_MEMORY_WAKE); +} + +void intel_display_skl_init_clock_gating(struct intel_display *display) +{ + /* + * WaCompressedResourceDisplayNewHashMode:skl,kbl + * Display WA #0390: skl,kbl + * + * Must match Sampler, Pixel Back End, and Media. See + * WaCompressedResourceSamplerPbeMediaNewHashMode. + */ + intel_de_rmw(display, CHICKEN_PAR1_1, 0, SKL_DE_COMPRESSED_HASH_MODE); + + intel_display_gen9_init_clock_gating(display); + + /* + * WaFbcTurnOffFbcWatermark:skl + * Display WA #0562: skl + */ + intel_de_rmw(display, DISP_ARB_CTL, 0, DISP_FBC_WM_DIS); +} + +void intel_display_kbl_init_clock_gating(struct intel_display *display) +{ + /* + * WaCompressedResourceDisplayNewHashMode:skl,kbl + * Display WA #0390: skl,kbl + * + * Must match Sampler, Pixel Back End, and Media. See + * WaCompressedResourceSamplerPbeMediaNewHashMode. + */ + intel_de_rmw(display, CHICKEN_PAR1_1, 0, SKL_DE_COMPRESSED_HASH_MODE); + + intel_display_gen9_init_clock_gating(display); + + /* + * WaFbcTurnOffFbcWatermark:kbl + * Display WA #0562: kbl + */ + intel_de_rmw(display, DISP_ARB_CTL, 0, DISP_FBC_WM_DIS); +} + +void intel_display_cfl_init_clock_gating(struct intel_display *display) +{ + /* + * WaCompressedResourceDisplayNewHashMode:skl,kbl (and cfl, cml) + * Display WA #0390: skl,kbl (and cfl, cml) + * + * Must match Sampler, Pixel Back End, and Media. See + * WaCompressedResourceSamplerPbeMediaNewHashMode. + * + * NOTE: this is the same workaround used for skl and kbl, + * because the original implementation was checking HAS_LLC(), + * which cfl/cml have, even though the comment for the + * workaround doesn't mention it. + * + */ + intel_de_rmw(display, CHICKEN_PAR1_1, 0, SKL_DE_COMPRESSED_HASH_MODE); + + intel_display_gen9_init_clock_gating(display); + + /* + * WaFbcTurnOffFbcWatermark:cfl + * Display WA #0562: cfl + */ + intel_de_rmw(display, DISP_ARB_CTL, 0, DISP_FBC_WM_DIS); +} + +void intel_display_bxt_init_clock_gating(struct intel_display *display) +{ + intel_display_gen9_init_clock_gating(display); + + /* + * Wa: Backlight PWM may stop in the asserted state, causing backlight + * to stay fully on. + */ + intel_de_write(display, GEN9_CLKGATE_DIS_0, + intel_de_read(display, GEN9_CLKGATE_DIS_0) | + PWM1_GATING_DIS | PWM2_GATING_DIS); + + /* + * Lower the display internal timeout. + * This is needed to avoid any hard hangs when DSI port PLL + * is off and a MMIO access is attempted by any privilege + * application, using batch buffers or any other means. + */ + intel_de_write(display, RM_TIMEOUT, MMIO_TIMEOUT_US(950)); + + /* + * WaFbcTurnOffFbcWatermark:bxt + * Display WA #0562: bxt + */ + intel_de_rmw(display, DISP_ARB_CTL, 0, DISP_FBC_WM_DIS); +} + +void intel_display_glk_init_clock_gating(struct intel_display *display) +{ + intel_display_gen9_init_clock_gating(display); + + /* + * WaDisablePWMClockGating:glk + * Backlight PWM may stop in the asserted state, causing backlight + * to stay fully on. + */ + intel_de_write(display, GEN9_CLKGATE_DIS_0, + intel_de_read(display, GEN9_CLKGATE_DIS_0) | + PWM1_GATING_DIS | PWM2_GATING_DIS); +} + +void intel_display_bdw_clock_gating_disable_fbcq(struct intel_display *display) +{ + /* WaFbcAsynchFlipDisableFbcQueue:hsw,bdw */ + intel_de_rmw(display, CHICKEN_PIPESL_1(PIPE_A), 0, HSW_FBCQ_DIS); +} + +void intel_display_bdw_clock_gating_vblank_in_srd(struct intel_display *display) +{ + enum pipe pipe; + + /* WaPsrDPAMaskVBlankInSRD:hsw */ + intel_de_rmw(display, CHICKEN_PAR1_1, 0, HSW_MASK_VBL_TO_PIPE_IN_SRD); + + for_each_pipe(display, pipe) { + /* WaPsrDPRSUnmaskVBlankInSRD:hsw,bdw */ + intel_de_rmw(display, CHICKEN_PIPESL_1(pipe), 0, + BDW_UNMASK_VBL_TO_REGS_IN_SRD); + } +} + +void intel_display_bdw_clock_gating_kvm_notif(struct intel_display *display) +{ + /* WaKVMNotificationOnConfigChange:bdw */ + intel_de_rmw(display, CHICKEN_PAR2_1, 0, + KVM_CONFIG_CHANGE_NOTIFICATION_SELECT); +} + +void intel_display_hsw_init_clock_gating(struct intel_display *display) +{ + enum pipe pipe; + + /* WaFbcAsynchFlipDisableFbcQueue:hsw,bdw */ + intel_de_rmw(display, CHICKEN_PIPESL_1(PIPE_A), 0, HSW_FBCQ_DIS); + + /* WaPsrDPAMaskVBlankInSRD:hsw */ + intel_de_rmw(display, CHICKEN_PAR1_1, 0, HSW_MASK_VBL_TO_PIPE_IN_SRD); + + for_each_pipe(display, pipe) { + /* WaPsrDPRSUnmaskVBlankInSRD:hsw,bdw */ + intel_de_rmw(display, CHICKEN_PIPESL_1(pipe), 0, + HSW_UNMASK_VBL_TO_REGS_IN_SRD); + } +} + +void intel_display_disable_trickle_feed(struct intel_display *display) +{ + enum pipe pipe; + + for_each_pipe(display, pipe) { + intel_de_rmw(display, DSPCNTR(display, pipe), 0, + DISP_TRICKLE_FEED_DISABLE); + + intel_de_rmw(display, DSPSURF(display, pipe), 0, 0); + intel_de_posting_read(display, DSPSURF(display, pipe)); + } +} + +void intel_display_ilk_init_clock_gating(struct intel_display *display) +{ + u32 dspclk_gate = ILK_VRHUNIT_CLOCK_GATE_DISABLE; + + /* + * Required for FBC + * WaFbcDisableDpfcClockGating:ilk + */ + dspclk_gate |= ILK_DPFCRUNIT_CLOCK_GATE_DISABLE | + ILK_DPFCUNIT_CLOCK_GATE_DISABLE | + ILK_DPFDUNIT_CLOCK_GATE_ENABLE; + + intel_de_write(display, ILK_DISPLAY_CHICKEN2, + intel_de_read(display, ILK_DISPLAY_CHICKEN2) | + ILK_DPARB_GATE | ILK_VSDPFD_FULL); + dspclk_gate |= ILK_DPARBUNIT_CLOCK_GATE_ENABLE; + intel_de_write(display, DISP_ARB_CTL, + intel_de_read(display, DISP_ARB_CTL) | + DISP_FBC_WM_DIS); + + if (display->platform.ironlake && display->platform.mobile) { + /* WaFbcAsynchFlipDisableFbcQueue:ilk */ + intel_de_rmw(display, ILK_DISPLAY_CHICKEN1, 0, ILK_FBCQ_DIS); + intel_de_rmw(display, ILK_DISPLAY_CHICKEN2, 0, ILK_DPARB_GATE); + } + + intel_de_write(display, ILK_DSPCLK_GATE_D, dspclk_gate); + intel_de_rmw(display, ILK_DISPLAY_CHICKEN2, 0, ILK_ELPIN_409_SELECT); + + intel_display_disable_trickle_feed(display); +} + +void intel_display_gen6_init_clock_gating(struct intel_display *display) +{ + u32 dspclk_gate = ILK_VRHUNIT_CLOCK_GATE_DISABLE; + + intel_de_write(display, ILK_DSPCLK_GATE_D, dspclk_gate); + intel_de_rmw(display, ILK_DISPLAY_CHICKEN2, 0, ILK_ELPIN_409_SELECT); + + intel_de_write(display, ILK_DISPLAY_CHICKEN1, + intel_de_read(display, ILK_DISPLAY_CHICKEN1) | + ILK_FBCQ_DIS | ILK_PABSTRETCH_DIS); + intel_de_write(display, ILK_DISPLAY_CHICKEN2, + intel_de_read(display, ILK_DISPLAY_CHICKEN2) | + ILK_DPARB_GATE | ILK_VSDPFD_FULL); + intel_de_write(display, ILK_DSPCLK_GATE_D, + intel_de_read(display, ILK_DSPCLK_GATE_D) | + ILK_DPARBUNIT_CLOCK_GATE_ENABLE | + ILK_DPFDUNIT_CLOCK_GATE_ENABLE); + + intel_display_disable_trickle_feed(display); +} + +void intel_display_ivb_init_clock_gating(struct intel_display *display) +{ + intel_de_write(display, ILK_DSPCLK_GATE_D, ILK_VRHUNIT_CLOCK_GATE_DISABLE); + intel_de_rmw(display, ILK_DISPLAY_CHICKEN1, 0, ILK_FBCQ_DIS); +} + +void intel_display_g4x_init_clock_gating(struct intel_display *display) +{ + u32 dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE | + OVRUNIT_CLOCK_GATE_DISABLE | + OVCUNIT_CLOCK_GATE_DISABLE; + + if (display->platform.gm45) + dspclk_gate |= DSSUNIT_CLOCK_GATE_DISABLE; + + intel_de_write(display, DSPCLK_GATE_D, dspclk_gate); + + intel_display_disable_trickle_feed(display); +} + +void intel_display_i965gm_init_clock_gating(struct intel_display *display) +{ + intel_de_write(display, DSPCLK_GATE_D, 0); +} diff --git a/drivers/gpu/drm/i915/display/intel_display_clock_gating.h b/drivers/gpu/drm/i915/display/intel_display_clock_gating.h new file mode 100644 index 000000000000..b6dd34ca92dd --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_display_clock_gating.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright 2026 Intel Corporation + */ + +#ifndef __INTEL_DISPLAY_CLOCK_GATING_H__ +#define __INTEL_DISPLAY_CLOCK_GATING_H__ + +struct intel_display; + +void intel_display_skl_init_clock_gating(struct intel_display *display); +void intel_display_kbl_init_clock_gating(struct intel_display *display); +void intel_display_cfl_init_clock_gating(struct intel_display *display); +void intel_display_bxt_init_clock_gating(struct intel_display *display); +void intel_display_glk_init_clock_gating(struct intel_display *display); +void intel_display_bdw_clock_gating_disable_fbcq(struct intel_display *display); +void intel_display_bdw_clock_gating_vblank_in_srd(struct intel_display *display); +void intel_display_bdw_clock_gating_kvm_notif(struct intel_display *display); +void intel_display_hsw_init_clock_gating(struct intel_display *display); +void intel_display_disable_trickle_feed(struct intel_display *display); +void intel_display_ilk_init_clock_gating(struct intel_display *display); +void intel_display_gen6_init_clock_gating(struct intel_display *display); +void intel_display_ivb_init_clock_gating(struct intel_display *display); +void intel_display_g4x_init_clock_gating(struct intel_display *display); +void intel_display_i965gm_init_clock_gating(struct intel_display *display); + +#endif /* __INTEL_DISPLAY_CLOCK_GATING_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_display_core.h b/drivers/gpu/drm/i915/display/intel_display_core.h index d9424d954b18..76745ce6a716 100644 --- a/drivers/gpu/drm/i915/display/intel_display_core.h +++ b/drivers/gpu/drm/i915/display/intel_display_core.h @@ -47,7 +47,7 @@ struct intel_dpll_global_funcs; struct intel_dpll_mgr; struct intel_fbdev; struct intel_fdi_funcs; -struct intel_hotplug_funcs; +struct intel_hotplug_irq_funcs; struct intel_initial_plane_config; struct intel_opregion; struct intel_overlay; @@ -59,7 +59,7 @@ struct task_struct; /* Amount of PSF GV points, BSpec precisely defines this */ #define I915_NUM_PSF_GV_POINTS 3 -struct intel_display_funcs { +struct intel_modeset_funcs { /* * Returns the active state of the crtc, and if the crtc is active, * fills out the pipe-config with the hw state. @@ -100,6 +100,9 @@ struct intel_audio_state { }; struct intel_audio { + /* internal display audio functions */ + const struct intel_audio_funcs *funcs; + /* hda/i915 audio component */ struct i915_audio_component *component; bool component_registered; @@ -124,6 +127,9 @@ struct intel_audio { * dpll, because on some platforms plls share registers. */ struct intel_dpll_global { + /* internal dpll functions */ + const struct intel_dpll_global_funcs *funcs; + struct mutex lock; int num_dpll; @@ -152,6 +158,9 @@ struct intel_frontbuffer_tracking { }; struct intel_hotplug { + /* internal hotplug irq functions */ + const struct intel_hotplug_irq_funcs *funcs; + struct delayed_work hotplug_work; const u32 *hpd, *pch_hpd; @@ -244,6 +253,9 @@ struct intel_vbt_data { }; struct intel_wm { + /* internal watermark functions */ + const struct intel_wm_funcs *funcs; + /* * Raw watermark latency values: * in 0.1us units for WM0, @@ -297,33 +309,6 @@ struct intel_display { /* list of all intel_crtcs sorted by pipe */ struct list_head pipe_list; - /* Display functions */ - struct { - /* Top level crtc-ish functions */ - const struct intel_display_funcs *display; - - /* Display CDCLK functions */ - const struct intel_cdclk_funcs *cdclk; - - /* Display pll funcs */ - const struct intel_dpll_global_funcs *dpll; - - /* irq display functions */ - const struct intel_hotplug_funcs *hotplug; - - /* pm display functions */ - const struct intel_wm_funcs *wm; - - /* fdi display functions */ - const struct intel_fdi_funcs *fdi; - - /* Display internal color functions */ - const struct intel_color_funcs *color; - - /* Display internal audio functions */ - const struct intel_audio_funcs *audio; - } funcs; - struct { bool any_task_allowed; struct task_struct *allowed_task; @@ -351,6 +336,9 @@ struct intel_display { } bw; struct { + /* Internal CDCLK functions */ + const struct intel_cdclk_funcs *funcs; + /* The current hardware cdclk configuration */ struct intel_cdclk_config hw; @@ -365,6 +353,9 @@ struct intel_display { } cdclk; struct { + /* internal color functions */ + const struct intel_color_funcs *funcs; + struct drm_property_blob *glk_linear_degamma_lut; } color; @@ -418,6 +409,9 @@ struct intel_display { } fbdev; struct { + /* internal fdi functions */ + const struct intel_fdi_funcs *funcs; + unsigned int pll_freq; u32 rx_config; } fdi; @@ -518,6 +512,11 @@ struct intel_display { u32 pipestat_irq_mask[I915_MAX_PIPES]; } irq; + struct { + /* Top level crtc-ish functions */ + const struct intel_modeset_funcs *funcs; + } modeset; + struct { /* protected by wm.wm_mutex */ u16 linetime[I915_MAX_PIPES]; @@ -559,12 +558,15 @@ struct intel_display { unsigned long mask; } quirks; + struct { + u32 count; + } reset; + struct { /* restore state for suspend/resume and display reset */ struct drm_atomic_commit *modeset_state; struct drm_modeset_acquire_ctx reset_ctx; /* modeset stuck tracking for reset */ - atomic_t pending_fb_pin; u32 saveDSPARB; u32 saveSWF0[16]; u32 saveSWF1[16]; diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index 2614c4863c87..81bef000a4e3 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -27,6 +27,7 @@ #include "intel_display_power.h" #include "intel_display_power_well.h" #include "intel_display_regs.h" +#include "intel_display_reset.h" #include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_dmc.h" @@ -416,11 +417,12 @@ static void intel_scaler_info(struct seq_file *m, struct intel_crtc *crtc) /* Not all platforms have a scaler */ if (num_scalers) { - seq_printf(m, "\tnum_scalers=%d, scaler_users=%x scaler_id=%d scaling_filter=%d", + seq_printf(m, "\tnum_scalers=%d, scaler_users=%x scaler_id=%d scaling_filter=%d sharpness_strength=%d", num_scalers, crtc_state->scaler_state.scaler_users, crtc_state->scaler_state.scaler_id, - crtc_state->hw.scaling_filter); + crtc_state->hw.scaling_filter, + crtc_state->hw.sharpness_strength); for (i = 0; i < num_scalers; i++) { const struct intel_scaler *sc = @@ -837,6 +839,7 @@ void intel_display_debugfs_register(struct intel_display *display) intel_bios_debugfs_register(display); intel_cdclk_debugfs_register(display); + intel_display_reset_debugfs_register(display); intel_dmc_debugfs_register(display); intel_dp_test_debugfs_register(display); intel_fbc_debugfs_register(display); diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h b/drivers/gpu/drm/i915/display/intel_display_device.h index 1170ac346615..074e3ba8fb77 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.h +++ b/drivers/gpu/drm/i915/display/intel_display_device.h @@ -200,6 +200,7 @@ struct intel_display_platforms { #define HAS_PSR_TRANS_PUSH_FRAME_CHANGE(__display) (DISPLAY_VER(__display) >= 20) #define HAS_SAGV(__display) (DISPLAY_VER(__display) >= 9 && \ !(__display)->platform.broxton && !(__display)->platform.geminilake) +#define HAS_SAGV_WM(__display) (DISPLAY_VER(__display) >= 12 && !(__display)->platform.rocketlake) #define HAS_TRANSCODER(__display, trans) ((DISPLAY_RUNTIME_INFO(__display)->cpu_transcoder_mask & \ BIT(trans)) != 0) #define HAS_UNCOMPRESSED_JOINER(__display) (DISPLAY_VER(__display) >= 13) diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index 70c1bba7c0a8..b5bfdebc66ca 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -2458,6 +2458,10 @@ void dg1_de_irq_postinstall(struct intel_display *display) intel_de_write(display, GEN11_DISPLAY_INT_CTL, GEN11_DISPLAY_IRQ_ENABLE); } +struct intel_display_irq_funcs { + void (*reset)(struct intel_display *display); +}; + void intel_display_irq_init(struct intel_display *display) { spin_lock_init(&display->irq.lock); diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index 1a2de99ad78f..80ecf373fb19 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -25,7 +25,7 @@ #include "intel_display_wa.h" #include "intel_dmc.h" #include "intel_dram.h" -#include "intel_mchbar_regs.h" +#include "intel_mchbar.h" #include "intel_parent.h" #include "intel_pch_refclk.h" #include "intel_pmdemand.h" @@ -1252,7 +1252,7 @@ static void assert_can_disable_lcpll(struct intel_display *display) static u32 hsw_read_dcomp(struct intel_display *display) { if (display->platform.haswell) - return intel_de_read(display, D_COMP_HSW); + return intel_mchbar_read(display, D_COMP_HSW); else return intel_de_read(display, D_COMP_BDW); } @@ -1420,9 +1420,7 @@ static void hsw_disable_pc8(struct intel_display *display) intel_init_pch_refclk(display); /* Many display registers don't survive PC8+ */ -#ifdef I915 /* FIXME */ intel_clock_gating_init(display->drm); -#endif } static void intel_pch_reset_handshake(struct intel_display *display, @@ -1890,9 +1888,9 @@ static bool vlv_punit_is_power_gated(struct intel_display *display, u32 reg0) { bool ret; - vlv_punit_get(display->drm); - ret = (vlv_punit_read(display->drm, reg0) & SSPM0_SSC_MASK) == SSPM0_SSC_PWR_GATE; - vlv_punit_put(display->drm); + vlv_punit_get(display); + ret = (vlv_punit_read(display, reg0) & SSPM0_SSC_MASK) == SSPM0_SSC_PWR_GATE; + vlv_punit_put(display); return ret; } diff --git a/drivers/gpu/drm/i915/display/intel_display_power_map.c b/drivers/gpu/drm/i915/display/intel_display_power_map.c index 65204d68a759..3400080d78d2 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power_map.c +++ b/drivers/gpu/drm/i915/display/intel_display_power_map.c @@ -4,13 +4,13 @@ */ #include +#include #include "intel_display_core.h" #include "intel_display_power_map.h" #include "intel_display_power_well.h" #include "intel_display_regs.h" #include "intel_display_types.h" -#include "vlv_iosf_sb_reg.h" #define __LIST_INLINE_ELEMS(__elem_type, ...) \ ((__elem_type[]) { __VA_ARGS__ }) diff --git a/drivers/gpu/drm/i915/display/intel_display_power_well.c b/drivers/gpu/drm/i915/display/intel_display_power_well.c index f855f0f88694..6fbfd46461b0 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power_well.c +++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c @@ -34,7 +34,6 @@ #include "intel_vga.h" #include "skl_watermark.h" #include "vlv_dpio_phy_regs.h" -#include "vlv_iosf_sb_reg.h" #include "vlv_sideband.h" /* @@ -1189,28 +1188,28 @@ static void vlv_set_power_well(struct intel_display *display, state = enable ? PUNIT_PWRGT_PWR_ON(pw_idx) : PUNIT_PWRGT_PWR_GATE(pw_idx); - vlv_punit_get(display->drm); + vlv_punit_get(display); - val = vlv_punit_read(display->drm, PUNIT_REG_PWRGT_STATUS); + val = vlv_punit_read(display, PUNIT_REG_PWRGT_STATUS); if ((val & mask) == state) goto out; - ctrl = vlv_punit_read(display->drm, PUNIT_REG_PWRGT_CTRL); + ctrl = vlv_punit_read(display, PUNIT_REG_PWRGT_CTRL); ctrl &= ~mask; ctrl |= state; - vlv_punit_write(display->drm, PUNIT_REG_PWRGT_CTRL, ctrl); + vlv_punit_write(display, PUNIT_REG_PWRGT_CTRL, ctrl); - ret = poll_timeout_us(val = vlv_punit_read(display->drm, PUNIT_REG_PWRGT_STATUS), + ret = poll_timeout_us(val = vlv_punit_read(display, PUNIT_REG_PWRGT_STATUS), (val & mask) == state, 500, 100 * 1000, false); if (ret) drm_err(display->drm, "timeout setting power well state %08x (%08x)\n", state, - vlv_punit_read(display->drm, PUNIT_REG_PWRGT_CTRL)); + vlv_punit_read(display, PUNIT_REG_PWRGT_CTRL)); out: - vlv_punit_put(display->drm); + vlv_punit_put(display); } static void vlv_power_well_enable(struct intel_display *display, @@ -1237,9 +1236,9 @@ static bool vlv_power_well_enabled(struct intel_display *display, mask = PUNIT_PWRGT_MASK(pw_idx); ctrl = PUNIT_PWRGT_PWR_ON(pw_idx); - vlv_punit_get(display->drm); + vlv_punit_get(display); - state = vlv_punit_read(display->drm, PUNIT_REG_PWRGT_STATUS) & mask; + state = vlv_punit_read(display, PUNIT_REG_PWRGT_STATUS) & mask; /* * We only ever set the power-on and power-gate states, anything * else is unexpected. @@ -1253,10 +1252,10 @@ static bool vlv_power_well_enabled(struct intel_display *display, * A transient state at this point would mean some unexpected party * is poking at the power controls too. */ - ctrl = vlv_punit_read(display->drm, PUNIT_REG_PWRGT_CTRL) & mask; + ctrl = vlv_punit_read(display, PUNIT_REG_PWRGT_CTRL) & mask; drm_WARN_ON(display->drm, ctrl != state); - vlv_punit_put(display->drm); + vlv_punit_put(display); return enabled; } @@ -1533,30 +1532,30 @@ static void chv_dpio_cmn_power_well_enable(struct intel_display *display, drm_err(display->drm, "Display PHY %d is not power up\n", phy); - vlv_dpio_get(display->drm); + vlv_dpio_get(display); /* Enable dynamic power down */ - tmp = vlv_dpio_read(display->drm, phy, CHV_CMN_DW28); + tmp = vlv_dpio_read(display, phy, CHV_CMN_DW28); tmp |= DPIO_DYNPWRDOWNEN_CH0 | DPIO_CL1POWERDOWNEN | DPIO_SUS_CLK_CONFIG_GATE_CLKREQ; - vlv_dpio_write(display->drm, phy, CHV_CMN_DW28, tmp); + vlv_dpio_write(display, phy, CHV_CMN_DW28, tmp); if (id == VLV_DISP_PW_DPIO_CMN_BC) { - tmp = vlv_dpio_read(display->drm, phy, CHV_CMN_DW6_CH1); + tmp = vlv_dpio_read(display, phy, CHV_CMN_DW6_CH1); tmp |= DPIO_DYNPWRDOWNEN_CH1; - vlv_dpio_write(display->drm, phy, CHV_CMN_DW6_CH1, tmp); + vlv_dpio_write(display, phy, CHV_CMN_DW6_CH1, tmp); } else { /* * Force the non-existing CL2 off. BXT does this * too, so maybe it saves some power even though * CL2 doesn't exist? */ - tmp = vlv_dpio_read(display->drm, phy, CHV_CMN_DW30); + tmp = vlv_dpio_read(display, phy, CHV_CMN_DW30); tmp |= DPIO_CL2_LDOFUSE_PWRENB; - vlv_dpio_write(display->drm, phy, CHV_CMN_DW30, tmp); + vlv_dpio_write(display, phy, CHV_CMN_DW30, tmp); } - vlv_dpio_put(display->drm); + vlv_dpio_put(display); display->power.chv_phy_control |= PHY_COM_LANE_RESET_DEASSERT(phy); intel_de_write(display, DISPLAY_PHY_CONTROL, @@ -1624,9 +1623,9 @@ static void assert_chv_phy_powergate(struct intel_display *display, enum dpio_ph else reg = CHV_CMN_DW6_CH1; - vlv_dpio_get(display->drm); - val = vlv_dpio_read(display->drm, phy, reg); - vlv_dpio_put(display->drm); + vlv_dpio_get(display); + val = vlv_dpio_read(display, phy, reg); + vlv_dpio_put(display); /* * This assumes !override is only used when the port is disabled. @@ -1740,9 +1739,9 @@ static bool chv_pipe_power_well_enabled(struct intel_display *display, bool enabled; u32 state, ctrl; - vlv_punit_get(display->drm); + vlv_punit_get(display); - state = vlv_punit_read(display->drm, PUNIT_REG_DSPSSPM) & DP_SSS_MASK(pipe); + state = vlv_punit_read(display, PUNIT_REG_DSPSSPM) & DP_SSS_MASK(pipe); /* * We only ever set the power-on and power-gate states, anything * else is unexpected. @@ -1755,10 +1754,10 @@ static bool chv_pipe_power_well_enabled(struct intel_display *display, * A transient state at this point would mean some unexpected party * is poking at the power controls too. */ - ctrl = vlv_punit_read(display->drm, PUNIT_REG_DSPSSPM) & DP_SSC_MASK(pipe); + ctrl = vlv_punit_read(display, PUNIT_REG_DSPSSPM) & DP_SSC_MASK(pipe); drm_WARN_ON(display->drm, ctrl << 16 != state); - vlv_punit_put(display->drm); + vlv_punit_put(display); return enabled; } @@ -1774,29 +1773,29 @@ static void chv_set_pipe_power_well(struct intel_display *display, state = enable ? DP_SSS_PWR_ON(pipe) : DP_SSS_PWR_GATE(pipe); - vlv_punit_get(display->drm); + vlv_punit_get(display); - ctrl = vlv_punit_read(display->drm, PUNIT_REG_DSPSSPM); + ctrl = vlv_punit_read(display, PUNIT_REG_DSPSSPM); if ((ctrl & DP_SSS_MASK(pipe)) == state) goto out; ctrl &= ~DP_SSC_MASK(pipe); ctrl |= enable ? DP_SSC_PWR_ON(pipe) : DP_SSC_PWR_GATE(pipe); - vlv_punit_write(display->drm, PUNIT_REG_DSPSSPM, ctrl); + vlv_punit_write(display, PUNIT_REG_DSPSSPM, ctrl); - ret = poll_timeout_us(ctrl = vlv_punit_read(display->drm, PUNIT_REG_DSPSSPM), + ret = poll_timeout_us(ctrl = vlv_punit_read(display, PUNIT_REG_DSPSSPM), (ctrl & DP_SSS_MASK(pipe)) == state, 500, 100 * 1000, false); if (ret) drm_err(display->drm, "timeout setting power well state %08x (%08x)\n", state, - vlv_punit_read(display->drm, PUNIT_REG_DSPSSPM)); + vlv_punit_read(display, PUNIT_REG_DSPSSPM)); #undef COND out: - vlv_punit_put(display->drm); + vlv_punit_put(display); } static void chv_pipe_power_well_sync_hw(struct intel_display *display, diff --git a/drivers/gpu/drm/i915/display/intel_display_regs.h b/drivers/gpu/drm/i915/display/intel_display_regs.h index 4746e9ebd920..bc508995ad8b 100644 --- a/drivers/gpu/drm/i915/display/intel_display_regs.h +++ b/drivers/gpu/drm/i915/display/intel_display_regs.h @@ -217,6 +217,34 @@ # define DPIOUNIT_CLOCK_GATE_DISABLE (1 << 6) /* 915-945 */ # define OVFUNIT_CLOCK_GATE_DISABLE (1 << 5) # define OVBUNIT_CLOCK_GATE_DISABLE (1 << 4) + +#define ILK_DISPLAY_CHICKEN1 _MMIO(0x42000) +#define ILK_FBCQ_DIS REG_BIT(22) +#define ILK_PABSTRETCH_DIS REG_BIT(21) +#define ILK_SABSTRETCH_DIS REG_BIT(20) +#define IVB_PRI_STRETCH_MAX_MASK REG_GENMASK(21, 20) +#define IVB_PRI_STRETCH_MAX_X8 REG_FIELD_PREP(IVB_PRI_STRETCH_MAX_MASK, 0) +#define IVB_PRI_STRETCH_MAX_X4 REG_FIELD_PREP(IVB_PRI_STRETCH_MAX_MASK, 1) +#define IVB_PRI_STRETCH_MAX_X2 REG_FIELD_PREP(IVB_PRI_STRETCH_MAX_MASK, 2) +#define IVB_PRI_STRETCH_MAX_X1 REG_FIELD_PREP(IVB_PRI_STRETCH_MAX_MASK, 3) +#define IVB_SPR_STRETCH_MAX_MASK REG_GENMASK(19, 18) +#define IVB_SPR_STRETCH_MAX_X8 REG_FIELD_PREP(IVB_SPR_STRETCH_MAX_MASK, 0) +#define IVB_SPR_STRETCH_MAX_X4 REG_FIELD_PREP(IVB_SPR_STRETCH_MAX_MASK, 1) +#define IVB_SPR_STRETCH_MAX_X2 REG_FIELD_PREP(IVB_SPR_STRETCH_MAX_MASK, 2) +#define IVB_SPR_STRETCH_MAX_X1 REG_FIELD_PREP(IVB_SPR_STRETCH_MAX_MASK, 3) + +#define ILK_DISPLAY_CHICKEN2 _MMIO(0x42004) +/* Required on all Ironlake and Sandybridge according to the B-Spec. */ +#define ILK_ELPIN_409_SELECT REG_BIT(25) +#define ILK_DPARB_GATE REG_BIT(22) +#define ILK_VSDPFD_FULL REG_BIT(21) + +#define ILK_DSPCLK_GATE_D _MMIO(0x42020) +#define ILK_VRHUNIT_CLOCK_GATE_DISABLE REG_BIT(28) +#define ILK_DPFCUNIT_CLOCK_GATE_DISABLE REG_BIT(9) +#define ILK_DPFCRUNIT_CLOCK_GATE_DISABLE REG_BIT(8) +#define ILK_DPFDUNIT_CLOCK_GATE_ENABLE REG_BIT(7) +#define ILK_DPARBUNIT_CLOCK_GATE_ENABLE REG_BIT(5) /* * This bit must be set on the 830 to prevent hangs when turning off the * overlay scaler. @@ -405,6 +433,9 @@ #define SKL_EDP_PSR_FIX_RDWRAP REG_BIT(3) #define IGNORE_PSR2_HW_TRACKING REG_BIT(1) +#define CHICKEN_PAR2_1 _MMIO(0x42090) +#define KVM_CONFIG_CHANGE_NOTIFICATION_SELECT REG_BIT(14) + /* * GEN9 clock gating regs */ @@ -2263,6 +2294,7 @@ #define TRANS_DP2_CTL(trans) _MMIO_TRANS(trans, _TRANS_DP2_CTL_A, _TRANS_DP2_CTL_B) #define TRANS_DP2_128B132B_CHANNEL_CODING REG_BIT(31) #define TRANS_DP2_PANEL_REPLAY_ENABLE REG_BIT(30) +#define TRANS_DP2_PR_TUNNELING_ENABLE REG_BIT(26) #define TRANS_DP2_DEBUG_ENABLE REG_BIT(23) #define _TRANS_DP2_VFREQHIGH_A 0x600a4 diff --git a/drivers/gpu/drm/i915/display/intel_display_reset.c b/drivers/gpu/drm/i915/display/intel_display_reset.c index 9481165ecfec..504ec7043cd9 100644 --- a/drivers/gpu/drm/i915/display/intel_display_reset.c +++ b/drivers/gpu/drm/i915/display/intel_display_reset.c @@ -3,6 +3,8 @@ * Copyright © 2023 Intel Corporation */ +#include + #include #include @@ -16,28 +18,23 @@ #include "intel_hotplug.h" #include "intel_pps.h" -bool intel_display_reset_test(struct intel_display *display) +bool intel_display_reset_supported(struct intel_display *display) { - return display->params.force_reset_modeset_test; + return display && HAS_DISPLAY(display); } -/* returns true if intel_display_reset_finish() needs to be called */ -bool intel_display_reset_prepare(struct intel_display *display, - modeset_stuck_fn modeset_stuck, void *context) +bool intel_display_reset_test(struct intel_display *display) +{ + return display && HAS_DISPLAY(display) && + display->params.force_reset_modeset_test; +} + +void intel_display_reset_prepare(struct intel_display *display) { struct drm_modeset_acquire_ctx *ctx = &display->restore.reset_ctx; struct drm_atomic_commit *state; int ret; - if (!HAS_DISPLAY(display)) - return false; - - if (atomic_read(&display->restore.pending_fb_pin)) { - drm_dbg_kms(display->drm, - "Modeset potentially stuck, unbreaking through wedging\n"); - modeset_stuck(context); - } - /* * Need mode_config.mutex so that we don't * trample ongoing ->detect() and whatnot. @@ -60,7 +57,7 @@ bool intel_display_reset_prepare(struct intel_display *display, ret = PTR_ERR(state); drm_err(display->drm, "Duplicating state failed with %i\n", ret); - return true; + return; } ret = drm_atomic_helper_disable_all(display->drm, ctx); @@ -68,13 +65,12 @@ bool intel_display_reset_prepare(struct intel_display *display, drm_err(display->drm, "Suspending crtc's failed with %i\n", ret); drm_atomic_commit_put(state); - return true; + return; } + display->reset.count++; display->restore.modeset_state = state; state->acquire_ctx = ctx; - - return true; } void intel_display_reset_finish(struct intel_display *display, bool test_only) @@ -83,9 +79,6 @@ void intel_display_reset_finish(struct intel_display *display, bool test_only) struct drm_atomic_commit *state; int ret; - if (!HAS_DISPLAY(display)) - return; - state = fetch_and_zero(&display->restore.modeset_state); if (!state) goto unlock; @@ -124,3 +117,10 @@ void intel_display_reset_finish(struct intel_display *display, bool test_only) drm_modeset_acquire_fini(ctx); mutex_unlock(&display->drm->mode_config.mutex); } + +void intel_display_reset_debugfs_register(struct intel_display *display) +{ + debugfs_create_u32("intel_display_reset_count", 0400, + display->drm->debugfs_root, + &display->reset.count); +} diff --git a/drivers/gpu/drm/i915/display/intel_display_reset.h b/drivers/gpu/drm/i915/display/intel_display_reset.h index 8b3bda134454..b88c330a3441 100644 --- a/drivers/gpu/drm/i915/display/intel_display_reset.h +++ b/drivers/gpu/drm/i915/display/intel_display_reset.h @@ -10,11 +10,11 @@ struct intel_display; -typedef void modeset_stuck_fn(void *context); - +bool intel_display_reset_supported(struct intel_display *display); bool intel_display_reset_test(struct intel_display *display); -bool intel_display_reset_prepare(struct intel_display *display, - modeset_stuck_fn modeset_stuck, void *context); +void intel_display_reset_prepare(struct intel_display *display); void intel_display_reset_finish(struct intel_display *display, bool test_only); +void intel_display_reset_debugfs_register(struct intel_display *display); + #endif /* __INTEL_RESET_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 44cb329216a7..26e59110e743 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -683,14 +683,15 @@ struct intel_plane_state { struct i915_vma *ggtt_vma; struct i915_vma *dpt_vma; - unsigned long flags; -#define PLANE_HAS_FENCE BIT(0) struct intel_fb_view view; /* for legacy cursor fb unpin */ struct drm_vblank_work unpin_work; + /* fenced region ID (-1 if none) */ + s8 fence_id; + /* Plane pxp decryption state */ bool decrypt; @@ -755,9 +756,7 @@ struct intel_plane_state { }; struct intel_initial_plane_config { - struct intel_framebuffer *fb; - struct intel_memory_region *mem; - resource_size_t phys_base; + struct drm_framebuffer *fb; struct i915_vma *vma; int size; u32 base; @@ -997,7 +996,7 @@ struct intel_casf { struct scaler_filter_coeff coeff[SCALER_FILTER_NUM_TAPS]; u8 strength; u8 win_size; - bool casf_enable; + bool enable; }; struct intel_crtc_state { @@ -1036,7 +1035,7 @@ struct intel_crtc_state { struct drm_property_blob *degamma_lut, *gamma_lut, *ctm; struct drm_display_mode mode, pipe_mode, adjusted_mode; enum drm_scaling_filter scaling_filter; - struct intel_casf casf_params; + u8 sharpness_strength; } hw; /* actual state of LUTs */ @@ -1223,6 +1222,7 @@ struct intel_crtc_state { /* Panel fitter placement and size for Ironlake+ */ struct { + struct intel_casf casf; struct drm_rect dst; bool enabled; bool force_thru; diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index 1667a829e708..0df4f42ba3e3 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -505,6 +505,14 @@ static void pipedmc_clock_gating_wa(struct intel_display *display, bool enable) static u32 pipedmc_interrupt_mask(struct intel_display *display) { + /* + * TODO: Check if PIPEDMC_ERROR bit enabling causes errors + * on PTL, enable it if validation passes + */ + if (DISPLAY_VER(display) >= 35) + return PIPEDMC_FLIPQ_PROG_DONE | + PIPEDMC_ERROR; + /* * FIXME PIPEDMC_ERROR not enabled for now due to LNL pipe B * triggering it during the first DC state transition. Figure @@ -1574,10 +1582,10 @@ void intel_dmc_update_dc6_allowed_count(struct intel_display *display, struct intel_dmc *dmc = display_to_dmc(display); u32 dc5_cur_count; - if (DISPLAY_VER(dmc->display) < 14) + if (DISPLAY_VER(display) < 14) return; - dc5_cur_count = intel_de_read(dmc->display, DG1_DMC_DEBUG_DC5_COUNT); + dc5_cur_count = intel_de_read(display, DG1_DMC_DEBUG_DC5_COUNT); if (!start_tracking) dmc->dc6_allowed.count += dc5_cur_count - dmc->dc6_allowed.dc5_start; diff --git a/drivers/gpu/drm/i915/display/intel_dmc_wl.c b/drivers/gpu/drm/i915/display/intel_dmc_wl.c index 73a3101514f3..ddf1a1f1ebc3 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc_wl.c +++ b/drivers/gpu/drm/i915/display/intel_dmc_wl.c @@ -46,7 +46,7 @@ * atomic variant of waiting MMIO. */ #define DMC_WAKELOCK_CTL_TIMEOUT_US 5000 -#define DMC_WAKELOCK_HOLD_TIME 50 +#define DMC_WAKELOCK_HOLD_TIME 5 /* * Possible non-negative values for the enable_dmc_wl param. diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 45c54970b0df..86123614b7ba 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1234,28 +1234,11 @@ int intel_dp_output_format_link_bpp_x16(enum intel_output_format output_format, return fxp_q4_from_int(pipe_bpp); } -static enum intel_output_format -intel_dp_sink_format(struct intel_connector *connector, - const struct drm_display_mode *mode) -{ - const struct drm_display_info *info = &connector->base.display_info; - - if (drm_mode_is_420_only(info, mode)) - return INTEL_OUTPUT_FORMAT_YCBCR420; - - return INTEL_OUTPUT_FORMAT_RGB; -} - static int intel_dp_mode_min_link_bpp_x16(struct intel_connector *connector, - const struct drm_display_mode *mode) + const struct drm_display_mode *mode, + enum intel_output_format output_format) { - enum intel_output_format output_format, sink_format; - - sink_format = intel_dp_sink_format(connector, mode); - - output_format = intel_dp_output_format(connector, sink_format); - return intel_dp_output_format_link_bpp_x16(output_format, intel_dp_min_bpp(output_format)); } @@ -1317,23 +1300,29 @@ intel_dp_tmds_clock_valid(struct intel_dp *intel_dp, return MODE_OK; } +static int frl_required_bw(int clock, int bpc, + enum intel_output_format sink_format) +{ + if (sink_format == INTEL_OUTPUT_FORMAT_YCBCR420) + clock /= 2; + + return clock * bpc * 3; +} + static enum drm_mode_status intel_dp_mode_valid_downstream(struct intel_connector *connector, const struct drm_display_mode *mode, - int target_clock) + int target_clock, + enum intel_output_format sink_format) { struct intel_dp *intel_dp = intel_attached_dp(connector); - const struct drm_display_info *info = &connector->base.display_info; - enum drm_mode_status status; - enum intel_output_format sink_format; /* If PCON supports FRL MODE, check FRL bandwidth constraints */ if (intel_dp->dfp.pcon_max_frl_bw) { - int link_bpp_x16 = intel_dp_mode_min_link_bpp_x16(connector, mode); - int target_bw; - int max_frl_bw; + int target_bw, max_frl_bw; - target_bw = fxp_q4_to_int_roundup(link_bpp_x16) * target_clock; + /* Assume 8bpc for the FRL bandwidth check */ + target_bw = frl_required_bw(target_clock, 8, sink_format); max_frl_bw = intel_dp->dfp.pcon_max_frl_bw; @@ -1350,25 +1339,36 @@ intel_dp_mode_valid_downstream(struct intel_connector *connector, target_clock > intel_dp->dfp.max_dotclock) return MODE_CLOCK_HIGH; - sink_format = intel_dp_sink_format(connector, mode); - /* Assume 8bpc for the DP++/HDMI/DVI TMDS clock check */ - status = intel_dp_tmds_clock_valid(intel_dp, target_clock, - 8, sink_format, true); + return intel_dp_tmds_clock_valid(intel_dp, target_clock, + 8, sink_format, true); +} - if (status != MODE_OK) { - if (sink_format == INTEL_OUTPUT_FORMAT_YCBCR420 || - !connector->base.ycbcr_420_allowed || - !drm_mode_is_420_also(info, mode)) - return status; - sink_format = INTEL_OUTPUT_FORMAT_YCBCR420; - status = intel_dp_tmds_clock_valid(intel_dp, target_clock, - 8, sink_format, true); - if (status != MODE_OK) - return status; +static enum drm_mode_status +intel_dp_sink_format_valid(struct intel_connector *connector, + const struct drm_display_mode *mode, + enum intel_output_format sink_format) +{ + struct intel_dp *intel_dp = intel_attached_dp(connector); + const struct drm_display_info *info = &connector->base.display_info; + + switch (sink_format) { + case INTEL_OUTPUT_FORMAT_YCBCR420: + if (intel_dp->dfp.min_tmds_clock && + !intel_dp_has_hdmi_sink(intel_dp)) + return MODE_NO_420; + + if (!connector->base.ycbcr_420_allowed || + !drm_mode_is_420(info, mode)) + return MODE_NO_420; + + return MODE_OK; + case INTEL_OUTPUT_FORMAT_RGB: + return MODE_OK; + default: + MISSING_CASE(sink_format); + return MODE_BAD; } - - return MODE_OK; } int intel_dp_max_hdisplay_per_pipe(struct intel_display *display) @@ -1442,15 +1442,14 @@ bool intel_dp_dotclk_valid(struct intel_display *display, } static enum drm_mode_status -intel_dp_mode_valid(struct drm_connector *_connector, - const struct drm_display_mode *mode) +intel_dp_mode_valid_format(struct intel_connector *connector, + const struct drm_display_mode *mode, + int target_clock, + enum intel_output_format sink_format) { - struct intel_display *display = to_intel_display(_connector->dev); - struct intel_connector *connector = to_intel_connector(_connector); + struct intel_display *display = to_intel_display(connector); struct intel_dp *intel_dp = intel_attached_dp(connector); - enum intel_output_format sink_format, output_format; - const struct drm_display_mode *fixed_mode; - int target_clock = mode->clock; + enum intel_output_format output_format; int max_rate, mode_rate, max_lanes, max_link_clock; u16 dsc_max_compressed_bpp = 0; enum drm_mode_status status; @@ -1458,29 +1457,10 @@ intel_dp_mode_valid(struct drm_connector *_connector, int num_joined_pipes; int link_bpp_x16; - status = intel_cpu_transcoder_mode_valid(display, mode); + status = intel_dp_sink_format_valid(connector, mode, sink_format); if (status != MODE_OK) return status; - if (mode->flags & DRM_MODE_FLAG_DBLCLK) - return MODE_H_ILLEGAL; - - if (mode->clock < 10000) - return MODE_CLOCK_LOW; - - if (intel_dp_hdisplay_bad(display, mode->hdisplay)) - return MODE_H_ILLEGAL; - - fixed_mode = intel_panel_fixed_mode(connector, mode); - if (intel_dp_is_edp(intel_dp) && fixed_mode) { - status = intel_panel_mode_valid(connector, mode); - if (status != MODE_OK) - return status; - - target_clock = fixed_mode->clock; - } - - sink_format = intel_dp_sink_format(connector, mode); output_format = intel_dp_output_format(connector, sink_format); max_link_clock = intel_dp_max_link_rate(intel_dp); @@ -1488,7 +1468,8 @@ intel_dp_mode_valid(struct drm_connector *_connector, max_rate = intel_dp_max_link_data_rate(intel_dp, max_link_clock, max_lanes); - link_bpp_x16 = intel_dp_mode_min_link_bpp_x16(connector, mode); + link_bpp_x16 = intel_dp_mode_min_link_bpp_x16(connector, mode, + output_format); mode_rate = intel_dp_link_required(max_link_clock, max_lanes, target_clock, mode->hdisplay, link_bpp_x16, 0); @@ -1578,7 +1559,70 @@ intel_dp_mode_valid(struct drm_connector *_connector, if (status != MODE_OK) return status; - return intel_dp_mode_valid_downstream(connector, mode, target_clock); + return intel_dp_mode_valid_downstream(connector, mode, + target_clock, sink_format); +} + +static enum drm_mode_status +intel_dp_mode_valid(struct drm_connector *_connector, + const struct drm_display_mode *mode) +{ + struct intel_display *display = to_intel_display(_connector->dev); + struct intel_connector *connector = to_intel_connector(_connector); + const struct drm_display_info *info = &connector->base.display_info; + struct intel_dp *intel_dp = intel_attached_dp(connector); + const struct drm_display_mode *fixed_mode; + int target_clock = mode->clock; + enum drm_mode_status status; + + status = intel_cpu_transcoder_mode_valid(display, mode); + if (status != MODE_OK) + return status; + + if (mode->flags & DRM_MODE_FLAG_DBLCLK) + return MODE_H_ILLEGAL; + + if (mode->clock < 10000) + return MODE_CLOCK_LOW; + + if (intel_dp_hdisplay_bad(display, mode->hdisplay)) + return MODE_H_ILLEGAL; + + fixed_mode = intel_panel_fixed_mode(connector, mode); + if (intel_dp_is_edp(intel_dp) && fixed_mode) { + status = intel_panel_mode_valid(connector, mode); + if (status != MODE_OK) + return status; + + target_clock = fixed_mode->clock; + } + + /* + * TODO: Even when using a 4:2:0 sink_format intel_dp_output_format() + * will always choose a 4:4:4 output_format if the DFP can do the + * 4:4:4->4:2:0 conversion for us. Thus a mode may still be rejected + * if we only have enough DP link bandwidth for 4:2:0 but not for + * 4:4:4. Another attempt with an explicit 4:2:0 output_format might + * be needed here. intel_dp_compute_config() would need the same + * logic, or else the actual modeset would still fail. + * + * Also a lot of the checks only depend on output_format but not + * sink_format, so we are potentially doing redundant work by + * testing the same output_format for two different sink_formats. + */ + if (drm_mode_is_420_only(info, mode)) { + status = intel_dp_mode_valid_format(connector, mode, target_clock, + INTEL_OUTPUT_FORMAT_YCBCR420); + } else { + status = intel_dp_mode_valid_format(connector, mode, target_clock, + INTEL_OUTPUT_FORMAT_RGB); + + if (status != MODE_OK && drm_mode_is_420_also(info, mode)) + status = intel_dp_mode_valid_format(connector, mode, target_clock, + INTEL_OUTPUT_FORMAT_YCBCR420); + } + + return status; } bool intel_dp_source_supports_tps3(struct intel_display *display) @@ -3124,6 +3168,21 @@ static void intel_dp_compute_vsc_colorimetry(const struct intel_crtc_state *crtc vsc->content_type = DP_CONTENT_TYPE_NOT_DEFINED; } +static bool intel_dp_needs_as_sdp(struct intel_dp *intel_dp, + struct intel_crtc_state *crtc_state) +{ + if (!intel_dp->as_sdp_supported) + return false; + + /* + * #TODO Implement AS SDP for DP branch device. + */ + if (drm_dp_is_branch(intel_dp->dpcd)) + return false; + + return crtc_state->vrr.enable; +} + static void intel_dp_compute_as_sdp(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state) { @@ -3131,7 +3190,12 @@ static void intel_dp_compute_as_sdp(struct intel_dp *intel_dp, const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; - if (!crtc_state->vrr.enable || !intel_dp->as_sdp_supported) + /* + * #FIXME: SDP/infoframe updates aren’t truly atomic, and with the new + * cdclk->tc clock crossing we may transiently send a corrupted packet + * if the update lands mid‑transmission. + */ + if (!intel_dp_needs_as_sdp(intel_dp, crtc_state)) return; crtc_state->infoframes.enable |= intel_hdmi_infoframe_enable(DP_SDP_ADAPTIVE_SYNC); @@ -3330,41 +3394,59 @@ static int intel_dp_compute_output_format(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state, struct drm_connector_state *conn_state, - bool respect_downstream_limits) + bool respect_downstream_limits, + enum intel_output_format sink_format) +{ + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + struct intel_connector *connector = intel_dp->attached_connector; + const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; + + if (intel_dp_sink_format_valid(connector, adjusted_mode, + sink_format) != MODE_OK) + return -EINVAL; + + crtc_state->sink_format = sink_format; + crtc_state->output_format = intel_dp_output_format(connector, crtc_state->sink_format); + + return intel_dp_compute_link_config(encoder, crtc_state, conn_state, + respect_downstream_limits); +} + +static int +intel_dp_compute_formats(struct intel_encoder *encoder, + struct intel_crtc_state *crtc_state, + struct drm_connector_state *conn_state, + bool respect_downstream_limits) { struct intel_display *display = to_intel_display(encoder); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct intel_connector *connector = intel_dp->attached_connector; const struct drm_display_info *info = &connector->base.display_info; const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; - bool ycbcr_420_only; int ret; - ycbcr_420_only = drm_mode_is_420_only(info, adjusted_mode); + if (drm_mode_is_420_only(info, adjusted_mode)) { + ret = intel_dp_compute_output_format(encoder, crtc_state, conn_state, + respect_downstream_limits, + INTEL_OUTPUT_FORMAT_YCBCR420); - if (ycbcr_420_only && !connector->base.ycbcr_420_allowed) { - drm_dbg_kms(display->drm, - "YCbCr 4:2:0 mode but YCbCr 4:2:0 output not possible. Falling back to RGB.\n"); - crtc_state->sink_format = INTEL_OUTPUT_FORMAT_RGB; + if (ret && !respect_downstream_limits) { + drm_dbg_kms(display->drm, + "YCbCr 4:2:0 mode but YCbCr 4:2:0 output not possible. Falling back to RGB.\n"); + + ret = intel_dp_compute_output_format(encoder, crtc_state, conn_state, + respect_downstream_limits, + INTEL_OUTPUT_FORMAT_RGB); + } } else { - crtc_state->sink_format = intel_dp_sink_format(connector, adjusted_mode); - } + ret = intel_dp_compute_output_format(encoder, crtc_state, conn_state, + respect_downstream_limits, + INTEL_OUTPUT_FORMAT_RGB); - crtc_state->output_format = intel_dp_output_format(connector, crtc_state->sink_format); - - ret = intel_dp_compute_link_config(encoder, crtc_state, conn_state, - respect_downstream_limits); - if (ret) { - if (crtc_state->sink_format == INTEL_OUTPUT_FORMAT_YCBCR420 || - !connector->base.ycbcr_420_allowed || - !drm_mode_is_420_also(info, adjusted_mode)) - return ret; - - crtc_state->sink_format = INTEL_OUTPUT_FORMAT_YCBCR420; - crtc_state->output_format = intel_dp_output_format(connector, - crtc_state->sink_format); - ret = intel_dp_compute_link_config(encoder, crtc_state, conn_state, - respect_downstream_limits); + if (ret && drm_mode_is_420_also(info, adjusted_mode)) + ret = intel_dp_compute_output_format(encoder, crtc_state, conn_state, + respect_downstream_limits, + INTEL_OUTPUT_FORMAT_YCBCR420); } return ret; @@ -3539,18 +3621,15 @@ intel_dp_compute_config(struct intel_encoder *encoder, * Try to respect downstream TMDS clock limits first, if * that fails assume the user might know something we don't. */ - ret = intel_dp_compute_output_format(encoder, pipe_config, conn_state, true); + ret = intel_dp_compute_formats(encoder, pipe_config, conn_state, true); if (ret) - ret = intel_dp_compute_output_format(encoder, pipe_config, conn_state, false); + ret = intel_dp_compute_formats(encoder, pipe_config, conn_state, false); if (ret) return ret; - if ((intel_dp_is_edp(intel_dp) && fixed_mode) || - pipe_config->output_format == INTEL_OUTPUT_FORMAT_YCBCR420) { - ret = intel_pfit_compute_config(pipe_config, conn_state); - if (ret) - return ret; - } + ret = intel_pfit_compute_config(pipe_config, conn_state); + if (ret) + return ret; pipe_config->limited_color_range = intel_dp_limited_color_range(pipe_config, conn_state); @@ -4505,7 +4584,7 @@ void intel_dp_get_dsc_sink_cap(u8 dpcd_rev, if (drm_dp_dpcd_readb(connector->dp.dsc_decompression_aux, DP_FEC_CAPABILITY, &connector->dp.fec_capability) < 0) { - drm_err(display->drm, "Failed to read FEC DPCD register\n"); + drm_dbg_kms(display->drm, "Could not read FEC DPCD register\n"); return; } diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index 54c585c59b90..a26094223f78 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -742,11 +742,14 @@ static void intel_dp_update_downspread_ctrl(struct intel_dp *intel_dp, void intel_dp_link_training_set_bw(struct intel_dp *intel_dp, int link_bw, int rate_select, int lane_count, - bool enhanced_framing) + bool enhanced_framing, bool post_lt_adj_req) { if (enhanced_framing) lane_count |= DP_LANE_COUNT_ENHANCED_FRAME_EN; + if (post_lt_adj_req) + lane_count |= DP_POST_LT_ADJ_REQ_GRANTED; + if (link_bw) { /* DP and eDP v1.3 and earlier link bw set method. */ u8 link_config[] = { link_bw, lane_count }; @@ -825,12 +828,21 @@ static u32 intel_dp_training_pattern(struct intel_dp *intel_dp, return DP_TRAINING_PATTERN_2; } +static bool intel_dp_use_post_lt_adj_req(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) +{ + return intel_dp->set_idle_link_train && + drm_dp_post_lt_adj_req_supported(intel_dp->dpcd) && + intel_dp_training_pattern(intel_dp, crtc_state, DP_PHY_DPRX) != DP_TRAINING_PATTERN_4; +} + static void intel_dp_update_link_bw_set(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state, u8 link_bw, u8 rate_select) { intel_dp_link_training_set_bw(intel_dp, link_bw, rate_select, crtc_state->lane_count, - crtc_state->enhanced_framing); + crtc_state->enhanced_framing, + intel_dp_use_post_lt_adj_req(intel_dp, crtc_state)); } /* @@ -1091,6 +1103,109 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp, return channel_eq; } +static bool +intel_dp_post_lt_adj_req(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) +{ + u8 link_status[DP_LINK_STATUS_SIZE]; + unsigned long deadline; + bool timeout = false; + bool success = false; + int changes = 0; + + if (!intel_dp_use_post_lt_adj_req(intel_dp, crtc_state)) + return true; + + if (drm_dp_dpcd_read_phy_link_status(&intel_dp->aux, DP_PHY_DPRX, + link_status) < 0) { + lt_err(intel_dp, DP_PHY_DPRX, "Failed to get link status\n"); + return false; + } + + deadline = jiffies + msecs_to_jiffies_timeout(200); + + for (;;) { + /* Make sure clock is still ok */ + if (!drm_dp_clock_recovery_ok(link_status, + crtc_state->lane_count)) { + intel_dp_dump_link_status(intel_dp, DP_PHY_DPRX, link_status); + lt_dbg(intel_dp, DP_PHY_DPRX, + "Clock recovery check failed, cannot continue POST_LT_ADJ_REQ\n"); + break; + } + + if (!drm_dp_channel_eq_ok(link_status, + crtc_state->lane_count)) { + intel_dp_dump_link_status(intel_dp, DP_PHY_DPRX, link_status); + lt_dbg(intel_dp, DP_PHY_DPRX, "Channel EQ check failed. cannot continue POST_LT_ADJ_REQ\n"); + break; + } + + if (!drm_dp_post_lt_adj_req_in_progress(link_status)) { + success = true; + intel_dp_dump_link_status(intel_dp, DP_PHY_DPRX, link_status); + lt_dbg(intel_dp, DP_PHY_DPRX, + "POST_LT_ADJ_REQ done (%d changes). DP Training successful\n", changes); + break; + } + + if (changes == 6) { + success = true; + intel_dp_dump_link_status(intel_dp, DP_PHY_DPRX, link_status); + lt_dbg(intel_dp, DP_PHY_DPRX, + "POST_LT_ADJ_REQ limit reached (%d changes). DP Training successful\n", changes); + break; + } + + if (timeout) { + success = true; + intel_dp_dump_link_status(intel_dp, DP_PHY_DPRX, link_status); + lt_dbg(intel_dp, DP_PHY_DPRX, + "POST_LT_ADJ_REQ timeout reached (%d changes). DP Training successful\n", changes); + break; + } + + fsleep(5000); + + if (drm_dp_dpcd_read_phy_link_status(&intel_dp->aux, DP_PHY_DPRX, + link_status) < 0) { + lt_err(intel_dp, DP_PHY_DPRX, "Failed to get link status\n"); + break; + } + + /* Update training set as requested by target */ + if (intel_dp_get_adjust_train(intel_dp, crtc_state, DP_PHY_DPRX, link_status)) { + deadline = jiffies + msecs_to_jiffies_timeout(200); + changes++; + + if (!intel_dp_update_link_train(intel_dp, crtc_state, DP_PHY_DPRX)) { + lt_err(intel_dp, DP_PHY_DPRX, "Failed to update link training\n"); + break; + } + } else if (time_after(jiffies, deadline)) { + timeout = true; + } + } + + return success; +} + +static void intel_dp_stop_post_lt_adj_req(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) +{ + u8 lane_count; + + if (!intel_dp_use_post_lt_adj_req(intel_dp, crtc_state)) + return; + + /* clear DP_POST_LT_ADJ_REQ_GRANTED */ + lane_count = crtc_state->lane_count; + if (crtc_state->enhanced_framing) + lane_count |= DP_LANE_COUNT_ENHANCED_FRAME_EN; + + drm_dp_dpcd_writeb(&intel_dp->aux, DP_LANE_COUNT_SET, lane_count); +} + static bool intel_dp_disable_dpcd_training_pattern(struct intel_dp *intel_dp, enum drm_dp_phy dp_phy) { @@ -1389,6 +1504,11 @@ intel_dp_link_train_all_phys(struct intel_dp *intel_dp, intel_dp_disable_dpcd_training_pattern(intel_dp, DP_PHY_DPRX); intel_dp->set_idle_link_train(intel_dp, crtc_state); + if (ret) + ret = intel_dp_post_lt_adj_req(intel_dp, crtc_state); + + intel_dp_stop_post_lt_adj_req(intel_dp, crtc_state); + return ret; } diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.h b/drivers/gpu/drm/i915/display/intel_dp_link_training.h index 1ba22ed6db08..33dcbde6a408 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.h +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.h @@ -21,7 +21,7 @@ void intel_dp_link_training_set_mode(struct intel_dp *intel_dp, int link_rate, bool is_vrr); void intel_dp_link_training_set_bw(struct intel_dp *intel_dp, int link_bw, int rate_select, int lane_count, - bool enhanced_framing); + bool enhanced_framing, bool post_lt_adj_req); bool intel_dp_get_adjust_train(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state, diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 249dfd84b51a..8f73e01db17c 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -721,7 +721,10 @@ static int mst_stream_compute_config(struct intel_encoder *encoder, pipe_config->sink_format = INTEL_OUTPUT_FORMAT_RGB; pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB; - pipe_config->has_pch_encoder = false; + + ret = intel_pfit_compute_config(pipe_config, conn_state); + if (ret) + return ret; for_each_joiner_candidate(connector, adjusted_mode, num_joined_pipes) { if (num_joined_pipes > 1) @@ -2144,7 +2147,7 @@ void intel_dp_mst_prepare_probe(struct intel_dp *intel_dp) intel_dp_link_training_set_mode(intel_dp, link_rate, false); intel_dp_link_training_set_bw(intel_dp, link_bw, rate_select, lane_count, - drm_dp_enhanced_frame_cap(intel_dp->dpcd)); + drm_dp_enhanced_frame_cap(intel_dp->dpcd), false); intel_mst_set_probed_link_params(intel_dp, link_rate, lane_count); } diff --git a/drivers/gpu/drm/i915/display/intel_dp_tunnel.c b/drivers/gpu/drm/i915/display/intel_dp_tunnel.c index 7363c9817297..11712a151f72 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_tunnel.c +++ b/drivers/gpu/drm/i915/display/intel_dp_tunnel.c @@ -296,6 +296,24 @@ bool intel_dp_tunnel_bw_alloc_is_enabled(struct intel_dp *intel_dp) return drm_dp_tunnel_bw_alloc_is_enabled(intel_dp->tunnel); } +/** + * intel_dp_tunnel_pr_optimization_supported - Query the PR BW optimization support + * @intel_dp: DP port object + * + * Query whether a DP tunnel supports the PR BW optimization. + * + * Returns %true if the BW allocation mode is supported on @intel_dp. + */ +bool intel_dp_tunnel_pr_optimization_supported(struct intel_dp *intel_dp) +{ + struct intel_display *display = to_intel_display(intel_dp); + + if (DISPLAY_VER(display) < 35) + return false; + + return drm_dp_tunnel_pr_optimization_supported(intel_dp->tunnel); +} + /** * intel_dp_tunnel_suspend - Suspend a DP tunnel connected on a port * @intel_dp: DP port object diff --git a/drivers/gpu/drm/i915/display/intel_dp_tunnel.h b/drivers/gpu/drm/i915/display/intel_dp_tunnel.h index 10ab9eebcef6..8273e681a512 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_tunnel.h +++ b/drivers/gpu/drm/i915/display/intel_dp_tunnel.h @@ -32,6 +32,7 @@ void intel_dp_tunnel_resume(struct intel_dp *intel_dp, void intel_dp_tunnel_suspend(struct intel_dp *intel_dp); bool intel_dp_tunnel_bw_alloc_is_enabled(struct intel_dp *intel_dp); +bool intel_dp_tunnel_pr_optimization_supported(struct intel_dp *intel_dp); void intel_dp_tunnel_atomic_cleanup_inherited_state(struct intel_atomic_state *state); @@ -76,6 +77,11 @@ static inline bool intel_dp_tunnel_bw_alloc_is_enabled(struct intel_dp *intel_dp return false; } +static inline bool intel_dp_tunnel_pr_optimization_supported(struct intel_dp *intel_dp) +{ + return false; +} + static inline void intel_dp_tunnel_atomic_cleanup_inherited_state(struct intel_atomic_state *state) {} diff --git a/drivers/gpu/drm/i915/display/intel_dpio_phy.c b/drivers/gpu/drm/i915/display/intel_dpio_phy.c index 8027bab2951b..68802b652316 100644 --- a/drivers/gpu/drm/i915/display/intel_dpio_phy.c +++ b/drivers/gpu/drm/i915/display/intel_dpio_phy.c @@ -301,7 +301,7 @@ void bxt_dpio_phy_set_signal_levels(struct intel_encoder *encoder, enum dpio_phy phy; int lane, n_entries; - trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); + trans = intel_ddi_buf_trans_get(encoder, crtc_state, &n_entries); if (drm_WARN_ON_ONCE(display->drm, !trans)) return; @@ -724,46 +724,46 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder, u32 val; int i; - vlv_dpio_get(display->drm); + vlv_dpio_get(display); /* Clear calc init */ - val = vlv_dpio_read(display->drm, phy, VLV_PCS01_DW10(ch)); + val = vlv_dpio_read(display, phy, VLV_PCS01_DW10(ch)); val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3); val &= ~(DPIO_PCS_TX1DEEMP_MASK | DPIO_PCS_TX2DEEMP_MASK); val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5; - vlv_dpio_write(display->drm, phy, VLV_PCS01_DW10(ch), val); + vlv_dpio_write(display, phy, VLV_PCS01_DW10(ch), val); if (crtc_state->lane_count > 2) { - val = vlv_dpio_read(display->drm, phy, VLV_PCS23_DW10(ch)); + val = vlv_dpio_read(display, phy, VLV_PCS23_DW10(ch)); val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3); val &= ~(DPIO_PCS_TX1DEEMP_MASK | DPIO_PCS_TX2DEEMP_MASK); val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5; - vlv_dpio_write(display->drm, phy, VLV_PCS23_DW10(ch), val); + vlv_dpio_write(display, phy, VLV_PCS23_DW10(ch), val); } - val = vlv_dpio_read(display->drm, phy, VLV_PCS01_DW9(ch)); + val = vlv_dpio_read(display, phy, VLV_PCS01_DW9(ch)); val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK); val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000; - vlv_dpio_write(display->drm, phy, VLV_PCS01_DW9(ch), val); + vlv_dpio_write(display, phy, VLV_PCS01_DW9(ch), val); if (crtc_state->lane_count > 2) { - val = vlv_dpio_read(display->drm, phy, VLV_PCS23_DW9(ch)); + val = vlv_dpio_read(display, phy, VLV_PCS23_DW9(ch)); val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK); val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000; - vlv_dpio_write(display->drm, phy, VLV_PCS23_DW9(ch), val); + vlv_dpio_write(display, phy, VLV_PCS23_DW9(ch), val); } /* Program swing deemph */ for (i = 0; i < crtc_state->lane_count; i++) { - val = vlv_dpio_read(display->drm, phy, CHV_TX_DW4(ch, i)); + val = vlv_dpio_read(display, phy, CHV_TX_DW4(ch, i)); val &= ~DPIO_SWING_DEEMPH9P5_MASK; val |= DPIO_SWING_DEEMPH9P5(deemph_reg_value); - vlv_dpio_write(display->drm, phy, CHV_TX_DW4(ch, i), val); + vlv_dpio_write(display, phy, CHV_TX_DW4(ch, i), val); } /* Program swing margin */ for (i = 0; i < crtc_state->lane_count; i++) { - val = vlv_dpio_read(display->drm, phy, CHV_TX_DW2(ch, i)); + val = vlv_dpio_read(display, phy, CHV_TX_DW2(ch, i)); val &= ~DPIO_SWING_MARGIN000_MASK; val |= DPIO_SWING_MARGIN000(margin_reg_value); @@ -776,7 +776,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder, val &= ~DPIO_UNIQ_TRANS_SCALE_MASK; val |= DPIO_UNIQ_TRANS_SCALE(0x9a); - vlv_dpio_write(display->drm, phy, CHV_TX_DW2(ch, i), val); + vlv_dpio_write(display, phy, CHV_TX_DW2(ch, i), val); } /* @@ -786,26 +786,26 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder, * 27 for ch0 and ch1. */ for (i = 0; i < crtc_state->lane_count; i++) { - val = vlv_dpio_read(display->drm, phy, CHV_TX_DW3(ch, i)); + val = vlv_dpio_read(display, phy, CHV_TX_DW3(ch, i)); if (uniq_trans_scale) val |= DPIO_TX_UNIQ_TRANS_SCALE_EN; else val &= ~DPIO_TX_UNIQ_TRANS_SCALE_EN; - vlv_dpio_write(display->drm, phy, CHV_TX_DW3(ch, i), val); + vlv_dpio_write(display, phy, CHV_TX_DW3(ch, i), val); } /* Start swing calculation */ - val = vlv_dpio_read(display->drm, phy, VLV_PCS01_DW10(ch)); + val = vlv_dpio_read(display, phy, VLV_PCS01_DW10(ch)); val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3; - vlv_dpio_write(display->drm, phy, VLV_PCS01_DW10(ch), val); + vlv_dpio_write(display, phy, VLV_PCS01_DW10(ch), val); if (crtc_state->lane_count > 2) { - val = vlv_dpio_read(display->drm, phy, VLV_PCS23_DW10(ch)); + val = vlv_dpio_read(display, phy, VLV_PCS23_DW10(ch)); val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3; - vlv_dpio_write(display->drm, phy, VLV_PCS23_DW10(ch), val); + vlv_dpio_write(display, phy, VLV_PCS23_DW10(ch), val); } - vlv_dpio_put(display->drm); + vlv_dpio_put(display); } static void __chv_data_lane_soft_reset(struct intel_encoder *encoder, @@ -818,38 +818,38 @@ static void __chv_data_lane_soft_reset(struct intel_encoder *encoder, enum dpio_phy phy = vlv_dig_port_to_phy(dig_port); u32 val; - val = vlv_dpio_read(display->drm, phy, VLV_PCS01_DW0(ch)); + val = vlv_dpio_read(display, phy, VLV_PCS01_DW0(ch)); if (reset) val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET); else val |= DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET; - vlv_dpio_write(display->drm, phy, VLV_PCS01_DW0(ch), val); + vlv_dpio_write(display, phy, VLV_PCS01_DW0(ch), val); if (crtc_state->lane_count > 2) { - val = vlv_dpio_read(display->drm, phy, VLV_PCS23_DW0(ch)); + val = vlv_dpio_read(display, phy, VLV_PCS23_DW0(ch)); if (reset) val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET); else val |= DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET; - vlv_dpio_write(display->drm, phy, VLV_PCS23_DW0(ch), val); + vlv_dpio_write(display, phy, VLV_PCS23_DW0(ch), val); } - val = vlv_dpio_read(display->drm, phy, VLV_PCS01_DW1(ch)); + val = vlv_dpio_read(display, phy, VLV_PCS01_DW1(ch)); val |= CHV_PCS_REQ_SOFTRESET_EN; if (reset) val &= ~DPIO_PCS_CLK_SOFT_RESET; else val |= DPIO_PCS_CLK_SOFT_RESET; - vlv_dpio_write(display->drm, phy, VLV_PCS01_DW1(ch), val); + vlv_dpio_write(display, phy, VLV_PCS01_DW1(ch), val); if (crtc_state->lane_count > 2) { - val = vlv_dpio_read(display->drm, phy, VLV_PCS23_DW1(ch)); + val = vlv_dpio_read(display, phy, VLV_PCS23_DW1(ch)); val |= CHV_PCS_REQ_SOFTRESET_EN; if (reset) val &= ~DPIO_PCS_CLK_SOFT_RESET; else val |= DPIO_PCS_CLK_SOFT_RESET; - vlv_dpio_write(display->drm, phy, VLV_PCS23_DW1(ch), val); + vlv_dpio_write(display, phy, VLV_PCS23_DW1(ch), val); } } @@ -859,9 +859,9 @@ void chv_data_lane_soft_reset(struct intel_encoder *encoder, { struct intel_display *display = to_intel_display(encoder); - vlv_dpio_get(display->drm); + vlv_dpio_get(display); __chv_data_lane_soft_reset(encoder, crtc_state, reset); - vlv_dpio_put(display->drm); + vlv_dpio_put(display); } void chv_phy_pre_pll_enable(struct intel_encoder *encoder, @@ -887,47 +887,47 @@ void chv_phy_pre_pll_enable(struct intel_encoder *encoder, chv_phy_powergate_lanes(encoder, true, lane_mask); - vlv_dpio_get(display->drm); + vlv_dpio_get(display); /* Assert data lane reset */ __chv_data_lane_soft_reset(encoder, crtc_state, true); /* program left/right clock distribution */ if (pipe != PIPE_B) { - val = vlv_dpio_read(display->drm, phy, CHV_CMN_DW5_CH0); + val = vlv_dpio_read(display, phy, CHV_CMN_DW5_CH0); val &= ~(CHV_BUFLEFTENA1_MASK | CHV_BUFRIGHTENA1_MASK); if (ch == DPIO_CH0) val |= CHV_BUFLEFTENA1_FORCE; if (ch == DPIO_CH1) val |= CHV_BUFRIGHTENA1_FORCE; - vlv_dpio_write(display->drm, phy, CHV_CMN_DW5_CH0, val); + vlv_dpio_write(display, phy, CHV_CMN_DW5_CH0, val); } else { - val = vlv_dpio_read(display->drm, phy, CHV_CMN_DW1_CH1); + val = vlv_dpio_read(display, phy, CHV_CMN_DW1_CH1); val &= ~(CHV_BUFLEFTENA2_MASK | CHV_BUFRIGHTENA2_MASK); if (ch == DPIO_CH0) val |= CHV_BUFLEFTENA2_FORCE; if (ch == DPIO_CH1) val |= CHV_BUFRIGHTENA2_FORCE; - vlv_dpio_write(display->drm, phy, CHV_CMN_DW1_CH1, val); + vlv_dpio_write(display, phy, CHV_CMN_DW1_CH1, val); } /* program clock channel usage */ - val = vlv_dpio_read(display->drm, phy, VLV_PCS01_DW8(ch)); + val = vlv_dpio_read(display, phy, VLV_PCS01_DW8(ch)); val |= DPIO_PCS_USEDCLKCHANNEL_OVRRIDE; if (pipe == PIPE_B) val |= DPIO_PCS_USEDCLKCHANNEL; else val &= ~DPIO_PCS_USEDCLKCHANNEL; - vlv_dpio_write(display->drm, phy, VLV_PCS01_DW8(ch), val); + vlv_dpio_write(display, phy, VLV_PCS01_DW8(ch), val); if (crtc_state->lane_count > 2) { - val = vlv_dpio_read(display->drm, phy, VLV_PCS23_DW8(ch)); + val = vlv_dpio_read(display, phy, VLV_PCS23_DW8(ch)); val |= DPIO_PCS_USEDCLKCHANNEL_OVRRIDE; if (pipe == PIPE_B) val |= DPIO_PCS_USEDCLKCHANNEL; else val &= ~DPIO_PCS_USEDCLKCHANNEL; - vlv_dpio_write(display->drm, phy, VLV_PCS23_DW8(ch), val); + vlv_dpio_write(display, phy, VLV_PCS23_DW8(ch), val); } /* @@ -935,14 +935,14 @@ void chv_phy_pre_pll_enable(struct intel_encoder *encoder, * matches the pipe, but here we need to * pick the CL based on the port. */ - val = vlv_dpio_read(display->drm, phy, CHV_CMN_DW19(ch)); + val = vlv_dpio_read(display, phy, CHV_CMN_DW19(ch)); if (pipe == PIPE_B) val |= CHV_CMN_USEDCLKCHANNEL; else val &= ~CHV_CMN_USEDCLKCHANNEL; - vlv_dpio_write(display->drm, phy, CHV_CMN_DW19(ch), val); + vlv_dpio_write(display, phy, CHV_CMN_DW19(ch), val); - vlv_dpio_put(display->drm); + vlv_dpio_put(display); } void chv_phy_pre_encoder_enable(struct intel_encoder *encoder, @@ -956,17 +956,17 @@ void chv_phy_pre_encoder_enable(struct intel_encoder *encoder, int data, i, stagger; u32 val; - vlv_dpio_get(display->drm); + vlv_dpio_get(display); /* allow hardware to manage TX FIFO reset source */ - val = vlv_dpio_read(display->drm, phy, VLV_PCS01_DW11(ch)); + val = vlv_dpio_read(display, phy, VLV_PCS01_DW11(ch)); val &= ~DPIO_LANEDESKEW_STRAP_OVRD; - vlv_dpio_write(display->drm, phy, VLV_PCS01_DW11(ch), val); + vlv_dpio_write(display, phy, VLV_PCS01_DW11(ch), val); if (crtc_state->lane_count > 2) { - val = vlv_dpio_read(display->drm, phy, VLV_PCS23_DW11(ch)); + val = vlv_dpio_read(display, phy, VLV_PCS23_DW11(ch)); val &= ~DPIO_LANEDESKEW_STRAP_OVRD; - vlv_dpio_write(display->drm, phy, VLV_PCS23_DW11(ch), val); + vlv_dpio_write(display, phy, VLV_PCS23_DW11(ch), val); } /* Program Tx lane latency optimal setting*/ @@ -976,7 +976,7 @@ void chv_phy_pre_encoder_enable(struct intel_encoder *encoder, data = 0; else data = (i == 1) ? 0 : DPIO_UPAR; - vlv_dpio_write(display->drm, phy, CHV_TX_DW14(ch, i), data); + vlv_dpio_write(display, phy, CHV_TX_DW14(ch, i), data); } /* Data lane stagger programming */ @@ -991,17 +991,17 @@ void chv_phy_pre_encoder_enable(struct intel_encoder *encoder, else stagger = 0x2; - val = vlv_dpio_read(display->drm, phy, VLV_PCS01_DW11(ch)); + val = vlv_dpio_read(display, phy, VLV_PCS01_DW11(ch)); val |= DPIO_TX2_STAGGER_MASK(0x1f); - vlv_dpio_write(display->drm, phy, VLV_PCS01_DW11(ch), val); + vlv_dpio_write(display, phy, VLV_PCS01_DW11(ch), val); if (crtc_state->lane_count > 2) { - val = vlv_dpio_read(display->drm, phy, VLV_PCS23_DW11(ch)); + val = vlv_dpio_read(display, phy, VLV_PCS23_DW11(ch)); val |= DPIO_TX2_STAGGER_MASK(0x1f); - vlv_dpio_write(display->drm, phy, VLV_PCS23_DW11(ch), val); + vlv_dpio_write(display, phy, VLV_PCS23_DW11(ch), val); } - vlv_dpio_write(display->drm, phy, VLV_PCS01_DW12(ch), + vlv_dpio_write(display, phy, VLV_PCS01_DW12(ch), DPIO_LANESTAGGER_STRAP(stagger) | DPIO_LANESTAGGER_STRAP_OVRD | DPIO_TX1_STAGGER_MASK(0x1f) | @@ -1009,7 +1009,7 @@ void chv_phy_pre_encoder_enable(struct intel_encoder *encoder, DPIO_TX2_STAGGER_MULT(0)); if (crtc_state->lane_count > 2) { - vlv_dpio_write(display->drm, phy, VLV_PCS23_DW12(ch), + vlv_dpio_write(display, phy, VLV_PCS23_DW12(ch), DPIO_LANESTAGGER_STRAP(stagger) | DPIO_LANESTAGGER_STRAP_OVRD | DPIO_TX1_STAGGER_MASK(0x1f) | @@ -1020,7 +1020,7 @@ void chv_phy_pre_encoder_enable(struct intel_encoder *encoder, /* Deassert data lane reset */ __chv_data_lane_soft_reset(encoder, crtc_state, false); - vlv_dpio_put(display->drm); + vlv_dpio_put(display); } void chv_phy_release_cl2_override(struct intel_encoder *encoder) @@ -1042,20 +1042,20 @@ void chv_phy_post_pll_disable(struct intel_encoder *encoder, enum pipe pipe = to_intel_crtc(old_crtc_state->uapi.crtc)->pipe; u32 val; - vlv_dpio_get(display->drm); + vlv_dpio_get(display); /* disable left/right clock distribution */ if (pipe != PIPE_B) { - val = vlv_dpio_read(display->drm, phy, CHV_CMN_DW5_CH0); + val = vlv_dpio_read(display, phy, CHV_CMN_DW5_CH0); val &= ~(CHV_BUFLEFTENA1_MASK | CHV_BUFRIGHTENA1_MASK); - vlv_dpio_write(display->drm, phy, CHV_CMN_DW5_CH0, val); + vlv_dpio_write(display, phy, CHV_CMN_DW5_CH0, val); } else { - val = vlv_dpio_read(display->drm, phy, CHV_CMN_DW1_CH1); + val = vlv_dpio_read(display, phy, CHV_CMN_DW1_CH1); val &= ~(CHV_BUFLEFTENA2_MASK | CHV_BUFRIGHTENA2_MASK); - vlv_dpio_write(display->drm, phy, CHV_CMN_DW1_CH1, val); + vlv_dpio_write(display, phy, CHV_CMN_DW1_CH1, val); } - vlv_dpio_put(display->drm); + vlv_dpio_put(display); /* * Leave the power down bit cleared for at least one @@ -1079,22 +1079,22 @@ void vlv_set_phy_signal_level(struct intel_encoder *encoder, enum dpio_channel ch = vlv_dig_port_to_channel(dig_port); enum dpio_phy phy = vlv_dig_port_to_phy(dig_port); - vlv_dpio_get(display->drm); + vlv_dpio_get(display); - vlv_dpio_write(display->drm, phy, VLV_TX_DW5_GRP(ch), 0x00000000); - vlv_dpio_write(display->drm, phy, VLV_TX_DW4_GRP(ch), demph_reg_value); - vlv_dpio_write(display->drm, phy, VLV_TX_DW2_GRP(ch), + vlv_dpio_write(display, phy, VLV_TX_DW5_GRP(ch), 0x00000000); + vlv_dpio_write(display, phy, VLV_TX_DW4_GRP(ch), demph_reg_value); + vlv_dpio_write(display, phy, VLV_TX_DW2_GRP(ch), uniqtranscale_reg_value); - vlv_dpio_write(display->drm, phy, VLV_TX_DW3_GRP(ch), 0x0C782040); + vlv_dpio_write(display, phy, VLV_TX_DW3_GRP(ch), 0x0C782040); if (tx3_demph) - vlv_dpio_write(display->drm, phy, VLV_TX_DW4(ch, 3), tx3_demph); + vlv_dpio_write(display, phy, VLV_TX_DW4(ch, 3), tx3_demph); - vlv_dpio_write(display->drm, phy, VLV_PCS_DW11_GRP(ch), 0x00030000); - vlv_dpio_write(display->drm, phy, VLV_PCS_DW9_GRP(ch), preemph_reg_value); - vlv_dpio_write(display->drm, phy, VLV_TX_DW5_GRP(ch), DPIO_TX_OCALINIT_EN); + vlv_dpio_write(display, phy, VLV_PCS_DW11_GRP(ch), 0x00030000); + vlv_dpio_write(display, phy, VLV_PCS_DW9_GRP(ch), preemph_reg_value); + vlv_dpio_write(display, phy, VLV_TX_DW5_GRP(ch), DPIO_TX_OCALINIT_EN); - vlv_dpio_put(display->drm); + vlv_dpio_put(display); } void vlv_phy_pre_pll_enable(struct intel_encoder *encoder, @@ -1106,23 +1106,23 @@ void vlv_phy_pre_pll_enable(struct intel_encoder *encoder, enum dpio_phy phy = vlv_dig_port_to_phy(dig_port); /* Program Tx lane resets to default */ - vlv_dpio_get(display->drm); + vlv_dpio_get(display); - vlv_dpio_write(display->drm, phy, VLV_PCS_DW0_GRP(ch), + vlv_dpio_write(display, phy, VLV_PCS_DW0_GRP(ch), DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET); - vlv_dpio_write(display->drm, phy, VLV_PCS_DW1_GRP(ch), + vlv_dpio_write(display, phy, VLV_PCS_DW1_GRP(ch), DPIO_PCS_CLK_CRI_RXEB_EIOS_EN | DPIO_PCS_CLK_CRI_RXDIGFILTSG_EN | DPIO_PCS_CLK_DATAWIDTH_8_10 | DPIO_PCS_CLK_SOFT_RESET); /* Fix up inter-pair skew failure */ - vlv_dpio_write(display->drm, phy, VLV_PCS_DW12_GRP(ch), 0x00750f00); - vlv_dpio_write(display->drm, phy, VLV_TX_DW11_GRP(ch), 0x00001500); - vlv_dpio_write(display->drm, phy, VLV_TX_DW14_GRP(ch), 0x40400000); + vlv_dpio_write(display, phy, VLV_PCS_DW12_GRP(ch), 0x00750f00); + vlv_dpio_write(display, phy, VLV_TX_DW11_GRP(ch), 0x00001500); + vlv_dpio_write(display, phy, VLV_TX_DW14_GRP(ch), 0x40400000); - vlv_dpio_put(display->drm); + vlv_dpio_put(display); } void vlv_phy_pre_encoder_enable(struct intel_encoder *encoder, @@ -1137,20 +1137,20 @@ void vlv_phy_pre_encoder_enable(struct intel_encoder *encoder, enum pipe pipe = crtc->pipe; u32 val; - vlv_dpio_get(display->drm); + vlv_dpio_get(display); /* Enable clock channels for this port */ val = DPIO_PCS_USEDCLKCHANNEL_OVRRIDE; if (pipe == PIPE_B) val |= DPIO_PCS_USEDCLKCHANNEL; val |= 0xc4; - vlv_dpio_write(display->drm, phy, VLV_PCS_DW8_GRP(ch), val); + vlv_dpio_write(display, phy, VLV_PCS_DW8_GRP(ch), val); /* Program lane clock */ - vlv_dpio_write(display->drm, phy, VLV_PCS_DW14_GRP(ch), 0x00760018); - vlv_dpio_write(display->drm, phy, VLV_PCS_DW23_GRP(ch), 0x00400888); + vlv_dpio_write(display, phy, VLV_PCS_DW14_GRP(ch), 0x00760018); + vlv_dpio_write(display, phy, VLV_PCS_DW23_GRP(ch), 0x00400888); - vlv_dpio_put(display->drm); + vlv_dpio_put(display); } void vlv_phy_reset_lanes(struct intel_encoder *encoder, @@ -1161,10 +1161,10 @@ void vlv_phy_reset_lanes(struct intel_encoder *encoder, enum dpio_channel ch = vlv_dig_port_to_channel(dig_port); enum dpio_phy phy = vlv_dig_port_to_phy(dig_port); - vlv_dpio_get(display->drm); - vlv_dpio_write(display->drm, phy, VLV_PCS_DW0_GRP(ch), 0x00000000); - vlv_dpio_write(display->drm, phy, VLV_PCS_DW1_GRP(ch), 0x00e00060); - vlv_dpio_put(display->drm); + vlv_dpio_get(display); + vlv_dpio_write(display, phy, VLV_PCS_DW0_GRP(ch), 0x00000000); + vlv_dpio_write(display, phy, VLV_PCS_DW1_GRP(ch), 0x00e00060); + vlv_dpio_put(display); } void vlv_wait_port_ready(struct intel_encoder *encoder, diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c b/drivers/gpu/drm/i915/display/intel_dpll.c index c7d37e74fbe9..f40807a5566b 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll.c +++ b/drivers/gpu/drm/i915/display/intel_dpll.c @@ -528,9 +528,9 @@ void vlv_crtc_clock_get(struct intel_crtc_state *crtc_state) if ((hw_state->dpll & DPLL_VCO_ENABLE) == 0) return; - vlv_dpio_get(display->drm); - tmp = vlv_dpio_read(display->drm, phy, VLV_PLL_DW3(ch)); - vlv_dpio_put(display->drm); + vlv_dpio_get(display); + tmp = vlv_dpio_read(display, phy, VLV_PLL_DW3(ch)); + vlv_dpio_put(display); clock.m1 = REG_FIELD_GET(DPIO_M1_DIV_MASK, tmp); clock.m2 = REG_FIELD_GET(DPIO_M2_DIV_MASK, tmp); @@ -556,13 +556,13 @@ void chv_crtc_clock_get(struct intel_crtc_state *crtc_state) if ((hw_state->dpll & DPLL_VCO_ENABLE) == 0) return; - vlv_dpio_get(display->drm); - cmn_dw13 = vlv_dpio_read(display->drm, phy, CHV_CMN_DW13(ch)); - pll_dw0 = vlv_dpio_read(display->drm, phy, CHV_PLL_DW0(ch)); - pll_dw1 = vlv_dpio_read(display->drm, phy, CHV_PLL_DW1(ch)); - pll_dw2 = vlv_dpio_read(display->drm, phy, CHV_PLL_DW2(ch)); - pll_dw3 = vlv_dpio_read(display->drm, phy, CHV_PLL_DW3(ch)); - vlv_dpio_put(display->drm); + vlv_dpio_get(display); + cmn_dw13 = vlv_dpio_read(display, phy, CHV_CMN_DW13(ch)); + pll_dw0 = vlv_dpio_read(display, phy, CHV_PLL_DW0(ch)); + pll_dw1 = vlv_dpio_read(display, phy, CHV_PLL_DW1(ch)); + pll_dw2 = vlv_dpio_read(display, phy, CHV_PLL_DW2(ch)); + pll_dw3 = vlv_dpio_read(display, phy, CHV_PLL_DW3(ch)); + vlv_dpio_put(display); clock.m1 = REG_FIELD_GET(DPIO_CHV_M1_DIV_MASK, pll_dw1) == DPIO_CHV_M1_DIV_BY_2 ? 2 : 0; clock.m2 = REG_FIELD_GET(DPIO_CHV_M2_DIV_MASK, pll_dw0) << 22; @@ -1735,7 +1735,7 @@ int intel_dpll_crtc_compute_clock(struct intel_atomic_state *state, if (!crtc_state->hw.enable) return 0; - ret = display->funcs.dpll->crtc_compute_clock(state, crtc); + ret = display->dpll.funcs->crtc_compute_clock(state, crtc); if (ret) { drm_dbg_kms(display->drm, "[CRTC:%d:%s] Couldn't calculate DPLL settings\n", crtc->base.base.id, crtc->base.name); @@ -1759,10 +1759,10 @@ int intel_dpll_crtc_get_dpll(struct intel_atomic_state *state, if (!crtc_state->hw.enable || crtc_state->intel_dpll) return 0; - if (!display->funcs.dpll->crtc_get_dpll) + if (!display->dpll.funcs->crtc_get_dpll) return 0; - ret = display->funcs.dpll->crtc_get_dpll(state, crtc); + ret = display->dpll.funcs->crtc_get_dpll(state, crtc); if (ret) { drm_dbg_kms(display->drm, "[CRTC:%d:%s] Couldn't get a shared DPLL\n", crtc->base.base.id, crtc->base.name); @@ -1776,27 +1776,27 @@ void intel_dpll_init_clock_hook(struct intel_display *display) { if (HAS_LT_PHY(display)) - display->funcs.dpll = &xe3plpd_dpll_funcs; + display->dpll.funcs = &xe3plpd_dpll_funcs; else if (DISPLAY_VER(display) >= 14) - display->funcs.dpll = &mtl_dpll_funcs; + display->dpll.funcs = &mtl_dpll_funcs; else if (display->platform.dg2) - display->funcs.dpll = &dg2_dpll_funcs; + display->dpll.funcs = &dg2_dpll_funcs; else if (DISPLAY_VER(display) >= 9 || HAS_DDI(display)) - display->funcs.dpll = &hsw_dpll_funcs; + display->dpll.funcs = &hsw_dpll_funcs; else if (HAS_PCH_SPLIT(display)) - display->funcs.dpll = &ilk_dpll_funcs; + display->dpll.funcs = &ilk_dpll_funcs; else if (display->platform.cherryview) - display->funcs.dpll = &chv_dpll_funcs; + display->dpll.funcs = &chv_dpll_funcs; else if (display->platform.valleyview) - display->funcs.dpll = &vlv_dpll_funcs; + display->dpll.funcs = &vlv_dpll_funcs; else if (display->platform.g4x) - display->funcs.dpll = &g4x_dpll_funcs; + display->dpll.funcs = &g4x_dpll_funcs; else if (display->platform.pineview) - display->funcs.dpll = &pnv_dpll_funcs; + display->dpll.funcs = &pnv_dpll_funcs; else if (DISPLAY_VER(display) != 2) - display->funcs.dpll = &i9xx_dpll_funcs; + display->dpll.funcs = &i9xx_dpll_funcs; else - display->funcs.dpll = &i8xx_dpll_funcs; + display->dpll.funcs = &i8xx_dpll_funcs; } static bool i9xx_has_pps(struct intel_display *display) @@ -1866,24 +1866,24 @@ static void vlv_pllb_recal_opamp(struct intel_display *display, * PLLB opamp always calibrates to max value of 0x3f, force enable it * and set it to a reasonable value instead. */ - tmp = vlv_dpio_read(display->drm, phy, VLV_PLL_DW17(ch)); + tmp = vlv_dpio_read(display, phy, VLV_PLL_DW17(ch)); tmp &= 0xffffff00; tmp |= 0x00000030; - vlv_dpio_write(display->drm, phy, VLV_PLL_DW17(ch), tmp); + vlv_dpio_write(display, phy, VLV_PLL_DW17(ch), tmp); - tmp = vlv_dpio_read(display->drm, phy, VLV_REF_DW11); + tmp = vlv_dpio_read(display, phy, VLV_REF_DW11); tmp &= 0x00ffffff; tmp |= 0x8c000000; - vlv_dpio_write(display->drm, phy, VLV_REF_DW11, tmp); + vlv_dpio_write(display, phy, VLV_REF_DW11, tmp); - tmp = vlv_dpio_read(display->drm, phy, VLV_PLL_DW17(ch)); + tmp = vlv_dpio_read(display, phy, VLV_PLL_DW17(ch)); tmp &= 0xffffff00; - vlv_dpio_write(display->drm, phy, VLV_PLL_DW17(ch), tmp); + vlv_dpio_write(display, phy, VLV_PLL_DW17(ch), tmp); - tmp = vlv_dpio_read(display->drm, phy, VLV_REF_DW11); + tmp = vlv_dpio_read(display, phy, VLV_REF_DW11); tmp &= 0x00ffffff; tmp |= 0xb0000000; - vlv_dpio_write(display->drm, phy, VLV_REF_DW11, tmp); + vlv_dpio_write(display, phy, VLV_REF_DW11, tmp); } static void vlv_prepare_pll(const struct intel_crtc_state *crtc_state) @@ -1896,7 +1896,7 @@ static void vlv_prepare_pll(const struct intel_crtc_state *crtc_state) enum pipe pipe = crtc->pipe; u32 tmp, coreclk; - vlv_dpio_get(display->drm); + vlv_dpio_get(display); /* See eDP HDMI DPIO driver vbios notes doc */ @@ -1905,15 +1905,15 @@ static void vlv_prepare_pll(const struct intel_crtc_state *crtc_state) vlv_pllb_recal_opamp(display, phy, ch); /* Set up Tx target for periodic Rcomp update */ - vlv_dpio_write(display->drm, phy, VLV_PCS_DW17_BCAST, 0x0100000f); + vlv_dpio_write(display, phy, VLV_PCS_DW17_BCAST, 0x0100000f); /* Disable target IRef on PLL */ - tmp = vlv_dpio_read(display->drm, phy, VLV_PLL_DW16(ch)); + tmp = vlv_dpio_read(display, phy, VLV_PLL_DW16(ch)); tmp &= 0x00ffffff; - vlv_dpio_write(display->drm, phy, VLV_PLL_DW16(ch), tmp); + vlv_dpio_write(display, phy, VLV_PLL_DW16(ch), tmp); /* Disable fast lock */ - vlv_dpio_write(display->drm, phy, VLV_CMN_DW0, 0x610); + vlv_dpio_write(display, phy, VLV_CMN_DW0, 0x610); /* Set idtafcrecal before PLL is enabled */ tmp = DPIO_M1_DIV(clock->m1) | @@ -1929,42 +1929,42 @@ static void vlv_prepare_pll(const struct intel_crtc_state *crtc_state) * Note: don't use the DAC post divider as it seems unstable. */ tmp |= DPIO_S1_DIV(DPIO_S1_DIV_HDMIDP); - vlv_dpio_write(display->drm, phy, VLV_PLL_DW3(ch), tmp); + vlv_dpio_write(display, phy, VLV_PLL_DW3(ch), tmp); tmp |= DPIO_ENABLE_CALIBRATION; - vlv_dpio_write(display->drm, phy, VLV_PLL_DW3(ch), tmp); + vlv_dpio_write(display, phy, VLV_PLL_DW3(ch), tmp); /* Set HBR and RBR LPF coefficients */ if (crtc_state->port_clock == 162000 || intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG) || intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) - vlv_dpio_write(display->drm, phy, VLV_PLL_DW18(ch), 0x009f0003); + vlv_dpio_write(display, phy, VLV_PLL_DW18(ch), 0x009f0003); else - vlv_dpio_write(display->drm, phy, VLV_PLL_DW18(ch), 0x00d0000f); + vlv_dpio_write(display, phy, VLV_PLL_DW18(ch), 0x00d0000f); if (intel_crtc_has_dp_encoder(crtc_state)) { /* Use SSC source */ if (pipe == PIPE_A) - vlv_dpio_write(display->drm, phy, VLV_PLL_DW5(ch), 0x0df40000); + vlv_dpio_write(display, phy, VLV_PLL_DW5(ch), 0x0df40000); else - vlv_dpio_write(display->drm, phy, VLV_PLL_DW5(ch), 0x0df70000); + vlv_dpio_write(display, phy, VLV_PLL_DW5(ch), 0x0df70000); } else { /* HDMI or VGA */ /* Use bend source */ if (pipe == PIPE_A) - vlv_dpio_write(display->drm, phy, VLV_PLL_DW5(ch), 0x0df70000); + vlv_dpio_write(display, phy, VLV_PLL_DW5(ch), 0x0df70000); else - vlv_dpio_write(display->drm, phy, VLV_PLL_DW5(ch), 0x0df40000); + vlv_dpio_write(display, phy, VLV_PLL_DW5(ch), 0x0df40000); } - coreclk = vlv_dpio_read(display->drm, phy, VLV_PLL_DW7(ch)); + coreclk = vlv_dpio_read(display, phy, VLV_PLL_DW7(ch)); coreclk = (coreclk & 0x0000ff00) | 0x01c00000; if (intel_crtc_has_dp_encoder(crtc_state)) coreclk |= 0x01000000; - vlv_dpio_write(display->drm, phy, VLV_PLL_DW7(ch), coreclk); + vlv_dpio_write(display, phy, VLV_PLL_DW7(ch), coreclk); - vlv_dpio_write(display->drm, phy, VLV_PLL_DW19(ch), 0x87871000); + vlv_dpio_write(display, phy, VLV_PLL_DW19(ch), 0x87871000); - vlv_dpio_put(display->drm); + vlv_dpio_put(display); } static void _vlv_enable_pll(const struct intel_crtc_state *crtc_state) @@ -2019,44 +2019,44 @@ static void chv_prepare_pll(const struct intel_crtc_state *crtc_state) m2_frac = clock->m2 & 0x3fffff; - vlv_dpio_get(display->drm); + vlv_dpio_get(display); /* p1 and p2 divider */ - vlv_dpio_write(display->drm, phy, CHV_CMN_DW13(ch), + vlv_dpio_write(display, phy, CHV_CMN_DW13(ch), DPIO_CHV_S1_DIV(5) | DPIO_CHV_P1_DIV(clock->p1) | DPIO_CHV_P2_DIV(clock->p2) | DPIO_CHV_K_DIV(1)); /* Feedback post-divider - m2 */ - vlv_dpio_write(display->drm, phy, CHV_PLL_DW0(ch), + vlv_dpio_write(display, phy, CHV_PLL_DW0(ch), DPIO_CHV_M2_DIV(clock->m2 >> 22)); /* Feedback refclk divider - n and m1 */ - vlv_dpio_write(display->drm, phy, CHV_PLL_DW1(ch), + vlv_dpio_write(display, phy, CHV_PLL_DW1(ch), DPIO_CHV_M1_DIV(DPIO_CHV_M1_DIV_BY_2) | DPIO_CHV_N_DIV(1)); /* M2 fraction division */ - vlv_dpio_write(display->drm, phy, CHV_PLL_DW2(ch), + vlv_dpio_write(display, phy, CHV_PLL_DW2(ch), DPIO_CHV_M2_FRAC_DIV(m2_frac)); /* M2 fraction division enable */ - tmp = vlv_dpio_read(display->drm, phy, CHV_PLL_DW3(ch)); + tmp = vlv_dpio_read(display, phy, CHV_PLL_DW3(ch)); tmp &= ~(DPIO_CHV_FEEDFWD_GAIN_MASK | DPIO_CHV_FRAC_DIV_EN); tmp |= DPIO_CHV_FEEDFWD_GAIN(2); if (m2_frac) tmp |= DPIO_CHV_FRAC_DIV_EN; - vlv_dpio_write(display->drm, phy, CHV_PLL_DW3(ch), tmp); + vlv_dpio_write(display, phy, CHV_PLL_DW3(ch), tmp); /* Program digital lock detect threshold */ - tmp = vlv_dpio_read(display->drm, phy, CHV_PLL_DW9(ch)); + tmp = vlv_dpio_read(display, phy, CHV_PLL_DW9(ch)); tmp &= ~(DPIO_CHV_INT_LOCK_THRESHOLD_MASK | DPIO_CHV_INT_LOCK_THRESHOLD_SEL_COARSE); tmp |= DPIO_CHV_INT_LOCK_THRESHOLD(0x5); if (!m2_frac) tmp |= DPIO_CHV_INT_LOCK_THRESHOLD_SEL_COARSE; - vlv_dpio_write(display->drm, phy, CHV_PLL_DW9(ch), tmp); + vlv_dpio_write(display, phy, CHV_PLL_DW9(ch), tmp); /* Loop filter */ if (clock->vco == 5400000) { @@ -2081,19 +2081,19 @@ static void chv_prepare_pll(const struct intel_crtc_state *crtc_state) DPIO_CHV_GAIN_CTRL(0x3); tribuf_calcntr = 0; } - vlv_dpio_write(display->drm, phy, CHV_PLL_DW6(ch), loopfilter); + vlv_dpio_write(display, phy, CHV_PLL_DW6(ch), loopfilter); - tmp = vlv_dpio_read(display->drm, phy, CHV_PLL_DW8(ch)); + tmp = vlv_dpio_read(display, phy, CHV_PLL_DW8(ch)); tmp &= ~DPIO_CHV_TDC_TARGET_CNT_MASK; tmp |= DPIO_CHV_TDC_TARGET_CNT(tribuf_calcntr); - vlv_dpio_write(display->drm, phy, CHV_PLL_DW8(ch), tmp); + vlv_dpio_write(display, phy, CHV_PLL_DW8(ch), tmp); /* AFC Recal */ - vlv_dpio_write(display->drm, phy, CHV_CMN_DW14(ch), - vlv_dpio_read(display->drm, phy, CHV_CMN_DW14(ch)) | + vlv_dpio_write(display, phy, CHV_CMN_DW14(ch), + vlv_dpio_read(display, phy, CHV_CMN_DW14(ch)) | DPIO_AFC_RECAL); - vlv_dpio_put(display->drm); + vlv_dpio_put(display); } static void _chv_enable_pll(const struct intel_crtc_state *crtc_state) @@ -2106,14 +2106,14 @@ static void _chv_enable_pll(const struct intel_crtc_state *crtc_state) enum pipe pipe = crtc->pipe; u32 tmp; - vlv_dpio_get(display->drm); + vlv_dpio_get(display); /* Enable back the 10bit clock to display controller */ - tmp = vlv_dpio_read(display->drm, phy, CHV_CMN_DW14(ch)); + tmp = vlv_dpio_read(display, phy, CHV_CMN_DW14(ch)); tmp |= DPIO_DCLKP_EN; - vlv_dpio_write(display->drm, phy, CHV_CMN_DW14(ch), tmp); + vlv_dpio_write(display, phy, CHV_CMN_DW14(ch), tmp); - vlv_dpio_put(display->drm); + vlv_dpio_put(display); /* * Need to wait > 100ns between dclkp clock enable bit and PLL enable. @@ -2247,14 +2247,14 @@ void chv_disable_pll(struct intel_display *display, enum pipe pipe) intel_de_write(display, DPLL(display, pipe), val); intel_de_posting_read(display, DPLL(display, pipe)); - vlv_dpio_get(display->drm); + vlv_dpio_get(display); /* Disable 10bit clock to display controller */ - val = vlv_dpio_read(display->drm, phy, CHV_CMN_DW14(ch)); + val = vlv_dpio_read(display, phy, CHV_CMN_DW14(ch)); val &= ~DPIO_DCLKP_EN; - vlv_dpio_write(display->drm, phy, CHV_CMN_DW14(ch), val); + vlv_dpio_write(display, phy, CHV_CMN_DW14(ch), val); - vlv_dpio_put(display->drm); + vlv_dpio_put(display); } void i9xx_disable_pll(const struct intel_crtc_state *crtc_state) diff --git a/drivers/gpu/drm/i915/display/intel_dram.c b/drivers/gpu/drm/i915/display/intel_dram.c index bd281d4b4c05..f103f7cba018 100644 --- a/drivers/gpu/drm/i915/display/intel_dram.c +++ b/drivers/gpu/drm/i915/display/intel_dram.c @@ -9,14 +9,14 @@ #include #include +#include "intel_de.h" #include "intel_display_core.h" #include "intel_display_utils.h" #include "intel_display_regs.h" #include "intel_dram.h" -#include "intel_mchbar_regs.h" +#include "intel_mchbar.h" #include "intel_parent.h" -#include "intel_uncore.h" -#include "vlv_iosf_sb.h" +#include "vlv_sideband.h" struct dram_dimm_info { u16 size; @@ -58,18 +58,15 @@ const char *intel_dram_type_str(enum intel_dram_type type) static enum intel_dram_type pnv_dram_type(struct intel_display *display) { - struct intel_uncore *uncore = to_intel_uncore(display->drm); - - return intel_uncore_read(uncore, CSHRDDR3CTL) & CSHRDDR3CTL_DDR3 ? + return intel_mchbar_read(display, CSHRDDR3CTL) & CSHRDDR3CTL_DDR3 ? INTEL_DRAM_DDR3 : INTEL_DRAM_DDR2; } static unsigned int pnv_mem_freq(struct intel_display *display) { - struct intel_uncore *uncore = to_intel_uncore(display->drm); u32 tmp; - tmp = intel_uncore_read(uncore, CLKCFG); + tmp = intel_mchbar_read(display, CLKCFG); switch (tmp & CLKCFG_MEM_MASK) { case CLKCFG_MEM_533: @@ -85,10 +82,9 @@ static unsigned int pnv_mem_freq(struct intel_display *display) static unsigned int ilk_mem_freq(struct intel_display *display) { - struct intel_uncore *uncore = to_intel_uncore(display->drm); u16 ddrpll; - ddrpll = intel_uncore_read16(uncore, DDRMPLL1); + ddrpll = intel_mchbar_read16(display, DDRMPLL1); switch (ddrpll & 0xff) { case 0xc: return 800000; @@ -109,9 +105,9 @@ static unsigned int chv_mem_freq(struct intel_display *display) { u32 val; - vlv_iosf_sb_get(display->drm, BIT(VLV_IOSF_SB_CCK)); - val = vlv_iosf_sb_read(display->drm, VLV_IOSF_SB_CCK, CCK_FUSE_REG); - vlv_iosf_sb_put(display->drm, BIT(VLV_IOSF_SB_CCK)); + vlv_cck_get(display); + val = vlv_cck_read(display, CCK_FUSE_REG); + vlv_cck_put(display); switch ((val >> 2) & 0x7) { case 3: @@ -125,9 +121,9 @@ static unsigned int vlv_mem_freq(struct intel_display *display) { u32 val; - vlv_iosf_sb_get(display->drm, BIT(VLV_IOSF_SB_PUNIT)); - val = vlv_iosf_sb_read(display->drm, VLV_IOSF_SB_PUNIT, PUNIT_REG_GPU_FREQ_STS); - vlv_iosf_sb_put(display->drm, BIT(VLV_IOSF_SB_PUNIT)); + vlv_punit_get(display); + val = vlv_punit_read(display, PUNIT_REG_GPU_FREQ_STS); + vlv_punit_put(display); switch ((val >> 6) & 3) { case 0: @@ -158,7 +154,6 @@ unsigned int intel_mem_freq(struct intel_display *display) static unsigned int i9xx_fsb_freq(struct intel_display *display) { - struct intel_uncore *uncore = to_intel_uncore(display->drm); u32 fsb; /* @@ -169,7 +164,7 @@ static unsigned int i9xx_fsb_freq(struct intel_display *display) * don't know which registers have that information, * and all the relevant docs have gone to bit heaven :( */ - fsb = intel_uncore_read(uncore, CLKCFG) & CLKCFG_FSB_MASK; + fsb = intel_mchbar_read(display, CLKCFG) & CLKCFG_FSB_MASK; if (display->platform.pineview || display->platform.mobile) { switch (fsb) { @@ -214,10 +209,9 @@ static unsigned int i9xx_fsb_freq(struct intel_display *display) static unsigned int ilk_fsb_freq(struct intel_display *display) { - struct intel_uncore *uncore = to_intel_uncore(display->drm); u16 fsb; - fsb = intel_uncore_read16(uncore, CSIPLL0) & 0x3ff; + fsb = intel_mchbar_read16(display, CSIPLL0) & 0x3ff; switch (fsb) { case 0x00c: @@ -484,7 +478,6 @@ intel_is_dram_symmetric(const struct dram_channel_info *ch0, static int skl_dram_get_channels_info(struct intel_display *display, struct dram_info *dram_info) { - struct intel_uncore *uncore = to_intel_uncore(display->drm); struct dram_channel_info ch0 = {}, ch1 = {}; u32 val; int ret; @@ -492,12 +485,12 @@ skl_dram_get_channels_info(struct intel_display *display, struct dram_info *dram /* Assume 16Gb+ DIMMs are present until proven otherwise */ dram_info->has_16gb_dimms = true; - val = intel_uncore_read(uncore, SKL_MAD_DIMM_CH0_0_0_0_MCHBAR_MCMAIN); + val = intel_mchbar_read(display, SKL_MAD_DIMM_CH0_0_0_0_MCHBAR_MCMAIN); ret = skl_dram_get_channel_info(display, &ch0, 0, val); if (ret == 0) dram_info->num_channels++; - val = intel_uncore_read(uncore, SKL_MAD_DIMM_CH1_0_0_0_MCHBAR_MCMAIN); + val = intel_mchbar_read(display, SKL_MAD_DIMM_CH1_0_0_0_MCHBAR_MCMAIN); ret = skl_dram_get_channel_info(display, &ch1, 1, val); if (ret == 0) dram_info->num_channels++; @@ -528,10 +521,9 @@ skl_dram_get_channels_info(struct intel_display *display, struct dram_info *dram static enum intel_dram_type skl_get_dram_type(struct intel_display *display) { - struct intel_uncore *uncore = to_intel_uncore(display->drm); u32 val; - val = intel_uncore_read(uncore, SKL_MAD_INTER_CHANNEL_0_0_0_MCHBAR_MCMAIN); + val = intel_mchbar_read(display, SKL_MAD_INTER_CHANNEL_0_0_0_MCHBAR_MCMAIN); switch (val & SKL_DRAM_DDR_TYPE_MASK) { case SKL_DRAM_DDR_TYPE_DDR3: @@ -642,7 +634,6 @@ static void bxt_get_dimm_info(struct dram_dimm_info *dimm, u32 val) static int bxt_get_dram_info(struct intel_display *display, struct dram_info *dram_info) { - struct intel_uncore *uncore = to_intel_uncore(display->drm); u32 val; u8 valid_ranks = 0; int i; @@ -654,7 +645,7 @@ static int bxt_get_dram_info(struct intel_display *display, struct dram_info *dr struct dram_dimm_info dimm; enum intel_dram_type type; - val = intel_uncore_read(uncore, BXT_D_CR_DRP0_DUNIT(i)); + val = intel_mchbar_read(display, BXT_D_CR_DRP0_DUNIT(i)); if (val == 0xFFFFFFFF) continue; @@ -767,8 +758,7 @@ static int gen12_get_dram_info(struct intel_display *display, struct dram_info * static int xelpdp_get_dram_info(struct intel_display *display, struct dram_info *dram_info) { - struct intel_uncore *uncore = to_intel_uncore(display->drm); - u32 val = intel_uncore_read(uncore, MTL_MEM_SS_INFO_GLOBAL); + u32 val = intel_de_read(display, MTL_MEM_SS_INFO_GLOBAL); switch (REG_FIELD_GET(MTL_DDR_TYPE_MASK, val)) { case 0: diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index 5768619f840f..1c0859d5f829 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -521,6 +521,11 @@ bool intel_fb_needs_64k_phys(u64 modifier) INTEL_PLANE_CAP_NEED64K_PHYS); } +bool intel_fb_needs_cpu_access(const struct drm_framebuffer *fb) +{ + return intel_fb_rc_ccs_cc_plane(fb) >= 0; +} + /** * intel_fb_is_tile4_modifier: Check if a modifier is a tile4 modifier type * @modifier: Modifier to check @@ -876,15 +881,6 @@ static void intel_tile_block_dims(const struct drm_framebuffer *fb, int color_pl *tile_height = 1; } -unsigned int intel_tile_row_size(const struct drm_framebuffer *fb, int color_plane) -{ - unsigned int tile_width, tile_height; - - intel_tile_dims(fb, color_plane, &tile_width, &tile_height); - - return fb->pitches[color_plane] * tile_height; -} - unsigned int intel_fb_align_height(const struct drm_framebuffer *fb, int color_plane, unsigned int height) @@ -1261,6 +1257,10 @@ static bool intel_plane_can_remap(const struct intel_plane_state *plane_state) if (intel_fb_is_ccs_modifier(fb->modifier)) return false; + /* TODO implement remapping with DPT */ + if (intel_fb_uses_dpt(fb)) + return false; + /* Linear needs a page aligned stride for remapping */ if (fb->modifier == DRM_FORMAT_MOD_LINEAR) { unsigned int alignment = intel_tile_size(display) - 1; @@ -1274,7 +1274,7 @@ static bool intel_plane_can_remap(const struct intel_plane_state *plane_state) return true; } -bool intel_fb_needs_pot_stride_remap(const struct intel_framebuffer *fb) +static bool intel_fb_needs_pot_stride_remap(const struct intel_framebuffer *fb) { struct intel_display *display = to_intel_display(fb->base.dev); @@ -1287,9 +1287,9 @@ bool intel_plane_uses_fence(const struct intel_plane_state *plane_state) struct intel_display *display = to_intel_display(plane_state); struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); - return DISPLAY_VER(display) < 4 || + return intel_plane_needs_fence(display) || (plane->fbc && !plane_state->no_fbc_reason && - plane_state->view.gtt.type == I915_GTT_VIEW_NORMAL); + i915_gtt_view_is_normal(&plane_state->view.gtt)); } static int intel_fb_pitch(const struct intel_framebuffer *fb, int color_plane, unsigned int rotation) @@ -1511,7 +1511,7 @@ static u32 calc_plane_remap_info(const struct intel_framebuffer *fb, int color_p plane_view_height_tiles(fb, color_plane, dims, y)); } - if (view->gtt.type == I915_GTT_VIEW_ROTATED) { + if (i915_gtt_view_is_rotated(&view->gtt)) { drm_WARN_ON(display->drm, remap_info->linear); check_array_bounds(display, view->gtt.rotated.plane, color_plane); @@ -1536,7 +1536,7 @@ static u32 calc_plane_remap_info(const struct intel_framebuffer *fb, int color_p /* rotate the tile dimensions to match the GTT view */ swap(tile_width, tile_height); } else { - drm_WARN_ON(display->drm, view->gtt.type != I915_GTT_VIEW_REMAPPED); + drm_WARN_ON(display->drm, !i915_gtt_view_is_remapped(&view->gtt)); check_array_bounds(display, view->gtt.remapped.plane, color_plane); @@ -1632,13 +1632,14 @@ calc_plane_normal_size(const struct intel_framebuffer *fb, int color_plane, static void intel_fb_view_init(struct intel_display *display, struct intel_fb_view *view, - enum i915_gtt_view_type view_type) + enum i915_gtt_view_type view_type, + const struct intel_framebuffer *fb) { memset(view, 0, sizeof(*view)); view->gtt.type = view_type; - if (view_type == I915_GTT_VIEW_REMAPPED && - (display->platform.alderlake_p || DISPLAY_VER(display) >= 14)) + if (i915_gtt_view_is_remapped(&view->gtt) && + intel_fb_needs_pot_stride_remap(fb)) view->gtt.remapped.plane_alignment = SZ_2M / PAGE_SIZE; } @@ -1704,16 +1705,19 @@ int intel_fill_fb_info(struct intel_display *display, struct intel_framebuffer * int i, num_planes = fb->base.format->num_planes; unsigned int tile_size = intel_tile_size(display); - intel_fb_view_init(display, &fb->normal_view, I915_GTT_VIEW_NORMAL); + intel_fb_view_init(display, &fb->normal_view, + I915_GTT_VIEW_NORMAL, fb); drm_WARN_ON(display->drm, intel_fb_supports_90_270_rotation(fb) && intel_fb_needs_pot_stride_remap(fb)); if (intel_fb_supports_90_270_rotation(fb)) - intel_fb_view_init(display, &fb->rotated_view, I915_GTT_VIEW_ROTATED); + intel_fb_view_init(display, &fb->rotated_view, + I915_GTT_VIEW_ROTATED, fb); if (intel_fb_needs_pot_stride_remap(fb)) - intel_fb_view_init(display, &fb->remapped_view, I915_GTT_VIEW_REMAPPED); + intel_fb_view_init(display, &fb->remapped_view, + I915_GTT_VIEW_REMAPPED, fb); for (i = 0; i < num_planes; i++) { struct fb_plane_view_dims view_dims; @@ -1840,8 +1844,9 @@ static void intel_plane_remap_gtt(struct intel_plane_state *plane_state) u32 gtt_offset = 0; intel_fb_view_init(display, &plane_state->view, - drm_rotation_90_or_270(rotation) ? I915_GTT_VIEW_ROTATED : - I915_GTT_VIEW_REMAPPED); + drm_rotation_90_or_270(rotation) ? + I915_GTT_VIEW_ROTATED : I915_GTT_VIEW_REMAPPED, + intel_fb); src_x = plane_state->uapi.src.x1 >> 16; src_y = plane_state->uapi.src.y1 >> 16; diff --git a/drivers/gpu/drm/i915/display/intel_fb.h b/drivers/gpu/drm/i915/display/intel_fb.h index 22514d5f2bb6..0a027e2595b2 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.h +++ b/drivers/gpu/drm/i915/display/intel_fb.h @@ -38,6 +38,7 @@ bool intel_fb_is_rc_ccs_cc_modifier(u64 modifier); bool intel_fb_is_mc_ccs_modifier(u64 modifier); bool intel_fb_needs_64k_phys(u64 modifier); bool intel_fb_is_tile4_modifier(u64 modifier); +bool intel_fb_needs_cpu_access(const struct drm_framebuffer *fb); bool intel_fb_is_ccs_aux_plane(const struct drm_framebuffer *fb, int color_plane); int intel_fb_rc_ccs_cc_plane(const struct drm_framebuffer *fb); @@ -62,7 +63,6 @@ int skl_main_to_aux_plane(const struct drm_framebuffer *fb, int main_plane); unsigned int intel_tile_size(struct intel_display *display); unsigned int intel_tile_width_bytes(const struct drm_framebuffer *fb, int color_plane); unsigned int intel_tile_height(const struct drm_framebuffer *fb, int color_plane); -unsigned int intel_tile_row_size(const struct drm_framebuffer *fb, int color_plane); unsigned int intel_fb_align_height(const struct drm_framebuffer *fb, int color_plane, unsigned int height); @@ -78,7 +78,6 @@ u32 intel_plane_compute_aligned_offset(int *x, int *y, const struct intel_plane_state *plane_state, int color_plane); -bool intel_fb_needs_pot_stride_remap(const struct intel_framebuffer *fb); bool intel_plane_uses_fence(const struct intel_plane_state *plane_state); bool intel_fb_supports_90_270_rotation(const struct intel_framebuffer *fb); diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.h b/drivers/gpu/drm/i915/display/intel_fb_pin.h index 81ab79da1af7..5825503c38ea 100644 --- a/drivers/gpu/drm/i915/display/intel_fb_pin.h +++ b/drivers/gpu/drm/i915/display/intel_fb_pin.h @@ -8,22 +8,29 @@ #include -struct drm_framebuffer; +struct drm_gem_object; struct i915_vma; struct intel_plane_state; struct i915_gtt_view; struct iosys_map; -struct i915_vma * -intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb, - const struct i915_gtt_view *view, - unsigned int alignment, - unsigned int phys_alignment, - unsigned int vtd_guard, - bool uses_fence, - unsigned long *out_flags); +struct intel_fb_pin_params { + const struct i915_gtt_view *view; + unsigned int alignment; + unsigned int phys_alignment; + unsigned int vtd_guard; + bool needs_cpu_lmem_access; + bool needs_low_address; + bool needs_physical; + bool needs_fence; +}; -void intel_fb_unpin_vma(struct i915_vma *vma, unsigned long flags); +struct i915_vma * +intel_fb_pin_to_ggtt(struct drm_gem_object *obj, + const struct intel_fb_pin_params *pin_params, + int *out_fence_id); + +void intel_fb_unpin_vma(struct i915_vma *vma, int fence_id); int intel_plane_pin_fb(struct intel_plane_state *new_plane_state, const struct intel_plane_state *old_plane_state); diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index 55cb3ceb3523..a7d02dd6ca96 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -1458,13 +1458,10 @@ static void intel_fbc_update_state(struct intel_atomic_state *state, fbc_state->fence_y_offset = intel_plane_fence_y_offset(plane_state); - drm_WARN_ON(display->drm, plane_state->flags & PLANE_HAS_FENCE && + drm_WARN_ON(display->drm, plane_state->fence_id >= 0 && !intel_fbc_has_fences(display)); - if (plane_state->flags & PLANE_HAS_FENCE) - fbc_state->fence_id = intel_parent_vma_fence_id(display, plane_state->ggtt_vma); - else - fbc_state->fence_id = -1; + fbc_state->fence_id = plane_state->fence_id; fbc_state->cfb_stride = intel_fbc_cfb_stride(plane_state); fbc_state->cfb_size = intel_fbc_cfb_size(plane_state); @@ -1487,9 +1484,7 @@ static bool intel_fbc_is_fence_ok(const struct intel_plane_state *plane_state) * so have no fence associated with it) due to aperture constraints * at the time of pinning. */ - return DISPLAY_VER(display) >= 9 || - (plane_state->flags & PLANE_HAS_FENCE && - intel_parent_vma_fence_id(display, plane_state->ggtt_vma) != -1); + return DISPLAY_VER(display) >= 9 || plane_state->fence_id >= 0; } static bool intel_fbc_is_cfb_ok(const struct intel_plane_state *plane_state) diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index bdaaf3edba0c..9ab0ac49abb7 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -54,13 +54,12 @@ #include "intel_fb.h" #include "intel_fb_pin.h" #include "intel_fbdev.h" -#include "intel_fbdev_fb.h" #include "intel_frontbuffer.h" +#include "intel_plane.h" struct intel_fbdev { struct intel_framebuffer *fb; struct i915_vma *vma; - unsigned long vma_flags; }; static struct intel_fbdev *to_intel_fbdev(struct drm_fb_helper *fb_helper) @@ -141,7 +140,7 @@ static void intel_fbdev_fb_destroy(struct fb_info *info) * the info->screen_base mmaping. Leaking the VMA is simpler than * trying to rectify all the possible error paths leading here. */ - intel_fb_unpin_vma(ifbdev->vma, ifbdev->vma_flags); + intel_fb_unpin_vma(ifbdev->vma, -1); drm_framebuffer_remove(fb_helper->fb); drm_client_release(&fb_helper->client); @@ -204,7 +203,8 @@ static const struct drm_fb_helper_funcs intel_fb_helper_funcs = { .fb_set_suspend = intelfb_set_suspend, }; -static void intel_fbdev_fill_mode_cmd(struct drm_fb_helper_surface_size *sizes, +static void intel_fbdev_fill_mode_cmd(struct intel_display *display, + struct drm_fb_helper_surface_size *sizes, struct drm_mode_fb_cmd2 *mode_cmd) { /* we don't do packed 24bpp */ @@ -215,7 +215,7 @@ static void intel_fbdev_fill_mode_cmd(struct drm_fb_helper_surface_size *sizes, mode_cmd->width = sizes->surface_width; mode_cmd->height = sizes->surface_height; - mode_cmd->pitches[0] = intel_fbdev_fb_pitch_align(mode_cmd->width * DIV_ROUND_UP(sizes->surface_bpp, 8)); + mode_cmd->pitches[0] = intel_bo_fbdev_pitch_align(display, mode_cmd->width * DIV_ROUND_UP(sizes->surface_bpp, 8)); mode_cmd->pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, sizes->surface_depth); mode_cmd->modifier[0] = DRM_FORMAT_MOD_LINEAR; @@ -230,12 +230,12 @@ __intel_fbdev_fb_alloc(struct intel_display *display, struct drm_gem_object *obj; int size; - intel_fbdev_fill_mode_cmd(sizes, &mode_cmd); + intel_fbdev_fill_mode_cmd(display, sizes, &mode_cmd); size = mode_cmd.pitches[0] * mode_cmd.height; size = PAGE_ALIGN(size); - obj = intel_fbdev_fb_bo_create(display->drm, size); + obj = intel_bo_fbdev_create(display, size); if (IS_ERR(obj)) { fb = ERR_CAST(obj); goto err; @@ -247,7 +247,7 @@ __intel_fbdev_fb_alloc(struct intel_display *display, mode_cmd.modifier[0]), &mode_cmd); if (IS_ERR(fb)) { - intel_fbdev_fb_bo_destroy(obj); + intel_bo_fbdev_destroy(obj); goto err; } @@ -265,11 +265,11 @@ int intel_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper, { struct intel_display *display = to_intel_display(helper->dev); struct intel_fbdev *ifbdev = to_intel_fbdev(helper); + struct intel_fb_pin_params pin_params = {}; struct intel_framebuffer *fb = ifbdev->fb; struct fb_info *info = helper->info; struct ref_tracker *wakeref; struct i915_vma *vma; - unsigned long flags = 0; bool prealloc = false; struct drm_gem_object *obj; int ret; @@ -306,15 +306,20 @@ int intel_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper, sizes->fb_height = fb->base.height; } + obj = intel_fb_bo(&fb->base); + /* Pin the GGTT vma for our access via info->screen_base. * This also validates that any existing fb inherited from the * BIOS is suitable for own access. */ - vma = intel_fb_pin_to_ggtt(&fb->base, &fb->normal_view.gtt, - fb->min_alignment, 0, - intel_fb_view_vtd_guard(&fb->base, &fb->normal_view, - DRM_MODE_ROTATE_0), - false, &flags); + pin_params.view = &fb->normal_view.gtt; + pin_params.alignment = fb->min_alignment; + pin_params.vtd_guard = intel_fb_view_vtd_guard(&fb->base, + &fb->normal_view, + DRM_MODE_ROTATE_0); + pin_params.needs_low_address = intel_plane_needs_low_address(display); + + vma = intel_fb_pin_to_ggtt(obj, &pin_params, NULL); if (IS_ERR(vma)) { ret = PTR_ERR(vma); goto out_unlock; @@ -325,9 +330,7 @@ int intel_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper, info->fbops = &intelfb_ops; - obj = intel_fb_bo(&fb->base); - - ret = intel_fbdev_fb_fill_info(display->drm, info, obj, vma); + ret = intel_bo_fbdev_fill_info(obj, info, vma); if (ret) goto out_unpin; @@ -345,14 +348,13 @@ int intel_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper, drm_dbg_kms(display->drm, "allocated %dx%d fb\n", fb->base.width, fb->base.height); ifbdev->fb = fb; ifbdev->vma = vma; - ifbdev->vma_flags = flags; intel_display_rpm_put(display, wakeref); return 0; out_unpin: - intel_fb_unpin_vma(vma, flags); + intel_fb_unpin_vma(vma, -1); out_unlock: intel_display_rpm_put(display, wakeref); diff --git a/drivers/gpu/drm/i915/display/intel_fbdev_fb.c b/drivers/gpu/drm/i915/display/intel_fbdev_fb.c deleted file mode 100644 index 6f84eb6355de..000000000000 --- a/drivers/gpu/drm/i915/display/intel_fbdev_fb.c +++ /dev/null @@ -1,118 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * Copyright © 2023 Intel Corporation - */ - -#include - -#include - -#include "gem/i915_gem_lmem.h" - -#include "i915_drv.h" -#include "intel_fbdev_fb.h" - -u32 intel_fbdev_fb_pitch_align(u32 stride) -{ - return ALIGN(stride, 64); -} - -bool intel_fbdev_fb_prefer_stolen(struct drm_device *drm, unsigned int size) -{ - struct drm_i915_private *i915 = to_i915(drm); - - /* Skip stolen on MTL as Wa_22018444074 mitigation. */ - if (IS_METEORLAKE(i915)) - return false; - - /* - * If the FB is too big, just don't use it since fbdev is not very - * important and we should probably use that space with FBC or other - * features. - */ - return i915->dsm.usable_size >= size * 2; -} - -struct drm_gem_object *intel_fbdev_fb_bo_create(struct drm_device *drm, int size) -{ - struct drm_i915_private *i915 = to_i915(drm); - struct drm_i915_gem_object *obj; - - obj = ERR_PTR(-ENODEV); - if (HAS_LMEM(i915)) { - obj = i915_gem_object_create_lmem(i915, size, - I915_BO_ALLOC_CONTIGUOUS | - I915_BO_ALLOC_USER); - } else { - if (intel_fbdev_fb_prefer_stolen(drm, size)) - obj = i915_gem_object_create_stolen(i915, size); - else - drm_info(drm, "Allocating fbdev: Stolen memory not preferred.\n"); - - if (IS_ERR(obj)) - obj = i915_gem_object_create_shmem(i915, size); - } - - if (IS_ERR(obj)) { - drm_err(drm, "failed to allocate framebuffer (%pe)\n", obj); - return ERR_PTR(-ENOMEM); - } - - return &obj->base; -} - -void intel_fbdev_fb_bo_destroy(struct drm_gem_object *obj) -{ - drm_gem_object_put(obj); -} - -int intel_fbdev_fb_fill_info(struct drm_device *drm, struct fb_info *info, - struct drm_gem_object *_obj, struct i915_vma *vma) -{ - struct drm_i915_private *i915 = to_i915(drm); - struct drm_i915_gem_object *obj = to_intel_bo(_obj); - struct i915_gem_ww_ctx ww; - void __iomem *vaddr; - int ret; - - if (i915_gem_object_is_lmem(obj)) { - struct intel_memory_region *mem = obj->mm.region; - - /* Use fbdev's framebuffer from lmem for discrete */ - info->fix.smem_start = - (unsigned long)(mem->io.start + - i915_gem_object_get_dma_address(obj, 0) - - mem->region.start); - info->fix.smem_len = obj->base.size; - } else { - struct i915_ggtt *ggtt = to_gt(i915)->ggtt; - - /* Our framebuffer is the entirety of fbdev's system memory */ - info->fix.smem_start = - (unsigned long)(ggtt->gmadr.start + i915_ggtt_offset(vma)); - info->fix.smem_len = vma->size; - } - - for_i915_gem_ww(&ww, ret, false) { - ret = i915_gem_object_lock(vma->obj, &ww); - - if (ret) - continue; - - vaddr = i915_vma_pin_iomap(vma); - if (IS_ERR(vaddr)) { - drm_err(drm, - "Failed to remap framebuffer into virtual memory (%pe)\n", vaddr); - ret = PTR_ERR(vaddr); - continue; - } - } - - if (ret) - return ret; - - info->screen_base = vaddr; - info->screen_size = intel_bo_to_drm_bo(obj)->size; - - return 0; -} diff --git a/drivers/gpu/drm/i915/display/intel_fbdev_fb.h b/drivers/gpu/drm/i915/display/intel_fbdev_fb.h deleted file mode 100644 index 34ed2b9c2b4f..000000000000 --- a/drivers/gpu/drm/i915/display/intel_fbdev_fb.h +++ /dev/null @@ -1,24 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * Copyright © 2023 Intel Corporation - */ - -#ifndef __INTEL_FBDEV_FB_H__ -#define __INTEL_FBDEV_FB_H__ - -#include - -struct drm_device; -struct drm_gem_object; -struct drm_mode_fb_cmd2; -struct fb_info; -struct i915_vma; - -u32 intel_fbdev_fb_pitch_align(u32 stride); -struct drm_gem_object *intel_fbdev_fb_bo_create(struct drm_device *drm, int size); -void intel_fbdev_fb_bo_destroy(struct drm_gem_object *obj); -int intel_fbdev_fb_fill_info(struct drm_device *drm, struct fb_info *info, - struct drm_gem_object *obj, struct i915_vma *vma); -bool intel_fbdev_fb_prefer_stolen(struct drm_device *drm, unsigned int size); - -#endif diff --git a/drivers/gpu/drm/i915/display/intel_fdi.c b/drivers/gpu/drm/i915/display/intel_fdi.c index feef8e3f2b4e..cd4c38691aed 100644 --- a/drivers/gpu/drm/i915/display/intel_fdi.c +++ b/drivers/gpu/drm/i915/display/intel_fdi.c @@ -11,6 +11,7 @@ #include "intel_atomic.h" #include "intel_crtc.h" #include "intel_ddi.h" +#include "intel_ddi_buf_trans.h" #include "intel_de.h" #include "intel_display_regs.h" #include "intel_display_types.h" @@ -122,7 +123,7 @@ void intel_fdi_link_train(struct intel_crtc *crtc, { struct intel_display *display = to_intel_display(crtc); - display->funcs.fdi->fdi_link_train(crtc, crtc_state); + display->fdi.funcs->fdi_link_train(crtc, crtc_state); } /** @@ -852,7 +853,7 @@ void hsw_fdi_link_train(struct intel_encoder *encoder, u32 temp, i, rx_ctl_val; int n_entries; - encoder->get_buf_trans(encoder, crtc_state, &n_entries); + intel_ddi_buf_trans_get(encoder, crtc_state, &n_entries); hsw_prepare_dp_ddi_buffers(encoder, crtc_state); @@ -1108,11 +1109,11 @@ void intel_fdi_init_hook(struct intel_display *display) { if (display->platform.ironlake) { - display->funcs.fdi = &ilk_funcs; + display->fdi.funcs = &ilk_funcs; } else if (display->platform.sandybridge) { - display->funcs.fdi = &gen6_funcs; + display->fdi.funcs = &gen6_funcs; } else if (display->platform.ivybridge) { /* FIXME: detect B0+ stepping and use auto training */ - display->funcs.fdi = &ivb_funcs; + display->fdi.funcs = &ivb_funcs; } } diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index 9b4ff3b80b05..982f698e9814 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -72,6 +72,7 @@ intel_hdcp_adjust_hdcp_line_rekeying(struct intel_encoder *encoder, static int intel_conn_to_vcpi(struct intel_atomic_state *state, struct intel_connector *connector) { + struct intel_display *display = to_intel_display(state); struct drm_dp_mst_topology_mgr *mgr; struct drm_dp_mst_atomic_payload *payload; struct drm_dp_mst_topology_state *mst_state; @@ -79,13 +80,19 @@ static int intel_conn_to_vcpi(struct intel_atomic_state *state, /* For HDMI this is forced to be 0x0. For DP SST also this is 0x0. */ if (!connector->mst.port) return 0; - mgr = connector->mst.port->mgr; - drm_modeset_lock(&mgr->base.lock, state->base.acquire_ctx); - mst_state = to_drm_dp_mst_topology_state(mgr->base.state); - payload = drm_atomic_get_mst_payload_state(mst_state, connector->mst.port); - if (drm_WARN_ON(mgr->dev, !payload)) + mgr = connector->mst.port->mgr; + mst_state = drm_atomic_get_new_mst_topology_state(&state->base, mgr); + if (!mst_state) { + drm_dbg_kms(display->drm, "MST topology still not created\n"); return 0; + } + + payload = drm_atomic_get_mst_payload_state(mst_state, connector->mst.port); + if (!payload) { + drm_dbg_kms(display->drm, "MST Payload not present\n"); + return 0; + } return payload->vcpi; } diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index f9858b91f497..3d66b9ed1d90 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -2021,6 +2021,51 @@ intel_hdmi_mode_clock_valid(struct drm_connector *_connector, int clock, return status; } +static enum drm_mode_status +intel_hdmi_sink_format_valid(struct intel_connector *connector, + const struct drm_display_mode *mode, + bool has_hdmi_sink, + enum intel_output_format sink_format) +{ + const struct drm_display_info *info = &connector->base.display_info; + + switch (sink_format) { + case INTEL_OUTPUT_FORMAT_YCBCR420: + if (!has_hdmi_sink || + !connector->base.ycbcr_420_allowed || + !drm_mode_is_420(info, mode)) + return MODE_NO_420; + + return MODE_OK; + case INTEL_OUTPUT_FORMAT_RGB: + return MODE_OK; + default: + MISSING_CASE(sink_format); + return MODE_BAD; + } +} + +static enum drm_mode_status +intel_hdmi_mode_valid_format(struct intel_connector *connector, + const struct drm_display_mode *mode, + int clock, bool has_hdmi_sink, + enum intel_output_format sink_format) +{ + struct intel_display *display = to_intel_display(connector); + enum drm_mode_status status; + + status = intel_hdmi_sink_format_valid(connector, mode, + has_hdmi_sink, sink_format); + if (status != MODE_OK) + return status; + + status = intel_pfit_mode_valid(display, mode, sink_format, 0); + if (status != MODE_OK) + return status; + + return intel_hdmi_mode_clock_valid(&connector->base, clock, has_hdmi_sink, sink_format); +} + static enum drm_mode_status intel_hdmi_mode_valid(struct drm_connector *_connector, const struct drm_display_mode *mode) @@ -2028,12 +2073,11 @@ intel_hdmi_mode_valid(struct drm_connector *_connector, struct intel_connector *connector = to_intel_connector(_connector); struct intel_display *display = to_intel_display(connector); struct intel_hdmi *hdmi = intel_attached_hdmi(connector); + const struct drm_display_info *info = &connector->base.display_info; enum drm_mode_status status; int clock = mode->clock; int max_dotclk = display->cdclk.max_dotclk_freq; bool has_hdmi_sink = intel_has_hdmi_sink(hdmi, connector->base.state); - bool ycbcr_420_only; - enum intel_output_format sink_format; status = intel_cpu_transcoder_mode_valid(display, mode); if (status != MODE_OK) @@ -2060,31 +2104,20 @@ intel_hdmi_mode_valid(struct drm_connector *_connector, if (clock > 600000) return MODE_CLOCK_HIGH; - ycbcr_420_only = drm_mode_is_420_only(&connector->base.display_info, mode); + if (drm_mode_is_420_only(info, mode)) { + status = intel_hdmi_mode_valid_format(connector, mode, clock, has_hdmi_sink, + INTEL_OUTPUT_FORMAT_YCBCR420); + } else { + status = intel_hdmi_mode_valid_format(connector, mode, clock, has_hdmi_sink, + INTEL_OUTPUT_FORMAT_RGB); - if (ycbcr_420_only) - sink_format = INTEL_OUTPUT_FORMAT_YCBCR420; - else - sink_format = INTEL_OUTPUT_FORMAT_RGB; - - status = intel_pfit_mode_valid(display, mode, sink_format, 0); + if (status != MODE_OK && drm_mode_is_420_also(info, mode)) + status = intel_hdmi_mode_valid_format(connector, mode, clock, has_hdmi_sink, + INTEL_OUTPUT_FORMAT_YCBCR420); + } if (status != MODE_OK) return status; - status = intel_hdmi_mode_clock_valid(&connector->base, clock, has_hdmi_sink, sink_format); - if (status != MODE_OK) { - if (ycbcr_420_only || - !connector->base.ycbcr_420_allowed || - !drm_mode_is_420_also(&connector->base.display_info, mode)) - return status; - - sink_format = INTEL_OUTPUT_FORMAT_YCBCR420; - status = intel_hdmi_mode_clock_valid(&connector->base, clock, has_hdmi_sink, - sink_format); - if (status != MODE_OK) - return status; - } - return intel_mode_valid_max_plane_size(display, mode, 1); } @@ -2241,20 +2274,6 @@ static bool intel_hdmi_has_audio(struct intel_encoder *encoder, return intel_conn_state->force_audio == HDMI_AUDIO_ON; } -static enum intel_output_format -intel_hdmi_sink_format(const struct intel_crtc_state *crtc_state, - struct intel_connector *connector, - bool ycbcr_420_output) -{ - if (!crtc_state->has_hdmi_sink) - return INTEL_OUTPUT_FORMAT_RGB; - - if (connector->base.ycbcr_420_allowed && ycbcr_420_output) - return INTEL_OUTPUT_FORMAT_YCBCR420; - else - return INTEL_OUTPUT_FORMAT_RGB; -} - static enum intel_output_format intel_hdmi_output_format(const struct intel_crtc_state *crtc_state) { @@ -2263,37 +2282,55 @@ intel_hdmi_output_format(const struct intel_crtc_state *crtc_state) static int intel_hdmi_compute_output_format(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state, - bool respect_downstream_limits) + struct intel_connector *connector, + bool respect_downstream_limits, + enum intel_output_format sink_format) +{ + const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; + + if (intel_hdmi_sink_format_valid(connector, adjusted_mode, + crtc_state->has_hdmi_sink, sink_format) != MODE_OK) + return -EINVAL; + + crtc_state->sink_format = sink_format; + crtc_state->output_format = intel_hdmi_output_format(crtc_state); + + return intel_hdmi_compute_clock(encoder, crtc_state, respect_downstream_limits); +} + +static int intel_hdmi_compute_formats(struct intel_encoder *encoder, + struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state, + bool respect_downstream_limits) { struct intel_display *display = to_intel_display(encoder); struct intel_connector *connector = to_intel_connector(conn_state->connector); const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; const struct drm_display_info *info = &connector->base.display_info; - bool ycbcr_420_only = drm_mode_is_420_only(info, adjusted_mode); int ret; - crtc_state->sink_format = - intel_hdmi_sink_format(crtc_state, connector, ycbcr_420_only); + if (drm_mode_is_420_only(info, adjusted_mode)) { + ret = intel_hdmi_compute_output_format(encoder, crtc_state, connector, + respect_downstream_limits, + INTEL_OUTPUT_FORMAT_YCBCR420); - if (ycbcr_420_only && crtc_state->sink_format != INTEL_OUTPUT_FORMAT_YCBCR420) { - drm_dbg_kms(display->drm, - "YCbCr 4:2:0 mode but YCbCr 4:2:0 output not possible. Falling back to RGB.\n"); - crtc_state->sink_format = INTEL_OUTPUT_FORMAT_RGB; - } + if (ret && !respect_downstream_limits) { + drm_dbg_kms(display->drm, + "YCbCr 4:2:0 mode but YCbCr 4:2:0 output not possible. Falling back to RGB.\n"); - crtc_state->output_format = intel_hdmi_output_format(crtc_state); - ret = intel_hdmi_compute_clock(encoder, crtc_state, respect_downstream_limits); - if (ret) { - if (crtc_state->sink_format == INTEL_OUTPUT_FORMAT_YCBCR420 || - !crtc_state->has_hdmi_sink || - !connector->base.ycbcr_420_allowed || - !drm_mode_is_420_also(info, adjusted_mode)) - return ret; + ret = intel_hdmi_compute_output_format(encoder, crtc_state, connector, + respect_downstream_limits, + INTEL_OUTPUT_FORMAT_RGB); + } + } else { + ret = intel_hdmi_compute_output_format(encoder, crtc_state, connector, + respect_downstream_limits, + INTEL_OUTPUT_FORMAT_RGB); - crtc_state->sink_format = INTEL_OUTPUT_FORMAT_YCBCR420; - crtc_state->output_format = intel_hdmi_output_format(crtc_state); - ret = intel_hdmi_compute_clock(encoder, crtc_state, respect_downstream_limits); + if (ret && drm_mode_is_420_also(info, adjusted_mode)) + ret = intel_hdmi_compute_output_format(encoder, crtc_state, connector, + respect_downstream_limits, + INTEL_OUTPUT_FORMAT_YCBCR420); } return ret; @@ -2370,9 +2407,9 @@ int intel_hdmi_compute_config(struct intel_encoder *encoder, * Try to respect downstream TMDS clock limits first, if * that fails assume the user might know something we don't. */ - ret = intel_hdmi_compute_output_format(encoder, pipe_config, conn_state, true); + ret = intel_hdmi_compute_formats(encoder, pipe_config, conn_state, true); if (ret) - ret = intel_hdmi_compute_output_format(encoder, pipe_config, conn_state, false); + ret = intel_hdmi_compute_formats(encoder, pipe_config, conn_state, false); if (ret) { drm_dbg_kms(display->drm, "unsupported HDMI clock (%d kHz), rejecting mode\n", @@ -2380,11 +2417,9 @@ int intel_hdmi_compute_config(struct intel_encoder *encoder, return ret; } - if (intel_hdmi_is_ycbcr420(pipe_config)) { - ret = intel_pfit_compute_config(pipe_config, conn_state); - if (ret) - return ret; - } + ret = intel_pfit_compute_config(pipe_config, conn_state); + if (ret) + return ret; pipe_config->limited_color_range = intel_hdmi_limited_color_range(pipe_config, conn_state); diff --git a/drivers/gpu/drm/i915/display/intel_hotplug_irq.c b/drivers/gpu/drm/i915/display/intel_hotplug_irq.c index 8865cb2ac569..539fd555edce 100644 --- a/drivers/gpu/drm/i915/display/intel_hotplug_irq.c +++ b/drivers/gpu/drm/i915/display/intel_hotplug_irq.c @@ -1420,7 +1420,7 @@ static void i915_hpd_irq_setup(struct intel_display *display) hotplug_en); } -struct intel_hotplug_funcs { +struct intel_hotplug_irq_funcs { /* Enable HPD sense and interrupts for all present encoders */ void (*hpd_irq_setup)(struct intel_display *display); /* Enable HPD sense for a single encoder */ @@ -1428,7 +1428,7 @@ struct intel_hotplug_funcs { }; #define HPD_FUNCS(platform) \ -static const struct intel_hotplug_funcs platform##_hpd_funcs = { \ +static const struct intel_hotplug_irq_funcs platform##_hpd_funcs = { \ .hpd_irq_setup = platform##_hpd_irq_setup, \ .hpd_enable_detection = platform##_hpd_enable_detection, \ } @@ -1447,8 +1447,8 @@ void intel_hpd_enable_detection(struct intel_encoder *encoder) { struct intel_display *display = to_intel_display(encoder); - if (display->funcs.hotplug) - display->funcs.hotplug->hpd_enable_detection(encoder); + if (display->hotplug.funcs) + display->hotplug.funcs->hpd_enable_detection(encoder); } void intel_hpd_irq_setup(struct intel_display *display) @@ -1457,8 +1457,8 @@ void intel_hpd_irq_setup(struct intel_display *display) !display->irq.vlv_display_irqs_enabled) return; - if (display->funcs.hotplug) - display->funcs.hotplug->hpd_irq_setup(display); + if (display->hotplug.funcs) + display->hotplug.funcs->hpd_irq_setup(display); } void intel_hotplug_irq_init(struct intel_display *display) @@ -1469,23 +1469,23 @@ void intel_hotplug_irq_init(struct intel_display *display) if (HAS_GMCH(display)) { if (HAS_HOTPLUG(display)) - display->funcs.hotplug = &i915_hpd_funcs; + display->hotplug.funcs = &i915_hpd_funcs; } else { if (HAS_PCH_DG2(display)) - display->funcs.hotplug = &icp_hpd_funcs; + display->hotplug.funcs = &icp_hpd_funcs; else if (HAS_PCH_DG1(display)) - display->funcs.hotplug = &dg1_hpd_funcs; + display->hotplug.funcs = &dg1_hpd_funcs; else if (DISPLAY_VER(display) >= 14) - display->funcs.hotplug = &xelpdp_hpd_funcs; + display->hotplug.funcs = &xelpdp_hpd_funcs; else if (DISPLAY_VER(display) >= 11) - display->funcs.hotplug = &gen11_hpd_funcs; + display->hotplug.funcs = &gen11_hpd_funcs; else if (display->platform.geminilake || display->platform.broxton) - display->funcs.hotplug = &bxt_hpd_funcs; + display->hotplug.funcs = &bxt_hpd_funcs; else if (INTEL_PCH_TYPE(display) >= PCH_ICP) - display->funcs.hotplug = &icp_hpd_funcs; + display->hotplug.funcs = &icp_hpd_funcs; else if (INTEL_PCH_TYPE(display) >= PCH_SPT) - display->funcs.hotplug = &spt_hpd_funcs; + display->hotplug.funcs = &spt_hpd_funcs; else - display->funcs.hotplug = &ilk_hpd_funcs; + display->hotplug.funcs = &ilk_hpd_funcs; } } diff --git a/drivers/gpu/drm/i915/display/intel_initial_plane.c b/drivers/gpu/drm/i915/display/intel_initial_plane.c index ee545c033da6..034fe199c2a1 100644 --- a/drivers/gpu/drm/i915/display/intel_initial_plane.c +++ b/drivers/gpu/drm/i915/display/intel_initial_plane.c @@ -1,26 +1,51 @@ // SPDX-License-Identifier: MIT /* Copyright © 2025 Intel Corporation */ +#include + +#include #include #include +#include "intel_crtc.h" +#include "intel_de.h" #include "intel_display_core.h" +#include "intel_display_regs.h" #include "intel_display_types.h" #include "intel_fb.h" #include "intel_frontbuffer.h" #include "intel_initial_plane.h" +#include "intel_parent.h" #include "intel_plane.h" +struct intel_initial_plane_configs { + struct intel_initial_plane_config config[I915_MAX_PIPES]; +}; + void intel_initial_plane_vblank_wait(struct intel_crtc *crtc) { struct intel_display *display = to_intel_display(crtc); + u32 start_ts, end_ts; + int ret; - display->parent->initial_plane->vblank_wait(&crtc->base); + /* xe doesn't have interrupts enabled this early */ + if (intel_parent_irq_enabled(display)) { + intel_crtc_wait_for_next_vblank(crtc); + return; + } + + start_ts = intel_de_read(display, PIPE_FRMTMSTMP(crtc->pipe)); + + ret = poll_timeout_us(end_ts = intel_de_read(display, PIPE_FRMTMSTMP(crtc->pipe)), + end_ts != start_ts, 1000, 1000 * 1000, false); + if (ret) + drm_warn(display->drm, "[CRTC:%d:%s] early vblank wait timed out\n", + crtc->base.base.id, crtc->base.name); } static const struct intel_plane_state * intel_reuse_initial_plane_obj(struct intel_crtc *this, - const struct intel_initial_plane_config plane_configs[]) + const struct intel_initial_plane_configs *all_plane_configs) { struct intel_display *display = to_intel_display(this); struct intel_crtc *crtc; @@ -39,7 +64,8 @@ intel_reuse_initial_plane_obj(struct intel_crtc *this, if (!plane_state->ggtt_vma) continue; - if (plane_configs[this->pipe].base == plane_configs[crtc->pipe].base) + if (all_plane_configs->config[this->pipe].base == + all_plane_configs->config[crtc->pipe].base) return plane_state; } @@ -50,17 +76,38 @@ static struct drm_gem_object * intel_alloc_initial_plane_obj(struct intel_display *display, struct intel_initial_plane_config *plane_config) { - struct intel_framebuffer *fb = plane_config->fb; + struct drm_framebuffer *fb = plane_config->fb; - switch (fb->base.modifier) { + switch (fb->modifier) { case DRM_FORMAT_MOD_LINEAR: + break; case I915_FORMAT_MOD_X_TILED: case I915_FORMAT_MOD_Y_TILED: - case I915_FORMAT_MOD_4_TILED: - break; + /* fenced region needed for linear CPU access to tiled FB */ + if (intel_parent_has_fenced_regions(display)) + break; + fallthrough; default: drm_dbg_kms(display->drm, "Unsupported modifier for initial FB: 0x%llx\n", - fb->base.modifier); + fb->modifier); + return NULL; + } + + /* + * Would need to preserve the DPT, its GGTT + * mapping, and the actual FB memory. + */ + if (intel_fb_modifier_uses_dpt(display, fb->modifier)) { + drm_dbg_kms(display->drm, "DPT not supported for initial FB\n"); + return NULL; + } + + /* + * Would need to preserve the 270 degree rotated + * GGTT mapping used by the display hardware. + */ + if (drm_rotation_90_or_270(plane_config->rotation)) { + drm_dbg_kms(display->drm, "90/270 degree rotation not supported for initial FB\n"); return NULL; } @@ -69,10 +116,10 @@ intel_alloc_initial_plane_obj(struct intel_display *display, static void intel_find_initial_plane_obj(struct intel_crtc *crtc, - struct intel_initial_plane_config plane_configs[]) + struct intel_initial_plane_configs *all_plane_configs) { struct intel_display *display = to_intel_display(crtc); - struct intel_initial_plane_config *plane_config = &plane_configs[crtc->pipe]; + struct intel_initial_plane_config *plane_config = &all_plane_configs->config[crtc->pipe]; struct intel_plane *plane = to_intel_plane(crtc->base.primary); struct intel_plane_state *plane_state = to_intel_plane_state(plane->base.state); struct drm_framebuffer *fb; @@ -88,12 +135,12 @@ intel_find_initial_plane_obj(struct intel_crtc *crtc, return; if (intel_alloc_initial_plane_obj(display, plane_config)) { - fb = &plane_config->fb->base; + fb = plane_config->fb; vma = plane_config->vma; } else { const struct intel_plane_state *other_plane_state; - other_plane_state = intel_reuse_initial_plane_obj(crtc, plane_configs); + other_plane_state = intel_reuse_initial_plane_obj(crtc, all_plane_configs); if (!other_plane_state) goto nofb; @@ -144,7 +191,7 @@ static void plane_config_fini(struct intel_display *display, struct intel_initial_plane_config *plane_config) { if (plane_config->fb) { - struct drm_framebuffer *fb = &plane_config->fb->base; + struct drm_framebuffer *fb = plane_config->fb; /* We may only have the stub and not a full framebuffer */ if (drm_framebuffer_read_refcount(fb)) @@ -158,14 +205,14 @@ static void plane_config_fini(struct intel_display *display, void intel_initial_plane_config(struct intel_display *display) { - struct intel_initial_plane_config plane_configs[I915_MAX_PIPES] = {}; + struct intel_initial_plane_configs all_plane_configs = {}; struct intel_crtc *crtc; for_each_intel_crtc(display->drm, crtc) { const struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); struct intel_initial_plane_config *plane_config = - &plane_configs[crtc->pipe]; + &all_plane_configs.config[crtc->pipe]; if (!crtc_state->hw.active) continue; @@ -177,15 +224,15 @@ void intel_initial_plane_config(struct intel_display *display) * can even allow for smooth boot transitions if the BIOS * fb is large enough for the active pipe configuration. */ - display->funcs.display->get_initial_plane_config(crtc, plane_config); + display->modeset.funcs->get_initial_plane_config(crtc, plane_config); /* * If the fb is shared between multiple heads, we'll * just get the first one. */ - intel_find_initial_plane_obj(crtc, plane_configs); + intel_find_initial_plane_obj(crtc, &all_plane_configs); - if (display->funcs.display->fixup_initial_plane_config(crtc, plane_config)) + if (display->modeset.funcs->fixup_initial_plane_config(crtc, plane_config)) intel_initial_plane_vblank_wait(crtc); plane_config_fini(display, plane_config); diff --git a/drivers/gpu/drm/i915/display/intel_lpe_audio.c b/drivers/gpu/drm/i915/display/intel_lpe_audio.c index 117b60656ca1..775493306a83 100644 --- a/drivers/gpu/drm/i915/display/intel_lpe_audio.c +++ b/drivers/gpu/drm/i915/display/intel_lpe_audio.c @@ -70,11 +70,11 @@ #include #include +#include #include "intel_audio_regs.h" #include "intel_de.h" #include "intel_lpe_audio.h" -#include "intel_pci_config.h" #define HAS_LPE_AUDIO(display) ((display)->audio.lpe.platdev) diff --git a/drivers/gpu/drm/i915/display/intel_lt_phy.c b/drivers/gpu/drm/i915/display/intel_lt_phy.c index 657ad5cb0eff..e2f9e1a2745f 100644 --- a/drivers/gpu/drm/i915/display/intel_lt_phy.c +++ b/drivers/gpu/drm/i915/display/intel_lt_phy.c @@ -2135,7 +2135,7 @@ void intel_lt_phy_set_signal_levels(struct intel_encoder *encoder, wakeref = intel_lt_phy_transaction_begin(encoder); - trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); + trans = intel_ddi_buf_trans_get(encoder, crtc_state, &n_entries); if (drm_WARN_ON_ONCE(display->drm, !trans)) { intel_lt_phy_transaction_end(encoder, wakeref); return; diff --git a/drivers/gpu/drm/i915/display/intel_mchbar.c b/drivers/gpu/drm/i915/display/intel_mchbar.c new file mode 100644 index 000000000000..a0d0a796c6bb --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_mchbar.c @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright © 2026 Intel Corporation + */ + +#include + +#include + +#include "intel_de.h" +#include "intel_display_core.h" +#include "intel_mchbar.h" + +static bool has_mchbar_mirror(struct intel_display *display) +{ + return DISPLAY_VER(display) < 14; +} + +static u32 mchbar_mirror_base(struct intel_display *display) +{ + if (DISPLAY_VER(display) >= 6) + return MCHBAR_MIRROR_BASE_SNB; + else + return MCHBAR_MIRROR_BASE; +} + +static u32 mchbar_mirror_end(struct intel_display *display) +{ + if (DISPLAY_VER(display) >= 12 && !display->platform.rocketlake) + return MCHBAR_MIRROR_END_TGL; + else if (DISPLAY_VER(display) >= 11) + return MCHBAR_MIRROR_END_ICL_RKL; + else if (DISPLAY_VER(display) >= 6) + return MCHBAR_MIRROR_END_SNB; + else + return MCHBAR_MIRROR_END; +} + +static u32 mchbar_mirror_len(struct intel_display *display) +{ + return mchbar_mirror_end(display) - mchbar_mirror_base(display) + 1; +} + +static bool is_mchbar_reg(struct intel_display *display, i915_reg_t reg) +{ + return has_mchbar_mirror(display) && + in_range32(i915_mmio_reg_offset(reg), + mchbar_mirror_base(display), + mchbar_mirror_len(display)); +} + +static void assert_is_mchbar_reg(struct intel_display *display, i915_reg_t reg) +{ + drm_WARN(display->drm, !is_mchbar_reg(display, reg), + "Reading non-MCHBAR register 0x%x\n", + i915_mmio_reg_offset(reg)); +} + +u16 intel_mchbar_read16(struct intel_display *display, i915_reg_t reg) +{ + assert_is_mchbar_reg(display, reg); + + return intel_de_read16(display, reg); +} + +u32 intel_mchbar_read(struct intel_display *display, i915_reg_t reg) +{ + assert_is_mchbar_reg(display, reg); + + return intel_de_read(display, reg); +} + +u64 intel_mchbar_read64_2x32(struct intel_display *display, i915_reg_t reg) +{ + assert_is_mchbar_reg(display, reg); + + return intel_de_read64_2x32(display, reg); +} diff --git a/drivers/gpu/drm/i915/display/intel_mchbar.h b/drivers/gpu/drm/i915/display/intel_mchbar.h new file mode 100644 index 000000000000..fb645c64796c --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_mchbar.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2026 Intel Corporation + */ + +#ifndef __INTEL_MCHBAR_H__ +#define __INTEL_MCHBAR_H__ + +#include + +#include + +#include "i915_reg_defs.h" + +struct intel_display; + +u16 intel_mchbar_read16(struct intel_display *display, i915_reg_t reg); +u32 intel_mchbar_read(struct intel_display *display, i915_reg_t reg); +u64 intel_mchbar_read64_2x32(struct intel_display *display, i915_reg_t reg); + +#endif /* __INTEL_MCHBAR_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_modeset_setup.c b/drivers/gpu/drm/i915/display/intel_modeset_setup.c index 9a0f89f1a1f2..e88082c8caac 100644 --- a/drivers/gpu/drm/i915/display/intel_modeset_setup.c +++ b/drivers/gpu/drm/i915/display/intel_modeset_setup.c @@ -83,7 +83,7 @@ static void intel_crtc_disable_noatomic_begin(struct intel_crtc *crtc, drm_WARN_ON(display->drm, IS_ERR(temp_crtc_state) || ret); } - display->funcs.display->crtc_disable(to_intel_atomic_state(state), crtc); + display->modeset.funcs->crtc_disable(to_intel_atomic_state(state), crtc); drm_atomic_commit_put(state); @@ -333,6 +333,7 @@ static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode; crtc_state->uapi.scaling_filter = crtc_state->hw.scaling_filter; + crtc_state->uapi.sharpness_strength = crtc_state->hw.sharpness_strength; if (DISPLAY_INFO(display)->color.degamma_lut_size) { /* assume 1:1 mapping */ diff --git a/drivers/gpu/drm/i915/display/intel_opregion.c b/drivers/gpu/drm/i915/display/intel_opregion.c index e25be56e678b..9f88b7cac9f7 100644 --- a/drivers/gpu/drm/i915/display/intel_opregion.c +++ b/drivers/gpu/drm/i915/display/intel_opregion.c @@ -34,13 +34,13 @@ #include #include #include +#include #include "intel_acpi.h" #include "intel_backlight.h" #include "intel_display_core.h" #include "intel_display_types.h" #include "intel_opregion.h" -#include "intel_pci_config.h" #define OPREGION_HEADER_OFFSET 0 #define OPREGION_ACPI_OFFSET 0x100 diff --git a/drivers/gpu/drm/i915/display/intel_overlay.c b/drivers/gpu/drm/i915/display/intel_overlay.c index 12a325ceae6f..a809aa2950ac 100644 --- a/drivers/gpu/drm/i915/display/intel_overlay.c +++ b/drivers/gpu/drm/i915/display/intel_overlay.c @@ -481,13 +481,9 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, if (ret != 0) return ret; - atomic_inc(&display->restore.pending_fb_pin); - vma = intel_parent_overlay_pin_fb(display, obj, &offset); - if (IS_ERR(vma)) { - ret = PTR_ERR(vma); - goto out_pin_section; - } + if (IS_ERR(vma)) + return PTR_ERR(vma); if (!intel_parent_overlay_is_active(display)) { const struct intel_crtc_state *crtc_state = @@ -571,8 +567,6 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, out_unpin: intel_parent_overlay_unpin_fb(display, vma); -out_pin_section: - atomic_dec(&display->restore.pending_fb_pin); return ret; } diff --git a/drivers/gpu/drm/i915/display/intel_parent.c b/drivers/gpu/drm/i915/display/intel_parent.c index 2e3bad2b3e6b..67b21a42d354 100644 --- a/drivers/gpu/drm/i915/display/intel_parent.c +++ b/drivers/gpu/drm/i915/display/intel_parent.c @@ -19,6 +19,7 @@ #include #include +#include #include "intel_display_core.h" #include "intel_parent.h" @@ -338,13 +339,37 @@ void intel_parent_stolen_node_free(struct intel_display *display, const struct i display->parent->stolen->node_free(node); } -/* vma */ -int intel_parent_vma_fence_id(struct intel_display *display, const struct i915_vma *vma) +/* vlv iosf */ +void intel_parent_vlv_iosf_get(struct intel_display *display, unsigned long unit_mask) { - if (!display->parent->vma) - return -1; + if (drm_WARN_ON_ONCE(display->drm, !display->parent->vlv_iosf)) + return; - return display->parent->vma->fence_id(vma); + display->parent->vlv_iosf->get(display->drm, unit_mask); +} + +void intel_parent_vlv_iosf_put(struct intel_display *display, unsigned long unit_mask) +{ + if (drm_WARN_ON_ONCE(display->drm, !display->parent->vlv_iosf)) + return; + + display->parent->vlv_iosf->put(display->drm, unit_mask); +} + +u32 intel_parent_vlv_iosf_read(struct intel_display *display, enum vlv_iosf_sb_unit unit, u32 addr) +{ + if (drm_WARN_ON_ONCE(display->drm, !display->parent->vlv_iosf)) + return 0; + + return display->parent->vlv_iosf->read(display->drm, unit, addr); +} + +int intel_parent_vlv_iosf_write(struct intel_display *display, enum vlv_iosf_sb_unit unit, u32 addr, u32 val) +{ + if (drm_WARN_ON_ONCE(display->drm, !display->parent->vlv_iosf)) + return -EINVAL; + + return display->parent->vlv_iosf->write(display->drm, unit, addr, val); } /* generic */ diff --git a/drivers/gpu/drm/i915/display/intel_parent.h b/drivers/gpu/drm/i915/display/intel_parent.h index 2013e5ed5aa9..5f0c835b9416 100644 --- a/drivers/gpu/drm/i915/display/intel_parent.h +++ b/drivers/gpu/drm/i915/display/intel_parent.h @@ -6,6 +6,7 @@ #include +enum vlv_iosf_sb_unit; struct dma_fence; struct drm_file; struct drm_gem_object; @@ -109,8 +110,11 @@ u64 intel_parent_stolen_node_size(struct intel_display *display, const struct in struct intel_stolen_node *intel_parent_stolen_node_alloc(struct intel_display *display); void intel_parent_stolen_node_free(struct intel_display *display, const struct intel_stolen_node *node); -/* vma */ -int intel_parent_vma_fence_id(struct intel_display *display, const struct i915_vma *vma); +/* vlv iosf */ +void intel_parent_vlv_iosf_get(struct intel_display *display, unsigned long unit_mask); +void intel_parent_vlv_iosf_put(struct intel_display *display, unsigned long unit_mask); +u32 intel_parent_vlv_iosf_read(struct intel_display *display, enum vlv_iosf_sb_unit unit, u32 addr); +int intel_parent_vlv_iosf_write(struct intel_display *display, enum vlv_iosf_sb_unit unit, u32 addr, u32 val); /* generic */ bool intel_parent_has_auxccs(struct intel_display *display); diff --git a/drivers/gpu/drm/i915/display/intel_pfit.c b/drivers/gpu/drm/i915/display/intel_pfit.c index 6dda496190e0..5b170c74a510 100644 --- a/drivers/gpu/drm/i915/display/intel_pfit.c +++ b/drivers/gpu/drm/i915/display/intel_pfit.c @@ -186,6 +186,7 @@ static int pch_panel_fitting(struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state) { struct intel_display *display = to_intel_display(crtc_state); + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; int pipe_src_w = drm_rect_width(&crtc_state->pipe_src); @@ -195,11 +196,22 @@ static int pch_panel_fitting(struct intel_crtc_state *crtc_state, /* Native modes don't need fitting */ if (adjusted_mode->crtc_hdisplay == pipe_src_w && adjusted_mode->crtc_vdisplay == pipe_src_h && - crtc_state->output_format != INTEL_OUTPUT_FORMAT_YCBCR420) + crtc_state->output_format != INTEL_OUTPUT_FORMAT_YCBCR420 && + crtc_state->hw.sharpness_strength == 0) return 0; switch (conn_state->scaling_mode) { case DRM_MODE_SCALE_CENTER: + if (adjusted_mode->crtc_hdisplay < pipe_src_w || + adjusted_mode->crtc_vdisplay < pipe_src_h) { + drm_dbg_kms(display->drm, + "[CRTC:%d:%s] pfit center mode source (%dx%d) exceeds display (%dx%d)\n", + crtc->base.base.id, crtc->base.name, + pipe_src_w, pipe_src_h, + adjusted_mode->crtc_hdisplay, + adjusted_mode->crtc_vdisplay); + return -EINVAL; + } width = pipe_src_w; height = pipe_src_h; x = (adjusted_mode->crtc_hdisplay - width + 1)/2; @@ -249,6 +261,16 @@ static int pch_panel_fitting(struct intel_crtc_state *crtc_state, return -EINVAL; } + if (crtc_state->hw.sharpness_strength && + (width != pipe_src_w || height != pipe_src_h || + crtc_state->hw.scaling_filter != DRM_SCALING_FILTER_DEFAULT || + crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB)) { + drm_dbg_kms(display->drm, + "[CRTC:%d:%s] no scaling/YCbCr output with sharpness filter\n", + crtc->base.base.id, crtc->base.name); + return -EINVAL; + } + drm_rect_init(&crtc_state->pch_pfit.dst, x, y, width, height); crtc_state->pch_pfit.enabled = true; diff --git a/drivers/gpu/drm/i915/display/intel_plane.c b/drivers/gpu/drm/i915/display/intel_plane.c index 99b0c8325dba..c181a7d063ec 100644 --- a/drivers/gpu/drm/i915/display/intel_plane.c +++ b/drivers/gpu/drm/i915/display/intel_plane.c @@ -70,6 +70,7 @@ static void intel_plane_state_reset(struct intel_plane_state *plane_state, __drm_atomic_helper_plane_state_reset(&plane_state->uapi, &plane->base); plane_state->scaler_id = -1; + plane_state->fence_id = -1; } struct intel_plane *intel_plane_alloc(void) @@ -137,7 +138,7 @@ intel_plane_duplicate_state(struct drm_plane *plane) intel_state->ggtt_vma = NULL; intel_state->dpt_vma = NULL; - intel_state->flags = 0; + intel_state->fence_id = -1; intel_state->damage = DRM_RECT_INIT(0, 0, 0, 0); /* add reference to fb */ @@ -170,6 +171,19 @@ intel_plane_destroy_state(struct drm_plane *plane, kfree(plane_state); } +bool intel_plane_needs_low_address(struct intel_display *display) +{ + /* + * Valleyview is definitely limited to scanning out the first + * 512MiB. Lets presume this behaviour was inherited from the + * g4x display engine and that all earlier gen are similarly + * limited. Testing suggests that it is a little more + * complicated than this. For example, Cherryview appears quite + * happy to scanout from anywhere within its global aperture. + */ + return HAS_GMCH(display); +} + bool intel_plane_needs_physical(struct intel_plane *plane) { struct intel_display *display = to_intel_display(plane); @@ -178,6 +192,15 @@ bool intel_plane_needs_physical(struct intel_plane *plane) DISPLAY_INFO(display)->cursor_needs_physical; } +bool intel_plane_needs_fence(struct intel_display *display) +{ + /* + * pre-i965 planes use the fence for tiled scanout. + * i965+ planes have their own tiled scanout control bit. + */ + return DISPLAY_VER(display) < 4; +} + bool intel_plane_can_async_flip(struct intel_plane *plane, const struct drm_format_info *info, u64 modifier) diff --git a/drivers/gpu/drm/i915/display/intel_plane.h b/drivers/gpu/drm/i915/display/intel_plane.h index 5a8f2f3baab5..7b5456f56f42 100644 --- a/drivers/gpu/drm/i915/display/intel_plane.h +++ b/drivers/gpu/drm/i915/display/intel_plane.h @@ -15,6 +15,7 @@ struct drm_rect; struct intel_atomic_state; struct intel_crtc; struct intel_crtc_state; +struct intel_display; struct intel_dsb; struct intel_plane; struct intel_plane_state; @@ -79,7 +80,9 @@ int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state); void intel_plane_set_invisible(struct intel_crtc_state *crtc_state, struct intel_plane_state *plane_state); void intel_plane_helper_add(struct intel_plane *plane); +bool intel_plane_needs_low_address(struct intel_display *display); bool intel_plane_needs_physical(struct intel_plane *plane); +bool intel_plane_needs_fence(struct intel_display *display); void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state, struct intel_plane_state *new_plane_state); int intel_plane_add_affected(struct intel_atomic_state *state, diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 3b6e885de1c9..9958230a3dd9 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -45,6 +45,7 @@ #include "intel_dmc.h" #include "intel_dp.h" #include "intel_dp_aux.h" +#include "intel_dp_tunnel.h" #include "intel_dsb.h" #include "intel_frontbuffer.h" #include "intel_hdmi.h" @@ -694,6 +695,9 @@ static void _psr_init_dpcd(struct intel_dp *intel_dp, struct intel_connector *co connector->dp.psr_caps.sync_latency = intel_dp_get_sink_sync_latency(intel_dp); + if (intel_has_quirk(display, QUIRK_DISABLE_PSR2)) + return; + if (DISPLAY_VER(display) >= 9 && connector->dp.psr_caps.dpcd[0] >= DP_PSR2_WITH_Y_COORD_IS_SUPPORTED) { bool y_req = connector->dp.psr_caps.dpcd[1] & @@ -1031,11 +1035,27 @@ static u8 frames_before_su_entry(struct intel_dp *intel_dp) return frames_before_su_entry; } +static bool intel_psr_allow_pr_bw_optimization(struct intel_dp *intel_dp) +{ + if (intel_dp_is_edp(intel_dp)) + return false; + + if (!intel_dp_tunnel_bw_alloc_is_enabled(intel_dp)) + return false; + + if (!intel_dp_tunnel_pr_optimization_supported(intel_dp)) + return false; + + return true; +} + static void dg2_activate_panel_replay(struct intel_dp *intel_dp) { struct intel_display *display = to_intel_display(intel_dp); struct intel_psr *psr = &intel_dp->psr; enum transcoder cpu_transcoder = intel_dp->psr.transcoder; + u32 dp2_ctl_set = TRANS_DP2_PANEL_REPLAY_ENABLE; + u32 dp2_ctl_clear = 0; if (intel_dp_is_edp(intel_dp) && psr->sel_update_enabled) { u32 val = psr->su_region_et_enabled ? @@ -1048,12 +1068,16 @@ static void dg2_activate_panel_replay(struct intel_dp *intel_dp) val); } + if (intel_psr_allow_pr_bw_optimization(intel_dp)) + dp2_ctl_set |= TRANS_DP2_PR_TUNNELING_ENABLE; + else + dp2_ctl_clear = TRANS_DP2_PR_TUNNELING_ENABLE; + intel_de_rmw(display, PSR2_MAN_TRK_CTL(display, intel_dp->psr.transcoder), 0, ADLP_PSR2_MAN_TRK_CTL_SF_CONTINUOS_FULL_FRAME); - intel_de_rmw(display, TRANS_DP2_CTL(intel_dp->psr.transcoder), 0, - TRANS_DP2_PANEL_REPLAY_ENABLE); + intel_de_rmw(display, TRANS_DP2_CTL(intel_dp->psr.transcoder), dp2_ctl_clear, dp2_ctl_set); } static void hsw_activate_psr2(struct intel_dp *intel_dp) diff --git a/drivers/gpu/drm/i915/display/intel_quirks.c b/drivers/gpu/drm/i915/display/intel_quirks.c index 883f297d4b83..33245f44c0d5 100644 --- a/drivers/gpu/drm/i915/display/intel_quirks.c +++ b/drivers/gpu/drm/i915/display/intel_quirks.c @@ -94,6 +94,12 @@ static void quirk_disable_edp_panel_replay(struct intel_dp *intel_dp) drm_info(display->drm, "Applying disable Panel Replay quirk\n"); } +static void quirk_disable_psr2(struct intel_display *display) +{ + intel_set_quirk(display, QUIRK_DISABLE_PSR2); + drm_info(display->drm, "PSR2 support not currently available for this setup, applying disable PSR2 quirk\n"); +} + struct intel_quirk { int device; int subsystem_vendor; @@ -250,6 +256,9 @@ static struct intel_quirk intel_quirks[] = { /* Dell XPS 13 7390 2-in-1 */ { 0x8a52, 0x1028, 0x08b0, quirk_edp_limit_rate_hbr2 }, + + /* Xiaomi Book Pro 14 2026 */ + { 0xb081, 0x1d72, 0x2424, quirk_disable_psr2 }, }; static const struct intel_dpcd_quirk intel_dpcd_quirks[] = { @@ -269,6 +278,14 @@ static const struct intel_dpcd_quirk intel_dpcd_quirks[] = { .sink_oui = SINK_OUI(0x00, 0x22, 0xb9), .hook = quirk_disable_edp_panel_replay, }, + /* Dell XPS 16 DA16260 */ + { + .device = DEVICE_ID_ANY, + .subsystem_vendor = 0x1028, + .subsystem_device = 0x0dba, + .sink_oui = SINK_OUI(0x00, 0x22, 0xb9), + .hook = quirk_disable_edp_panel_replay, + }, }; void intel_init_quirks(struct intel_display *display) diff --git a/drivers/gpu/drm/i915/display/intel_quirks.h b/drivers/gpu/drm/i915/display/intel_quirks.h index 83214eb94b0c..970a4fe52faf 100644 --- a/drivers/gpu/drm/i915/display/intel_quirks.h +++ b/drivers/gpu/drm/i915/display/intel_quirks.h @@ -22,6 +22,7 @@ enum intel_quirk_id { QUIRK_FW_SYNC_LEN, QUIRK_EDP_LIMIT_RATE_HBR2, QUIRK_DISABLE_EDP_PANEL_REPLAY, + QUIRK_DISABLE_PSR2, }; void intel_init_quirks(struct intel_display *display); diff --git a/drivers/gpu/drm/i915/display/intel_rom.c b/drivers/gpu/drm/i915/display/intel_rom.c index d573059fb0d9..54f842c09fb0 100644 --- a/drivers/gpu/drm/i915/display/intel_rom.c +++ b/drivers/gpu/drm/i915/display/intel_rom.c @@ -7,8 +7,9 @@ #include +#include "intel_de.h" +#include "intel_display_types.h" #include "intel_rom.h" -#include "intel_uncore.h" #include "intel_oprom_regs.h" struct intel_rom { @@ -17,7 +18,7 @@ struct intel_rom { void __iomem *oprom; /* for SPI */ - struct intel_uncore *uncore; + struct intel_display *display; loff_t offset; size_t size; @@ -30,10 +31,10 @@ struct intel_rom { static u32 spi_read32(struct intel_rom *rom, loff_t offset) { - intel_uncore_write(rom->uncore, PRIMARY_SPI_ADDRESS, - rom->offset + offset); + intel_de_write(rom->display, PRIMARY_SPI_ADDRESS, + rom->offset + offset); - return intel_uncore_read(rom->uncore, PRIMARY_SPI_TRIGGER); + return intel_de_read(rom->display, PRIMARY_SPI_TRIGGER); } static u16 spi_read16(struct intel_rom *rom, loff_t offset) @@ -50,13 +51,13 @@ struct intel_rom *intel_rom_spi(struct drm_device *drm) if (!rom) return NULL; - rom->uncore = to_intel_uncore(drm); + rom->display = to_intel_display(drm); - static_region = intel_uncore_read(rom->uncore, SPI_STATIC_REGIONS); + static_region = intel_de_read(rom->display, SPI_STATIC_REGIONS); static_region &= OPTIONROM_SPI_REGIONID_MASK; - intel_uncore_write(rom->uncore, PRIMARY_SPI_REGIONID, static_region); + intel_de_write(rom->display, PRIMARY_SPI_REGIONID, static_region); - rom->offset = intel_uncore_read(rom->uncore, OROM_OFFSET) & OROM_OFFSET_MASK; + rom->offset = intel_de_read(rom->display, OROM_OFFSET) & OROM_OFFSET_MASK; rom->size = 0x200000; diff --git a/drivers/gpu/drm/i915/display/intel_snps_phy.c b/drivers/gpu/drm/i915/display/intel_snps_phy.c index 295030742294..5e5dde8f3e3a 100644 --- a/drivers/gpu/drm/i915/display/intel_snps_phy.c +++ b/drivers/gpu/drm/i915/display/intel_snps_phy.c @@ -72,7 +72,7 @@ void intel_snps_phy_set_signal_levels(struct intel_encoder *encoder, enum phy phy = intel_encoder_to_phy(encoder); int n_entries, ln; - trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); + trans = intel_ddi_buf_trans_get(encoder, crtc_state, &n_entries); if (drm_WARN_ON_ONCE(display->drm, !trans)) return; diff --git a/drivers/gpu/drm/i915/display/intel_vblank.c b/drivers/gpu/drm/i915/display/intel_vblank.c index 1b7cfe226ff8..0726a2abed38 100644 --- a/drivers/gpu/drm/i915/display/intel_vblank.c +++ b/drivers/gpu/drm/i915/display/intel_vblank.c @@ -109,8 +109,8 @@ u32 i915_get_vblank_counter(struct drm_crtc *crtc) * we get a low value that's stable across two reads of the high * register. */ - frame = intel_de_read64_2x32(display, PIPEFRAMEPIXEL(display, pipe), - PIPEFRAME(display, pipe)); + frame = intel_de_read64_2x32_volatile(display, PIPEFRAMEPIXEL(display, pipe), + PIPEFRAME(display, pipe)); pixel = frame & PIPE_PIXEL_MASK; frame = (frame >> PIPE_FRAME_LOW_SHIFT) & 0xffffff; diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index 8a957804cb97..1b09992ce9fd 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -55,6 +55,16 @@ bool intel_vrr_is_capable(struct intel_connector *connector) if (connector->mst.dp) return false; intel_dp = intel_attached_dp(connector); + /* + * Among non-MST DP branch devices, only an HDMI 2.1 sink connected + * via a PCON could support VRR. However, supporting VRR through a + * PCON requires non-trivial changes that are not implemented yet. + * Until that support exists, avoid VRR on all DP branch devices. + * + * TODO: Add support for VRR for DP->HDMI 2.1 PCON. + */ + if (drm_dp_is_branch(intel_dp->dpcd)) + return false; if (!drm_dp_sink_can_do_video_without_timing_msa(intel_dp->dpcd)) return false; @@ -1053,11 +1063,9 @@ void intel_vrr_get_config(struct intel_crtc_state *crtc_state) if (crtc_state->cmrr.enable) { crtc_state->cmrr.cmrr_n = - intel_de_read64_2x32(display, TRANS_CMRR_N_LO(display, cpu_transcoder), - TRANS_CMRR_N_HI(display, cpu_transcoder)); + intel_de_read64_2x32(display, TRANS_CMRR_N_LO(display, cpu_transcoder)); crtc_state->cmrr.cmrr_m = - intel_de_read64_2x32(display, TRANS_CMRR_M_LO(display, cpu_transcoder), - TRANS_CMRR_M_HI(display, cpu_transcoder)); + intel_de_read64_2x32(display, TRANS_CMRR_M_LO(display, cpu_transcoder)); } if (DISPLAY_VER(display) >= 13) { diff --git a/drivers/gpu/drm/i915/display/intel_wm.c b/drivers/gpu/drm/i915/display/intel_wm.c index f887a664fe22..b4aded774ce6 100644 --- a/drivers/gpu/drm/i915/display/intel_wm.c +++ b/drivers/gpu/drm/i915/display/intel_wm.c @@ -48,8 +48,8 @@ */ void intel_update_watermarks(struct intel_display *display) { - if (display->funcs.wm->update_wm) - display->funcs.wm->update_wm(display); + if (display->wm.funcs->update_wm) + display->wm.funcs->update_wm(display); } int intel_wm_compute(struct intel_atomic_state *state, @@ -57,10 +57,10 @@ int intel_wm_compute(struct intel_atomic_state *state, { struct intel_display *display = to_intel_display(state); - if (!display->funcs.wm->compute_watermarks) + if (!display->wm.funcs->compute_watermarks) return 0; - return display->funcs.wm->compute_watermarks(state, crtc); + return display->wm.funcs->compute_watermarks(state, crtc); } bool intel_initial_watermarks(struct intel_atomic_state *state, @@ -68,8 +68,8 @@ bool intel_initial_watermarks(struct intel_atomic_state *state, { struct intel_display *display = to_intel_display(state); - if (display->funcs.wm->initial_watermarks) { - display->funcs.wm->initial_watermarks(state, crtc); + if (display->wm.funcs->initial_watermarks) { + display->wm.funcs->initial_watermarks(state, crtc); return true; } @@ -81,8 +81,8 @@ void intel_atomic_update_watermarks(struct intel_atomic_state *state, { struct intel_display *display = to_intel_display(state); - if (display->funcs.wm->atomic_update_watermarks) - display->funcs.wm->atomic_update_watermarks(state, crtc); + if (display->wm.funcs->atomic_update_watermarks) + display->wm.funcs->atomic_update_watermarks(state, crtc); } void intel_optimize_watermarks(struct intel_atomic_state *state, @@ -90,30 +90,30 @@ void intel_optimize_watermarks(struct intel_atomic_state *state, { struct intel_display *display = to_intel_display(state); - if (display->funcs.wm->optimize_watermarks) - display->funcs.wm->optimize_watermarks(state, crtc); + if (display->wm.funcs->optimize_watermarks) + display->wm.funcs->optimize_watermarks(state, crtc); } int intel_compute_global_watermarks(struct intel_atomic_state *state) { struct intel_display *display = to_intel_display(state); - if (display->funcs.wm->compute_global_watermarks) - return display->funcs.wm->compute_global_watermarks(state); + if (display->wm.funcs->compute_global_watermarks) + return display->wm.funcs->compute_global_watermarks(state); return 0; } void intel_wm_get_hw_state(struct intel_display *display) { - if (display->funcs.wm->get_hw_state) - return display->funcs.wm->get_hw_state(display); + if (display->wm.funcs->get_hw_state) + return display->wm.funcs->get_hw_state(display); } void intel_wm_sanitize(struct intel_display *display) { - if (display->funcs.wm->sanitize) - return display->funcs.wm->sanitize(display); + if (display->wm.funcs->sanitize) + return display->wm.funcs->sanitize(display); } bool intel_wm_plane_visible(const struct intel_crtc_state *crtc_state, diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c b/drivers/gpu/drm/i915/display/skl_scaler.c index 7c5cb188ebf0..308b8d363bba 100644 --- a/drivers/gpu/drm/i915/display/skl_scaler.c +++ b/drivers/gpu/drm/i915/display/skl_scaler.c @@ -270,6 +270,11 @@ int skl_update_scaler_crtc(struct intel_crtc_state *crtc_state) { const struct drm_display_mode *pipe_mode = &crtc_state->hw.pipe_mode; int width, height; + int ret; + + ret = intel_casf_compute_config(crtc_state); + if (ret) + return ret; if (crtc_state->pch_pfit.enabled) { width = drm_rect_width(&crtc_state->pch_pfit.dst); @@ -284,8 +289,7 @@ int skl_update_scaler_crtc(struct intel_crtc_state *crtc_state) drm_rect_width(&crtc_state->pipe_src), drm_rect_height(&crtc_state->pipe_src), width, height, NULL, 0, - crtc_state->pch_pfit.enabled || - intel_casf_needs_scaler(crtc_state)); + crtc_state->pch_pfit.enabled); } /** @@ -323,19 +327,24 @@ int skl_update_scaler_plane(struct intel_crtc_state *crtc_state, need_scaler); } +static bool scaler_has_casf(struct intel_display *display, int scaler_id) +{ + return HAS_CASF(display) && scaler_id == 1; +} + static int intel_allocate_scaler(struct intel_crtc_scaler_state *scaler_state, struct intel_crtc *crtc, struct intel_plane_state *plane_state, bool casf_scaler) { + struct intel_display *display = to_intel_display(crtc); int i; for (i = 0; i < crtc->num_scalers; i++) { if (scaler_state->scalers[i].in_use) continue; - /* CASF needs second scaler */ - if (!plane_state && casf_scaler && i != 1) + if (casf_scaler && !scaler_has_casf(display, i)) continue; scaler_state->scalers[i].in_use = true; @@ -529,14 +538,11 @@ static int setup_crtc_scaler(struct intel_atomic_state *state, struct intel_crtc_scaler_state *scaler_state = &crtc_state->scaler_state; - if (intel_casf_needs_scaler(crtc_state) && crtc_state->pch_pfit.enabled) - return -EINVAL; - return intel_atomic_setup_scaler(crtc_state, hweight32(scaler_state->scaler_users), crtc, "CRTC", crtc->base.base.id, NULL, &scaler_state->scaler_id, - intel_casf_needs_scaler(crtc_state)); + crtc_state->pch_pfit.casf.enable); } static int setup_plane_scaler(struct intel_atomic_state *state, @@ -725,9 +731,9 @@ static void glk_program_nearest_filter_coefs(struct intel_display *display, GLK_PS_COEF_INDEX_SET(pipe, id, set), 0); } -static u32 skl_scaler_get_filter_select(enum drm_scaling_filter filter) +static u32 skl_scaler_get_filter_select(enum drm_scaling_filter filter, bool casf) { - if (filter == DRM_SCALING_FILTER_NEAREST_NEIGHBOR) + if (filter == DRM_SCALING_FILTER_NEAREST_NEIGHBOR || casf) return (PS_FILTER_PROGRAMMED | PS_Y_VERT_FILTER_SELECT(0) | PS_Y_HORZ_FILTER_SELECT(0) | @@ -752,50 +758,14 @@ static void skl_scaler_setup_filter(struct intel_display *display, } } -#define CASF_SCALER_FILTER_SELECT \ - (PS_FILTER_PROGRAMMED | \ - PS_Y_VERT_FILTER_SELECT(0) | \ - PS_Y_HORZ_FILTER_SELECT(0) | \ - PS_UV_VERT_FILTER_SELECT(0) | \ - PS_UV_HORZ_FILTER_SELECT(0)) - -void skl_scaler_setup_casf(struct intel_crtc_state *crtc_state) +static u32 casf_sharpness_ctl(const struct intel_crtc_state *crtc_state) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct intel_display *display = to_intel_display(crtc); - struct drm_display_mode *adjusted_mode = - &crtc_state->hw.adjusted_mode; - struct intel_crtc_scaler_state *scaler_state = - &crtc_state->scaler_state; - struct drm_rect src, dest; - int id, width, height; - int x = 0, y = 0; - enum pipe pipe = crtc->pipe; - u32 ps_ctrl; + if (!crtc_state->pch_pfit.casf.enable) + return 0; - width = adjusted_mode->crtc_hdisplay; - height = adjusted_mode->crtc_vdisplay; - - drm_rect_init(&dest, x, y, width, height); - - width = drm_rect_width(&dest); - height = drm_rect_height(&dest); - id = scaler_state->scaler_id; - - drm_rect_init(&src, 0, 0, - drm_rect_width(&crtc_state->pipe_src) << 16, - drm_rect_height(&crtc_state->pipe_src) << 16); - - trace_intel_pipe_scaler_update_arm(crtc, id, x, y, width, height); - - ps_ctrl = PS_SCALER_EN | PS_BINDING_PIPE | scaler_state->scalers[id].mode | - CASF_SCALER_FILTER_SELECT; - - intel_de_write_fw(display, SKL_PS_CTRL(pipe, id), ps_ctrl); - intel_de_write_fw(display, SKL_PS_WIN_POS(pipe, id), - PS_WIN_XPOS(x) | PS_WIN_YPOS(y)); - intel_de_write_fw(display, SKL_PS_WIN_SZ(pipe, id), - PS_WIN_XSIZE(width) | PS_WIN_YSIZE(height)); + return FILTER_EN | + FILTER_STRENGTH(crtc_state->pch_pfit.casf.strength) | + crtc_state->pch_pfit.casf.win_size; } void skl_pfit_enable(const struct intel_crtc_state *crtc_state) @@ -839,12 +809,20 @@ void skl_pfit_enable(const struct intel_crtc_state *crtc_state) id = scaler_state->scaler_id; ps_ctrl = PS_SCALER_EN | PS_BINDING_PIPE | scaler_state->scalers[id].mode | - skl_scaler_get_filter_select(crtc_state->hw.scaling_filter); + skl_scaler_get_filter_select(crtc_state->hw.scaling_filter, + crtc_state->pch_pfit.casf.enable); trace_intel_pipe_scaler_update_arm(crtc, id, x, y, width, height); - skl_scaler_setup_filter(display, NULL, pipe, id, 0, - crtc_state->hw.scaling_filter); + if (crtc_state->pch_pfit.casf.enable) + intel_casf_setup(crtc_state); + else + skl_scaler_setup_filter(display, NULL, pipe, id, 0, + crtc_state->hw.scaling_filter); + + if (scaler_has_casf(display, id)) + intel_de_write_fw(display, SHARPNESS_CTL(crtc->pipe), + casf_sharpness_ctl(crtc_state)); intel_de_write_fw(display, SKL_PS_CTRL(pipe, id), ps_ctrl); @@ -905,7 +883,7 @@ skl_program_plane_scaler(struct intel_dsb *dsb, } ps_ctrl = PS_SCALER_EN | PS_BINDING_PLANE(plane->id) | scaler->mode | - skl_scaler_get_filter_select(plane_state->hw.scaling_filter); + skl_scaler_get_filter_select(plane_state->hw.scaling_filter, false); trace_intel_plane_scaler_update_arm(plane, scaler_id, crtc_x, crtc_y, crtc_w, crtc_h); @@ -932,6 +910,9 @@ static void skl_detach_scaler(struct intel_dsb *dsb, trace_intel_scaler_disable_arm(crtc, id); + if (scaler_has_casf(display, id)) + intel_de_write_dsb(display, dsb, SHARPNESS_CTL(crtc->pipe), 0); + intel_de_write_dsb(display, dsb, SKL_PS_CTRL(crtc->pipe, id), 0); intel_de_write_dsb(display, dsb, SKL_PS_WIN_POS(crtc->pipe, id), 0); intel_de_write_dsb(display, dsb, SKL_PS_WIN_SZ(crtc->pipe, id), 0); @@ -982,22 +963,19 @@ void skl_scaler_get_config(struct intel_crtc_state *crtc_state) id = i; - /* Read CASF regs for second scaler */ - if (HAS_CASF(display) && id == 1) + if (scaler_has_casf(display, i)) intel_casf_sharpness_get_config(crtc_state); - if (!crtc_state->hw.casf_params.casf_enable) - crtc_state->pch_pfit.enabled = true; + crtc_state->pch_pfit.enabled = true; pos = intel_de_read(display, SKL_PS_WIN_POS(crtc->pipe, i)); size = intel_de_read(display, SKL_PS_WIN_SZ(crtc->pipe, i)); - if (!crtc_state->hw.casf_params.casf_enable) - drm_rect_init(&crtc_state->pch_pfit.dst, - REG_FIELD_GET(PS_WIN_XPOS_MASK, pos), - REG_FIELD_GET(PS_WIN_YPOS_MASK, pos), - REG_FIELD_GET(PS_WIN_XSIZE_MASK, size), - REG_FIELD_GET(PS_WIN_YSIZE_MASK, size)); + drm_rect_init(&crtc_state->pch_pfit.dst, + REG_FIELD_GET(PS_WIN_XPOS_MASK, pos), + REG_FIELD_GET(PS_WIN_YPOS_MASK, pos), + REG_FIELD_GET(PS_WIN_XSIZE_MASK, size), + REG_FIELD_GET(PS_WIN_YSIZE_MASK, size)); scaler_state->scalers[i].in_use = true; break; diff --git a/drivers/gpu/drm/i915/display/skl_scaler.h b/drivers/gpu/drm/i915/display/skl_scaler.h index 7e8d819c019d..5deabca909e6 100644 --- a/drivers/gpu/drm/i915/display/skl_scaler.h +++ b/drivers/gpu/drm/i915/display/skl_scaler.h @@ -36,8 +36,6 @@ void skl_scaler_disable(const struct intel_crtc_state *old_crtc_state); void skl_scaler_get_config(struct intel_crtc_state *crtc_state); -void skl_scaler_setup_casf(struct intel_crtc_state *crtc_state); - enum drm_mode_status skl_scaler_mode_valid(struct intel_display *display, const struct drm_display_mode *mode, diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index 7a9d494334b5..ef431dd32e74 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -2126,6 +2126,19 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state) return 0; } + +/* Divide a U16.16 fixed-point value by 2, staying in fixed-point domain */ +static inline u32 fp_16_16_div2(u32 fp) +{ + return fp >> 1; +} + +/* Convert a U16.16 fixed-point value to integer, rounding up */ +static inline int fp_16_16_to_int_ceil(u32 fp) +{ + return DIV_ROUND_UP(fp, 1 << 16); +} + static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state) { struct intel_display *display = to_intel_display(plane_state); @@ -2139,10 +2152,16 @@ static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state) int min_height = intel_plane_min_height(plane, fb, uv_plane, rotation); int max_width = intel_plane_max_width(plane, fb, uv_plane, rotation); int max_height = intel_plane_max_height(plane, fb, uv_plane, rotation); - int x = plane_state->uapi.src.x1 >> 17; - int y = plane_state->uapi.src.y1 >> 17; - int w = drm_rect_width(&plane_state->uapi.src) >> 17; - int h = drm_rect_height(&plane_state->uapi.src) >> 17; + + /* + * LNL+ UV surface start/size = + * ceiling(half of Y plane start/size). Use ceiling division + * unconditionally; it is a no-op for even values. + */ + int x = fp_16_16_to_int_ceil(fp_16_16_div2(plane_state->uapi.src.x1)); + int y = fp_16_16_to_int_ceil(fp_16_16_div2(plane_state->uapi.src.y1)); + int w = fp_16_16_to_int_ceil(fp_16_16_div2(drm_rect_width(&plane_state->uapi.src))); + int h = fp_16_16_to_int_ceil(fp_16_16_div2(drm_rect_height(&plane_state->uapi.src))); u32 offset; /* FIXME not quite sure how/if these apply to the chroma plane */ @@ -3148,12 +3167,6 @@ skl_get_initial_plane_config(struct intel_crtc *crtc, fb->format = drm_get_format_info(display->drm, fourcc, fb->modifier); - if (!display->params.enable_dpt && - intel_fb_modifier_uses_dpt(display, fb->modifier)) { - drm_dbg_kms(display->drm, "DPT disabled, skipping initial FB\n"); - goto error; - } - /* * DRM_MODE_ROTATE_ is counter clockwise to stay compatible with Xrandr * while i915 HW rotation is clockwise, that's why this swapping. @@ -3206,7 +3219,7 @@ skl_get_initial_plane_config(struct intel_crtc *crtc, fb->width, fb->height, fb->format->cpp[0] * 8, base, fb->pitches[0], plane_config->size); - plane_config->fb = intel_fb; + plane_config->fb = &intel_fb->base; return; error: diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c index e0ac4e2ce4dc..96d2dcbe7bbc 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.c +++ b/drivers/gpu/drm/i915/display/skl_watermark.c @@ -308,15 +308,6 @@ static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state) enum plane_id plane_id; int max_level = INT_MAX; - if (!intel_has_sagv(display)) - return false; - - if (!crtc_state->hw.active) - return true; - - if (crtc_state->hw.pipe_mode.flags & DRM_MODE_FLAG_INTERLACE) - return false; - for_each_plane_id_on_crtc(crtc, plane_id) { const struct skl_plane_wm *wm = &crtc_state->wm.skl.optimal.planes[plane_id]; @@ -359,9 +350,6 @@ static bool tgl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state) struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); enum plane_id plane_id; - if (!crtc_state->hw.active) - return true; - for_each_plane_id_on_crtc(crtc, plane_id) { const struct skl_plane_wm *wm = &crtc_state->wm.skl.optimal.planes[plane_id]; @@ -377,6 +365,9 @@ bool intel_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); + if (!display->sagv.block_time_us) + return false; + if (!display->params.enable_sagv) return false; @@ -388,7 +379,13 @@ bool intel_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state) if (crtc_state->inherited) return false; - if (DISPLAY_VER(display) >= 12) + if (!crtc_state->hw.active) + return true; + + if (crtc_state->hw.pipe_mode.flags & DRM_MODE_FLAG_INTERLACE) + return false; + + if (HAS_SAGV_WM(display)) return tgl_crtc_can_enable_sagv(crtc_state); else return skl_crtc_can_enable_sagv(crtc_state); @@ -1939,7 +1936,7 @@ static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state, result->enable = true; result->auto_min_alloc_wm_enable = xe3_auto_min_alloc_capable(plane, level); - if (DISPLAY_VER(display) < 12 && display->sagv.block_time_us) + if (!HAS_SAGV_WM(display) && display->sagv.block_time_us) result->can_sagv = latency >= display->sagv.block_time_us; } @@ -2065,7 +2062,7 @@ static int skl_build_plane_wm_single(struct intel_crtc_state *crtc_state, skl_compute_transition_wm(display, &wm->trans_wm, &wm->wm[0], &wm_params); - if (DISPLAY_VER(display) >= 12) { + if (HAS_SAGV_WM(display)) { tgl_compute_sagv_wm(crtc_state, plane, &wm_params, wm); skl_compute_transition_wm(display, &wm->sagv.trans_wm, @@ -2324,7 +2321,7 @@ static int skl_wm_check_vblank(struct intel_crtc_state *crtc_state) } } - if (DISPLAY_VER(display) >= 12 && + if (HAS_SAGV_WM(display) && display->sagv.block_time_us && skl_prefill_vblank_too_short(&ctx, crtc_state, display->sagv.block_time_us)) { @@ -2616,6 +2613,26 @@ skl_print_plane_ddb_changes(struct intel_plane *plane, skl_ddb_entry_size(old), skl_ddb_entry_size(new)); } +#define PLANE_WM_EN_FMT "%cwm0,%cwm1,%cwm2,%cwm3,%cwm4,%cwm5,%cwm6,%cwm7,%ctwm,%cswm,%cstwm" +#define PLANE_WM_EN_ARGS(__wm) \ + enast((__wm)->wm[0].enable), enast((__wm)->wm[1].enable), \ + enast((__wm)->wm[2].enable), enast((__wm)->wm[3].enable), \ + enast((__wm)->wm[4].enable), enast((__wm)->wm[5].enable), \ + enast((__wm)->wm[6].enable), enast((__wm)->wm[7].enable), \ + enast((__wm)->trans_wm.enable), \ + enast((__wm)->sagv.wm0.enable), \ + enast((__wm)->sagv.trans_wm.enable) + +#define PLANE_WM_FMT "%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%5d" +#define PLANE_WM_ARGS(__wm, __field) \ + (__wm)->wm[0].__field, (__wm)->wm[1].__field, \ + (__wm)->wm[2].__field, (__wm)->wm[3].__field, \ + (__wm)->wm[4].__field, (__wm)->wm[5].__field, \ + (__wm)->wm[6].__field, (__wm)->wm[7].__field, \ + (__wm)->trans_wm.__field, \ + (__wm)->sagv.wm0.__field, \ + (__wm)->sagv.trans_wm.__field + static noinline_for_stack void skl_print_plane_wm_changes(struct intel_plane *plane, const struct skl_plane_wm *old_wm, @@ -2624,112 +2641,44 @@ skl_print_plane_wm_changes(struct intel_plane *plane, struct intel_display *display = to_intel_display(plane); drm_dbg_kms(display->drm, - "[PLANE:%d:%s] level %cwm0,%cwm1,%cwm2,%cwm3,%cwm4,%cwm5,%cwm6,%cwm7,%ctwm,%cswm,%cstwm" - " -> %cwm0,%cwm1,%cwm2,%cwm3,%cwm4,%cwm5,%cwm6,%cwm7,%ctwm,%cswm,%cstwm\n", + "[PLANE:%d:%s] level " PLANE_WM_EN_FMT " -> " PLANE_WM_EN_FMT "\n", plane->base.base.id, plane->base.name, - enast(old_wm->wm[0].enable), enast(old_wm->wm[1].enable), - enast(old_wm->wm[2].enable), enast(old_wm->wm[3].enable), - enast(old_wm->wm[4].enable), enast(old_wm->wm[5].enable), - enast(old_wm->wm[6].enable), enast(old_wm->wm[7].enable), - enast(old_wm->trans_wm.enable), - enast(old_wm->sagv.wm0.enable), - enast(old_wm->sagv.trans_wm.enable), - enast(new_wm->wm[0].enable), enast(new_wm->wm[1].enable), - enast(new_wm->wm[2].enable), enast(new_wm->wm[3].enable), - enast(new_wm->wm[4].enable), enast(new_wm->wm[5].enable), - enast(new_wm->wm[6].enable), enast(new_wm->wm[7].enable), - enast(new_wm->trans_wm.enable), - enast(new_wm->sagv.wm0.enable), - enast(new_wm->sagv.trans_wm.enable)); + PLANE_WM_EN_ARGS(old_wm), + PLANE_WM_EN_ARGS(new_wm)); drm_dbg_kms(display->drm, - "[PLANE:%d:%s] lines %c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%4d" - " -> %c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%4d\n", + "[PLANE:%d:%s] lines " PLANE_WM_FMT " -> " PLANE_WM_FMT "\n", plane->base.base.id, plane->base.name, - enast(old_wm->wm[0].ignore_lines), old_wm->wm[0].lines, - enast(old_wm->wm[1].ignore_lines), old_wm->wm[1].lines, - enast(old_wm->wm[2].ignore_lines), old_wm->wm[2].lines, - enast(old_wm->wm[3].ignore_lines), old_wm->wm[3].lines, - enast(old_wm->wm[4].ignore_lines), old_wm->wm[4].lines, - enast(old_wm->wm[5].ignore_lines), old_wm->wm[5].lines, - enast(old_wm->wm[6].ignore_lines), old_wm->wm[6].lines, - enast(old_wm->wm[7].ignore_lines), old_wm->wm[7].lines, - enast(old_wm->trans_wm.ignore_lines), old_wm->trans_wm.lines, - enast(old_wm->sagv.wm0.ignore_lines), old_wm->sagv.wm0.lines, - enast(old_wm->sagv.trans_wm.ignore_lines), old_wm->sagv.trans_wm.lines, - enast(new_wm->wm[0].ignore_lines), new_wm->wm[0].lines, - enast(new_wm->wm[1].ignore_lines), new_wm->wm[1].lines, - enast(new_wm->wm[2].ignore_lines), new_wm->wm[2].lines, - enast(new_wm->wm[3].ignore_lines), new_wm->wm[3].lines, - enast(new_wm->wm[4].ignore_lines), new_wm->wm[4].lines, - enast(new_wm->wm[5].ignore_lines), new_wm->wm[5].lines, - enast(new_wm->wm[6].ignore_lines), new_wm->wm[6].lines, - enast(new_wm->wm[7].ignore_lines), new_wm->wm[7].lines, - enast(new_wm->trans_wm.ignore_lines), new_wm->trans_wm.lines, - enast(new_wm->sagv.wm0.ignore_lines), new_wm->sagv.wm0.lines, - enast(new_wm->sagv.trans_wm.ignore_lines), new_wm->sagv.trans_wm.lines); + PLANE_WM_ARGS(old_wm, lines), + PLANE_WM_ARGS(new_wm, lines)); drm_dbg_kms(display->drm, - "[PLANE:%d:%s] blocks %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%5d" - " -> %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%5d\n", + "[PLANE:%d:%s] blocks " PLANE_WM_FMT " -> " PLANE_WM_FMT "\n", plane->base.base.id, plane->base.name, - old_wm->wm[0].blocks, old_wm->wm[1].blocks, - old_wm->wm[2].blocks, old_wm->wm[3].blocks, - old_wm->wm[4].blocks, old_wm->wm[5].blocks, - old_wm->wm[6].blocks, old_wm->wm[7].blocks, - old_wm->trans_wm.blocks, - old_wm->sagv.wm0.blocks, - old_wm->sagv.trans_wm.blocks, - new_wm->wm[0].blocks, new_wm->wm[1].blocks, - new_wm->wm[2].blocks, new_wm->wm[3].blocks, - new_wm->wm[4].blocks, new_wm->wm[5].blocks, - new_wm->wm[6].blocks, new_wm->wm[7].blocks, - new_wm->trans_wm.blocks, - new_wm->sagv.wm0.blocks, - new_wm->sagv.trans_wm.blocks); + PLANE_WM_ARGS(old_wm, blocks), + PLANE_WM_ARGS(new_wm, blocks)); drm_dbg_kms(display->drm, - "[PLANE:%d:%s] min_ddb %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%5d" - " -> %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%5d\n", + "[PLANE:%d:%s] min_ddb " PLANE_WM_FMT " -> " PLANE_WM_FMT "\n", plane->base.base.id, plane->base.name, - old_wm->wm[0].min_ddb_alloc, old_wm->wm[1].min_ddb_alloc, - old_wm->wm[2].min_ddb_alloc, old_wm->wm[3].min_ddb_alloc, - old_wm->wm[4].min_ddb_alloc, old_wm->wm[5].min_ddb_alloc, - old_wm->wm[6].min_ddb_alloc, old_wm->wm[7].min_ddb_alloc, - old_wm->trans_wm.min_ddb_alloc, - old_wm->sagv.wm0.min_ddb_alloc, - old_wm->sagv.trans_wm.min_ddb_alloc, - new_wm->wm[0].min_ddb_alloc, new_wm->wm[1].min_ddb_alloc, - new_wm->wm[2].min_ddb_alloc, new_wm->wm[3].min_ddb_alloc, - new_wm->wm[4].min_ddb_alloc, new_wm->wm[5].min_ddb_alloc, - new_wm->wm[6].min_ddb_alloc, new_wm->wm[7].min_ddb_alloc, - new_wm->trans_wm.min_ddb_alloc, - new_wm->sagv.wm0.min_ddb_alloc, - new_wm->sagv.trans_wm.min_ddb_alloc); + PLANE_WM_ARGS(old_wm, min_ddb_alloc), + PLANE_WM_ARGS(new_wm, min_ddb_alloc)); if (DISPLAY_VER(display) >= 11) return; drm_dbg_kms(display->drm, - "[PLANE:%d:%s] min_ddb_uv %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%5d" - " -> %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%5d\n", + "[PLANE:%d:%s] min_ddb_uv " PLANE_WM_FMT " -> " PLANE_WM_FMT "\n", plane->base.base.id, plane->base.name, - old_wm->wm[0].min_ddb_alloc_uv, old_wm->wm[1].min_ddb_alloc_uv, - old_wm->wm[2].min_ddb_alloc_uv, old_wm->wm[3].min_ddb_alloc_uv, - old_wm->wm[4].min_ddb_alloc_uv, old_wm->wm[5].min_ddb_alloc_uv, - old_wm->wm[6].min_ddb_alloc_uv, old_wm->wm[7].min_ddb_alloc_uv, - old_wm->trans_wm.min_ddb_alloc_uv, - old_wm->sagv.wm0.min_ddb_alloc_uv, - old_wm->sagv.trans_wm.min_ddb_alloc_uv, - new_wm->wm[0].min_ddb_alloc_uv, new_wm->wm[1].min_ddb_alloc_uv, - new_wm->wm[2].min_ddb_alloc_uv, new_wm->wm[3].min_ddb_alloc_uv, - new_wm->wm[4].min_ddb_alloc_uv, new_wm->wm[5].min_ddb_alloc_uv, - new_wm->wm[6].min_ddb_alloc_uv, new_wm->wm[7].min_ddb_alloc_uv, - new_wm->trans_wm.min_ddb_alloc_uv, - new_wm->sagv.wm0.min_ddb_alloc_uv, - new_wm->sagv.trans_wm.min_ddb_alloc_uv); + PLANE_WM_ARGS(old_wm, min_ddb_alloc_uv), + PLANE_WM_ARGS(new_wm, min_ddb_alloc_uv)); } +#undef PLANE_WM_EN_FMT +#undef PLANE_WM_EN_ARGS +#undef PLANE_WM_FMT +#undef PLANE_WM_ARGS + static void skl_print_wm_changes(struct intel_atomic_state *state) { @@ -2997,8 +2946,9 @@ skl_compute_wm(struct intel_atomic_state *state) * other crtcs can't be allowed to use the more optimal * normal (ie. non-SAGV) watermarks. */ - pipe_wm->use_sagv_wm = !HAS_HW_SAGV_WM(display) && - DISPLAY_VER(display) >= 12 && + pipe_wm->use_sagv_wm = + HAS_SAGV_WM(display) && + !HAS_HW_SAGV_WM(display) && intel_crtc_can_enable_sagv(new_crtc_state); ret = skl_wm_add_affected_planes(state, crtc); @@ -3064,7 +3014,7 @@ static void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc, val = intel_de_read(display, CUR_WM_SAGV_TRANS(pipe)); skl_wm_level_from_reg_val(display, val, &wm->sagv.trans_wm); - } else if (DISPLAY_VER(display) >= 12) { + } else if (HAS_SAGV_WM(display)) { wm->sagv.wm0 = wm->wm[0]; wm->sagv.trans_wm = wm->trans_wm; } @@ -3919,6 +3869,40 @@ void skl_wm_plane_disable_noatomic(struct intel_crtc *crtc, sizeof(crtc_state->wm.skl.optimal.planes[plane->id])); } +static void skl_wm_level_verify(struct intel_plane *plane, + const char *wm_name, + const struct skl_wm_level *hw_wm_level, + const struct skl_wm_level *sw_wm_level) +{ + struct intel_display *display = to_intel_display(plane); + + if (skl_wm_level_equals(hw_wm_level, sw_wm_level)) + return; + + drm_err(display->drm, + "[PLANE:%d:%s] mismatch in %s (expected e=%d b=%u l=%u, got e=%d b=%u l=%u)\n", + plane->base.base.id, plane->base.name, wm_name, + sw_wm_level->enable, sw_wm_level->blocks, sw_wm_level->lines, + hw_wm_level->enable, hw_wm_level->blocks, hw_wm_level->lines); +} + +static void skl_ddb_entry_verify(struct intel_plane *plane, + const char *ddb_name, + const struct skl_ddb_entry *hw_ddb_entry, + const struct skl_ddb_entry *sw_ddb_entry) +{ + struct intel_display *display = to_intel_display(plane); + + if (skl_ddb_entry_equal(hw_ddb_entry, sw_ddb_entry)) + return; + + drm_err(display->drm, + "[PLANE:%d:%s] mismatch in %s (expected (%u,%u), found (%u,%u))\n", + plane->base.base.id, plane->base.name, ddb_name, + sw_ddb_entry->start, sw_ddb_entry->end, + hw_ddb_entry->start, hw_ddb_entry->end); +} + void intel_wm_state_verify(struct intel_atomic_state *state, struct intel_crtc *crtc) { @@ -3958,86 +3942,42 @@ void intel_wm_state_verify(struct intel_atomic_state *state, hw_enabled_slices); for_each_intel_plane_on_crtc(display->drm, crtc, plane) { - const struct skl_ddb_entry *hw_ddb_entry, *sw_ddb_entry; - const struct skl_wm_level *hw_wm_level, *sw_wm_level; + const struct skl_plane_wm *hw_plane_wm = + &hw->wm.planes[plane->id]; + const struct skl_plane_wm *sw_plane_wm = + &sw_wm->planes[plane->id]; - /* Watermarks */ for (level = 0; level < display->wm.num_levels; level++) { - hw_wm_level = &hw->wm.planes[plane->id].wm[level]; - sw_wm_level = skl_plane_wm_level(sw_wm, plane->id, level); + char wm_name[16]; - if (skl_wm_level_equals(hw_wm_level, sw_wm_level)) - continue; + snprintf(wm_name, sizeof(wm_name), "WM%d", level); - drm_err(display->drm, - "[PLANE:%d:%s] mismatch in WM%d (expected e=%d b=%u l=%u, got e=%d b=%u l=%u)\n", - plane->base.base.id, plane->base.name, level, - sw_wm_level->enable, - sw_wm_level->blocks, - sw_wm_level->lines, - hw_wm_level->enable, - hw_wm_level->blocks, - hw_wm_level->lines); + skl_wm_level_verify(plane, wm_name, + &hw_plane_wm->wm[level], + skl_plane_wm_level(sw_wm, plane->id, level)); } - hw_wm_level = &hw->wm.planes[plane->id].trans_wm; - sw_wm_level = skl_plane_trans_wm(sw_wm, plane->id); + skl_wm_level_verify(plane, "trans WM", + &hw_plane_wm->trans_wm, + skl_plane_trans_wm(sw_wm, plane->id)); - if (!skl_wm_level_equals(hw_wm_level, sw_wm_level)) { - drm_err(display->drm, - "[PLANE:%d:%s] mismatch in trans WM (expected e=%d b=%u l=%u, got e=%d b=%u l=%u)\n", - plane->base.base.id, plane->base.name, - sw_wm_level->enable, - sw_wm_level->blocks, - sw_wm_level->lines, - hw_wm_level->enable, - hw_wm_level->blocks, - hw_wm_level->lines); + if (HAS_HW_SAGV_WM(display)) { + skl_wm_level_verify(plane, "SAGV WM", + &hw_plane_wm->sagv.wm0, + &sw_plane_wm->sagv.wm0); + + skl_wm_level_verify(plane, "SAGV trans WM", + &hw_plane_wm->sagv.trans_wm, + &sw_plane_wm->sagv.trans_wm); } - hw_wm_level = &hw->wm.planes[plane->id].sagv.wm0; - sw_wm_level = &sw_wm->planes[plane->id].sagv.wm0; + skl_ddb_entry_verify(plane, "DDB", + &hw->ddb[plane->id], + &new_crtc_state->wm.skl.plane_ddb[plane->id]); - if (HAS_HW_SAGV_WM(display) && - !skl_wm_level_equals(hw_wm_level, sw_wm_level)) { - drm_err(display->drm, - "[PLANE:%d:%s] mismatch in SAGV WM (expected e=%d b=%u l=%u, got e=%d b=%u l=%u)\n", - plane->base.base.id, plane->base.name, - sw_wm_level->enable, - sw_wm_level->blocks, - sw_wm_level->lines, - hw_wm_level->enable, - hw_wm_level->blocks, - hw_wm_level->lines); - } - - hw_wm_level = &hw->wm.planes[plane->id].sagv.trans_wm; - sw_wm_level = &sw_wm->planes[plane->id].sagv.trans_wm; - - if (HAS_HW_SAGV_WM(display) && - !skl_wm_level_equals(hw_wm_level, sw_wm_level)) { - drm_err(display->drm, - "[PLANE:%d:%s] mismatch in SAGV trans WM (expected e=%d b=%u l=%u, got e=%d b=%u l=%u)\n", - plane->base.base.id, plane->base.name, - sw_wm_level->enable, - sw_wm_level->blocks, - sw_wm_level->lines, - hw_wm_level->enable, - hw_wm_level->blocks, - hw_wm_level->lines); - } - - /* DDB */ - hw_ddb_entry = &hw->ddb[plane->id]; - sw_ddb_entry = &new_crtc_state->wm.skl.plane_ddb[plane->id]; - - if (!skl_ddb_entry_equal(hw_ddb_entry, sw_ddb_entry)) { - drm_err(display->drm, - "[PLANE:%d:%s] mismatch in DDB (expected (%u,%u), found (%u,%u))\n", - plane->base.base.id, plane->base.name, - sw_ddb_entry->start, sw_ddb_entry->end, - hw_ddb_entry->start, hw_ddb_entry->end); - } + skl_ddb_entry_verify(plane, "DDB Y", + &hw->ddb_y[plane->id], + &new_crtc_state->wm.skl.plane_ddb_y[plane->id]); } kfree(hw); @@ -4055,7 +3995,7 @@ void skl_wm_init(struct intel_display *display) skl_setup_wm_latency(display); - display->funcs.wm = &skl_wm_funcs; + display->wm.funcs = &skl_wm_funcs; } static int skl_watermark_ipc_status_show(struct seq_file *m, void *data) diff --git a/drivers/gpu/drm/i915/display/vlv_clock.c b/drivers/gpu/drm/i915/display/vlv_clock.c index 1abdae453514..a589cdb74903 100644 --- a/drivers/gpu/drm/i915/display/vlv_clock.c +++ b/drivers/gpu/drm/i915/display/vlv_clock.c @@ -22,11 +22,11 @@ int vlv_clock_get_hpll_vco(struct drm_device *drm) int hpll_freq, vco_freq[] = { 800, 1600, 2000, 2400 }; if (!display->vlv_clock.hpll_freq) { - vlv_cck_get(drm); + vlv_cck_get(display); /* Obtain SKU information */ - hpll_freq = vlv_cck_read(drm, CCK_FUSE_REG) & + hpll_freq = vlv_cck_read(display, CCK_FUSE_REG) & CCK_FUSE_HPLL_FREQ_MASK; - vlv_cck_put(drm); + vlv_cck_put(display); display->vlv_clock.hpll_freq = vco_freq[hpll_freq] * 1000; @@ -39,12 +39,13 @@ int vlv_clock_get_hpll_vco(struct drm_device *drm) static int vlv_clock_get_cck(struct drm_device *drm, const char *name, u32 reg, int ref_freq) { + struct intel_display *display = to_intel_display(drm); u32 val; int divider; - vlv_cck_get(drm); - val = vlv_cck_read(drm, reg); - vlv_cck_put(drm); + vlv_cck_get(display); + val = vlv_cck_read(display, reg); + vlv_cck_put(display); divider = val & CCK_FREQUENCY_VALUES; diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c index d4db73c184e5..76e8cd0f65a4 100644 --- a/drivers/gpu/drm/i915/display/vlv_dsi.c +++ b/drivers/gpu/drm/i915/display/vlv_dsi.c @@ -254,16 +254,16 @@ static int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd, bool hs, static void band_gap_reset(struct intel_display *display) { - vlv_flisdsi_get(display->drm); + vlv_flisdsi_get(display); - vlv_flisdsi_write(display->drm, 0x08, 0x0001); - vlv_flisdsi_write(display->drm, 0x0F, 0x0005); - vlv_flisdsi_write(display->drm, 0x0F, 0x0025); + vlv_flisdsi_write(display, 0x08, 0x0001); + vlv_flisdsi_write(display, 0x0F, 0x0005); + vlv_flisdsi_write(display, 0x0F, 0x0025); udelay(150); - vlv_flisdsi_write(display->drm, 0x0F, 0x0000); - vlv_flisdsi_write(display->drm, 0x08, 0x0000); + vlv_flisdsi_write(display, 0x0F, 0x0000); + vlv_flisdsi_write(display, 0x08, 0x0000); - vlv_flisdsi_put(display->drm); + vlv_flisdsi_put(display); } static int intel_dsi_compute_config(struct intel_encoder *encoder, @@ -461,11 +461,11 @@ static void vlv_dsi_device_ready(struct intel_encoder *encoder) drm_dbg_kms(display->drm, "\n"); - vlv_flisdsi_get(display->drm); + vlv_flisdsi_get(display); /* program rcomp for compliance, reduce from 50 ohms to 45 ohms * needed everytime after power gate */ - vlv_flisdsi_write(display->drm, 0x04, 0x0004); - vlv_flisdsi_put(display->drm); + vlv_flisdsi_write(display, 0x04, 0x0004); + vlv_flisdsi_put(display); /* bandgap reset is needed after everytime we do power gate */ band_gap_reset(display); diff --git a/drivers/gpu/drm/i915/display/vlv_dsi_pll.c b/drivers/gpu/drm/i915/display/vlv_dsi_pll.c index a2da6285890b..68b73cca2aec 100644 --- a/drivers/gpu/drm/i915/display/vlv_dsi_pll.c +++ b/drivers/gpu/drm/i915/display/vlv_dsi_pll.c @@ -219,11 +219,11 @@ void vlv_dsi_pll_enable(struct intel_encoder *encoder, drm_dbg_kms(display->drm, "\n"); - vlv_cck_get(display->drm); + vlv_cck_get(display); - vlv_cck_write(display->drm, CCK_REG_DSI_PLL_CONTROL, 0); - vlv_cck_write(display->drm, CCK_REG_DSI_PLL_DIVIDER, config->dsi_pll.div); - vlv_cck_write(display->drm, CCK_REG_DSI_PLL_CONTROL, + vlv_cck_write(display, CCK_REG_DSI_PLL_CONTROL, 0); + vlv_cck_write(display, CCK_REG_DSI_PLL_DIVIDER, config->dsi_pll.div); + vlv_cck_write(display, CCK_REG_DSI_PLL_CONTROL, config->dsi_pll.ctrl & ~DSI_PLL_VCO_EN); /* wait at least 0.5 us after ungating before enabling VCO, @@ -231,17 +231,17 @@ void vlv_dsi_pll_enable(struct intel_encoder *encoder, */ usleep_range(10, 50); - vlv_cck_write(display->drm, CCK_REG_DSI_PLL_CONTROL, config->dsi_pll.ctrl); + vlv_cck_write(display, CCK_REG_DSI_PLL_CONTROL, config->dsi_pll.ctrl); - ret = poll_timeout_us(val = vlv_cck_read(display->drm, CCK_REG_DSI_PLL_CONTROL), + ret = poll_timeout_us(val = vlv_cck_read(display, CCK_REG_DSI_PLL_CONTROL), val & DSI_PLL_LOCK, 500, 20 * 1000, false); if (ret) { - vlv_cck_put(display->drm); + vlv_cck_put(display); drm_err(display->drm, "DSI PLL lock failed\n"); return; } - vlv_cck_put(display->drm); + vlv_cck_put(display); drm_dbg_kms(display->drm, "DSI PLL locked\n"); } @@ -253,14 +253,14 @@ void vlv_dsi_pll_disable(struct intel_encoder *encoder) drm_dbg_kms(display->drm, "\n"); - vlv_cck_get(display->drm); + vlv_cck_get(display); - tmp = vlv_cck_read(display->drm, CCK_REG_DSI_PLL_CONTROL); + tmp = vlv_cck_read(display, CCK_REG_DSI_PLL_CONTROL); tmp &= ~DSI_PLL_VCO_EN; tmp |= DSI_PLL_LDO_GATE; - vlv_cck_write(display->drm, CCK_REG_DSI_PLL_CONTROL, tmp); + vlv_cck_write(display, CCK_REG_DSI_PLL_CONTROL, tmp); - vlv_cck_put(display->drm); + vlv_cck_put(display); } static bool has_dsic_clock(struct intel_display *display) @@ -333,10 +333,10 @@ u32 vlv_dsi_get_pclk(struct intel_encoder *encoder, drm_dbg_kms(display->drm, "\n"); - vlv_cck_get(display->drm); - pll_ctl = vlv_cck_read(display->drm, CCK_REG_DSI_PLL_CONTROL); - pll_div = vlv_cck_read(display->drm, CCK_REG_DSI_PLL_DIVIDER); - vlv_cck_put(display->drm); + vlv_cck_get(display); + pll_ctl = vlv_cck_read(display, CCK_REG_DSI_PLL_CONTROL); + pll_div = vlv_cck_read(display, CCK_REG_DSI_PLL_DIVIDER); + vlv_cck_put(display); config->dsi_pll.ctrl = pll_ctl & ~DSI_PLL_LOCK; config->dsi_pll.div = pll_div; @@ -603,9 +603,9 @@ static void assert_dsi_pll(struct intel_display *display, bool state) { bool cur_state; - vlv_cck_get(display->drm); - cur_state = vlv_cck_read(display->drm, CCK_REG_DSI_PLL_CONTROL) & DSI_PLL_VCO_EN; - vlv_cck_put(display->drm); + vlv_cck_get(display); + cur_state = vlv_cck_read(display, CCK_REG_DSI_PLL_CONTROL) & DSI_PLL_VCO_EN; + vlv_cck_put(display); INTEL_DISPLAY_STATE_WARN(display, cur_state != state, "DSI PLL state assertion failure (expected %s, current %s)\n", diff --git a/drivers/gpu/drm/i915/display/vlv_sideband.c b/drivers/gpu/drm/i915/display/vlv_sideband.c index e18045f2b89d..068f58bd9a2b 100644 --- a/drivers/gpu/drm/i915/display/vlv_sideband.c +++ b/drivers/gpu/drm/i915/display/vlv_sideband.c @@ -6,8 +6,74 @@ #include "intel_display_core.h" #include "intel_display_types.h" #include "intel_dpio_phy.h" +#include "intel_parent.h" #include "vlv_sideband.h" +void vlv_bunit_get(struct intel_display *display) +{ + intel_parent_vlv_iosf_get(display, BIT(VLV_IOSF_SB_BUNIT)); +} + +u32 vlv_bunit_read(struct intel_display *display, u32 reg) +{ + return intel_parent_vlv_iosf_read(display, VLV_IOSF_SB_BUNIT, reg); +} + +void vlv_bunit_write(struct intel_display *display, u32 reg, u32 val) +{ + intel_parent_vlv_iosf_write(display, VLV_IOSF_SB_BUNIT, reg, val); +} + +void vlv_bunit_put(struct intel_display *display) +{ + intel_parent_vlv_iosf_put(display, BIT(VLV_IOSF_SB_BUNIT)); +} + +void vlv_cck_get(struct intel_display *display) +{ + intel_parent_vlv_iosf_get(display, BIT(VLV_IOSF_SB_CCK)); +} + +u32 vlv_cck_read(struct intel_display *display, u32 reg) +{ + return intel_parent_vlv_iosf_read(display, VLV_IOSF_SB_CCK, reg); +} + +void vlv_cck_write(struct intel_display *display, u32 reg, u32 val) +{ + intel_parent_vlv_iosf_write(display, VLV_IOSF_SB_CCK, reg, val); +} + +void vlv_cck_put(struct intel_display *display) +{ + intel_parent_vlv_iosf_put(display, BIT(VLV_IOSF_SB_CCK)); +} + +void vlv_ccu_get(struct intel_display *display) +{ + intel_parent_vlv_iosf_get(display, BIT(VLV_IOSF_SB_CCU)); +} + +u32 vlv_ccu_read(struct intel_display *display, u32 reg) +{ + return intel_parent_vlv_iosf_read(display, VLV_IOSF_SB_CCU, reg); +} + +void vlv_ccu_write(struct intel_display *display, u32 reg, u32 val) +{ + intel_parent_vlv_iosf_write(display, VLV_IOSF_SB_CCU, reg, val); +} + +void vlv_ccu_put(struct intel_display *display) +{ + intel_parent_vlv_iosf_put(display, BIT(VLV_IOSF_SB_CCU)); +} + +void vlv_dpio_get(struct intel_display *display) +{ + intel_parent_vlv_iosf_get(display, BIT(VLV_IOSF_SB_DPIO) | BIT(VLV_IOSF_SB_DPIO_2)); +} + static enum vlv_iosf_sb_unit vlv_dpio_phy_to_unit(struct intel_display *display, enum dpio_phy phy) { @@ -21,13 +87,12 @@ static enum vlv_iosf_sb_unit vlv_dpio_phy_to_unit(struct intel_display *display, return VLV_IOSF_SB_DPIO; } -u32 vlv_dpio_read(struct drm_device *drm, enum dpio_phy phy, int reg) +u32 vlv_dpio_read(struct intel_display *display, enum dpio_phy phy, int reg) { - struct intel_display *display = to_intel_display(drm); enum vlv_iosf_sb_unit unit = vlv_dpio_phy_to_unit(display, phy); u32 val; - val = vlv_iosf_sb_read(drm, unit, reg); + val = intel_parent_vlv_iosf_read(display, unit, reg); /* * FIXME: There might be some registers where all 1's is a valid value, @@ -40,11 +105,70 @@ u32 vlv_dpio_read(struct drm_device *drm, enum dpio_phy phy, int reg) return val; } -void vlv_dpio_write(struct drm_device *drm, +void vlv_dpio_write(struct intel_display *display, enum dpio_phy phy, int reg, u32 val) { - struct intel_display *display = to_intel_display(drm); enum vlv_iosf_sb_unit unit = vlv_dpio_phy_to_unit(display, phy); - vlv_iosf_sb_write(drm, unit, reg, val); + intel_parent_vlv_iosf_write(display, unit, reg, val); +} + +void vlv_dpio_put(struct intel_display *display) +{ + intel_parent_vlv_iosf_put(display, BIT(VLV_IOSF_SB_DPIO) | BIT(VLV_IOSF_SB_DPIO_2)); +} + +void vlv_flisdsi_get(struct intel_display *display) +{ + intel_parent_vlv_iosf_get(display, BIT(VLV_IOSF_SB_FLISDSI)); +} + +u32 vlv_flisdsi_read(struct intel_display *display, u32 reg) +{ + return intel_parent_vlv_iosf_read(display, VLV_IOSF_SB_FLISDSI, reg); +} + +void vlv_flisdsi_write(struct intel_display *display, u32 reg, u32 val) +{ + intel_parent_vlv_iosf_write(display, VLV_IOSF_SB_FLISDSI, reg, val); +} + +void vlv_flisdsi_put(struct intel_display *display) +{ + intel_parent_vlv_iosf_put(display, BIT(VLV_IOSF_SB_FLISDSI)); +} + +void vlv_nc_get(struct intel_display *display) +{ + intel_parent_vlv_iosf_get(display, BIT(VLV_IOSF_SB_NC)); +} + +u32 vlv_nc_read(struct intel_display *display, u8 addr) +{ + return intel_parent_vlv_iosf_read(display, VLV_IOSF_SB_NC, addr); +} + +void vlv_nc_put(struct intel_display *display) +{ + intel_parent_vlv_iosf_put(display, BIT(VLV_IOSF_SB_NC)); +} + +void vlv_punit_get(struct intel_display *display) +{ + intel_parent_vlv_iosf_get(display, BIT(VLV_IOSF_SB_PUNIT)); +} + +u32 vlv_punit_read(struct intel_display *display, u32 addr) +{ + return intel_parent_vlv_iosf_read(display, VLV_IOSF_SB_PUNIT, addr); +} + +int vlv_punit_write(struct intel_display *display, u32 addr, u32 val) +{ + return intel_parent_vlv_iosf_write(display, VLV_IOSF_SB_PUNIT, addr, val); +} + +void vlv_punit_put(struct intel_display *display) +{ + intel_parent_vlv_iosf_put(display, BIT(VLV_IOSF_SB_PUNIT)); } diff --git a/drivers/gpu/drm/i915/display/vlv_sideband.h b/drivers/gpu/drm/i915/display/vlv_sideband.h index 2c240d81fead..60a66abc1649 100644 --- a/drivers/gpu/drm/i915/display/vlv_sideband.h +++ b/drivers/gpu/drm/i915/display/vlv_sideband.h @@ -4,153 +4,45 @@ #ifndef _VLV_SIDEBAND_H_ #define _VLV_SIDEBAND_H_ -#include #include -#include "vlv_iosf_sb.h" -#include "vlv_iosf_sb_reg.h" +#include enum dpio_phy; -struct drm_device; +struct intel_display; -static inline void vlv_bunit_get(struct drm_device *drm) -{ - vlv_iosf_sb_get(drm, BIT(VLV_IOSF_SB_BUNIT)); -} +void vlv_bunit_get(struct intel_display *display); +u32 vlv_bunit_read(struct intel_display *display, u32 reg); +void vlv_bunit_write(struct intel_display *display, u32 reg, u32 val); +void vlv_bunit_put(struct intel_display *display); -static inline u32 vlv_bunit_read(struct drm_device *drm, u32 reg) -{ - return vlv_iosf_sb_read(drm, VLV_IOSF_SB_BUNIT, reg); -} +void vlv_cck_get(struct intel_display *display); +u32 vlv_cck_read(struct intel_display *display, u32 reg); +void vlv_cck_write(struct intel_display *display, u32 reg, u32 val); +void vlv_cck_put(struct intel_display *display); -static inline void vlv_bunit_write(struct drm_device *drm, u32 reg, u32 val) -{ - vlv_iosf_sb_write(drm, VLV_IOSF_SB_BUNIT, reg, val); -} +void vlv_ccu_get(struct intel_display *display); +u32 vlv_ccu_read(struct intel_display *display, u32 reg); +void vlv_ccu_write(struct intel_display *display, u32 reg, u32 val); +void vlv_ccu_put(struct intel_display *display); -static inline void vlv_bunit_put(struct drm_device *drm) -{ - vlv_iosf_sb_put(drm, BIT(VLV_IOSF_SB_BUNIT)); -} +void vlv_dpio_get(struct intel_display *display); +u32 vlv_dpio_read(struct intel_display *display, enum dpio_phy phy, int reg); +void vlv_dpio_write(struct intel_display *display, enum dpio_phy phy, int reg, u32 val); +void vlv_dpio_put(struct intel_display *display); -static inline void vlv_cck_get(struct drm_device *drm) -{ - vlv_iosf_sb_get(drm, BIT(VLV_IOSF_SB_CCK)); -} +void vlv_flisdsi_get(struct intel_display *display); +u32 vlv_flisdsi_read(struct intel_display *display, u32 reg); +void vlv_flisdsi_write(struct intel_display *display, u32 reg, u32 val); +void vlv_flisdsi_put(struct intel_display *display); -static inline u32 vlv_cck_read(struct drm_device *drm, u32 reg) -{ - return vlv_iosf_sb_read(drm, VLV_IOSF_SB_CCK, reg); -} +void vlv_nc_get(struct intel_display *display); +u32 vlv_nc_read(struct intel_display *display, u8 addr); +void vlv_nc_put(struct intel_display *display); -static inline void vlv_cck_write(struct drm_device *drm, u32 reg, u32 val) -{ - vlv_iosf_sb_write(drm, VLV_IOSF_SB_CCK, reg, val); -} - -static inline void vlv_cck_put(struct drm_device *drm) -{ - vlv_iosf_sb_put(drm, BIT(VLV_IOSF_SB_CCK)); -} - -static inline void vlv_ccu_get(struct drm_device *drm) -{ - vlv_iosf_sb_get(drm, BIT(VLV_IOSF_SB_CCU)); -} - -static inline u32 vlv_ccu_read(struct drm_device *drm, u32 reg) -{ - return vlv_iosf_sb_read(drm, VLV_IOSF_SB_CCU, reg); -} - -static inline void vlv_ccu_write(struct drm_device *drm, u32 reg, u32 val) -{ - vlv_iosf_sb_write(drm, VLV_IOSF_SB_CCU, reg, val); -} - -static inline void vlv_ccu_put(struct drm_device *drm) -{ - vlv_iosf_sb_put(drm, BIT(VLV_IOSF_SB_CCU)); -} - -static inline void vlv_dpio_get(struct drm_device *drm) -{ - vlv_iosf_sb_get(drm, BIT(VLV_IOSF_SB_DPIO) | BIT(VLV_IOSF_SB_DPIO_2)); -} - -#ifdef I915 -u32 vlv_dpio_read(struct drm_device *drm, enum dpio_phy phy, int reg); -void vlv_dpio_write(struct drm_device *drm, - enum dpio_phy phy, int reg, u32 val); -#else -static inline u32 vlv_dpio_read(struct drm_device *drm, int phy, int reg) -{ - return 0; -} -static inline void vlv_dpio_write(struct drm_device *drm, - int phy, int reg, u32 val) -{ -} -#endif - -static inline void vlv_dpio_put(struct drm_device *drm) -{ - vlv_iosf_sb_put(drm, BIT(VLV_IOSF_SB_DPIO) | BIT(VLV_IOSF_SB_DPIO_2)); -} - -static inline void vlv_flisdsi_get(struct drm_device *drm) -{ - vlv_iosf_sb_get(drm, BIT(VLV_IOSF_SB_FLISDSI)); -} - -static inline u32 vlv_flisdsi_read(struct drm_device *drm, u32 reg) -{ - return vlv_iosf_sb_read(drm, VLV_IOSF_SB_FLISDSI, reg); -} - -static inline void vlv_flisdsi_write(struct drm_device *drm, u32 reg, u32 val) -{ - vlv_iosf_sb_write(drm, VLV_IOSF_SB_FLISDSI, reg, val); -} - -static inline void vlv_flisdsi_put(struct drm_device *drm) -{ - vlv_iosf_sb_put(drm, BIT(VLV_IOSF_SB_FLISDSI)); -} - -static inline void vlv_nc_get(struct drm_device *drm) -{ - vlv_iosf_sb_get(drm, BIT(VLV_IOSF_SB_NC)); -} - -static inline u32 vlv_nc_read(struct drm_device *drm, u8 addr) -{ - return vlv_iosf_sb_read(drm, VLV_IOSF_SB_NC, addr); -} - -static inline void vlv_nc_put(struct drm_device *drm) -{ - vlv_iosf_sb_put(drm, BIT(VLV_IOSF_SB_NC)); -} - -static inline void vlv_punit_get(struct drm_device *drm) -{ - vlv_iosf_sb_get(drm, BIT(VLV_IOSF_SB_PUNIT)); -} - -static inline u32 vlv_punit_read(struct drm_device *drm, u32 addr) -{ - return vlv_iosf_sb_read(drm, VLV_IOSF_SB_PUNIT, addr); -} - -static inline int vlv_punit_write(struct drm_device *drm, u32 addr, u32 val) -{ - return vlv_iosf_sb_write(drm, VLV_IOSF_SB_PUNIT, addr, val); -} - -static inline void vlv_punit_put(struct drm_device *drm) -{ - vlv_iosf_sb_put(drm, BIT(VLV_IOSF_SB_PUNIT)); -} +void vlv_punit_get(struct intel_display *display); +u32 vlv_punit_read(struct intel_display *display, u32 addr); +int vlv_punit_write(struct intel_display *display, u32 addr, u32 val); +void vlv_punit_put(struct intel_display *display); #endif /* _VLV_SIDEBAND_H_ */ diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c index 77f85359f279..1cfdcf5c1118 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include "gem/i915_gem_lmem.h" #include "gem/i915_gem_region.h" @@ -23,8 +25,6 @@ #include "i915_reg.h" #include "i915_utils.h" #include "i915_vgpu.h" -#include "intel_mchbar_regs.h" -#include "intel_pci_config.h" struct intel_stolen_node { struct drm_i915_private *i915; diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c index 08c4e735481b..64ca5bbc53c6 100644 --- a/drivers/gpu/drm/i915/gt/intel_ggtt.c +++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "gem/i915_gem_lmem.h" @@ -20,7 +21,6 @@ #include "intel_gpu_commands.h" #include "intel_gt.h" #include "intel_gt_regs.h" -#include "intel_pci_config.h" #include "intel_ring.h" #include "i915_drv.h" #include "i915_pci.h" diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c b/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c index ac9aede82320..6efc1ed3831b 100644 --- a/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c +++ b/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c @@ -7,6 +7,7 @@ #include #include +#include #include "display/intel_display.h" #include "i915_drv.h" @@ -15,7 +16,6 @@ #include "i915_pvinfo.h" #include "i915_vgpu.h" #include "intel_gt_regs.h" -#include "intel_mchbar_regs.h" /** * DOC: fence register handling diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c index d76121e117e1..5c7f862f7100 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt.c +++ b/drivers/gpu/drm/i915/gt/intel_gt.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "gem/i915_gem_internal.h" #include "gem/i915_gem_lmem.h" @@ -28,7 +29,6 @@ #include "intel_gt_requests.h" #include "intel_migrate.h" #include "intel_mocs.h" -#include "intel_pci_config.h" #include "intel_rc6.h" #include "intel_renderstate.h" #include "intel_rps.h" diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm_debugfs.c b/drivers/gpu/drm/i915/gt/intel_gt_pm_debugfs.c index babaf16e72f2..adf2512e2ed5 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_pm_debugfs.c +++ b/drivers/gpu/drm/i915/gt/intel_gt_pm_debugfs.c @@ -19,7 +19,6 @@ #include "intel_gt_pm_debugfs.h" #include "intel_gt_regs.h" #include "intel_llc.h" -#include "intel_mchbar_regs.h" #include "intel_pcode.h" #include "intel_rc6.h" #include "intel_rps.h" diff --git a/drivers/gpu/drm/i915/gt/intel_llc.c b/drivers/gpu/drm/i915/gt/intel_llc.c index bcd707e3d436..82d9a8e50867 100644 --- a/drivers/gpu/drm/i915/gt/intel_llc.c +++ b/drivers/gpu/drm/i915/gt/intel_llc.c @@ -7,12 +7,12 @@ #include #include +#include #include "i915_drv.h" #include "i915_reg.h" #include "intel_gt.h" #include "intel_llc.h" -#include "intel_mchbar_regs.h" #include "intel_pcode.h" #include "intel_rps.h" diff --git a/drivers/gpu/drm/i915/gt/intel_region_lmem.c b/drivers/gpu/drm/i915/gt/intel_region_lmem.c index a30060fd4429..b8a39567a334 100644 --- a/drivers/gpu/drm/i915/gt/intel_region_lmem.c +++ b/drivers/gpu/drm/i915/gt/intel_region_lmem.c @@ -4,12 +4,12 @@ */ #include +#include #include "i915_drv.h" #include "i915_pci.h" #include "i915_reg.h" #include "intel_memory_region.h" -#include "intel_pci_config.h" #include "intel_region_lmem.h" #include "intel_region_ttm.h" #include "gem/i915_gem_lmem.h" diff --git a/drivers/gpu/drm/i915/gt/intel_reset.c b/drivers/gpu/drm/i915/gt/intel_reset.c index 984d0056c01c..0b5f3fc58009 100644 --- a/drivers/gpu/drm/i915/gt/intel_reset.c +++ b/drivers/gpu/drm/i915/gt/intel_reset.c @@ -7,6 +7,9 @@ #include #include +#include +#include + #include "display/intel_display_reset.h" #include "display/intel_overlay.h" #include "gem/i915_gem_context.h" @@ -27,8 +30,6 @@ #include "intel_gt_pm.h" #include "intel_gt_print.h" #include "intel_gt_requests.h" -#include "intel_mchbar_regs.h" -#include "intel_pci_config.h" #include "intel_reset.h" #define RESET_MAX_RETRIES 3 @@ -966,6 +967,7 @@ static void nop_submit_request(struct i915_request *request) static void __intel_gt_set_wedged(struct intel_gt *gt) { + struct intel_display *display = gt->i915->display; struct intel_engine_cs *engine; intel_engine_mask_t awake; enum intel_engine_id id; @@ -983,7 +985,8 @@ static void __intel_gt_set_wedged(struct intel_gt *gt) awake = reset_prepare(gt); /* Even if the GPU reset fails, it should still stop the engines */ - if (!intel_gt_gpu_reset_clobbers_display(gt)) + if (!intel_gt_gpu_reset_clobbers_display(gt) && + !intel_display_reset_test(display)) intel_gt_reset_all_engines(gt); for_each_engine(engine, gt, id) @@ -1397,11 +1400,6 @@ int intel_engine_reset(struct intel_engine_cs *engine, const char *msg) return err; } -static void display_reset_modeset_stuck(void *gt) -{ - intel_gt_set_wedged(gt); -} - static void intel_gt_reset_global(struct intel_gt *gt, u32 engine_mask, const char *reason) @@ -1424,16 +1422,25 @@ static void intel_gt_reset_global(struct intel_gt *gt, bool need_display_reset; bool reset_display; - need_display_reset = intel_gt_gpu_reset_clobbers_display(gt) && + need_display_reset = + intel_display_reset_supported(display) && + intel_gt_gpu_reset_clobbers_display(gt) && intel_has_gpu_reset(gt); - reset_display = intel_display_reset_test(display) || + reset_display = + intel_display_reset_test(display) || need_display_reset; - if (reset_display) - reset_display = intel_display_reset_prepare(display, - display_reset_modeset_stuck, - gt); + if (reset_display) { + if (atomic_read(&i915->pending_fb_pin)) { + drm_dbg_kms(&i915->drm, + "Modeset potentially stuck, unbreaking through wedging\n"); + + intel_gt_set_wedged(gt); + } + + intel_display_reset_prepare(display); + } intel_gt_reset(gt, engine_mask, reason); @@ -1501,9 +1508,10 @@ void intel_gt_handle_error(struct intel_gt *gt, /* * Try engine reset when available. We fall back to full reset if - * single reset fails. + * single reset fails. Display reset test needs a full reset. */ - if (!intel_uc_uses_guc_submission(>->uc) && + if (!intel_display_reset_test(gt->i915->display) && + !intel_uc_uses_guc_submission(>->uc) && intel_has_reset_engine(gt) && !intel_gt_is_wedged(gt)) { local_bh_disable(); for_each_engine_masked(engine, gt, engine_mask, tmp) { diff --git a/drivers/gpu/drm/i915/gt/intel_rps.c b/drivers/gpu/drm/i915/gt/intel_rps.c index 844f2716a386..a33b19c04737 100644 --- a/drivers/gpu/drm/i915/gt/intel_rps.c +++ b/drivers/gpu/drm/i915/gt/intel_rps.c @@ -5,9 +5,10 @@ #include -#include #include +#include #include +#include #include "display/intel_display_rps.h" #include "display/vlv_clock.h" @@ -25,7 +26,6 @@ #include "intel_gt_pm_irq.h" #include "intel_gt_print.h" #include "intel_gt_regs.h" -#include "intel_mchbar_regs.h" #include "intel_pcode.h" #include "intel_rps.h" #include "vlv_iosf_sb.h" diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c index fa9af08f9708..a75f05ff1110 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c @@ -16,7 +16,6 @@ #include "i915_wait_util.h" #include "intel_guc_print.h" #include "intel_guc_slpc.h" -#include "intel_mchbar_regs.h" /** * DOC: SLPC - Dynamic Frequency management diff --git a/drivers/gpu/drm/i915/gvt/cfg_space.c b/drivers/gpu/drm/i915/gvt/cfg_space.c index 1937e04d3791..e00c1478a24e 100644 --- a/drivers/gpu/drm/i915/gvt/cfg_space.c +++ b/drivers/gpu/drm/i915/gvt/cfg_space.c @@ -32,10 +32,10 @@ */ #include +#include #include "gvt.h" #include "i915_drv.h" -#include "intel_pci_config.h" enum { INTEL_GVT_PCI_BAR_GTTMMIO = 0, diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index a34f56630af9..9f61867e2478 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -71,7 +71,6 @@ #include "i915_drv.h" #include "i915_pvinfo.h" #include "i915_reg.h" -#include "intel_mchbar_regs.h" #include "sched_policy.h" /* XXX FIXME i915 has changed PP_XXX definition */ diff --git a/drivers/gpu/drm/i915/i915_bo.c b/drivers/gpu/drm/i915/i915_bo.c index 1789f7cab05c..559341103ca7 100644 --- a/drivers/gpu/drm/i915/i915_bo.c +++ b/drivers/gpu/drm/i915/i915_bo.c @@ -1,11 +1,14 @@ // SPDX-License-Identifier: MIT /* Copyright © 2024 Intel Corporation */ +#include + #include #include #include #include "display/intel_fb.h" +#include "gem/i915_gem_lmem.h" #include "gem/i915_gem_mman.h" #include "gem/i915_gem_object.h" #include "gem/i915_gem_object_frontbuffer.h" @@ -141,6 +144,111 @@ i915_bo_framebuffer_lookup(struct drm_device *drm, return intel_bo_to_drm_bo(obj); } +#if IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION) +static u32 i915_bo_fbdev_pitch_align(u32 stride) +{ + return ALIGN(stride, 64); +} + +bool i915_bo_fbdev_prefer_stolen(struct drm_i915_private *i915, unsigned int size) +{ + /* Skip stolen on MTL as Wa_22018444074 mitigation. */ + if (IS_METEORLAKE(i915)) + return false; + + /* + * If the FB is too big, just don't use it since fbdev is not very + * important and we should probably use that space with FBC or other + * features. + */ + return i915->dsm.usable_size >= size * 2; +} + +static struct drm_gem_object *i915_bo_fbdev_create(struct drm_device *drm, int size) +{ + struct drm_i915_private *i915 = to_i915(drm); + struct drm_i915_gem_object *obj; + + obj = ERR_PTR(-ENODEV); + if (HAS_LMEM(i915)) { + obj = i915_gem_object_create_lmem(i915, size, + I915_BO_ALLOC_CONTIGUOUS | + I915_BO_ALLOC_USER); + } else { + if (i915_bo_fbdev_prefer_stolen(i915, size)) + obj = i915_gem_object_create_stolen(i915, size); + else + drm_info(drm, "Allocating fbdev: Stolen memory not preferred.\n"); + + if (IS_ERR(obj)) + obj = i915_gem_object_create_shmem(i915, size); + } + + if (IS_ERR(obj)) { + drm_err(drm, "failed to allocate framebuffer (%pe)\n", obj); + return ERR_PTR(-ENOMEM); + } + + return &obj->base; +} + +static void i915_bo_fbdev_destroy(struct drm_gem_object *obj) +{ + drm_gem_object_put(obj); +} + +static int i915_bo_fbdev_fill_info(struct drm_gem_object *_obj, struct fb_info *info, + struct i915_vma *vma) +{ + struct drm_i915_private *i915 = to_i915(_obj->dev); + struct drm_i915_gem_object *obj = to_intel_bo(_obj); + struct i915_gem_ww_ctx ww; + void __iomem *vaddr; + int ret; + + if (i915_gem_object_is_lmem(obj)) { + struct intel_memory_region *mem = obj->mm.region; + + /* Use fbdev's framebuffer from lmem for discrete */ + info->fix.smem_start = + (unsigned long)(mem->io.start + + i915_gem_object_get_dma_address(obj, 0) - + mem->region.start); + info->fix.smem_len = obj->base.size; + } else { + struct i915_ggtt *ggtt = to_gt(i915)->ggtt; + + /* Our framebuffer is the entirety of fbdev's system memory */ + info->fix.smem_start = + (unsigned long)(ggtt->gmadr.start + i915_ggtt_offset(vma)); + info->fix.smem_len = vma->size; + } + + for_i915_gem_ww(&ww, ret, false) { + ret = i915_gem_object_lock(vma->obj, &ww); + + if (ret) + continue; + + vaddr = i915_vma_pin_iomap(vma); + if (IS_ERR(vaddr)) { + drm_err(&i915->drm, + "Failed to remap framebuffer into virtual memory (%pe)\n", vaddr); + ret = PTR_ERR(vaddr); + continue; + } + } + + if (ret) + return ret; + + info->screen_base = vaddr; + info->screen_size = intel_bo_to_drm_bo(obj)->size; + + return 0; +} +#endif + const struct intel_display_bo_interface i915_display_bo_interface = { .is_tiled = i915_bo_is_tiled, .is_userptr = i915_bo_is_userptr, @@ -153,4 +261,10 @@ const struct intel_display_bo_interface i915_display_bo_interface = { .framebuffer_init = i915_bo_framebuffer_init, .framebuffer_fini = i915_bo_framebuffer_fini, .framebuffer_lookup = i915_bo_framebuffer_lookup, +#if IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION) + .fbdev_create = i915_bo_fbdev_create, + .fbdev_destroy = i915_bo_fbdev_destroy, + .fbdev_fill_info = i915_bo_fbdev_fill_info, + .fbdev_pitch_align = i915_bo_fbdev_pitch_align, +#endif }; diff --git a/drivers/gpu/drm/i915/i915_bo.h b/drivers/gpu/drm/i915/i915_bo.h index 57255d052dd9..39ba62696550 100644 --- a/drivers/gpu/drm/i915/i915_bo.h +++ b/drivers/gpu/drm/i915/i915_bo.h @@ -4,6 +4,12 @@ #ifndef __I915_BO_H__ #define __I915_BO_H__ +#include + +struct drm_i915_private; + +bool i915_bo_fbdev_prefer_stolen(struct drm_i915_private *i915, unsigned int size); + extern const struct intel_display_bo_interface i915_display_bo_interface; #endif /* __I915_BO_H__ */ diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 4778ba664ec7..a3e27f9e4f47 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "gem/i915_gem_context.h" #include "gt/intel_gt.h" @@ -57,7 +58,6 @@ #include "i915_reg.h" #include "i915_scheduler.h" #include "i915_wait_util.h" -#include "intel_mchbar_regs.h" static inline struct drm_i915_private *node_to_i915(struct drm_info_node *node) { diff --git a/drivers/gpu/drm/i915/i915_dpt.c b/drivers/gpu/drm/i915/i915_dpt.c index 9f47bb563c85..fcd7cced771d 100644 --- a/drivers/gpu/drm/i915/i915_dpt.c +++ b/drivers/gpu/drm/i915/i915_dpt.c @@ -129,7 +129,6 @@ static void dpt_cleanup(struct i915_address_space *vm) struct i915_vma *i915_dpt_pin_to_ggtt(struct intel_dpt *dpt, unsigned int alignment) { struct drm_i915_private *i915 = dpt->vm.i915; - struct intel_display *display = i915->display; struct ref_tracker *wakeref; struct i915_vma *vma; void __iomem *iomem; @@ -141,7 +140,7 @@ struct i915_vma *i915_dpt_pin_to_ggtt(struct intel_dpt *dpt, unsigned int alignm pin_flags |= PIN_MAPPABLE; wakeref = intel_runtime_pm_get(&i915->runtime_pm); - atomic_inc(&display->restore.pending_fb_pin); + atomic_inc(&i915->pending_fb_pin); for_i915_gem_ww(&ww, err, true) { err = i915_gem_object_lock(dpt->obj, &ww); @@ -171,7 +170,7 @@ struct i915_vma *i915_dpt_pin_to_ggtt(struct intel_dpt *dpt, unsigned int alignm dpt->obj->mm.dirty = true; - atomic_dec(&display->restore.pending_fb_pin); + atomic_dec(&i915->pending_fb_pin); intel_runtime_pm_put(&i915->runtime_pm, wakeref); return err ? ERR_PTR(err) : vma; diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index 385a634c3ed0..a4bd4f8e18b2 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -122,7 +122,6 @@ #include "intel_cpu_info.h" #include "intel_gvt.h" #include "intel_memory_region.h" -#include "intel_pci_config.h" #include "intel_pcode.h" #include "intel_region_ttm.h" #include "vlv_iosf_sb.h" @@ -311,6 +310,7 @@ static void i915_driver_late_release(struct drm_i915_private *dev_priv) i915_params_free(&dev_priv->params); intel_display_device_remove(display); + dev_priv->display = NULL; } /** @@ -750,9 +750,8 @@ static bool has_auxccs(struct drm_device *drm) { struct drm_i915_private *i915 = to_i915(drm); - return IS_GRAPHICS_VER(i915, 9, 12) || - IS_ALDERLAKE_P(i915) || - IS_METEORLAKE(i915); + return IS_GRAPHICS_VER(i915, 9, 12) && + !HAS_FLAT_CCS(i915); } static bool has_fenced_regions(struct drm_device *drm) @@ -780,7 +779,7 @@ static const struct intel_display_parent_interface parent = { .rpm = &i915_display_rpm_interface, .rps = &i915_display_rps_interface, .stolen = &i915_display_stolen_interface, - .vma = &i915_display_vma_interface, + .vlv_iosf = &i915_display_vlv_iosf_interface, .fence_priority_display = fence_priority_display, .has_auxccs = has_auxccs, diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index dafee3dcd1c5..844ed79e7211 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -315,6 +315,8 @@ struct drm_i915_private { /* The TTM device structure. */ struct ttm_device bdev; + atomic_t pending_fb_pin; + I915_SELFTEST_DECLARE(struct i915_selftest_stash selftest;) /* diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.c b/drivers/gpu/drm/i915/i915_fb_pin.c similarity index 66% rename from drivers/gpu/drm/i915/display/intel_fb_pin.c rename to drivers/gpu/drm/i915/i915_fb_pin.c index 738d77a1468a..b0e121462ca3 100644 --- a/drivers/gpu/drm/i915/display/intel_fb_pin.c +++ b/drivers/gpu/drm/i915/i915_fb_pin.c @@ -9,30 +9,24 @@ #include +#include "display/intel_display_core.h" +#include "display/intel_display_types.h" +#include "display/intel_fb.h" +#include "display/intel_fb_pin.h" +#include "display/intel_plane.h" + #include "gem/i915_gem_domain.h" #include "gem/i915_gem_object.h" +#include "i915_dpt.h" #include "i915_drv.h" #include "i915_vma.h" -#include "intel_display_core.h" -#include "intel_display_rpm.h" -#include "intel_display_types.h" -#include "i915_dpt.h" -#include "intel_fb.h" -#include "intel_fb_pin.h" -#include "intel_plane.h" static struct i915_vma * -intel_fb_pin_to_dpt(const struct drm_framebuffer *fb, - const struct i915_gtt_view *view, - unsigned int alignment, - unsigned long *out_flags, - struct intel_dpt *dpt) +intel_fb_pin_to_dpt(struct drm_gem_object *_obj, struct intel_dpt *dpt, + const struct intel_fb_pin_params *pin_params) { - struct drm_device *dev = fb->dev; - struct intel_display *display = to_intel_display(dev); - struct drm_i915_private *dev_priv = to_i915(dev); - struct drm_gem_object *_obj = intel_fb_bo(fb); + struct drm_i915_private *i915 = to_i915(_obj->dev); struct drm_i915_gem_object *obj = to_intel_bo(_obj); struct i915_address_space *vm = i915_dpt_to_vm(dpt); struct i915_gem_ww_ctx ww; @@ -43,20 +37,20 @@ intel_fb_pin_to_dpt(const struct drm_framebuffer *fb, * We are not syncing against the binding (and potential migrations) * below, so this vm must never be async. */ - if (drm_WARN_ON(&dev_priv->drm, vm->bind_async_flags)) + if (drm_WARN_ON(&i915->drm, vm->bind_async_flags)) return ERR_PTR(-EINVAL); if (WARN_ON(!i915_gem_object_is_framebuffer(obj))) return ERR_PTR(-EINVAL); - atomic_inc(&display->restore.pending_fb_pin); + atomic_inc(&i915->pending_fb_pin); for_i915_gem_ww(&ww, ret, true) { ret = i915_gem_object_lock(obj, &ww); if (ret) continue; - if (HAS_LMEM(dev_priv)) { + if (HAS_LMEM(i915)) { unsigned int flags = obj->flags; /* @@ -65,7 +59,7 @@ intel_fb_pin_to_dpt(const struct drm_framebuffer *fb, * ensure it is always in the mappable part of lmem, if this is * a small-bar device. */ - if (intel_fb_rc_ccs_cc_plane(fb) >= 0) + if (pin_params->needs_cpu_lmem_access) flags &= ~I915_BO_ALLOC_GPU_ONLY; ret = __i915_gem_object_migrate(obj, &ww, INTEL_REGION_LMEM_0, flags); @@ -77,19 +71,20 @@ intel_fb_pin_to_dpt(const struct drm_framebuffer *fb, if (ret) continue; - vma = i915_vma_instance(obj, vm, view); + vma = i915_vma_instance(obj, vm, pin_params->view); if (IS_ERR(vma)) { ret = PTR_ERR(vma); continue; } - if (i915_vma_misplaced(vma, 0, alignment, 0)) { + if (i915_vma_misplaced(vma, 0, pin_params->alignment, 0)) { ret = i915_vma_unbind(vma); if (ret) continue; } - ret = i915_vma_pin_ww(vma, &ww, 0, alignment, PIN_GLOBAL); + ret = i915_vma_pin_ww(vma, &ww, 0, pin_params->alignment, + PIN_GLOBAL); if (ret) continue; } @@ -98,41 +93,36 @@ intel_fb_pin_to_dpt(const struct drm_framebuffer *fb, goto err; } - vma->display_alignment = max(vma->display_alignment, alignment); + vma->display_alignment = max(vma->display_alignment, + pin_params->alignment); i915_gem_object_flush_if_display(obj); i915_vma_get(vma); err: - atomic_dec(&display->restore.pending_fb_pin); + atomic_dec(&i915->pending_fb_pin); return vma; } struct i915_vma * -intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb, - const struct i915_gtt_view *view, - unsigned int alignment, - unsigned int phys_alignment, - unsigned int vtd_guard, - bool uses_fence, - unsigned long *out_flags) +intel_fb_pin_to_ggtt(struct drm_gem_object *_obj, + const struct intel_fb_pin_params *pin_params, + int *out_fence_id) { - struct drm_device *dev = fb->dev; - struct intel_display *display = to_intel_display(dev); - struct drm_i915_private *dev_priv = to_i915(dev); - struct drm_gem_object *_obj = intel_fb_bo(fb); + struct drm_i915_private *i915 = to_i915(_obj->dev); struct drm_i915_gem_object *obj = to_intel_bo(_obj); - struct ref_tracker *wakeref; + intel_wakeref_t wakeref; struct i915_gem_ww_ctx ww; struct i915_vma *vma; unsigned int pinctl; int ret; - if (drm_WARN_ON(dev, !i915_gem_object_is_framebuffer(obj))) + if (drm_WARN_ON(&i915->drm, !i915_gem_object_is_framebuffer(obj))) return ERR_PTR(-EINVAL); - if (drm_WARN_ON(dev, alignment && !is_power_of_2(alignment))) + if (drm_WARN_ON(&i915->drm, pin_params->alignment && + !is_power_of_2(pin_params->alignment))) return ERR_PTR(-EINVAL); /* @@ -142,42 +132,40 @@ intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb, * intel_runtime_pm_put(), so it is correct to wrap only the * pin/unpin/fence and not more. */ - wakeref = intel_display_rpm_get(display); + wakeref = intel_runtime_pm_get(&i915->runtime_pm); - atomic_inc(&display->restore.pending_fb_pin); + atomic_inc(&i915->pending_fb_pin); - /* - * Valleyview is definitely limited to scanning out the first - * 512MiB. Lets presume this behaviour was inherited from the - * g4x display engine and that all earlier gen are similarly - * limited. Testing suggests that it is a little more - * complicated than this. For example, Cherryview appears quite - * happy to scanout from anywhere within its global aperture. - */ pinctl = 0; - if (HAS_GMCH(display)) + /* PIN_MAPPABLE limits the address to GMADR size */ + if (pin_params->needs_low_address) pinctl |= PIN_MAPPABLE; i915_gem_ww_ctx_init(&ww, true); retry: ret = i915_gem_object_lock(obj, &ww); - if (!ret && phys_alignment) - ret = i915_gem_object_attach_phys(obj, phys_alignment); - else if (!ret && HAS_LMEM(dev_priv)) + if (!ret && pin_params->needs_physical) + ret = i915_gem_object_attach_phys(obj, pin_params->phys_alignment); + else if (!ret && HAS_LMEM(i915)) ret = i915_gem_object_migrate(obj, &ww, INTEL_REGION_LMEM_0); if (!ret) ret = i915_gem_object_pin_pages(obj); if (ret) goto err; - vma = i915_gem_object_pin_to_display_plane(obj, &ww, alignment, - vtd_guard, view, pinctl); + vma = i915_gem_object_pin_to_display_plane(obj, &ww, + pin_params->alignment, + pin_params->vtd_guard, + pin_params->view, pinctl); if (IS_ERR(vma)) { ret = PTR_ERR(vma); goto err_unpin; } - if (uses_fence && i915_vma_is_map_and_fenceable(vma)) { + if (out_fence_id) + *out_fence_id = -1; + + if (out_fence_id && i915_vma_is_map_and_fenceable(vma)) { /* * Install a fence for tiled scan-out. Pre-i965 always needs a * fence, whereas 965+ only requires a fence if using @@ -196,14 +184,14 @@ intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb, * mode that matches the user configuration. */ ret = i915_vma_pin_fence(vma); - if (ret != 0 && DISPLAY_VER(display) < 4) { + if (ret != 0 && pin_params->needs_fence) { i915_vma_unpin(vma); goto err_unpin; } ret = 0; if (vma->fence) - *out_flags |= PLANE_HAS_FENCE; + *out_fence_id = vma->fence->id; } i915_vma_get(vma); @@ -220,14 +208,14 @@ intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb, if (ret) vma = ERR_PTR(ret); - atomic_dec(&display->restore.pending_fb_pin); - intel_display_rpm_put(display, wakeref); + atomic_dec(&i915->pending_fb_pin); + intel_runtime_pm_put(&i915->runtime_pm, wakeref); return vma; } -void intel_fb_unpin_vma(struct i915_vma *vma, unsigned long flags) +void intel_fb_unpin_vma(struct i915_vma *vma, int fence_id) { - if (flags & PLANE_HAS_FENCE) + if (fence_id >= 0) i915_vma_unpin_fence(vma); i915_vma_unpin(vma); i915_vma_put(vma); @@ -265,35 +253,46 @@ int intel_plane_pin_fb(struct intel_plane_state *plane_state, const struct intel_plane_state *old_plane_state) { struct intel_display *display = to_intel_display(plane_state); + struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev); struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); const struct intel_framebuffer *fb = to_intel_framebuffer(plane_state->hw.fb); struct i915_vma *vma; if (!intel_fb_uses_dpt(&fb->base)) { - vma = intel_fb_pin_to_ggtt(&fb->base, &plane_state->view.gtt, - intel_plane_fb_min_alignment(plane_state), - intel_plane_fb_min_phys_alignment(plane_state), - intel_plane_fb_vtd_guard(plane_state), - intel_plane_uses_fence(plane_state), - &plane_state->flags); + struct intel_fb_pin_params pin_params = { + .view = &plane_state->view.gtt, + .alignment = intel_plane_fb_min_alignment(plane_state), + .phys_alignment = intel_plane_fb_min_phys_alignment(plane_state), + .vtd_guard = intel_plane_fb_vtd_guard(plane_state), + .needs_cpu_lmem_access = intel_fb_needs_cpu_access(&fb->base), + .needs_low_address = intel_plane_needs_low_address(display), + .needs_physical = intel_plane_needs_physical(plane), + .needs_fence = intel_plane_needs_fence(display), + }; + int fence_id = -1; + + vma = intel_fb_pin_to_ggtt(intel_fb_bo(&fb->base), &pin_params, + intel_plane_uses_fence(plane_state) ? &fence_id : NULL); if (IS_ERR(vma)) return PTR_ERR(vma); plane_state->ggtt_vma = vma; - + plane_state->fence_id = fence_id; } else { - unsigned int alignment = intel_plane_fb_min_alignment(plane_state); + struct intel_fb_pin_params pin_params = { + .view = &plane_state->view.gtt, + .alignment = intel_plane_fb_min_alignment(plane_state), + .needs_cpu_lmem_access = intel_fb_needs_cpu_access(&fb->base), + }; - vma = i915_dpt_pin_to_ggtt(fb->dpt, alignment / 512); + vma = i915_dpt_pin_to_ggtt(fb->dpt, pin_params.alignment / 512); if (IS_ERR(vma)) return PTR_ERR(vma); plane_state->ggtt_vma = vma; - vma = intel_fb_pin_to_dpt(&fb->base, &plane_state->view.gtt, - alignment, &plane_state->flags, - fb->dpt); + vma = intel_fb_pin_to_dpt(intel_fb_bo(&fb->base), fb->dpt, &pin_params); if (IS_ERR(vma)) { i915_dpt_unpin_from_ggtt(fb->dpt); plane_state->ggtt_vma = NULL; @@ -308,7 +307,7 @@ int intel_plane_pin_fb(struct intel_plane_state *plane_state, * The DPT object contains only one vma, and there is no VT-d * guard, so the VMA's offset within the DPT is always 0. */ - drm_WARN_ON(display->drm, i915_dpt_offset(plane_state->dpt_vma)); + drm_WARN_ON(&i915->drm, i915_dpt_offset(plane_state->dpt_vma)); } /* @@ -338,12 +337,14 @@ void intel_plane_unpin_fb(struct intel_plane_state *old_plane_state) if (!intel_fb_uses_dpt(&fb->base)) { vma = fetch_and_zero(&old_plane_state->ggtt_vma); - if (vma) - intel_fb_unpin_vma(vma, old_plane_state->flags); + if (vma) { + intel_fb_unpin_vma(vma, old_plane_state->fence_id); + old_plane_state->fence_id = -1; + } } else { vma = fetch_and_zero(&old_plane_state->dpt_vma); if (vma) - intel_fb_unpin_vma(vma, old_plane_state->flags); + intel_fb_unpin_vma(vma, -1); vma = fetch_and_zero(&old_plane_state->ggtt_vma); if (vma) diff --git a/drivers/gpu/drm/i915/i915_freq.c b/drivers/gpu/drm/i915/i915_freq.c index 9bdaea34aef9..9547d087555f 100644 --- a/drivers/gpu/drm/i915/i915_freq.c +++ b/drivers/gpu/drm/i915/i915_freq.c @@ -2,10 +2,10 @@ /* Copyright © 2025 Intel Corporation */ #include +#include #include "i915_drv.h" #include "i915_freq.h" -#include "intel_mchbar_regs.h" unsigned int i9xx_fsb_freq(struct drm_i915_private *i915) { diff --git a/drivers/gpu/drm/i915/i915_gmch.c b/drivers/gpu/drm/i915/i915_gmch.c index 2d55831b3c58..b0ef6ef577a3 100644 --- a/drivers/gpu/drm/i915/i915_gmch.c +++ b/drivers/gpu/drm/i915/i915_gmch.c @@ -5,10 +5,10 @@ #include #include +#include #include "i915_drv.h" #include "i915_gmch.h" -#include "intel_pci_config.h" static void i915_gmch_bridge_release(struct drm_device *dev, void *bridge) { diff --git a/drivers/gpu/drm/i915/i915_gtt_view_types.h b/drivers/gpu/drm/i915/i915_gtt_view_types.h index c084f67bc880..9c4f38db32ff 100644 --- a/drivers/gpu/drm/i915/i915_gtt_view_types.h +++ b/drivers/gpu/drm/i915/i915_gtt_view_types.h @@ -56,4 +56,19 @@ struct i915_gtt_view { }; }; +static inline bool i915_gtt_view_is_normal(const struct i915_gtt_view *view) +{ + return view->type == I915_GTT_VIEW_NORMAL; +} + +static inline bool i915_gtt_view_is_remapped(const struct i915_gtt_view *view) +{ + return view->type == I915_GTT_VIEW_REMAPPED; +} + +static inline bool i915_gtt_view_is_rotated(const struct i915_gtt_view *view) +{ + return view->type == I915_GTT_VIEW_ROTATED; +} + #endif /* __I915_GTT_VIEW_TYPES_H__ */ diff --git a/drivers/gpu/drm/i915/i915_hwmon.c b/drivers/gpu/drm/i915/i915_hwmon.c index c4a799f5fe92..da643b38064c 100644 --- a/drivers/gpu/drm/i915/i915_hwmon.c +++ b/drivers/gpu/drm/i915/i915_hwmon.c @@ -10,11 +10,11 @@ #include #include +#include #include "i915_drv.h" #include "i915_hwmon.h" #include "i915_reg.h" -#include "intel_mchbar_regs.h" #include "intel_pcode.h" #include "gt/intel_gt.h" #include "gt/intel_gt_regs.h" diff --git a/drivers/gpu/drm/i915/i915_initial_plane.c b/drivers/gpu/drm/i915/i915_initial_plane.c index 390a9248d631..4902c0748664 100644 --- a/drivers/gpu/drm/i915/i915_initial_plane.c +++ b/drivers/gpu/drm/i915/i915_initial_plane.c @@ -9,18 +9,13 @@ #include "display/intel_crtc.h" #include "display/intel_display_types.h" #include "display/intel_fb.h" -#include "display/intel_fbdev_fb.h" #include "gem/i915_gem_lmem.h" #include "gem/i915_gem_region.h" +#include "i915_bo.h" #include "i915_drv.h" #include "i915_initial_plane.h" -static void i915_initial_plane_vblank_wait(struct drm_crtc *crtc) -{ - intel_crtc_wait_for_next_vblank(to_intel_crtc(crtc)); -} - static enum intel_memory_type initial_plane_memory_type(struct drm_i915_private *i915) { @@ -34,14 +29,14 @@ initial_plane_memory_type(struct drm_i915_private *i915) static bool initial_plane_phys(struct drm_i915_private *i915, - struct intel_initial_plane_config *plane_config) + u32 base, resource_size_t *out_phys_base, + struct intel_memory_region **out_mem) { struct i915_ggtt *ggtt = to_gt(i915)->ggtt; struct intel_memory_region *mem; enum intel_memory_type mem_type; bool is_present, is_local; dma_addr_t dma_addr; - u32 base; mem_type = initial_plane_memory_type(i915); mem = intel_memory_region_by_type(i915, mem_type); @@ -52,7 +47,7 @@ initial_plane_phys(struct drm_i915_private *i915, return false; } - base = round_down(plane_config->base, I915_GTT_MIN_ALIGNMENT); + base = round_down(base, I915_GTT_MIN_ALIGNMENT); dma_addr = intel_ggtt_read_entry(&ggtt->vm, base, &is_present, &is_local); @@ -77,8 +72,8 @@ initial_plane_phys(struct drm_i915_private *i915, drm_dbg(&i915->drm, "Using dma_addr=%pa, based on initial plane programming\n", &dma_addr); - plane_config->phys_base = dma_addr - mem->region.start; - plane_config->mem = mem; + *out_phys_base = dma_addr - mem->region.start; + *out_mem = mem; return true; } @@ -99,12 +94,9 @@ initial_plane_vma(struct drm_i915_private *i915, if (plane_config->size == 0) return NULL; - if (!initial_plane_phys(i915, plane_config)) + if (!initial_plane_phys(i915, plane_config->base, &phys_base, &mem)) return NULL; - phys_base = plane_config->phys_base; - mem = plane_config->mem; - base = round_down(plane_config->base, I915_GTT_MIN_ALIGNMENT); size = round_up(plane_config->base + plane_config->size, mem->min_page_size); @@ -118,7 +110,7 @@ initial_plane_vma(struct drm_i915_private *i915, if (IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION) && IS_ENABLED(CONFIG_FRAMEBUFFER_CONSOLE) && mem == i915->mm.stolen_region && - !intel_fbdev_fb_prefer_stolen(&i915->drm, size)) { + !i915_bo_fbdev_prefer_stolen(i915, size)) { drm_dbg_kms(&i915->drm, "Initial FB size exceeds half of stolen, discarding\n"); return NULL; } @@ -140,7 +132,7 @@ initial_plane_vma(struct drm_i915_private *i915, i915_gem_object_set_cache_coherency(obj, HAS_WT(i915) ? I915_CACHE_WT : I915_CACHE_NONE); - tiling = intel_fb_modifier_to_tiling(plane_config->fb->base.modifier); + tiling = intel_fb_modifier_to_tiling(plane_config->fb->modifier); switch (tiling) { case I915_TILING_NONE: @@ -148,7 +140,7 @@ initial_plane_vma(struct drm_i915_private *i915, case I915_TILING_X: case I915_TILING_Y: obj->tiling_and_stride = - plane_config->fb->base.pitches[0] | + plane_config->fb->pitches[0] | tiling; break; default: @@ -226,7 +218,7 @@ i915_alloc_initial_plane_obj(struct drm_device *drm, { struct drm_i915_private *i915 = to_i915(drm); struct drm_mode_fb_cmd2 mode_cmd = {}; - struct drm_framebuffer *fb = &plane_config->fb->base; + struct drm_framebuffer *fb = plane_config->fb; struct i915_vma *vma; vma = initial_plane_vma(i915, plane_config); @@ -268,7 +260,7 @@ i915_initial_plane_setup(struct drm_plane_state *_plane_state, plane_state->ggtt_vma = i915_vma_get(vma); if (intel_plane_uses_fence(plane_state) && i915_vma_pin_fence(vma) == 0 && vma->fence) - plane_state->flags |= PLANE_HAS_FENCE; + plane_state->fence_id = vma->fence->id; plane_state->surf = i915_ggtt_offset(plane_state->ggtt_vma); @@ -285,7 +277,6 @@ static void i915_plane_config_fini(struct intel_initial_plane_config *plane_conf } const struct intel_display_initial_plane_interface i915_display_initial_plane_interface = { - .vblank_wait = i915_initial_plane_vblank_wait, .alloc_obj = i915_alloc_initial_plane_obj, .setup = i915_initial_plane_setup, .config_fini = i915_plane_config_fini, diff --git a/drivers/gpu/drm/i915/i915_overlay.c b/drivers/gpu/drm/i915/i915_overlay.c index c2d712bd2b0d..6de550a17756 100644 --- a/drivers/gpu/drm/i915/i915_overlay.c +++ b/drivers/gpu/drm/i915/i915_overlay.c @@ -7,6 +7,7 @@ #include #include +#include #include "gem/i915_gem_internal.h" #include "gem/i915_gem_object_frontbuffer.h" @@ -18,7 +19,6 @@ #include "i915_drv.h" #include "i915_overlay.h" #include "i915_reg.h" -#include "intel_pci_config.h" #include "display/intel_frontbuffer.h" @@ -354,11 +354,14 @@ static struct i915_vma *i915_overlay_pin_fb(struct drm_device *drm, struct drm_gem_object *obj, u32 *offset) { + struct drm_i915_private *i915 = to_i915(drm); struct drm_i915_gem_object *new_bo = to_intel_bo(obj); struct i915_gem_ww_ctx ww; struct i915_vma *vma; int ret; + atomic_inc(&i915->pending_fb_pin); + i915_gem_ww_ctx_init(&ww, true); retry: ret = i915_gem_object_lock(new_bo, &ww); @@ -373,6 +376,9 @@ static struct i915_vma *i915_overlay_pin_fb(struct drm_device *drm, goto retry; } i915_gem_ww_ctx_fini(&ww); + + atomic_dec(&i915->pending_fb_pin); + if (ret) return ERR_PTR(ret); diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index d966a00520f1..82415af47d54 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -24,6 +24,7 @@ #include #include +#include #include #include "display/intel_display_driver.h" @@ -35,7 +36,6 @@ #include "i915_drv.h" #include "i915_pci.h" #include "i915_reg.h" -#include "intel_pci_config.h" __diag_push(); __diag_ignore_all("-Woverride-init", "Allow field initialization overrides for device info"); diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 5d99b99b0c57..64e906380131 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -494,21 +494,6 @@ #define GEN7_FF_DS_SCHED_LOAD_BALANCE (0x1 << 4) /* Default */ #define GEN7_FF_DS_SCHED_HW (0x0 << 4) -#define ILK_DISPLAY_CHICKEN1 _MMIO(0x42000) -#define ILK_FBCQ_DIS REG_BIT(22) -#define ILK_PABSTRETCH_DIS REG_BIT(21) -#define ILK_SABSTRETCH_DIS REG_BIT(20) -#define IVB_PRI_STRETCH_MAX_MASK REG_GENMASK(21, 20) -#define IVB_PRI_STRETCH_MAX_X8 REG_FIELD_PREP(IVB_PRI_STRETCH_MAX_MASK, 0) -#define IVB_PRI_STRETCH_MAX_X4 REG_FIELD_PREP(IVB_PRI_STRETCH_MAX_MASK, 1) -#define IVB_PRI_STRETCH_MAX_X2 REG_FIELD_PREP(IVB_PRI_STRETCH_MAX_MASK, 2) -#define IVB_PRI_STRETCH_MAX_X1 REG_FIELD_PREP(IVB_PRI_STRETCH_MAX_MASK, 3) -#define IVB_SPR_STRETCH_MAX_MASK REG_GENMASK(19, 18) -#define IVB_SPR_STRETCH_MAX_X8 REG_FIELD_PREP(IVB_SPR_STRETCH_MAX_MASK, 0) -#define IVB_SPR_STRETCH_MAX_X4 REG_FIELD_PREP(IVB_SPR_STRETCH_MAX_MASK, 1) -#define IVB_SPR_STRETCH_MAX_X2 REG_FIELD_PREP(IVB_SPR_STRETCH_MAX_MASK, 2) -#define IVB_SPR_STRETCH_MAX_X1 REG_FIELD_PREP(IVB_SPR_STRETCH_MAX_MASK, 3) - #define DPLL_TEST _MMIO(0x606c) #define DPLLB_TEST_SDVO_DIV_1 (0 << 22) #define DPLLB_TEST_SDVO_DIV_2 (1 << 22) @@ -700,26 +685,10 @@ #define DG1_MSTR_IRQ REG_BIT(31) #define DG1_MSTR_TILE(t) REG_BIT(t) -#define ILK_DISPLAY_CHICKEN2 _MMIO(0x42004) -/* Required on all Ironlake and Sandybridge according to the B-Spec. */ -#define ILK_ELPIN_409_SELECT REG_BIT(25) -#define ILK_DPARB_GATE REG_BIT(22) -#define ILK_VSDPFD_FULL REG_BIT(21) - -#define ILK_DSPCLK_GATE_D _MMIO(0x42020) -#define ILK_VRHUNIT_CLOCK_GATE_DISABLE REG_BIT(28) -#define ILK_DPFCUNIT_CLOCK_GATE_DISABLE REG_BIT(9) -#define ILK_DPFCRUNIT_CLOCK_GATE_DISABLE REG_BIT(8) -#define ILK_DPFDUNIT_CLOCK_GATE_ENABLE REG_BIT(7) -#define ILK_DPARBUNIT_CLOCK_GATE_ENABLE REG_BIT(5) - #define IVB_CHICKEN3 _MMIO(0x4200c) #define CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE REG_BIT(5) #define CHICKEN3_DGMG_DONE_FIX_DISABLE REG_BIT(2) -#define CHICKEN_PAR2_1 _MMIO(0x42090) -#define KVM_CONFIG_CHANGE_NOTIFICATION_SELECT REG_BIT(14) - #define VLV_PMWGICZ _MMIO(0x1300a4) #define HSW_EDRAM_CAP _MMIO(0x120010) diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index 6a3a4d4244dc..afc192d9931b 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -27,7 +27,6 @@ #include #include -#include #include "display/intel_fb.h" #include "display/intel_frontbuffer.h" @@ -2333,12 +2332,3 @@ int __init i915_vma_module_init(void) return 0; } - -static int i915_vma_fence_id(const struct i915_vma *vma) -{ - return vma->fence ? vma->fence->id : -1; -} - -const struct intel_display_vma_interface i915_display_vma_interface = { - .fence_id = i915_vma_fence_id, -}; diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h index fa2d9b429db6..892306ab935d 100644 --- a/drivers/gpu/drm/i915/i915_vma.h +++ b/drivers/gpu/drm/i915/i915_vma.h @@ -476,6 +476,4 @@ int i915_vma_module_init(void); I915_SELFTEST_DECLARE(int i915_vma_get_pages(struct i915_vma *vma)); I915_SELFTEST_DECLARE(void i915_vma_put_pages(struct i915_vma *vma)); -extern const struct intel_display_vma_interface i915_display_vma_interface; - #endif diff --git a/drivers/gpu/drm/i915/intel_clock_gating.c b/drivers/gpu/drm/i915/intel_clock_gating.c index ee2489a2fbe7..86bdeb20f427 100644 --- a/drivers/gpu/drm/i915/intel_clock_gating.c +++ b/drivers/gpu/drm/i915/intel_clock_gating.c @@ -26,13 +26,11 @@ */ #include -#include #include +#include +#include -#include "display/i9xx_plane_regs.h" -#include "display/intel_display.h" -#include "display/intel_display_core.h" -#include "display/intel_display_regs.h" +#include "display/intel_display_clock_gating.h" #include "display/intel_pch.h" #include "gt/intel_engine_regs.h" #include "gt/intel_gt.h" @@ -42,43 +40,14 @@ #include "i915_drv.h" #include "i915_reg.h" #include "intel_clock_gating.h" -#include "intel_mchbar_regs.h" #include "vlv_iosf_sb.h" struct drm_i915_clock_gating_funcs { void (*init_clock_gating)(struct drm_i915_private *i915); }; -static void gen9_init_clock_gating(struct drm_i915_private *i915) -{ - if (HAS_LLC(i915)) { - /* - * WaCompressedResourceDisplayNewHashMode:skl,kbl - * Display WA #0390: skl,kbl - * - * Must match Sampler, Pixel Back End, and Media. See - * WaCompressedResourceSamplerPbeMediaNewHashMode. - */ - intel_uncore_rmw(&i915->uncore, CHICKEN_PAR1_1, 0, SKL_DE_COMPRESSED_HASH_MODE); - } - - /* See Bspec note for PSR2_CTL bit 31, Wa#828:skl,bxt,kbl,cfl */ - intel_uncore_rmw(&i915->uncore, CHICKEN_PAR1_1, 0, SKL_EDP_PSR_FIX_RDWRAP); - - /* WaEnableChickenDCPR:skl,bxt,kbl,glk,cfl */ - intel_uncore_rmw(&i915->uncore, GEN8_CHICKEN_DCPR_1, 0, MASK_WAKEMEM); - - /* - * WaFbcWakeMemOn:skl,bxt,kbl,glk,cfl - * Display WA #0859: skl,bxt,kbl,glk,cfl - */ - intel_uncore_rmw(&i915->uncore, DISP_ARB_CTL, 0, DISP_FBC_MEMORY_WAKE); -} - static void bxt_init_clock_gating(struct drm_i915_private *i915) { - gen9_init_clock_gating(i915); - /* WaDisableSDEUnitClockGating:bxt */ intel_uncore_rmw(&i915->uncore, GEN8_UCGCTL6, 0, GEN8_SDEUNIT_CLOCK_GATE_DISABLE); @@ -88,111 +57,23 @@ static void bxt_init_clock_gating(struct drm_i915_private *i915) */ intel_uncore_rmw(&i915->uncore, GEN8_UCGCTL6, 0, GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ); - /* - * Wa: Backlight PWM may stop in the asserted state, causing backlight - * to stay fully on. - */ - intel_uncore_write(&i915->uncore, GEN9_CLKGATE_DIS_0, - intel_uncore_read(&i915->uncore, GEN9_CLKGATE_DIS_0) | - PWM1_GATING_DIS | PWM2_GATING_DIS); - - /* - * Lower the display internal timeout. - * This is needed to avoid any hard hangs when DSI port PLL - * is off and a MMIO access is attempted by any privilege - * application, using batch buffers or any other means. - */ - intel_uncore_write(&i915->uncore, RM_TIMEOUT, MMIO_TIMEOUT_US(950)); - - /* - * WaFbcTurnOffFbcWatermark:bxt - * Display WA #0562: bxt - */ - intel_uncore_rmw(&i915->uncore, DISP_ARB_CTL, 0, DISP_FBC_WM_DIS); + intel_display_bxt_init_clock_gating(i915->display); } static void glk_init_clock_gating(struct drm_i915_private *i915) { - gen9_init_clock_gating(i915); - - /* - * WaDisablePWMClockGating:glk - * Backlight PWM may stop in the asserted state, causing backlight - * to stay fully on. - */ - intel_uncore_write(&i915->uncore, GEN9_CLKGATE_DIS_0, - intel_uncore_read(&i915->uncore, GEN9_CLKGATE_DIS_0) | - PWM1_GATING_DIS | PWM2_GATING_DIS); -} - -static void g4x_disable_trickle_feed(struct drm_i915_private *dev_priv) -{ - struct intel_display *display = dev_priv->display; - enum pipe pipe; - - for_each_pipe(display, pipe) { - intel_uncore_rmw(&dev_priv->uncore, DSPCNTR(display, pipe), - 0, DISP_TRICKLE_FEED_DISABLE); - - intel_uncore_rmw(&dev_priv->uncore, DSPSURF(display, pipe), - 0, 0); - intel_uncore_posting_read(&dev_priv->uncore, - DSPSURF(display, pipe)); - } + intel_display_glk_init_clock_gating(i915->display); } static void ilk_init_clock_gating(struct drm_i915_private *i915) { - u32 dspclk_gate = ILK_VRHUNIT_CLOCK_GATE_DISABLE; - - /* - * Required for FBC - * WaFbcDisableDpfcClockGating:ilk - */ - dspclk_gate |= ILK_DPFCRUNIT_CLOCK_GATE_DISABLE | - ILK_DPFCUNIT_CLOCK_GATE_DISABLE | - ILK_DPFDUNIT_CLOCK_GATE_ENABLE; - intel_uncore_write(&i915->uncore, PCH_3DCGDIS0, MARIUNIT_CLOCK_GATE_DISABLE | SVSMUNIT_CLOCK_GATE_DISABLE); intel_uncore_write(&i915->uncore, PCH_3DCGDIS1, VFMUNIT_CLOCK_GATE_DISABLE); - /* - * According to the spec the following bits should be set in - * order to enable memory self-refresh - * The bit 22/21 of 0x42004 - * The bit 5 of 0x42020 - * The bit 15 of 0x45000 - */ - intel_uncore_write(&i915->uncore, ILK_DISPLAY_CHICKEN2, - (intel_uncore_read(&i915->uncore, ILK_DISPLAY_CHICKEN2) | - ILK_DPARB_GATE | ILK_VSDPFD_FULL)); - dspclk_gate |= ILK_DPARBUNIT_CLOCK_GATE_ENABLE; - intel_uncore_write(&i915->uncore, DISP_ARB_CTL, - (intel_uncore_read(&i915->uncore, DISP_ARB_CTL) | - DISP_FBC_WM_DIS)); - - /* - * Based on the document from hardware guys the following bits - * should be set unconditionally in order to enable FBC. - * The bit 22 of 0x42000 - * The bit 22 of 0x42004 - * The bit 7,8,9 of 0x42020. - */ - if (IS_IRONLAKE_M(i915)) { - /* WaFbcAsynchFlipDisableFbcQueue:ilk */ - intel_uncore_rmw(&i915->uncore, ILK_DISPLAY_CHICKEN1, 0, ILK_FBCQ_DIS); - intel_uncore_rmw(&i915->uncore, ILK_DISPLAY_CHICKEN2, 0, ILK_DPARB_GATE); - } - - intel_uncore_write(&i915->uncore, ILK_DSPCLK_GATE_D, dspclk_gate); - - intel_uncore_rmw(&i915->uncore, ILK_DISPLAY_CHICKEN2, 0, ILK_ELPIN_409_SELECT); - - g4x_disable_trickle_feed(i915); - + intel_display_ilk_init_clock_gating(i915->display); intel_pch_init_clock_gating(i915->display); } @@ -209,11 +90,7 @@ static void gen6_check_mch_setup(struct drm_i915_private *i915) static void gen6_init_clock_gating(struct drm_i915_private *i915) { - u32 dspclk_gate = ILK_VRHUNIT_CLOCK_GATE_DISABLE; - - intel_uncore_write(&i915->uncore, ILK_DSPCLK_GATE_D, dspclk_gate); - - intel_uncore_rmw(&i915->uncore, ILK_DISPLAY_CHICKEN2, 0, ILK_ELPIN_409_SELECT); + intel_display_gen6_init_clock_gating(i915->display); intel_uncore_write(&i915->uncore, GEN6_UCGCTL1, intel_uncore_read(&i915->uncore, GEN6_UCGCTL1) | @@ -248,19 +125,6 @@ static void gen6_init_clock_gating(struct drm_i915_private *i915) * * WaFbcAsynchFlipDisableFbcQueue:snb */ - intel_uncore_write(&i915->uncore, ILK_DISPLAY_CHICKEN1, - intel_uncore_read(&i915->uncore, ILK_DISPLAY_CHICKEN1) | - ILK_FBCQ_DIS | ILK_PABSTRETCH_DIS); - intel_uncore_write(&i915->uncore, ILK_DISPLAY_CHICKEN2, - intel_uncore_read(&i915->uncore, ILK_DISPLAY_CHICKEN2) | - ILK_DPARB_GATE | ILK_VSDPFD_FULL); - intel_uncore_write(&i915->uncore, ILK_DSPCLK_GATE_D, - intel_uncore_read(&i915->uncore, ILK_DSPCLK_GATE_D) | - ILK_DPARBUNIT_CLOCK_GATE_ENABLE | - ILK_DPFDUNIT_CLOCK_GATE_ENABLE); - - g4x_disable_trickle_feed(i915); - intel_pch_init_clock_gating(i915->display); gen6_check_mch_setup(i915); @@ -302,22 +166,15 @@ static void dg2_init_clock_gating(struct drm_i915_private *i915) static void cfl_init_clock_gating(struct drm_i915_private *i915) { intel_pch_init_clock_gating(i915->display); - gen9_init_clock_gating(i915); /* WAC6entrylatency:cfl */ intel_uncore_rmw(&i915->uncore, FBC_LLC_READ_CTRL, 0, FBC_LLC_FULLY_OPEN); - /* - * WaFbcTurnOffFbcWatermark:cfl - * Display WA #0562: cfl - */ - intel_uncore_rmw(&i915->uncore, DISP_ARB_CTL, 0, DISP_FBC_WM_DIS); + intel_display_cfl_init_clock_gating(i915->display); } static void kbl_init_clock_gating(struct drm_i915_private *i915) { - gen9_init_clock_gating(i915); - /* WAC6entrylatency:kbl */ intel_uncore_rmw(&i915->uncore, FBC_LLC_READ_CTRL, 0, FBC_LLC_FULLY_OPEN); @@ -331,17 +188,11 @@ static void kbl_init_clock_gating(struct drm_i915_private *i915) intel_uncore_rmw(&i915->uncore, GEN6_UCGCTL1, 0, GEN6_GAMUNIT_CLOCK_GATE_DISABLE); - /* - * WaFbcTurnOffFbcWatermark:kbl - * Display WA #0562: kbl - */ - intel_uncore_rmw(&i915->uncore, DISP_ARB_CTL, 0, DISP_FBC_WM_DIS); + intel_display_kbl_init_clock_gating(i915->display); } static void skl_init_clock_gating(struct drm_i915_private *i915) { - gen9_init_clock_gating(i915); - /* WaDisableDopClockGating:skl */ intel_uncore_rmw(&i915->uncore, GEN7_MISCCPCTL, GEN7_DOP_CLOCK_GATE_ENABLE, 0); @@ -349,32 +200,17 @@ static void skl_init_clock_gating(struct drm_i915_private *i915) /* WAC6entrylatency:skl */ intel_uncore_rmw(&i915->uncore, FBC_LLC_READ_CTRL, 0, FBC_LLC_FULLY_OPEN); - /* - * WaFbcTurnOffFbcWatermark:skl - * Display WA #0562: skl - */ - intel_uncore_rmw(&i915->uncore, DISP_ARB_CTL, 0, DISP_FBC_WM_DIS); + intel_display_skl_init_clock_gating(i915->display); } static void bdw_init_clock_gating(struct drm_i915_private *i915) { - struct intel_display *display = i915->display; - enum pipe pipe; - - /* WaFbcAsynchFlipDisableFbcQueue:hsw,bdw */ - intel_uncore_rmw(&i915->uncore, CHICKEN_PIPESL_1(PIPE_A), 0, HSW_FBCQ_DIS); + intel_display_bdw_clock_gating_disable_fbcq(i915->display); /* WaSwitchSolVfFArbitrationPriority:bdw */ intel_uncore_rmw(&i915->uncore, GAM_ECOCHK, 0, HSW_ECOCHK_ARB_PRIO_SOL); - /* WaPsrDPAMaskVBlankInSRD:bdw */ - intel_uncore_rmw(&i915->uncore, CHICKEN_PAR1_1, 0, HSW_MASK_VBL_TO_PIPE_IN_SRD); - - for_each_pipe(display, pipe) { - /* WaPsrDPRSUnmaskVBlankInSRD:bdw */ - intel_uncore_rmw(&i915->uncore, CHICKEN_PIPESL_1(pipe), - 0, BDW_UNMASK_VBL_TO_REGS_IN_SRD); - } + intel_display_bdw_clock_gating_vblank_in_srd(i915->display); /* WaVSRefCountFullforceMissDisable:bdw */ /* WaDSRefCountFullforceMissDisable:bdw */ @@ -390,9 +226,7 @@ static void bdw_init_clock_gating(struct drm_i915_private *i915) /* WaProgramL3SqcReg1Default:bdw */ gen8_set_l3sqc_credits(i915, 30, 2); - /* WaKVMNotificationOnConfigChange:bdw */ - intel_uncore_rmw(&i915->uncore, CHICKEN_PAR2_1, - 0, KVM_CONFIG_CHANGE_NOTIFICATION_SELECT); + intel_display_bdw_clock_gating_kvm_notif(i915->display); intel_pch_init_clock_gating(i915->display); @@ -406,20 +240,7 @@ static void bdw_init_clock_gating(struct drm_i915_private *i915) static void hsw_init_clock_gating(struct drm_i915_private *i915) { - struct intel_display *display = i915->display; - enum pipe pipe; - - /* WaFbcAsynchFlipDisableFbcQueue:hsw,bdw */ - intel_uncore_rmw(&i915->uncore, CHICKEN_PIPESL_1(PIPE_A), 0, HSW_FBCQ_DIS); - - /* WaPsrDPAMaskVBlankInSRD:hsw */ - intel_uncore_rmw(&i915->uncore, CHICKEN_PAR1_1, 0, HSW_MASK_VBL_TO_PIPE_IN_SRD); - - for_each_pipe(display, pipe) { - /* WaPsrDPRSUnmaskVBlankInSRD:hsw */ - intel_uncore_rmw(&i915->uncore, CHICKEN_PIPESL_1(pipe), - 0, HSW_UNMASK_VBL_TO_REGS_IN_SRD); - } + intel_display_hsw_init_clock_gating(i915->display); /* This is required by WaCatErrorRejectionIssue:hsw */ intel_uncore_rmw(&i915->uncore, GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, @@ -435,10 +256,7 @@ static void ivb_init_clock_gating(struct drm_i915_private *i915) { struct intel_display *display = i915->display; - intel_uncore_write(&i915->uncore, ILK_DSPCLK_GATE_D, ILK_VRHUNIT_CLOCK_GATE_DISABLE); - - /* WaFbcAsynchFlipDisableFbcQueue:ivb */ - intel_uncore_rmw(&i915->uncore, ILK_DISPLAY_CHICKEN1, 0, ILK_FBCQ_DIS); + intel_display_ivb_init_clock_gating(display); /* WaDisableBackToBackFlipFix:ivb */ intel_uncore_write(&i915->uncore, IVB_CHICKEN3, @@ -467,13 +285,12 @@ static void ivb_init_clock_gating(struct drm_i915_private *i915) intel_uncore_rmw(&i915->uncore, GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, 0, GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); - g4x_disable_trickle_feed(i915); + intel_display_disable_trickle_feed(display); intel_uncore_rmw(&i915->uncore, GEN6_MBCUNIT_SNPCR, GEN6_MBC_SNPCR_MASK, GEN6_MBC_SNPCR_MED); - if (!HAS_PCH_NOP(display)) - intel_pch_init_clock_gating(display); + intel_pch_init_clock_gating(display); gen6_check_mch_setup(i915); } @@ -540,21 +357,12 @@ static void chv_init_clock_gating(struct drm_i915_private *i915) static void g4x_init_clock_gating(struct drm_i915_private *i915) { - u32 dspclk_gate; - intel_uncore_write(&i915->uncore, RENCLK_GATE_D1, 0); intel_uncore_write(&i915->uncore, RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE | GS_UNIT_CLOCK_GATE_DISABLE | CL_UNIT_CLOCK_GATE_DISABLE); intel_uncore_write(&i915->uncore, RAMCLK_GATE_D, 0); - dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE | - OVRUNIT_CLOCK_GATE_DISABLE | - OVCUNIT_CLOCK_GATE_DISABLE; - if (IS_GM45(i915)) - dspclk_gate |= DSSUNIT_CLOCK_GATE_DISABLE; - intel_uncore_write(&i915->uncore, DSPCLK_GATE_D, dspclk_gate); - - g4x_disable_trickle_feed(i915); + intel_display_g4x_init_clock_gating(i915->display); } static void i965gm_init_clock_gating(struct drm_i915_private *i915) @@ -563,7 +371,7 @@ static void i965gm_init_clock_gating(struct drm_i915_private *i915) intel_uncore_write(uncore, RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE); intel_uncore_write(uncore, RENCLK_GATE_D2, 0); - intel_uncore_write(uncore, DSPCLK_GATE_D, 0); + intel_display_i965gm_init_clock_gating(i915->display); intel_uncore_write(uncore, RAMCLK_GATE_D, 0); intel_uncore_write16(uncore, DEUC, 0); intel_uncore_write(uncore, diff --git a/drivers/gpu/drm/i915/intel_gvt_mmio_table.c b/drivers/gpu/drm/i915/intel_gvt_mmio_table.c index ae42818ab6e0..de118fae0a49 100644 --- a/drivers/gpu/drm/i915/intel_gvt_mmio_table.c +++ b/drivers/gpu/drm/i915/intel_gvt_mmio_table.c @@ -7,6 +7,7 @@ #include #include +#include #include "display/bxt_dpio_phy_regs.h" #include "display/i9xx_plane_regs.h" @@ -44,7 +45,6 @@ #include "i915_pvinfo.h" #include "i915_reg.h" #include "intel_gvt.h" -#include "intel_mchbar_regs.h" #define MMIO_F(reg, s) do { \ int ret; \ diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c index 27dc0e40a8d7..796c9b070e41 100644 --- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c +++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c @@ -277,6 +277,7 @@ void mock_destroy_device(struct drm_i915_private *i915) struct device *dev = i915->drm.dev; intel_display_device_remove(i915->display); + i915->display = NULL; devres_release_group(dev, NULL); put_device(dev); diff --git a/drivers/gpu/drm/i915/vlv_iosf_sb.c b/drivers/gpu/drm/i915/vlv_iosf_sb.c index 38a75651b0dc..1f0332b4ad0d 100644 --- a/drivers/gpu/drm/i915/vlv_iosf_sb.c +++ b/drivers/gpu/drm/i915/vlv_iosf_sb.c @@ -4,6 +4,7 @@ */ #include +#include #include "i915_drv.h" #include "i915_iosf_mbi.h" @@ -229,3 +230,10 @@ void vlv_iosf_sb_fini(struct drm_i915_private *i915) if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) mutex_destroy(&i915->vlv_iosf_sb.lock); } + +const struct intel_display_vlv_iosf_interface i915_display_vlv_iosf_interface = { + .get = vlv_iosf_sb_get, + .put = vlv_iosf_sb_put, + .read = vlv_iosf_sb_read, + .write = vlv_iosf_sb_write, +}; diff --git a/drivers/gpu/drm/i915/vlv_iosf_sb.h b/drivers/gpu/drm/i915/vlv_iosf_sb.h index e2fea29a30ea..8129ba11c750 100644 --- a/drivers/gpu/drm/i915/vlv_iosf_sb.h +++ b/drivers/gpu/drm/i915/vlv_iosf_sb.h @@ -8,23 +8,11 @@ #include -#include "vlv_iosf_sb_reg.h" +#include struct drm_device; struct drm_i915_private; -enum vlv_iosf_sb_unit { - VLV_IOSF_SB_BUNIT, - VLV_IOSF_SB_CCK, - VLV_IOSF_SB_CCU, - VLV_IOSF_SB_DPIO, - VLV_IOSF_SB_DPIO_2, - VLV_IOSF_SB_FLISDSI, - VLV_IOSF_SB_GPIO, - VLV_IOSF_SB_NC, - VLV_IOSF_SB_PUNIT, -}; - void vlv_iosf_sb_init(struct drm_i915_private *i915); void vlv_iosf_sb_fini(struct drm_i915_private *i915); @@ -34,4 +22,6 @@ void vlv_iosf_sb_put(struct drm_device *drm, unsigned long unit_mask); u32 vlv_iosf_sb_read(struct drm_device *drm, enum vlv_iosf_sb_unit unit, u32 addr); int vlv_iosf_sb_write(struct drm_device *drm, enum vlv_iosf_sb_unit unit, u32 addr, u32 val); +extern const struct intel_display_vlv_iosf_interface i915_display_vlv_iosf_interface; + #endif /* _VLV_IOSF_SB_H_ */ diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile index bd1697733335..09661f079d03 100644 --- a/drivers/gpu/drm/xe/Makefile +++ b/drivers/gpu/drm/xe/Makefile @@ -216,7 +216,6 @@ $(obj)/i915-display/%.o: $(srctree)/drivers/gpu/drm/i915/display/%.c FORCE # Display code specific to xe xe-$(CONFIG_DRM_XE_DISPLAY) += \ - display/intel_fbdev_fb.o \ display/xe_display.o \ display/xe_display_bo.o \ display/xe_display_pcode.o \ @@ -266,6 +265,7 @@ xe-$(CONFIG_DRM_XE_DISPLAY) += \ i915-display/intel_display_power.o \ i915-display/intel_display_power_map.o \ i915-display/intel_display_power_well.o \ + i915-display/intel_display_reset.o \ i915-display/intel_display_rpm.o \ i915-display/intel_display_rps.o \ i915-display/intel_display_trace.o \ @@ -309,6 +309,7 @@ xe-$(CONFIG_DRM_XE_DISPLAY) += \ i915-display/intel_link_bw.o \ i915-display/intel_lspcon.o \ i915-display/intel_lt_phy.o \ + i915-display/intel_mchbar.o \ i915-display/intel_modeset_lock.o \ i915-display/intel_modeset_setup.o \ i915-display/intel_modeset_verify.o \ @@ -335,7 +336,8 @@ xe-$(CONFIG_DRM_XE_DISPLAY) += \ i915-display/skl_prefill.o \ i915-display/skl_scaler.o \ i915-display/skl_universal_plane.o \ - i915-display/skl_watermark.o + i915-display/skl_watermark.o \ + i915-display/vlv_sideband.o ifeq ($(CONFIG_ACPI),y) xe-$(CONFIG_DRM_XE_DISPLAY) += \ diff --git a/drivers/gpu/drm/xe/compat-i915-headers/intel_clock_gating.h b/drivers/gpu/drm/xe/compat-i915-headers/intel_clock_gating.h index ce986f0e8f38..552975a30ba2 100644 --- a/drivers/gpu/drm/xe/compat-i915-headers/intel_clock_gating.h +++ b/drivers/gpu/drm/xe/compat-i915-headers/intel_clock_gating.h @@ -3,4 +3,12 @@ * Copyright © 2023 Intel Corporation */ -#include "../../i915/intel_clock_gating.h" +#ifndef __INTEL_CLOCK_GATING_H__ +#define __INTEL_CLOCK_GATING_H__ + +struct drm_device; + +static inline void intel_clock_gating_init(struct drm_device *drm) {} +static inline void intel_clock_gating_hooks_init(struct drm_device *drm) {} + +#endif /* __INTEL_CLOCK_GATING_H__ */ diff --git a/drivers/gpu/drm/xe/compat-i915-headers/intel_mchbar_regs.h b/drivers/gpu/drm/xe/compat-i915-headers/intel_mchbar_regs.h deleted file mode 100644 index 55b316985340..000000000000 --- a/drivers/gpu/drm/xe/compat-i915-headers/intel_mchbar_regs.h +++ /dev/null @@ -1,6 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * Copyright © 2023 Intel Corporation - */ - -#include "../../i915/intel_mchbar_regs.h" diff --git a/drivers/gpu/drm/xe/compat-i915-headers/intel_pci_config.h b/drivers/gpu/drm/xe/compat-i915-headers/intel_pci_config.h deleted file mode 100644 index 8c15867fd613..000000000000 --- a/drivers/gpu/drm/xe/compat-i915-headers/intel_pci_config.h +++ /dev/null @@ -1,6 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * Copyright © 2023 Intel Corporation - */ - -#include "../../i915/intel_pci_config.h" diff --git a/drivers/gpu/drm/xe/compat-i915-headers/vlv_iosf_sb.h b/drivers/gpu/drm/xe/compat-i915-headers/vlv_iosf_sb.h deleted file mode 100644 index 69e1935e9cdf..000000000000 --- a/drivers/gpu/drm/xe/compat-i915-headers/vlv_iosf_sb.h +++ /dev/null @@ -1,42 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * Copyright © 2013-2021 Intel Corporation - */ - -#ifndef _VLV_IOSF_SB_H_ -#define _VLV_IOSF_SB_H_ - -#include - -#include "vlv_iosf_sb_reg.h" - -struct drm_device; - -enum vlv_iosf_sb_unit { - VLV_IOSF_SB_BUNIT, - VLV_IOSF_SB_CCK, - VLV_IOSF_SB_CCU, - VLV_IOSF_SB_DPIO, - VLV_IOSF_SB_DPIO_2, - VLV_IOSF_SB_FLISDSI, - VLV_IOSF_SB_GPIO, - VLV_IOSF_SB_NC, - VLV_IOSF_SB_PUNIT, -}; - -static inline void vlv_iosf_sb_get(struct drm_device *drm, unsigned long ports) -{ -} -static inline u32 vlv_iosf_sb_read(struct drm_device *drm, enum vlv_iosf_sb_unit unit, u32 addr) -{ - return 0; -} -static inline int vlv_iosf_sb_write(struct drm_device *drm, enum vlv_iosf_sb_unit unit, u32 addr, u32 val) -{ - return 0; -} -static inline void vlv_iosf_sb_put(struct drm_device *drm, unsigned long ports) -{ -} - -#endif /* _VLV_IOSF_SB_H_ */ diff --git a/drivers/gpu/drm/xe/compat-i915-headers/vlv_iosf_sb_reg.h b/drivers/gpu/drm/xe/compat-i915-headers/vlv_iosf_sb_reg.h deleted file mode 100644 index cb7fa8e794a6..000000000000 --- a/drivers/gpu/drm/xe/compat-i915-headers/vlv_iosf_sb_reg.h +++ /dev/null @@ -1,6 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * Copyright © 2023 Intel Corporation - */ - -#include "../../i915/vlv_iosf_sb_reg.h" diff --git a/drivers/gpu/drm/xe/display/intel_fbdev_fb.c b/drivers/gpu/drm/xe/display/intel_fbdev_fb.c deleted file mode 100644 index d7030e4d814c..000000000000 --- a/drivers/gpu/drm/xe/display/intel_fbdev_fb.c +++ /dev/null @@ -1,120 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * Copyright © 2023 Intel Corporation - */ - -#include - -#include "intel_fbdev_fb.h" -#include "xe_bo.h" -#include "xe_ttm_stolen_mgr.h" -#include "xe_wa.h" - -#include - -/* - * FIXME: There shouldn't be any reason to have XE_PAGE_SIZE stride - * alignment. The same 64 as i915 uses should be fine, and we shouldn't need to - * have driver specific values. However, dropping the stride alignment to 64 - * leads to underflowing the bo pin count in the atomic cleanup work. - */ -u32 intel_fbdev_fb_pitch_align(u32 stride) -{ - return ALIGN(stride, XE_PAGE_SIZE); -} - -bool intel_fbdev_fb_prefer_stolen(struct drm_device *drm, unsigned int size) -{ - struct xe_device *xe = to_xe_device(drm); - struct ttm_resource_manager *stolen; - - stolen = ttm_manager_type(&xe->ttm, XE_PL_STOLEN); - if (!stolen) - return false; - - if (IS_DGFX(xe)) - return false; - - if (XE_DEVICE_WA(xe, 22019338487_display)) - return false; - - /* - * If the FB is too big, just don't use it since fbdev is not very - * important and we should probably use that space with FBC or other - * features. - */ - return stolen->size >= size * 2; -} - -struct drm_gem_object *intel_fbdev_fb_bo_create(struct drm_device *drm, int size) -{ - struct xe_device *xe = to_xe_device(drm); - struct xe_bo *obj; - - obj = ERR_PTR(-ENODEV); - - if (intel_fbdev_fb_prefer_stolen(drm, size)) { - obj = xe_bo_create_pin_map_novm(xe, xe_device_get_root_tile(xe), - size, - ttm_bo_type_kernel, - XE_BO_FLAG_FORCE_WC | - XE_BO_FLAG_STOLEN | - XE_BO_FLAG_GGTT, - false); - if (!IS_ERR(obj)) - drm_info(&xe->drm, "Allocated fbdev into stolen\n"); - else - drm_info(&xe->drm, "Allocated fbdev into stolen failed: %li\n", PTR_ERR(obj)); - } else { - drm_info(&xe->drm, "Allocating fbdev: Stolen memory not preferred.\n"); - } - - if (IS_ERR(obj)) { - obj = xe_bo_create_pin_map_novm(xe, xe_device_get_root_tile(xe), size, - ttm_bo_type_kernel, - XE_BO_FLAG_FORCE_WC | - XE_BO_FLAG_VRAM_IF_DGFX(xe_device_get_root_tile(xe)) | - XE_BO_FLAG_GGTT, - false); - } - - if (IS_ERR(obj)) { - drm_err(&xe->drm, "failed to allocate framebuffer (%pe)\n", obj); - return ERR_PTR(-ENOMEM); - } - - return &obj->ttm.base; -} - -void intel_fbdev_fb_bo_destroy(struct drm_gem_object *obj) -{ - xe_bo_unpin_map_no_vm(gem_to_xe_bo(obj)); -} - -int intel_fbdev_fb_fill_info(struct drm_device *drm, struct fb_info *info, - struct drm_gem_object *_obj, struct i915_vma *vma) -{ - struct xe_bo *obj = gem_to_xe_bo(_obj); - struct pci_dev *pdev = to_pci_dev(drm->dev); - - if (!(obj->flags & XE_BO_FLAG_SYSTEM)) { - if (obj->flags & XE_BO_FLAG_STOLEN) - info->fix.smem_start = xe_ttm_stolen_io_offset(obj, 0); - else - info->fix.smem_start = - pci_resource_start(pdev, 2) + - xe_bo_addr(obj, 0, XE_PAGE_SIZE); - - info->fix.smem_len = obj->ttm.base.size; - } else { - /* XXX: Pure fiction, as the BO may not be physically accessible.. */ - info->fix.smem_start = 0; - info->fix.smem_len = obj->ttm.base.size; - } - XE_WARN_ON(iosys_map_is_null(&obj->vmap)); - - info->screen_base = obj->vmap.vaddr_iomem; - info->screen_size = obj->ttm.base.size; - - return 0; -} diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c index 00dfa68af29a..0747044f7c2a 100644 --- a/drivers/gpu/drm/xe/display/xe_display.c +++ b/drivers/gpu/drm/xe/display/xe_display.c @@ -520,9 +520,10 @@ void xe_display_pm_runtime_resume(struct xe_device *xe) static void display_device_remove(struct drm_device *dev, void *arg) { - struct intel_display *display = arg; + struct xe_device *xe = arg; - intel_display_device_remove(display); + intel_display_device_remove(xe->display); + xe->display = NULL; } static bool irq_enabled(struct drm_device *drm) @@ -587,12 +588,12 @@ int xe_display_probe(struct xe_device *xe) if (IS_ERR(display)) return PTR_ERR(display); - err = drmm_add_action_or_reset(&xe->drm, display_device_remove, display); + xe->display = display; + + err = drmm_add_action_or_reset(&xe->drm, display_device_remove, xe); if (err) return err; - xe->display = display; - if (intel_display_device_present(display)) return 0; diff --git a/drivers/gpu/drm/xe/display/xe_display_bo.c b/drivers/gpu/drm/xe/display/xe_display_bo.c index 1d81b9908265..dc0d78ff2d79 100644 --- a/drivers/gpu/drm/xe/display/xe_display_bo.c +++ b/drivers/gpu/drm/xe/display/xe_display_bo.c @@ -1,6 +1,8 @@ // SPDX-License-Identifier: MIT /* Copyright © 2024 Intel Corporation */ +#include + #include #include @@ -8,6 +10,10 @@ #include "xe_bo.h" #include "xe_display_bo.h" #include "xe_pxp.h" +#include "xe_ttm_stolen_mgr.h" +#include "xe_wa.h" + +#include static bool xe_display_bo_is_protected(struct drm_gem_object *obj) { @@ -101,6 +107,114 @@ xe_display_bo_framebuffer_lookup(struct drm_device *drm, return gem; } +#if IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION) +/* + * FIXME: There shouldn't be any reason to have XE_PAGE_SIZE stride + * alignment. The same 64 as i915 uses should be fine, and we shouldn't need to + * have driver specific values. However, dropping the stride alignment to 64 + * leads to underflowing the bo pin count in the atomic cleanup work. + */ +static u32 xe_display_bo_fbdev_pitch_align(u32 stride) +{ + return ALIGN(stride, XE_PAGE_SIZE); +} + +bool xe_display_bo_fbdev_prefer_stolen(struct xe_device *xe, unsigned int size) +{ + struct ttm_resource_manager *stolen; + + stolen = ttm_manager_type(&xe->ttm, XE_PL_STOLEN); + if (!stolen) + return false; + + if (IS_DGFX(xe)) + return false; + + if (XE_DEVICE_WA(xe, 22019338487_display)) + return false; + + /* + * If the FB is too big, just don't use it since fbdev is not very + * important and we should probably use that space with FBC or other + * features. + */ + return stolen->size >= size * 2; +} + +static struct drm_gem_object *xe_display_bo_fbdev_create(struct drm_device *drm, int size) +{ + struct xe_device *xe = to_xe_device(drm); + struct xe_bo *obj; + + obj = ERR_PTR(-ENODEV); + + if (xe_display_bo_fbdev_prefer_stolen(xe, size)) { + obj = xe_bo_create_pin_map_novm(xe, xe_device_get_root_tile(xe), + size, + ttm_bo_type_kernel, + XE_BO_FLAG_FORCE_WC | + XE_BO_FLAG_STOLEN | + XE_BO_FLAG_GGTT, + false); + if (!IS_ERR(obj)) + drm_info(&xe->drm, "Allocated fbdev into stolen\n"); + else + drm_info(&xe->drm, "Allocated fbdev into stolen failed: %li\n", PTR_ERR(obj)); + } else { + drm_info(&xe->drm, "Allocating fbdev: Stolen memory not preferred.\n"); + } + + if (IS_ERR(obj)) { + obj = xe_bo_create_pin_map_novm(xe, xe_device_get_root_tile(xe), size, + ttm_bo_type_kernel, + XE_BO_FLAG_FORCE_WC | + XE_BO_FLAG_VRAM_IF_DGFX(xe_device_get_root_tile(xe)) | + XE_BO_FLAG_GGTT, + false); + } + + if (IS_ERR(obj)) { + drm_err(&xe->drm, "failed to allocate framebuffer (%pe)\n", obj); + return ERR_PTR(-ENOMEM); + } + + return &obj->ttm.base; +} + +static void xe_display_bo_fbdev_destroy(struct drm_gem_object *obj) +{ + xe_bo_unpin_map_no_vm(gem_to_xe_bo(obj)); +} + +static int xe_display_bo_fbdev_fill_info(struct drm_gem_object *_obj, struct fb_info *info, + struct i915_vma *vma) +{ + struct xe_bo *obj = gem_to_xe_bo(_obj); + struct pci_dev *pdev = to_pci_dev(_obj->dev->dev); + + if (!(obj->flags & XE_BO_FLAG_SYSTEM)) { + if (obj->flags & XE_BO_FLAG_STOLEN) + info->fix.smem_start = xe_ttm_stolen_io_offset(obj, 0); + else + info->fix.smem_start = + pci_resource_start(pdev, 2) + + xe_bo_addr(obj, 0, XE_PAGE_SIZE); + + info->fix.smem_len = obj->ttm.base.size; + } else { + /* XXX: Pure fiction, as the BO may not be physically accessible.. */ + info->fix.smem_start = 0; + info->fix.smem_len = obj->ttm.base.size; + } + XE_WARN_ON(iosys_map_is_null(&obj->vmap)); + + info->screen_base = obj->vmap.vaddr_iomem; + info->screen_size = obj->ttm.base.size; + + return 0; +} +#endif + const struct intel_display_bo_interface xe_display_bo_interface = { .is_protected = xe_display_bo_is_protected, .key_check = xe_pxp_obj_key_check, @@ -109,4 +223,10 @@ const struct intel_display_bo_interface xe_display_bo_interface = { .framebuffer_init = xe_display_bo_framebuffer_init, .framebuffer_fini = xe_display_bo_framebuffer_fini, .framebuffer_lookup = xe_display_bo_framebuffer_lookup, +#if IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION) + .fbdev_create = xe_display_bo_fbdev_create, + .fbdev_destroy = xe_display_bo_fbdev_destroy, + .fbdev_fill_info = xe_display_bo_fbdev_fill_info, + .fbdev_pitch_align = xe_display_bo_fbdev_pitch_align, +#endif }; diff --git a/drivers/gpu/drm/xe/display/xe_display_bo.h b/drivers/gpu/drm/xe/display/xe_display_bo.h index 6879c104b0b1..c72056884ff4 100644 --- a/drivers/gpu/drm/xe/display/xe_display_bo.h +++ b/drivers/gpu/drm/xe/display/xe_display_bo.h @@ -4,6 +4,12 @@ #ifndef __XE_DISPLAY_BO_H__ #define __XE_DISPLAY_BO_H__ +#include + +struct xe_device; + +bool xe_display_bo_fbdev_prefer_stolen(struct xe_device *xe, unsigned int size); + extern const struct intel_display_bo_interface xe_display_bo_interface; #endif diff --git a/drivers/gpu/drm/xe/display/xe_fb_pin.c b/drivers/gpu/drm/xe/display/xe_fb_pin.c index d670a3cf1b84..948446346c53 100644 --- a/drivers/gpu/drm/xe/display/xe_fb_pin.c +++ b/drivers/gpu/drm/xe/display/xe_fb_pin.c @@ -140,22 +140,21 @@ write_dpt_remapped(struct xe_bo *bo, } } -static int __xe_pin_fb_vma_dpt(const struct intel_framebuffer *fb, - const struct i915_gtt_view *view, - struct i915_vma *vma, - unsigned int alignment) +static int __xe_pin_fb_vma_dpt(struct drm_gem_object *obj, + const struct intel_fb_pin_params *pin_params, + struct i915_vma *vma) { - struct xe_device *xe = to_xe_device(fb->base.dev); + struct xe_device *xe = to_xe_device(obj->dev); struct xe_tile *tile0 = xe_device_get_root_tile(xe); struct xe_ggtt *ggtt = tile0->mem.ggtt; - struct drm_gem_object *obj = intel_fb_bo(&fb->base); + const struct i915_gtt_view *view = pin_params->view; struct xe_bo *bo = gem_to_xe_bo(obj), *dpt; u32 dpt_size, size = bo->ttm.base.size; if (view->type == I915_GTT_VIEW_NORMAL) dpt_size = ALIGN(size / XE_PAGE_SIZE * 8, XE_PAGE_SIZE); else if (view->type == I915_GTT_VIEW_REMAPPED) - dpt_size = ALIGN(intel_remapped_info_size(&fb->remapped_view.gtt.remapped) * 8, + dpt_size = ALIGN(intel_remapped_info_size(&view->remapped) * 8, XE_PAGE_SIZE); else /* display uses 4K tiles instead of bytes here, convert to entries.. */ @@ -169,7 +168,7 @@ static int __xe_pin_fb_vma_dpt(const struct intel_framebuffer *fb, XE_BO_FLAG_VRAM0 | XE_BO_FLAG_GGTT | XE_BO_FLAG_PAGETABLE, - alignment, false); + pin_params->alignment, false); else dpt = xe_bo_create_pin_map_at_novm(xe, tile0, dpt_size, ~0ull, @@ -177,7 +176,7 @@ static int __xe_pin_fb_vma_dpt(const struct intel_framebuffer *fb, XE_BO_FLAG_STOLEN | XE_BO_FLAG_GGTT | XE_BO_FLAG_PAGETABLE, - alignment, false); + pin_params->alignment, false); if (IS_ERR(dpt)) dpt = xe_bo_create_pin_map_at_novm(xe, tile0, dpt_size, ~0ull, @@ -186,7 +185,7 @@ static int __xe_pin_fb_vma_dpt(const struct intel_framebuffer *fb, XE_BO_FLAG_GGTT | XE_BO_FLAG_PAGETABLE | XE_BO_FLAG_FORCE_WC, - alignment, false); + pin_params->alignment, false); if (IS_ERR(dpt)) return PTR_ERR(dpt); @@ -269,14 +268,13 @@ static void write_ggtt_rotated_node(struct xe_ggtt *ggtt, struct xe_ggtt_node *n rot_info->plane[i].dst_stride); } -static int __xe_pin_fb_vma_ggtt(const struct intel_framebuffer *fb, - const struct i915_gtt_view *view, - struct i915_vma *vma, - unsigned int alignment) +static int __xe_pin_fb_vma_ggtt(struct drm_gem_object *obj, + const struct intel_fb_pin_params *pin_params, + struct i915_vma *vma) { - struct drm_gem_object *obj = intel_fb_bo(&fb->base); + const struct i915_gtt_view *view = pin_params->view; struct xe_bo *bo = gem_to_xe_bo(obj); - struct xe_device *xe = to_xe_device(fb->base.dev); + struct xe_device *xe = to_xe_device(obj->dev); struct xe_tile *tile0 = xe_device_get_root_tile(xe); struct xe_ggtt *ggtt = tile0->mem.ggtt; u64 pte, size; @@ -319,14 +317,11 @@ static int __xe_pin_fb_vma_ggtt(const struct intel_framebuffer *fb, return ret; } -static struct i915_vma *__xe_pin_fb_vma(const struct intel_framebuffer *fb, - const struct i915_gtt_view *view, - unsigned int alignment) +static struct i915_vma *__xe_pin_fb_vma(struct drm_gem_object *obj, bool is_dpt, + const struct intel_fb_pin_params *pin_params) { - struct drm_device *dev = fb->base.dev; - struct xe_device *xe = to_xe_device(dev); + struct xe_device *xe = to_xe_device(obj->dev); struct i915_vma *vma = kzalloc(sizeof(*vma), GFP_KERNEL); - struct drm_gem_object *obj = intel_fb_bo(&fb->base); struct xe_bo *bo = gem_to_xe_bo(obj); struct xe_validation_ctx ctx; struct drm_exec exec; @@ -337,7 +332,7 @@ static struct i915_vma *__xe_pin_fb_vma(const struct intel_framebuffer *fb, refcount_set(&vma->ref, 1); if (IS_DGFX(to_xe_device(bo->ttm.base.dev)) && - intel_fb_rc_ccs_cc_plane(&fb->base) >= 0 && + pin_params->needs_cpu_lmem_access && !(bo->flags & XE_BO_FLAG_NEEDS_CPU_ACCESS)) { struct xe_vram_region *vram = xe_device_get_root_tile(xe)->mem.vram; @@ -377,10 +372,10 @@ static struct i915_vma *__xe_pin_fb_vma(const struct intel_framebuffer *fb, goto err; vma->bo = bo; - if (intel_fb_uses_dpt(&fb->base)) - ret = __xe_pin_fb_vma_dpt(fb, view, vma, alignment); + if (is_dpt) + ret = __xe_pin_fb_vma_dpt(obj, pin_params, vma); else - ret = __xe_pin_fb_vma_ggtt(fb, view, vma, alignment); + ret = __xe_pin_fb_vma_ggtt(obj, pin_params, vma); if (ret) goto err_unpin; @@ -414,20 +409,17 @@ static void __xe_unpin_fb_vma(struct i915_vma *vma) } struct i915_vma * -intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb, - const struct i915_gtt_view *view, - unsigned int alignment, - unsigned int phys_alignment, - unsigned int vtd_guard, - bool uses_fence, - unsigned long *out_flags) +intel_fb_pin_to_ggtt(struct drm_gem_object *obj, + const struct intel_fb_pin_params *pin_params, + int *out_fence_id) { - *out_flags = 0; + if (out_fence_id) + *out_fence_id = -1; - return __xe_pin_fb_vma(to_intel_framebuffer(fb), view, alignment); + return __xe_pin_fb_vma(obj, false, pin_params); } -void intel_fb_unpin_vma(struct i915_vma *vma, unsigned long flags) +void intel_fb_unpin_vma(struct i915_vma *vma, int fence_id) { __xe_unpin_fb_vma(vma); } @@ -474,9 +466,12 @@ int intel_plane_pin_fb(struct intel_plane_state *new_plane_state, struct drm_gem_object *obj = intel_fb_bo(fb); struct xe_bo *bo = gem_to_xe_bo(obj); struct i915_vma *vma; - struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); struct intel_plane *plane = to_intel_plane(new_plane_state->uapi.plane); - unsigned int alignment = plane->min_alignment(plane, fb, 0); + struct intel_fb_pin_params pin_params = { + .view = &new_plane_state->view.gtt, + .alignment = plane->min_alignment(plane, fb, 0), + .needs_cpu_lmem_access = intel_fb_needs_cpu_access(fb), + }; if (reuse_vma(new_plane_state, old_plane_state)) return 0; @@ -484,7 +479,7 @@ int intel_plane_pin_fb(struct intel_plane_state *new_plane_state, /* We reject creating !SCANOUT fb's, so this is weird.. */ drm_WARN_ON(bo->ttm.base.dev, !(bo->flags & XE_BO_FLAG_FORCE_WC)); - vma = __xe_pin_fb_vma(intel_fb, &new_plane_state->view.gtt, alignment); + vma = __xe_pin_fb_vma(obj, intel_fb_uses_dpt(fb), &pin_params); if (IS_ERR(vma)) return PTR_ERR(vma); diff --git a/drivers/gpu/drm/xe/display/xe_initial_plane.c b/drivers/gpu/drm/xe/display/xe_initial_plane.c index 8bcae552dddc..8e3c0c4b81fe 100644 --- a/drivers/gpu/drm/xe/display/xe_initial_plane.c +++ b/drivers/gpu/drm/xe/display/xe_initial_plane.c @@ -7,34 +7,16 @@ #include "regs/xe_gtt_defs.h" -#include "intel_crtc.h" -#include "intel_display_regs.h" #include "intel_display_types.h" #include "intel_fb.h" #include "intel_fb_pin.h" -#include "intel_fbdev_fb.h" #include "xe_bo.h" +#include "xe_display_bo.h" #include "xe_display_vma.h" #include "xe_ggtt.h" #include "xe_mmio.h" #include "xe_vram_types.h" -/* Early xe has no irq */ -static void xe_initial_plane_vblank_wait(struct drm_crtc *_crtc) -{ - struct intel_crtc *crtc = to_intel_crtc(_crtc); - struct xe_device *xe = to_xe_device(crtc->base.dev); - struct xe_reg pipe_frmtmstmp = XE_REG(i915_mmio_reg_offset(PIPE_FRMTMSTMP(crtc->pipe))); - u32 timestamp; - int ret; - - timestamp = xe_mmio_read32(xe_root_tile_mmio(xe), pipe_frmtmstmp); - - ret = xe_mmio_wait32_not(xe_root_tile_mmio(xe), pipe_frmtmstmp, ~0U, timestamp, 40000U, ×tamp, false); - if (ret < 0) - drm_warn(&xe->drm, "waiting for early vblank failed with %i\n", ret); -} - static struct xe_bo * initial_plane_bo(struct xe_device *xe, struct intel_initial_plane_config *plane_config) @@ -86,7 +68,8 @@ initial_plane_bo(struct xe_device *xe, flags |= XE_BO_FLAG_STOLEN; if (IS_ENABLED(CONFIG_FRAMEBUFFER_CONSOLE) && - !intel_fbdev_fb_prefer_stolen(&xe->drm, plane_config->size)) { + IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION) && + !xe_display_bo_fbdev_prefer_stolen(xe, plane_config->size)) { drm_info(&xe->drm, "Initial FB size exceeds half of stolen, discarding\n"); return NULL; } @@ -114,7 +97,7 @@ xe_alloc_initial_plane_obj(struct drm_device *drm, { struct xe_device *xe = to_xe_device(drm); struct drm_mode_fb_cmd2 mode_cmd = { 0 }; - struct drm_framebuffer *fb = &plane_config->fb->base; + struct drm_framebuffer *fb = plane_config->fb; struct xe_bo *bo; mode_cmd.pixel_format = fb->format->format; @@ -151,9 +134,11 @@ xe_initial_plane_setup(struct drm_plane_state *_plane_state, { struct intel_plane_state *plane_state = to_intel_plane_state(_plane_state); struct i915_vma *vma; + struct intel_fb_pin_params pin_params = { + .view = &plane_state->view.gtt, + }; - vma = intel_fb_pin_to_ggtt(fb, &plane_state->view.gtt, - 0, 0, 0, false, &plane_state->flags); + vma = intel_fb_pin_to_ggtt(intel_fb_bo(fb), &pin_params, NULL); if (IS_ERR(vma)) return PTR_ERR(vma); @@ -171,7 +156,6 @@ static void xe_plane_config_fini(struct intel_initial_plane_config *plane_config } const struct intel_display_initial_plane_interface xe_display_initial_plane_interface = { - .vblank_wait = xe_initial_plane_vblank_wait, .alloc_obj = xe_alloc_initial_plane_obj, .setup = xe_initial_plane_setup, .config_fini = xe_plane_config_fini, diff --git a/include/drm/display/drm_dp_tunnel.h b/include/drm/display/drm_dp_tunnel.h index 6c565c5e66a8..57f5e90ba8fd 100644 --- a/include/drm/display/drm_dp_tunnel.h +++ b/include/drm/display/drm_dp_tunnel.h @@ -53,6 +53,7 @@ int drm_dp_tunnel_destroy(struct drm_dp_tunnel *tunnel); int drm_dp_tunnel_enable_bw_alloc(struct drm_dp_tunnel *tunnel); int drm_dp_tunnel_disable_bw_alloc(struct drm_dp_tunnel *tunnel); bool drm_dp_tunnel_bw_alloc_is_enabled(const struct drm_dp_tunnel *tunnel); +bool drm_dp_tunnel_pr_optimization_supported(const struct drm_dp_tunnel *tunnel); int drm_dp_tunnel_alloc_bw(struct drm_dp_tunnel *tunnel, int bw); int drm_dp_tunnel_get_allocated_bw(struct drm_dp_tunnel *tunnel); int drm_dp_tunnel_update_state(struct drm_dp_tunnel *tunnel); @@ -140,6 +141,11 @@ static inline bool drm_dp_tunnel_bw_alloc_is_enabled(const struct drm_dp_tunnel return false; } +static inline bool drm_dp_tunnel_pr_optimization_supported(const struct drm_dp_tunnel *tunnel) +{ + return false; +} + static inline int drm_dp_tunnel_alloc_bw(struct drm_dp_tunnel *tunnel, int bw) { diff --git a/include/drm/intel/display_parent_interface.h b/include/drm/intel/display_parent_interface.h index 97ec94a2e749..270dc028bec2 100644 --- a/include/drm/intel/display_parent_interface.h +++ b/include/drm/intel/display_parent_interface.h @@ -6,8 +6,8 @@ #include +enum vlv_iosf_sb_unit; struct dma_fence; -struct drm_crtc; struct drm_device; struct drm_file; struct drm_framebuffer; @@ -15,6 +15,7 @@ struct drm_gem_object; struct drm_mode_fb_cmd2; struct drm_plane_state; struct drm_scanout_buffer; +struct fb_info; struct i915_vma; struct intel_dpt; struct intel_dsb_buffer; @@ -43,6 +44,12 @@ struct intel_display_bo_interface { struct drm_gem_object *(*framebuffer_lookup)(struct drm_device *drm, struct drm_file *filp, const struct drm_mode_fb_cmd2 *user_mode_cmd); +#if IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION) + struct drm_gem_object *(*fbdev_create)(struct drm_device *drm, int size); + void (*fbdev_destroy)(struct drm_gem_object *obj); + int (*fbdev_fill_info)(struct drm_gem_object *obj, struct fb_info *info, struct i915_vma *vma); + u32 (*fbdev_pitch_align)(u32 stride); +#endif }; struct intel_display_dpt_interface { @@ -79,11 +86,10 @@ struct intel_display_hdcp_interface { }; struct intel_display_initial_plane_interface { - void (*vblank_wait)(struct drm_crtc *crtc); struct drm_gem_object *(*alloc_obj)(struct drm_device *drm, struct intel_initial_plane_config *plane_config); int (*setup)(struct drm_plane_state *plane_state, struct intel_initial_plane_config *plane_config, struct drm_framebuffer *fb, struct i915_vma *vma); - void (*config_fini)(struct intel_initial_plane_config *plane_configs); + void (*config_fini)(struct intel_initial_plane_config *plane_config); }; struct intel_display_irq_interface { @@ -176,8 +182,11 @@ struct intel_display_stolen_interface { void (*node_free)(const struct intel_stolen_node *node); }; -struct intel_display_vma_interface { - int (*fence_id)(const struct i915_vma *vma); +struct intel_display_vlv_iosf_interface { + void (*get)(struct drm_device *drm, unsigned long unit_mask); + void (*put)(struct drm_device *drm, unsigned long unit_mask); + u32 (*read)(struct drm_device *drm, enum vlv_iosf_sb_unit unit, u32 addr); + int (*write)(struct drm_device *drm, enum vlv_iosf_sb_unit unit, u32 addr, u32 val); }; /** @@ -235,8 +244,8 @@ struct intel_display_parent_interface { /** @stolen: Stolen memory. */ const struct intel_display_stolen_interface *stolen; - /** @vma: VMA interface. Optional. */ - const struct intel_display_vma_interface *vma; + /** @vlv_iosf: VLV IOSF sideband. Optional. */ + const struct intel_display_vlv_iosf_interface *vlv_iosf; /* Generic independent functions */ struct { diff --git a/drivers/gpu/drm/i915/intel_mchbar_regs.h b/include/drm/intel/mchbar_regs.h similarity index 98% rename from drivers/gpu/drm/i915/intel_mchbar_regs.h rename to include/drm/intel/mchbar_regs.h index 614d4017b57b..ca0d421be16c 100644 --- a/drivers/gpu/drm/i915/intel_mchbar_regs.h +++ b/include/drm/intel/mchbar_regs.h @@ -16,11 +16,16 @@ * every way. It is not accessible from the CP register read instructions. * * Starting from Haswell, you can't write registers using the MCHBAR mirror, - * just read. + * just read. On MTL+ the mirror no longer exists. */ #define MCHBAR_MIRROR_BASE 0x10000 +#define MCHBAR_MIRROR_END 0x13fff + #define MCHBAR_MIRROR_BASE_SNB 0x140000 +#define MCHBAR_MIRROR_END_SNB 0x147fff +#define MCHBAR_MIRROR_END_ICL_RKL 0x14ffff +#define MCHBAR_MIRROR_END_TGL 0x15ffff #define CTG_STOLEN_RESERVED _MMIO(MCHBAR_MIRROR_BASE + 0x34) #define ELK_STOLEN_RESERVED _MMIO(MCHBAR_MIRROR_BASE + 0x48) diff --git a/drivers/gpu/drm/i915/intel_pci_config.h b/include/drm/intel/pci_config.h similarity index 100% rename from drivers/gpu/drm/i915/intel_pci_config.h rename to include/drm/intel/pci_config.h diff --git a/drivers/gpu/drm/i915/vlv_iosf_sb_reg.h b/include/drm/intel/vlv_iosf_sb_regs.h similarity index 95% rename from drivers/gpu/drm/i915/vlv_iosf_sb_reg.h rename to include/drm/intel/vlv_iosf_sb_regs.h index f977fb3b6e17..42d1def5534b 100644 --- a/drivers/gpu/drm/i915/vlv_iosf_sb_reg.h +++ b/include/drm/intel/vlv_iosf_sb_regs.h @@ -3,8 +3,20 @@ * Copyright © 2022 Intel Corporation */ -#ifndef _VLV_IOSF_SB_REG_H_ -#define _VLV_IOSF_SB_REG_H_ +#ifndef _VLV_IOSF_SB_REGS_H_ +#define _VLV_IOSF_SB_REGS_H_ + +enum vlv_iosf_sb_unit { + VLV_IOSF_SB_BUNIT, + VLV_IOSF_SB_CCK, + VLV_IOSF_SB_CCU, + VLV_IOSF_SB_DPIO, + VLV_IOSF_SB_DPIO_2, + VLV_IOSF_SB_FLISDSI, + VLV_IOSF_SB_GPIO, + VLV_IOSF_SB_NC, + VLV_IOSF_SB_PUNIT, +}; /* See configdb bunit SB addr map */ #define BUNIT_REG_BISOC 0x11 @@ -177,4 +189,4 @@ #define CCK_FREQUENCY_STATUS_SHIFT 8 #define CCK_FREQUENCY_VALUES (0x1f << 0) -#endif /* _VLV_IOSF_SB_REG_H_ */ +#endif /* _VLV_IOSF_SB_REGS_H_ */