Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'drm-intel-next-2026-01-15' of https://gitlab.freedesktop.org/drm/i915/kernel into drm-next

Beyond Display:
- Make 'guc_hw_reg_state' static as it isn't exported (Ben)
- Fix doc build on mei related interface header (Jani)

Display related:
- Fix ggtt fb alignment on Xe display (Tvrtko)
- More display clean-up towards deduplication and full separation (Jani)
- Use the consolidated HDMI tables (Suraj)
- Account for DSC slice overhead (Ankit)
- Prepare GVT for display modularization (Ankit, Jani)
- Enable/Disable DC balance along with VRR DSB (Mitul, Ville)
- Protection against unsupported modes in LT PHY (Suraj)
- Display W/a addition and fixes (Gustavo)
- Fix many SPDX identifier comments (Ankit)
- Incorporate Xe3_LPD changes for CD2X divider (Gustavo)
- Clean up link BW/DSC slice config computation (Imre)

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

From: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patch.msgid.link/aWkNThVRSkGAfUVv@intel.com

+2017 -1443
+5 -1
drivers/gpu/drm/i915/Makefile
··· 78 78 i915-y += \ 79 79 i915_display_pc8.o \ 80 80 i915_hdcp_gsc.o \ 81 + i915_initial_plane.o \ 81 82 i915_panic.o 82 83 83 84 # "Graphics Technology" (aka we talk to the gpu) ··· 289 288 display/intel_hotplug.o \ 290 289 display/intel_hotplug_irq.o \ 291 290 display/intel_hti.o \ 291 + display/intel_initial_plane.o \ 292 292 display/intel_link_bw.o \ 293 293 display/intel_load_detect.o \ 294 294 display/intel_lpe_audio.o \ ··· 302 300 display/intel_pch_display.o \ 303 301 display/intel_pch_refclk.o \ 304 302 display/intel_plane.o \ 305 - display/intel_plane_initial.o \ 306 303 display/intel_pmdemand.o \ 307 304 display/intel_psr.o \ 308 305 display/intel_quirks.o \ ··· 381 380 382 381 i915-$(CONFIG_DRM_I915_DP_TUNNEL) += \ 383 382 display/intel_dp_tunnel.o 383 + 384 + i915-$(CONFIG_DRM_I915_GVT) += \ 385 + display/intel_gvt_api.o 384 386 385 387 i915-y += \ 386 388 i915_perf.o
+8 -9
drivers/gpu/drm/i915/display/i9xx_wm.c
··· 7 7 8 8 #include <drm/drm_print.h> 9 9 10 - #include "i915_drv.h" 11 10 #include "i915_reg.h" 12 11 #include "i9xx_wm.h" 13 12 #include "i9xx_wm_regs.h" ··· 16 17 #include "intel_display.h" 17 18 #include "intel_display_regs.h" 18 19 #include "intel_display_trace.h" 20 + #include "intel_display_utils.h" 19 21 #include "intel_dram.h" 20 22 #include "intel_fb.h" 21 23 #include "intel_mchbar_regs.h" ··· 1863 1863 struct intel_crtc *crtc) 1864 1864 { 1865 1865 struct intel_display *display = to_intel_display(crtc); 1866 - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 1867 - struct intel_uncore *uncore = &dev_priv->uncore; 1866 + struct intel_uncore *uncore = to_intel_uncore(display->drm); 1868 1867 const struct intel_crtc_state *crtc_state = 1869 1868 intel_atomic_get_new_crtc_state(state, crtc); 1870 1869 const struct vlv_fifo_state *fifo_state = ··· 2742 2743 2743 2744 static void hsw_read_wm_latency(struct intel_display *display, u16 wm[]) 2744 2745 { 2745 - struct drm_i915_private *i915 = to_i915(display->drm); 2746 + struct intel_uncore *uncore = to_intel_uncore(display->drm); 2746 2747 u64 sskpd; 2747 2748 2748 2749 display->wm.num_levels = 5; 2749 2750 2750 - sskpd = intel_uncore_read64(&i915->uncore, MCH_SSKPD); 2751 + sskpd = intel_uncore_read64(uncore, MCH_SSKPD); 2751 2752 2752 2753 wm[0] = REG_FIELD_GET64(SSKPD_NEW_WM0_MASK_HSW, sskpd); 2753 2754 if (wm[0] == 0) ··· 2760 2761 2761 2762 static void snb_read_wm_latency(struct intel_display *display, u16 wm[]) 2762 2763 { 2763 - struct drm_i915_private *i915 = to_i915(display->drm); 2764 + struct intel_uncore *uncore = to_intel_uncore(display->drm); 2764 2765 u32 sskpd; 2765 2766 2766 2767 display->wm.num_levels = 4; 2767 2768 2768 - sskpd = intel_uncore_read(&i915->uncore, MCH_SSKPD); 2769 + sskpd = intel_uncore_read(uncore, MCH_SSKPD); 2769 2770 2770 2771 wm[0] = REG_FIELD_GET(SSKPD_WM0_MASK_SNB, sskpd); 2771 2772 wm[1] = REG_FIELD_GET(SSKPD_WM1_MASK_SNB, sskpd); ··· 2775 2776 2776 2777 static void ilk_read_wm_latency(struct intel_display *display, u16 wm[]) 2777 2778 { 2778 - struct drm_i915_private *i915 = to_i915(display->drm); 2779 + struct intel_uncore *uncore = to_intel_uncore(display->drm); 2779 2780 u32 mltr; 2780 2781 2781 2782 display->wm.num_levels = 3; 2782 2783 2783 - mltr = intel_uncore_read(&i915->uncore, MLTR_ILK); 2784 + mltr = intel_uncore_read(uncore, MLTR_ILK); 2784 2785 2785 2786 /* ILK primary LP0 latency is 700 ns */ 2786 2787 wm[0] = 7;
+2 -2
drivers/gpu/drm/i915/display/intel_alpm.h
··· 1 - /* SPDX-License-Identifier: MIT 2 - * 1 + /* SPDX-License-Identifier: MIT */ 2 + /* 3 3 * Copyright © 2024 Intel Corporation 4 4 */ 5 5
+8 -11
drivers/gpu/drm/i915/display/intel_bw.c
··· 6 6 #include <drm/drm_atomic_state_helper.h> 7 7 #include <drm/drm_print.h> 8 8 9 - #include "i915_drv.h" 10 9 #include "i915_reg.h" 11 10 #include "intel_bw.h" 12 11 #include "intel_crtc.h" ··· 74 75 struct intel_qgv_point *sp, 75 76 int point) 76 77 { 77 - struct drm_i915_private *i915 = to_i915(display->drm); 78 + struct intel_uncore *uncore = to_intel_uncore(display->drm); 78 79 u32 dclk_ratio, dclk_reference; 79 80 u32 val; 80 81 81 - val = intel_uncore_read(&i915->uncore, SA_PERF_STATUS_0_0_0_MCHBAR_PC); 82 + val = intel_uncore_read(uncore, SA_PERF_STATUS_0_0_0_MCHBAR_PC); 82 83 dclk_ratio = REG_FIELD_GET(DG1_QCLK_RATIO_MASK, val); 83 84 if (val & DG1_QCLK_REFERENCE) 84 85 dclk_reference = 6; /* 6 * 16.666 MHz = 100 MHz */ ··· 86 87 dclk_reference = 8; /* 8 * 16.666 MHz = 133 MHz */ 87 88 sp->dclk = DIV_ROUND_UP((16667 * dclk_ratio * dclk_reference) + 500, 1000); 88 89 89 - val = intel_uncore_read(&i915->uncore, SKL_MC_BIOS_DATA_0_0_0_MCHBAR_PCU); 90 + val = intel_uncore_read(uncore, SKL_MC_BIOS_DATA_0_0_0_MCHBAR_PCU); 90 91 if (val & DG1_GEAR_TYPE) 91 92 sp->dclk *= 2; 92 93 93 94 if (sp->dclk == 0) 94 95 return -EINVAL; 95 96 96 - val = intel_uncore_read(&i915->uncore, MCHBAR_CH0_CR_TC_PRE_0_0_0_MCHBAR); 97 + val = intel_uncore_read(uncore, MCHBAR_CH0_CR_TC_PRE_0_0_0_MCHBAR); 97 98 sp->t_rp = REG_FIELD_GET(DG1_DRAM_T_RP_MASK, val); 98 99 sp->t_rdpre = REG_FIELD_GET(DG1_DRAM_T_RDPRE_MASK, val); 99 100 100 - val = intel_uncore_read(&i915->uncore, MCHBAR_CH0_CR_TC_PRE_0_0_0_MCHBAR_HIGH); 101 + val = intel_uncore_read(uncore, MCHBAR_CH0_CR_TC_PRE_0_0_0_MCHBAR_HIGH); 101 102 sp->t_rcd = REG_FIELD_GET(DG1_DRAM_T_RCD_MASK, val); 102 103 sp->t_ras = REG_FIELD_GET(DG1_DRAM_T_RAS_MASK, val); 103 104 ··· 211 212 static int mtl_read_qgv_point_info(struct intel_display *display, 212 213 struct intel_qgv_point *sp, int point) 213 214 { 214 - struct drm_i915_private *i915 = to_i915(display->drm); 215 + struct intel_uncore *uncore = to_intel_uncore(display->drm); 215 216 u32 val, val2; 216 217 u16 dclk; 217 218 218 - val = intel_uncore_read(&i915->uncore, 219 - MTL_MEM_SS_INFO_QGV_POINT_LOW(point)); 220 - val2 = intel_uncore_read(&i915->uncore, 221 - MTL_MEM_SS_INFO_QGV_POINT_HIGH(point)); 219 + val = intel_uncore_read(uncore, MTL_MEM_SS_INFO_QGV_POINT_LOW(point)); 220 + val2 = intel_uncore_read(uncore, MTL_MEM_SS_INFO_QGV_POINT_HIGH(point)); 222 221 dclk = REG_FIELD_GET(MTL_DCLK_MASK, val); 223 222 sp->dclk = DIV_ROUND_CLOSEST(16667 * dclk, 1000); 224 223 sp->t_rp = REG_FIELD_GET(MTL_TRP_MASK, val);
+51 -9
drivers/gpu/drm/i915/display/intel_cdclk.c
··· 39 39 #include "intel_display_regs.h" 40 40 #include "intel_display_types.h" 41 41 #include "intel_display_utils.h" 42 + #include "intel_display_wa.h" 42 43 #include "intel_dram.h" 43 44 #include "intel_mchbar_regs.h" 44 45 #include "intel_pci_config.h" ··· 1859 1858 1860 1859 static void icl_cdclk_pll_disable(struct intel_display *display) 1861 1860 { 1861 + /* 1862 + * Wa_13012396614: 1863 + * Fixes: A sporadic race condition between MDCLK selection and PLL 1864 + * enabling. 1865 + * Workaround: 1866 + * Change programming of MDCLK source selection in CDCLK_CTL: 1867 + * - When disabling the CDCLK PLL, first set MDCLK source to be CD2XCLK. 1868 + * - When enabling the CDCLK PLL, update MDCLK source selection only 1869 + * after the PLL is enabled (which is already done as part of the 1870 + * normal flow of _bxt_set_cdclk()). 1871 + */ 1872 + if (intel_display_wa(display, 13012396614)) 1873 + intel_de_rmw(display, CDCLK_CTL, MDCLK_SOURCE_SEL_MASK, MDCLK_SOURCE_SEL_CD2XCLK); 1874 + 1862 1875 intel_de_rmw(display, BXT_DE_PLL_ENABLE, 1863 1876 BXT_DE_PLL_PLL_ENABLE, 0); 1864 1877 ··· 1948 1933 static u32 bxt_cdclk_cd2x_div_sel(struct intel_display *display, 1949 1934 int cdclk, int vco, u16 waveform) 1950 1935 { 1936 + u32 ret; 1937 + 1951 1938 /* cdclk = vco / 2 / div{1,1.5,2,4} */ 1952 1939 switch (cdclk_divider(cdclk, vco, waveform)) { 1953 1940 default: ··· 1958 1941 drm_WARN_ON(display->drm, vco != 0); 1959 1942 fallthrough; 1960 1943 case 2: 1961 - return BXT_CDCLK_CD2X_DIV_SEL_1; 1944 + ret = BXT_CDCLK_CD2X_DIV_SEL_1; 1945 + break; 1962 1946 case 3: 1963 - return BXT_CDCLK_CD2X_DIV_SEL_1_5; 1947 + ret = BXT_CDCLK_CD2X_DIV_SEL_1_5; 1948 + break; 1964 1949 case 4: 1965 - return BXT_CDCLK_CD2X_DIV_SEL_2; 1950 + ret = BXT_CDCLK_CD2X_DIV_SEL_2; 1951 + break; 1966 1952 case 8: 1967 - return BXT_CDCLK_CD2X_DIV_SEL_4; 1953 + ret = BXT_CDCLK_CD2X_DIV_SEL_4; 1954 + break; 1968 1955 } 1956 + 1957 + /* 1958 + * On Xe3_LPD onward, the expectation is to always have 1959 + * BXT_CDCLK_CD2X_DIV_SEL_1 as the default. 1960 + */ 1961 + if (DISPLAY_VER(display) >= 30) 1962 + drm_WARN_ON(display->drm, ret != BXT_CDCLK_CD2X_DIV_SEL_1); 1963 + 1964 + return ret; 1969 1965 } 1970 1966 1971 1967 static u16 cdclk_squash_waveform(struct intel_display *display, ··· 2166 2136 2167 2137 waveform = cdclk_squash_waveform(display, cdclk); 2168 2138 2169 - val = bxt_cdclk_cd2x_div_sel(display, cdclk, vco, waveform) | 2170 - bxt_cdclk_cd2x_pipe(display, pipe); 2139 + val = bxt_cdclk_cd2x_div_sel(display, cdclk, vco, waveform); 2140 + 2141 + if (DISPLAY_VER(display) < 30) 2142 + val |= bxt_cdclk_cd2x_pipe(display, pipe); 2171 2143 2172 2144 /* 2173 2145 * Disable SSA Precharge when CD clock frequency < 500 MHz, ··· 2179 2147 cdclk >= 500000) 2180 2148 val |= BXT_CDCLK_SSA_PRECHARGE_ENABLE; 2181 2149 2182 - if (DISPLAY_VER(display) >= 20) 2183 - val |= xe2lpd_mdclk_source_sel(display); 2184 - else 2150 + if (DISPLAY_VER(display) >= 20) { 2151 + /* 2152 + * Wa_13012396614 requires selecting CD2XCLK as MDCLK source 2153 + * prior to disabling the PLL, which is already handled by 2154 + * icl_cdclk_pll_disable(). Here we are just making sure 2155 + * we keep the expected value. 2156 + */ 2157 + if (intel_display_wa(display, 13012396614) && vco == 0) 2158 + val |= MDCLK_SOURCE_SEL_CD2XCLK; 2159 + else 2160 + val |= xe2lpd_mdclk_source_sel(display); 2161 + } else { 2185 2162 val |= skl_cdclk_decimal(cdclk); 2163 + } 2186 2164 2187 2165 return val; 2188 2166 }
-2
drivers/gpu/drm/i915/display/intel_connector.c
··· 31 31 #include <drm/drm_print.h> 32 32 #include <drm/drm_probe_helper.h> 33 33 34 - #include "i915_drv.h" 35 - #include "i915_utils.h" /* for i915_inject_probe_failure() */ 36 34 #include "intel_connector.h" 37 35 #include "intel_display_core.h" 38 36 #include "intel_display_debugfs.h"
+8
drivers/gpu/drm/i915/display/intel_crtc_state_dump.c
··· 303 303 drm_printf(&p, "vrr: vmin vblank: %d, vmax vblank: %d, vmin vtotal: %d, vmax vtotal: %d\n", 304 304 intel_vrr_vmin_vblank_start(pipe_config), intel_vrr_vmax_vblank_start(pipe_config), 305 305 intel_vrr_vmin_vtotal(pipe_config), intel_vrr_vmax_vtotal(pipe_config)); 306 + drm_printf(&p, "vrr: dc balance: %s, vmin: %d vmax: %d guardband: %d, slope: %d max increase: %d max decrease: %d vblank target: %d\n", 307 + str_yes_no(pipe_config->vrr.dc_balance.enable), 308 + pipe_config->vrr.dc_balance.vmin, pipe_config->vrr.dc_balance.vmax, 309 + pipe_config->vrr.dc_balance.guardband, 310 + pipe_config->vrr.dc_balance.slope, 311 + pipe_config->vrr.dc_balance.max_increase, 312 + pipe_config->vrr.dc_balance.max_decrease, 313 + pipe_config->vrr.dc_balance.vblank_target); 306 314 307 315 drm_printf(&p, "requested mode: " DRM_MODE_FMT "\n", 308 316 DRM_MODE_ARG(&pipe_config->hw.mode));
+8 -5
drivers/gpu/drm/i915/display/intel_cx0_phy.c
··· 2671 2671 hw_state->cx0pll.use_c10 = false; 2672 2672 hw_state->cx0pll.lane_count = crtc_state->lane_count; 2673 2673 2674 - /* try computed C20 HDMI tables before using consolidated tables */ 2675 - if (!is_dp) 2676 - /* TODO: Update SSC state for HDMI as well */ 2677 - err = intel_c20_compute_hdmi_tmds_pll(crtc_state, &hw_state->cx0pll.c20); 2678 - 2674 + /* 2675 + * Try the ideal C20 HDMI tables before computing them, since the calculated 2676 + * values, although correct, may not be optimal. 2677 + */ 2679 2678 if (err) 2680 2679 err = intel_c20pll_calc_state_from_table(crtc_state, encoder, 2681 2680 &hw_state->cx0pll); 2681 + 2682 + /* TODO: Update SSC state for HDMI as well */ 2683 + if (!is_dp && err) 2684 + err = intel_c20_compute_hdmi_tmds_pll(crtc_state, &hw_state->cx0pll.c20); 2682 2685 2683 2686 if (err) 2684 2687 return err;
+1 -1
drivers/gpu/drm/i915/display/intel_cx0_phy.h
··· 1 - // SPDX-License-Identifier: MIT 1 + /* SPDX-License-Identifier: MIT */ 2 2 /* 3 3 * Copyright © 2023 Intel Corporation 4 4 */
+2 -2
drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h
··· 1 - /* SPDX-License-Identifier: MIT 2 - * 1 + /* SPDX-License-Identifier: MIT */ 2 + /* 3 3 * Copyright © 2023 Intel Corporation 4 4 */ 5 5
+37 -9
drivers/gpu/drm/i915/display/intel_display.c
··· 50 50 #include "g4x_hdmi.h" 51 51 #include "hsw_ips.h" 52 52 #include "i915_config.h" 53 - #include "i915_drv.h" 54 53 #include "i915_reg.h" 55 54 #include "i9xx_plane.h" 56 55 #include "i9xx_plane_regs.h" ··· 99 100 #include "intel_frontbuffer.h" 100 101 #include "intel_hdmi.h" 101 102 #include "intel_hotplug.h" 103 + #include "intel_initial_plane.h" 102 104 #include "intel_link_bw.h" 103 105 #include "intel_lt_phy.h" 104 106 #include "intel_lvds.h" ··· 113 113 #include "intel_pfit.h" 114 114 #include "intel_pipe_crc.h" 115 115 #include "intel_plane.h" 116 - #include "intel_plane_initial.h" 117 116 #include "intel_pmdemand.h" 118 117 #include "intel_pps.h" 119 118 #include "intel_psr.h" ··· 638 639 if ((crtc_state->active_planes & ~BIT(PLANE_CURSOR)) == 0 && 639 640 hsw_ips_disable(crtc_state)) { 640 641 crtc_state->ips_enabled = false; 641 - intel_plane_initial_vblank_wait(crtc); 642 + intel_initial_plane_vblank_wait(crtc); 642 643 } 643 644 644 645 /* ··· 652 653 */ 653 654 if (HAS_GMCH(display) && 654 655 intel_set_memory_cxsr(display, false)) 655 - intel_plane_initial_vblank_wait(crtc); 656 + intel_initial_plane_vblank_wait(crtc); 656 657 657 658 /* 658 659 * Gen2 reports pipe underruns whenever all planes are disabled. ··· 662 663 intel_set_cpu_fifo_underrun_reporting(display, crtc->pipe, false); 663 664 664 665 intel_plane_disable_arm(NULL, plane, crtc_state); 665 - intel_plane_initial_vblank_wait(crtc); 666 + intel_initial_plane_vblank_wait(crtc); 666 667 } 667 668 668 669 unsigned int ··· 1157 1158 1158 1159 if (intel_crtc_vrr_disabling(state, crtc)) { 1159 1160 intel_vrr_disable(old_crtc_state); 1161 + intel_vrr_dcb_reset(old_crtc_state, crtc); 1160 1162 intel_crtc_update_active_timings(old_crtc_state, false); 1161 1163 } 1162 1164 ··· 5476 5476 PIPE_CONF_CHECK_LLI(cmrr.cmrr_m); 5477 5477 PIPE_CONF_CHECK_LLI(cmrr.cmrr_n); 5478 5478 PIPE_CONF_CHECK_BOOL(cmrr.enable); 5479 + PIPE_CONF_CHECK_I(vrr.dc_balance.vmin); 5480 + PIPE_CONF_CHECK_I(vrr.dc_balance.vmax); 5481 + PIPE_CONF_CHECK_I(vrr.dc_balance.guardband); 5482 + PIPE_CONF_CHECK_I(vrr.dc_balance.slope); 5483 + PIPE_CONF_CHECK_I(vrr.dc_balance.max_increase); 5484 + PIPE_CONF_CHECK_I(vrr.dc_balance.max_decrease); 5485 + PIPE_CONF_CHECK_I(vrr.dc_balance.vblank_target); 5479 5486 } 5480 5487 5481 5488 if (!fastset || intel_vrr_always_use_vrr_tg(display)) { ··· 6863 6856 intel_crtc_update_active_timings(new_crtc_state, 6864 6857 new_crtc_state->vrr.enable); 6865 6858 6859 + if (new_crtc_state->vrr.dc_balance.enable) 6860 + intel_vrr_dcb_increment_flip_count(new_crtc_state, crtc); 6861 + 6866 6862 /* 6867 6863 * We usually enable FIFO underrun interrupts as part of the 6868 6864 * CRTC enable sequence during modesets. But when we inherit a ··· 7164 7154 7165 7155 static void intel_atomic_commit_fence_wait(struct intel_atomic_state *intel_state) 7166 7156 { 7167 - struct drm_i915_private *i915 = to_i915(intel_state->base.dev); 7168 7157 struct drm_plane *plane; 7169 7158 struct drm_plane_state *new_plane_state; 7170 7159 long ret; ··· 7172 7163 for_each_new_plane_in_state(&intel_state->base, plane, new_plane_state, i) { 7173 7164 if (new_plane_state->fence) { 7174 7165 ret = dma_fence_wait_timeout(new_plane_state->fence, false, 7175 - i915_fence_timeout(i915)); 7166 + i915_fence_timeout()); 7176 7167 if (ret <= 0) 7177 7168 break; 7178 7169 ··· 7328 7319 if (new_crtc_state->use_flipq) 7329 7320 intel_flipq_wait_dmc_halt(new_crtc_state->dsb_commit, crtc); 7330 7321 7322 + if (new_crtc_state->vrr.dc_balance.enable) { 7323 + /* 7324 + * Pause the DMC DC balancing for the remainder of 7325 + * the commit so that vmin/vmax won't change after 7326 + * we've baked them into the DSB vblank evasion 7327 + * commands. 7328 + * 7329 + * FIXME maybe need a small delay here to make sure 7330 + * DMC has finished updating the values? Or we need 7331 + * a better DMC<->driver protocol that gives is real 7332 + * guarantees about that... 7333 + */ 7334 + intel_pipedmc_dcb_disable(NULL, crtc); 7335 + } 7336 + 7331 7337 if (intel_crtc_needs_color_update(new_crtc_state)) 7332 7338 intel_color_commit_noarm(new_crtc_state->dsb_commit, 7333 7339 new_crtc_state); ··· 7396 7372 intel_dsb_wait_for_delayed_vblank(state, new_crtc_state->dsb_commit); 7397 7373 intel_vrr_check_push_sent(new_crtc_state->dsb_commit, 7398 7374 new_crtc_state); 7375 + 7376 + if (new_crtc_state->vrr.dc_balance.enable) 7377 + intel_pipedmc_dcb_enable(new_crtc_state->dsb_commit, crtc); 7378 + 7399 7379 intel_dsb_interrupt(new_crtc_state->dsb_commit); 7400 7380 } 7401 7381 ··· 7409 7381 static void intel_atomic_commit_tail(struct intel_atomic_state *state) 7410 7382 { 7411 7383 struct intel_display *display = to_intel_display(state); 7412 - struct drm_i915_private __maybe_unused *dev_priv = to_i915(display->drm); 7384 + struct intel_uncore *uncore = to_intel_uncore(display->drm); 7413 7385 struct intel_crtc_state *new_crtc_state, *old_crtc_state; 7414 7386 struct intel_crtc *crtc; 7415 7387 struct intel_power_domain_mask put_domains[I915_MAX_PIPES] = {}; ··· 7619 7591 * so enable debugging for the next modeset - and hope we catch 7620 7592 * the culprit. 7621 7593 */ 7622 - intel_uncore_arm_unclaimed_mmio_detection(&dev_priv->uncore); 7594 + intel_uncore_arm_unclaimed_mmio_detection(uncore); 7623 7595 } 7624 7596 /* 7625 7597 * Delay re-enabling DC states by 17 ms to avoid the off->on->off
+18
drivers/gpu/drm/i915/display/intel_display_device.h
··· 205 205 #define HAS_ULTRAJOINER(__display) (((__display)->platform.dgfx && \ 206 206 DISPLAY_VER(__display) == 14) && HAS_DSC(__display)) 207 207 #define HAS_VRR(__display) (DISPLAY_VER(__display) >= 11) 208 + #define HAS_VRR_DC_BALANCE(__display) (DISPLAY_VER(__display) >= 30) 208 209 #define INTEL_NUM_PIPES(__display) (hweight8(DISPLAY_RUNTIME_INFO(__display)->pipe_mask)) 209 210 #define OVERLAY_NEEDS_PHYSICAL(__display) (DISPLAY_INFO(__display)->overlay_needs_physical) 210 211 #define SUPPORTS_TV(__display) (DISPLAY_INFO(__display)->supports_tv) ··· 260 259 ((id) == ARLS_HOST_BRIDGE_PCI_ID2) || \ 261 260 ((id) == ARLS_HOST_BRIDGE_PCI_ID3) || \ 262 261 ((id) == ARLS_HOST_BRIDGE_PCI_ID4)) 262 + 263 + #define INTEL_DISPLAY_DEVICE_PIPE_OFFSET(display, pipe) \ 264 + (DISPLAY_INFO((display))->pipe_offsets[(pipe)] - \ 265 + DISPLAY_INFO((display))->pipe_offsets[PIPE_A] + \ 266 + DISPLAY_MMIO_BASE((display))) 267 + 268 + #define INTEL_DISPLAY_DEVICE_TRANS_OFFSET(display, trans) \ 269 + (DISPLAY_INFO((display))->trans_offsets[(trans)] - \ 270 + DISPLAY_INFO((display))->trans_offsets[TRANSCODER_A] + \ 271 + DISPLAY_MMIO_BASE((display))) 272 + 273 + #define INTEL_DISPLAY_DEVICE_CURSOR_OFFSET(display, pipe) \ 274 + (DISPLAY_INFO((display))->cursor_offsets[(pipe)] - \ 275 + DISPLAY_INFO((display))->cursor_offsets[PIPE_A] + \ 276 + DISPLAY_MMIO_BASE((display))) 277 + 278 + #define DISPLAY_MMIO_BASE(display) (DISPLAY_INFO((display))->mmio_offset) 263 279 264 280 struct intel_display_runtime_info { 265 281 struct intel_display_ip_ver {
+1 -3
drivers/gpu/drm/i915/display/intel_display_driver.c
··· 18 18 #include <drm/drm_probe_helper.h> 19 19 #include <drm/drm_vblank.h> 20 20 21 - #include "i915_drv.h" 22 - #include "i915_utils.h" /* for i915_inject_probe_failure() */ 23 21 #include "i9xx_wm.h" 24 22 #include "intel_acpi.h" 25 23 #include "intel_atomic.h" ··· 52 54 #include "intel_hdcp.h" 53 55 #include "intel_hotplug.h" 54 56 #include "intel_hti.h" 57 + #include "intel_initial_plane.h" 55 58 #include "intel_modeset_lock.h" 56 59 #include "intel_modeset_setup.h" 57 60 #include "intel_opregion.h" 58 61 #include "intel_overlay.h" 59 - #include "intel_plane_initial.h" 60 62 #include "intel_pmdemand.h" 61 63 #include "intel_pps.h" 62 64 #include "intel_psr.h"
+1 -1
drivers/gpu/drm/i915/display/intel_display_params.h
··· 1 - // SPDX-License-Identifier: MIT 1 + /* SPDX-License-Identifier: MIT */ 2 2 /* 3 3 * Copyright © 2023 Intel Corporation 4 4 */
+1 -2
drivers/gpu/drm/i915/display/intel_display_power.c
··· 8 8 9 9 #include <drm/drm_print.h> 10 10 11 - #include "i915_drv.h" 12 11 #include "i915_reg.h" 13 12 #include "intel_backlight_regs.h" 14 13 #include "intel_cdclk.h" ··· 30 31 #include "intel_pmdemand.h" 31 32 #include "intel_pps_regs.h" 32 33 #include "intel_snps_phy.h" 34 + #include "intel_step.h" 33 35 #include "skl_watermark.h" 34 36 #include "skl_watermark_regs.h" 35 37 #include "vlv_sideband.h" ··· 1328 1328 */ 1329 1329 static void hsw_restore_lcpll(struct intel_display *display) 1330 1330 { 1331 - struct drm_i915_private __maybe_unused *dev_priv = to_i915(display->drm); 1332 1331 u32 val; 1333 1332 int ret; 1334 1333
+4 -11
drivers/gpu/drm/i915/display/intel_display_reg_defs.h
··· 8 8 9 9 #include "i915_reg_defs.h" 10 10 11 - #define DISPLAY_MMIO_BASE(dev_priv) (DISPLAY_INFO(dev_priv)->mmio_offset) 12 - 13 11 #define VLV_DISPLAY_BASE 0x180000 14 12 15 13 /* ··· 34 36 * Device info offset array based helpers for groups of registers with unevenly 35 37 * spaced base offsets. 36 38 */ 37 - #define _MMIO_PIPE2(display, pipe, reg) _MMIO(DISPLAY_INFO(display)->pipe_offsets[(pipe)] - \ 38 - DISPLAY_INFO(display)->pipe_offsets[PIPE_A] + \ 39 - DISPLAY_MMIO_BASE(display) + (reg)) 40 - #define _MMIO_TRANS2(display, tran, reg) _MMIO(DISPLAY_INFO(display)->trans_offsets[(tran)] - \ 41 - DISPLAY_INFO(display)->trans_offsets[TRANSCODER_A] + \ 42 - DISPLAY_MMIO_BASE(display) + (reg)) 43 - #define _MMIO_CURSOR2(display, pipe, reg) _MMIO(DISPLAY_INFO(display)->cursor_offsets[(pipe)] - \ 44 - DISPLAY_INFO(display)->cursor_offsets[PIPE_A] + \ 45 - DISPLAY_MMIO_BASE(display) + (reg)) 39 + 40 + #define _MMIO_PIPE2(display, pipe, reg) _MMIO(INTEL_DISPLAY_DEVICE_PIPE_OFFSET((display), (pipe)) + (reg)) 41 + #define _MMIO_TRANS2(display, trans, reg) _MMIO(INTEL_DISPLAY_DEVICE_TRANS_OFFSET((display), (trans)) + (reg)) 42 + #define _MMIO_CURSOR2(display, pipe, reg) _MMIO(INTEL_DISPLAY_DEVICE_CURSOR_OFFSET((display), (pipe)) + (reg)) 46 43 47 44 #endif /* __INTEL_DISPLAY_REG_DEFS_H__ */
+11
drivers/gpu/drm/i915/display/intel_display_types.h
··· 1385 1385 u8 pipeline_full; 1386 1386 u16 flipline, vmin, vmax, guardband; 1387 1387 u32 vsync_end, vsync_start; 1388 + struct { 1389 + bool enable; 1390 + u16 vmin, vmax; 1391 + u16 guardband, slope; 1392 + u16 max_increase, max_decrease; 1393 + u16 vblank_target; 1394 + } dc_balance; 1388 1395 } vrr; 1389 1396 1390 1397 /* Content Match Refresh Rate state */ ··· 1531 1524 enum transcoder cpu_transcoder; 1532 1525 struct intel_link_m_n m_n, m2_n2; 1533 1526 } drrs; 1527 + 1528 + struct { 1529 + u64 flip_count; 1530 + } dc_balance; 1534 1531 1535 1532 int scanline_offset; 1536 1533
-4
drivers/gpu/drm/i915/display/intel_display_utils.h
··· 9 9 10 10 struct intel_display; 11 11 12 - #ifndef MISSING_CASE 13 12 #define MISSING_CASE(x) WARN(1, "Missing case (%s == %ld)\n", \ 14 13 __stringify(x), (long)(x)) 15 - #endif 16 14 17 - #ifndef fetch_and_zero 18 15 #define fetch_and_zero(ptr) ({ \ 19 16 typeof(*ptr) __T = *(ptr); \ 20 17 *(ptr) = (typeof(*ptr))0; \ 21 18 __T; \ 22 19 }) 23 - #endif 24 20 25 21 #define KHz(x) (1000 * (x)) 26 22 #define MHz(x) KHz(1000 * (x))
+8 -6
drivers/gpu/drm/i915/display/intel_display_wa.c
··· 62 62 bool __intel_display_wa(struct intel_display *display, enum intel_display_wa wa, const char *name) 63 63 { 64 64 switch (wa) { 65 + case INTEL_DISPLAY_WA_13012396614: 66 + return DISPLAY_VERx100(display) == 3000; 67 + case INTEL_DISPLAY_WA_14011503117: 68 + return DISPLAY_VER(display) == 13; 69 + case INTEL_DISPLAY_WA_14025769978: 70 + return DISPLAY_VER(display) == 35; 71 + case INTEL_DISPLAY_WA_15018326506: 72 + return display->platform.battlemage; 65 73 case INTEL_DISPLAY_WA_16023588340: 66 74 return intel_display_needs_wa_16023588340(display); 67 75 case INTEL_DISPLAY_WA_16025573575: 68 76 return intel_display_needs_wa_16025573575(display); 69 - case INTEL_DISPLAY_WA_14011503117: 70 - return DISPLAY_VER(display) == 13; 71 77 case INTEL_DISPLAY_WA_22014263786: 72 78 return IS_DISPLAY_VERx100(display, 1100, 1400); 73 - case INTEL_DISPLAY_WA_15018326506: 74 - return display->platform.battlemage; 75 - case INTEL_DISPLAY_WA_14025769978: 76 - return DISPLAY_VER(display) == 35; 77 79 default: 78 80 drm_WARN(display->drm, 1, "Missing Wa number: %s\n", name); 79 81 break;
+9 -3
drivers/gpu/drm/i915/display/intel_display_wa.h
··· 21 21 bool intel_display_needs_wa_16023588340(struct intel_display *display); 22 22 #endif 23 23 24 + /* 25 + * This enum lists display workarounds; each entry here must have a 26 + * corresponding case in __intel_display_wa(). Keep both sorted by lineage 27 + * number. 28 + */ 24 29 enum intel_display_wa { 30 + INTEL_DISPLAY_WA_13012396614, 31 + INTEL_DISPLAY_WA_14011503117, 32 + INTEL_DISPLAY_WA_14025769978, 33 + INTEL_DISPLAY_WA_15018326506, 25 34 INTEL_DISPLAY_WA_16023588340, 26 35 INTEL_DISPLAY_WA_16025573575, 27 - INTEL_DISPLAY_WA_14011503117, 28 36 INTEL_DISPLAY_WA_22014263786, 29 - INTEL_DISPLAY_WA_15018326506, 30 - INTEL_DISPLAY_WA_14025769978, 31 37 }; 32 38 33 39 bool __intel_display_wa(struct intel_display *display, enum intel_display_wa wa, const char *name);
+25
drivers/gpu/drm/i915/display/intel_dmc.c
··· 859 859 dmc_id, num_handlers, event_id); 860 860 } 861 861 862 + void intel_dmc_configure_dc_balance_event(struct intel_display *display, 863 + enum pipe pipe, bool enable) 864 + { 865 + enum intel_dmc_id dmc_id = PIPE_TO_DMC_ID(pipe); 866 + 867 + dmc_configure_event(display, dmc_id, PIPEDMC_EVENT_ADAPTIVE_DCB_TRIGGER, enable); 868 + } 869 + 862 870 /** 863 871 * intel_dmc_block_pkgc() - block PKG C-state 864 872 * @display: display instance ··· 1762 1754 enum intel_dmc_id dmc_id = PIPE_TO_DMC_ID(crtc->pipe); 1763 1755 1764 1756 return dmc ? dmc->dmc_info[dmc_id].start_mmioaddr : 0; 1757 + } 1758 + 1759 + void intel_pipedmc_dcb_enable(struct intel_dsb *dsb, struct intel_crtc *crtc) 1760 + { 1761 + struct intel_display *display = to_intel_display(crtc); 1762 + enum pipe pipe = crtc->pipe; 1763 + 1764 + intel_de_write_dsb(display, dsb, PIPEDMC_DCB_CTL(pipe), 1765 + PIPEDMC_ADAPTIVE_DCB_ENABLE); 1766 + } 1767 + 1768 + void intel_pipedmc_dcb_disable(struct intel_dsb *dsb, struct intel_crtc *crtc) 1769 + { 1770 + struct intel_display *display = to_intel_display(crtc); 1771 + enum pipe pipe = crtc->pipe; 1772 + 1773 + intel_de_write_dsb(display, dsb, PIPEDMC_DCB_CTL(pipe), 0); 1765 1774 }
+5
drivers/gpu/drm/i915/display/intel_dmc.h
··· 15 15 struct intel_crtc_state; 16 16 struct intel_display; 17 17 struct intel_dmc_snapshot; 18 + struct intel_dsb; 18 19 19 20 void intel_dmc_init(struct intel_display *display); 20 21 void intel_dmc_load_program(struct intel_display *display); ··· 25 24 void intel_dmc_disable_pipe(const struct intel_crtc_state *crtc_state); 26 25 void intel_dmc_block_pkgc(struct intel_display *display, enum pipe pipe, 27 26 bool block); 27 + void intel_dmc_configure_dc_balance_event(struct intel_display *display, 28 + enum pipe pipe, bool enable); 28 29 void intel_dmc_start_pkgc_exit_at_start_of_undelayed_vblank(struct intel_display *display, 29 30 enum pipe pipe, bool enable); 30 31 void intel_dmc_fini(struct intel_display *display); ··· 42 39 void assert_main_dmc_loaded(struct intel_display *display); 43 40 44 41 void intel_pipedmc_irq_handler(struct intel_display *display, enum pipe pipe); 42 + void intel_pipedmc_dcb_enable(struct intel_dsb *dsb, struct intel_crtc *crtc); 43 + void intel_pipedmc_dcb_disable(struct intel_dsb *dsb, struct intel_crtc *crtc); 45 44 46 45 u32 intel_pipedmc_start_mmioaddr(struct intel_crtc *crtc); 47 46 void intel_pipedmc_enable_event(struct intel_crtc *crtc,
+60
drivers/gpu/drm/i915/display/intel_dmc_regs.h
··· 584 584 #define PTL_PIPEDMC_EXEC_TIME_LINES(start_mmioaddr) _MMIO((start_mmioaddr) + 0x6b8) 585 585 #define PTL_PIPEDMC_END_OF_EXEC_GB(start_mmioaddr) _MMIO((start_mmioaddr) + 0x6c0) 586 586 587 + #define _PIPEDMC_DCB_CTL_A 0x5f1a0 588 + #define _PIPEDMC_DCB_CTL_B 0x5f5a0 589 + #define PIPEDMC_DCB_CTL(pipe) _MMIO_PIPE((pipe), _PIPEDMC_DCB_CTL_A,\ 590 + _PIPEDMC_DCB_CTL_B) 591 + #define PIPEDMC_ADAPTIVE_DCB_ENABLE REG_BIT(31) 592 + 593 + #define _PIPEDMC_DCB_VBLANK_A 0x5f1bc 594 + #define _PIPEDMC_DCB_VBLANK_B 0x5f5bc 595 + #define PIPEDMC_DCB_VBLANK(pipe) _MMIO_PIPE((pipe), _PIPEDMC_DCB_VBLANK_A,\ 596 + _PIPEDMC_DCB_VBLANK_B) 597 + 598 + #define _PIPEDMC_DCB_SLOPE_A 0x5f1b8 599 + #define _PIPEDMC_DCB_SLOPE_B 0x5f5b8 600 + #define PIPEDMC_DCB_SLOPE(pipe) _MMIO_PIPE((pipe), _PIPEDMC_DCB_SLOPE_A,\ 601 + _PIPEDMC_DCB_SLOPE_B) 602 + 603 + #define _PIPEDMC_DCB_GUARDBAND_A 0x5f1b4 604 + #define _PIPEDMC_DCB_GUARDBAND_B 0x5f5b4 605 + #define PIPEDMC_DCB_GUARDBAND(pipe) _MMIO_PIPE((pipe), _PIPEDMC_DCB_GUARDBAND_A,\ 606 + _PIPEDMC_DCB_GUARDBAND_B) 607 + 608 + #define _PIPEDMC_DCB_MAX_INCREASE_A 0x5f1ac 609 + #define _PIPEDMC_DCB_MAX_INCREASE_B 0x5f5ac 610 + #define PIPEDMC_DCB_MAX_INCREASE(pipe) _MMIO_PIPE((pipe), _PIPEDMC_DCB_MAX_INCREASE_A,\ 611 + _PIPEDMC_DCB_MAX_INCREASE_B) 612 + 613 + #define _PIPEDMC_DCB_MAX_DECREASE_A 0x5f1b0 614 + #define _PIPEDMC_DCB_MAX_DECREASE_B 0x5f5b0 615 + #define PIPEDMC_DCB_MAX_DECREASE(pipe) _MMIO_PIPE((pipe), _PIPEDMC_DCB_MAX_DECREASE_A,\ 616 + _PIPEDMC_DCB_MAX_DECREASE_B) 617 + 618 + #define _PIPEDMC_DCB_VMIN_A 0x5f1a4 619 + #define _PIPEDMC_DCB_VMIN_B 0x5f5a4 620 + #define PIPEDMC_DCB_VMIN(pipe) _MMIO_PIPE((pipe), _PIPEDMC_DCB_VMIN_A,\ 621 + _PIPEDMC_DCB_VMIN_B) 622 + 623 + #define _PIPEDMC_DCB_VMAX_A 0x5f1a8 624 + #define _PIPEDMC_DCB_VMAX_B 0x5f5a8 625 + #define PIPEDMC_DCB_VMAX(pipe) _MMIO_PIPE((pipe), _PIPEDMC_DCB_VMAX_A,\ 626 + _PIPEDMC_DCB_VMAX_B) 627 + 628 + #define _PIPEDMC_DCB_DEBUG_A 0x5f1c0 629 + #define _PIPEDMC_DCB_DEBUG_B 0x5f5c0 630 + #define PIPEDMC_DCB_DEBUG(pipe) _MMIO_PIPE(pipe, _PIPEDMC_DCB_DEBUG_A,\ 631 + _PIPEDMC_DCB_DEBUG_B) 632 + 633 + #define _PIPEDMC_EVT_CTL_3_A 0x5f040 634 + #define _PIPEDMC_EVT_CTL_3_B 0x5f440 635 + #define PIPEDMC_EVT_CTL_3(pipe) _MMIO_PIPE(pipe, _PIPEDMC_EVT_CTL_3_A,\ 636 + _PIPEDMC_EVT_CTL_3_B) 637 + 638 + #define _PIPEDMC_DCB_FLIP_COUNT_A 0x906a4 639 + #define _PIPEDMC_DCB_FLIP_COUNT_B 0x986a4 640 + #define PIPEDMC_DCB_FLIP_COUNT(pipe) _MMIO_PIPE(pipe, _PIPEDMC_DCB_FLIP_COUNT_A,\ 641 + _PIPEDMC_DCB_FLIP_COUNT_B) 642 + 643 + #define _PIPEDMC_DCB_BALANCE_RESET_A 0x906a8 644 + #define _PIPEDMC_DCB_BALANCE_RESET_B 0x986a8 645 + #define PIPEDMC_DCB_BALANCE_RESET(pipe) _MMIO_PIPE(pipe, _PIPEDMC_DCB_BALANCE_RESET_A,\ 646 + _PIPEDMC_DCB_BALANCE_RESET_B) 587 647 #endif /* __INTEL_DMC_REGS_H__ */
+242 -273
drivers/gpu/drm/i915/display/intel_dp.c
··· 868 868 return 6144 * 8; 869 869 } 870 870 871 - static u32 intel_dp_dsc_nearest_valid_bpp(struct intel_display *display, u32 bpp, u32 pipe_bpp) 871 + static int align_min_vesa_compressed_bpp_x16(int min_link_bpp_x16) 872 872 { 873 - u32 bits_per_pixel = bpp; 874 873 int i; 875 874 876 - /* Error out if the max bpp is less than smallest allowed valid bpp */ 877 - if (bits_per_pixel < valid_dsc_bpp[0]) { 878 - drm_dbg_kms(display->drm, "Unsupported BPP %u, min %u\n", 879 - bits_per_pixel, valid_dsc_bpp[0]); 880 - return 0; 875 + for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp); i++) { 876 + int vesa_bpp_x16 = fxp_q4_from_int(valid_dsc_bpp[i]); 877 + 878 + if (vesa_bpp_x16 >= min_link_bpp_x16) 879 + return vesa_bpp_x16; 881 880 } 882 881 883 - /* From XE_LPD onwards we support from bpc upto uncompressed bpp-1 BPPs */ 884 - if (DISPLAY_VER(display) >= 13) { 885 - bits_per_pixel = min(bits_per_pixel, pipe_bpp - 1); 882 + return 0; 883 + } 886 884 887 - /* 888 - * According to BSpec, 27 is the max DSC output bpp, 889 - * 8 is the min DSC output bpp. 890 - * While we can still clamp higher bpp values to 27, saving bandwidth, 891 - * if it is required to oompress up to bpp < 8, means we can't do 892 - * that and probably means we can't fit the required mode, even with 893 - * DSC enabled. 894 - */ 895 - if (bits_per_pixel < 8) { 896 - drm_dbg_kms(display->drm, 897 - "Unsupported BPP %u, min 8\n", 898 - bits_per_pixel); 899 - return 0; 900 - } 901 - bits_per_pixel = min_t(u32, bits_per_pixel, 27); 902 - } else { 903 - /* Find the nearest match in the array of known BPPs from VESA */ 904 - for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) { 905 - if (bits_per_pixel < valid_dsc_bpp[i + 1]) 906 - break; 907 - } 908 - drm_dbg_kms(display->drm, "Set dsc bpp from %d to VESA %d\n", 909 - bits_per_pixel, valid_dsc_bpp[i]); 885 + static int align_max_vesa_compressed_bpp_x16(int max_link_bpp_x16) 886 + { 887 + int i; 910 888 911 - bits_per_pixel = valid_dsc_bpp[i]; 889 + for (i = ARRAY_SIZE(valid_dsc_bpp) - 1; i >= 0; i--) { 890 + int vesa_bpp_x16 = fxp_q4_from_int(valid_dsc_bpp[i]); 891 + 892 + if (vesa_bpp_x16 <= max_link_bpp_x16) 893 + return vesa_bpp_x16; 912 894 } 913 895 914 - return bits_per_pixel; 896 + return 0; 915 897 } 916 898 917 899 static int bigjoiner_interface_bits(struct intel_display *display) ··· 957 975 max_bpp = min(max_bpp, ultrajoiner_ram_max_bpp(mode_hdisplay)); 958 976 959 977 return max_bpp; 960 - } 961 - 962 - /* TODO: return a bpp_x16 value */ 963 - u16 intel_dp_dsc_get_max_compressed_bpp(struct intel_display *display, 964 - u32 link_clock, u32 lane_count, 965 - u32 mode_clock, u32 mode_hdisplay, 966 - int num_joined_pipes, 967 - enum intel_output_format output_format, 968 - u32 pipe_bpp, 969 - u32 timeslots) 970 - { 971 - u32 bits_per_pixel, joiner_max_bpp; 972 - 973 - /* 974 - * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)* 975 - * (LinkSymbolClock)* 8 * (TimeSlots / 64) 976 - * for SST -> TimeSlots is 64(i.e all TimeSlots that are available) 977 - * for MST -> TimeSlots has to be calculated, based on mode requirements 978 - * 979 - * Due to FEC overhead, the available bw is reduced to 97.2261%. 980 - * To support the given mode: 981 - * Bandwidth required should be <= Available link Bandwidth * FEC Overhead 982 - * =>ModeClock * bits_per_pixel <= Available Link Bandwidth * FEC Overhead 983 - * =>bits_per_pixel <= Available link Bandwidth * FEC Overhead / ModeClock 984 - * =>bits_per_pixel <= (NumberOfLanes * LinkSymbolClock) * 8 (TimeSlots / 64) / 985 - * (ModeClock / FEC Overhead) 986 - * =>bits_per_pixel <= (NumberOfLanes * LinkSymbolClock * TimeSlots) / 987 - * (ModeClock / FEC Overhead * 8) 988 - */ 989 - bits_per_pixel = ((link_clock * lane_count) * timeslots) / 990 - (intel_dp_mode_to_fec_clock(mode_clock) * 8); 991 - 992 - /* Bandwidth required for 420 is half, that of 444 format */ 993 - if (output_format == INTEL_OUTPUT_FORMAT_YCBCR420) 994 - bits_per_pixel *= 2; 995 - 996 - /* 997 - * According to DSC 1.2a Section 4.1.1 Table 4.1 the maximum 998 - * supported PPS value can be 63.9375 and with the further 999 - * mention that for 420, 422 formats, bpp should be programmed double 1000 - * the target bpp restricting our target bpp to be 31.9375 at max. 1001 - */ 1002 - if (output_format == INTEL_OUTPUT_FORMAT_YCBCR420) 1003 - bits_per_pixel = min_t(u32, bits_per_pixel, 31); 1004 - 1005 - drm_dbg_kms(display->drm, "Max link bpp is %u for %u timeslots " 1006 - "total bw %u pixel clock %u\n", 1007 - bits_per_pixel, timeslots, 1008 - (link_clock * lane_count * 8), 1009 - intel_dp_mode_to_fec_clock(mode_clock)); 1010 - 1011 - joiner_max_bpp = get_max_compressed_bpp_with_joiner(display, mode_clock, 1012 - mode_hdisplay, num_joined_pipes); 1013 - bits_per_pixel = min(bits_per_pixel, joiner_max_bpp); 1014 - 1015 - bits_per_pixel = intel_dp_dsc_nearest_valid_bpp(display, bits_per_pixel, pipe_bpp); 1016 - 1017 - return bits_per_pixel; 1018 978 } 1019 979 1020 980 u8 intel_dp_dsc_get_slice_count(const struct intel_connector *connector, ··· 1479 1555 dsc_slice_count = 1480 1556 drm_dp_dsc_sink_max_slice_count(connector->dp.dsc_dpcd, 1481 1557 true); 1558 + dsc = dsc_max_compressed_bpp && dsc_slice_count; 1482 1559 } else if (drm_dp_sink_supports_fec(connector->dp.fec_capability)) { 1483 - dsc_max_compressed_bpp = 1484 - intel_dp_dsc_get_max_compressed_bpp(display, 1485 - max_link_clock, 1486 - max_lanes, 1487 - target_clock, 1488 - mode->hdisplay, 1489 - num_joined_pipes, 1490 - output_format, 1491 - pipe_bpp, 64); 1492 - dsc_slice_count = 1493 - intel_dp_dsc_get_slice_count(connector, 1494 - target_clock, 1495 - mode->hdisplay, 1496 - num_joined_pipes); 1497 - } 1560 + unsigned long bw_overhead_flags = 0; 1498 1561 1499 - dsc = dsc_max_compressed_bpp && dsc_slice_count; 1562 + if (!drm_dp_is_uhbr_rate(max_link_clock)) 1563 + bw_overhead_flags |= DRM_DP_BW_OVERHEAD_FEC; 1564 + 1565 + dsc = intel_dp_mode_valid_with_dsc(connector, 1566 + max_link_clock, max_lanes, 1567 + target_clock, mode->hdisplay, 1568 + num_joined_pipes, 1569 + output_format, pipe_bpp, 1570 + bw_overhead_flags); 1571 + } 1500 1572 } 1501 1573 1502 1574 if (intel_dp_joiner_needs_dsc(display, num_joined_pipes) && !dsc) ··· 1814 1894 return intel_dp_dsc_min_src_input_bpc(); 1815 1895 } 1816 1896 1897 + static int align_min_sink_dsc_input_bpp(const struct intel_connector *connector, 1898 + int min_pipe_bpp) 1899 + { 1900 + u8 dsc_bpc[3]; 1901 + int num_bpc; 1902 + int i; 1903 + 1904 + num_bpc = drm_dp_dsc_sink_supported_input_bpcs(connector->dp.dsc_dpcd, 1905 + dsc_bpc); 1906 + for (i = num_bpc - 1; i >= 0; i--) { 1907 + if (dsc_bpc[i] * 3 >= min_pipe_bpp) 1908 + return dsc_bpc[i] * 3; 1909 + } 1910 + 1911 + return 0; 1912 + } 1913 + 1914 + static int align_max_sink_dsc_input_bpp(const struct intel_connector *connector, 1915 + int max_pipe_bpp) 1916 + { 1917 + u8 dsc_bpc[3]; 1918 + int num_bpc; 1919 + int i; 1920 + 1921 + num_bpc = drm_dp_dsc_sink_supported_input_bpcs(connector->dp.dsc_dpcd, 1922 + dsc_bpc); 1923 + for (i = 0; i < num_bpc; i++) { 1924 + if (dsc_bpc[i] * 3 <= max_pipe_bpp) 1925 + return dsc_bpc[i] * 3; 1926 + } 1927 + 1928 + return 0; 1929 + } 1930 + 1817 1931 int intel_dp_dsc_compute_max_bpp(const struct intel_connector *connector, 1818 1932 u8 max_req_bpc) 1819 1933 { 1820 1934 struct intel_display *display = to_intel_display(connector); 1821 - int i, num_bpc; 1822 - u8 dsc_bpc[3] = {}; 1823 1935 int dsc_max_bpc; 1824 1936 1825 1937 dsc_max_bpc = intel_dp_dsc_max_src_input_bpc(display); ··· 1861 1909 1862 1910 dsc_max_bpc = min(dsc_max_bpc, max_req_bpc); 1863 1911 1864 - num_bpc = drm_dp_dsc_sink_supported_input_bpcs(connector->dp.dsc_dpcd, 1865 - dsc_bpc); 1866 - for (i = 0; i < num_bpc; i++) { 1867 - if (dsc_max_bpc >= dsc_bpc[i]) 1868 - return dsc_bpc[i] * 3; 1869 - } 1870 - 1871 - return 0; 1912 + return align_max_sink_dsc_input_bpp(connector, dsc_max_bpc * 3); 1872 1913 } 1873 1914 1874 1915 static int intel_dp_source_dsc_version_minor(struct intel_display *display) ··· 1992 2047 struct intel_crtc_state *pipe_config, 1993 2048 struct drm_connector_state *conn_state, 1994 2049 const struct link_config_limits *limits, 1995 - int dsc_bpp_x16, 1996 - int timeslots) 2050 + int dsc_bpp_x16) 1997 2051 { 1998 2052 const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; 1999 2053 int link_rate, lane_count; ··· 2052 2108 2053 2109 static 2054 2110 u16 intel_dp_dsc_max_sink_compressed_bppx16(const struct intel_connector *connector, 2055 - const struct intel_crtc_state *pipe_config, 2111 + enum intel_output_format output_format, 2056 2112 int bpc) 2057 2113 { 2058 2114 u16 max_bppx16 = drm_edp_dsc_sink_output_bpp(connector->dp.dsc_dpcd); ··· 2063 2119 * If support not given in DPCD 67h, 68h use the Maximum Allowed bit rate 2064 2120 * values as given in spec Table 2-157 DP v2.0 2065 2121 */ 2066 - switch (pipe_config->output_format) { 2122 + switch (output_format) { 2067 2123 case INTEL_OUTPUT_FORMAT_RGB: 2068 2124 case INTEL_OUTPUT_FORMAT_YCBCR444: 2069 2125 return (3 * bpc) << 4; 2070 2126 case INTEL_OUTPUT_FORMAT_YCBCR420: 2071 2127 return (3 * (bpc / 2)) << 4; 2072 2128 default: 2073 - MISSING_CASE(pipe_config->output_format); 2129 + MISSING_CASE(output_format); 2074 2130 break; 2075 2131 } 2076 2132 2077 2133 return 0; 2078 2134 } 2079 2135 2080 - int intel_dp_dsc_sink_min_compressed_bpp(const struct intel_crtc_state *pipe_config) 2136 + static int intel_dp_dsc_sink_min_compressed_bpp(enum intel_output_format output_format) 2081 2137 { 2082 2138 /* From Mandatory bit rate range Support Table 2-157 (DP v2.0) */ 2083 - switch (pipe_config->output_format) { 2139 + switch (output_format) { 2084 2140 case INTEL_OUTPUT_FORMAT_RGB: 2085 2141 case INTEL_OUTPUT_FORMAT_YCBCR444: 2086 2142 return 8; 2087 2143 case INTEL_OUTPUT_FORMAT_YCBCR420: 2088 2144 return 6; 2089 2145 default: 2090 - MISSING_CASE(pipe_config->output_format); 2146 + MISSING_CASE(output_format); 2091 2147 break; 2092 2148 } 2093 2149 2094 2150 return 0; 2095 2151 } 2096 2152 2097 - int intel_dp_dsc_sink_max_compressed_bpp(const struct intel_connector *connector, 2098 - const struct intel_crtc_state *pipe_config, 2099 - int bpc) 2153 + static int intel_dp_dsc_sink_max_compressed_bpp(const struct intel_connector *connector, 2154 + enum intel_output_format output_format, 2155 + int bpc) 2100 2156 { 2101 2157 return intel_dp_dsc_max_sink_compressed_bppx16(connector, 2102 - pipe_config, bpc) >> 4; 2158 + output_format, bpc) >> 4; 2103 2159 } 2104 2160 2105 2161 int intel_dp_dsc_min_src_compressed_bpp(void) ··· 2157 2213 bool intel_dp_dsc_valid_compressed_bpp(struct intel_dp *intel_dp, int bpp_x16) 2158 2214 { 2159 2215 struct intel_display *display = to_intel_display(intel_dp); 2160 - int i; 2161 2216 2162 2217 if (DISPLAY_VER(display) >= 13) { 2163 2218 if (intel_dp->force_dsc_fractional_bpp_en && !fxp_q4_to_frac(bpp_x16)) ··· 2168 2225 if (fxp_q4_to_frac(bpp_x16)) 2169 2226 return false; 2170 2227 2171 - for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp); i++) { 2172 - if (fxp_q4_to_int(bpp_x16) == valid_dsc_bpp[i]) 2173 - return true; 2174 - } 2228 + return align_max_vesa_compressed_bpp_x16(bpp_x16) == bpp_x16; 2229 + } 2175 2230 2176 - return false; 2231 + static int align_min_compressed_bpp_x16(const struct intel_connector *connector, int min_bpp_x16) 2232 + { 2233 + struct intel_display *display = to_intel_display(connector); 2234 + 2235 + if (DISPLAY_VER(display) >= 13) { 2236 + int bpp_step_x16 = intel_dp_dsc_bpp_step_x16(connector); 2237 + 2238 + drm_WARN_ON(display->drm, !is_power_of_2(bpp_step_x16)); 2239 + 2240 + return round_up(min_bpp_x16, bpp_step_x16); 2241 + } else { 2242 + return align_min_vesa_compressed_bpp_x16(min_bpp_x16); 2243 + } 2244 + } 2245 + 2246 + static int align_max_compressed_bpp_x16(const struct intel_connector *connector, 2247 + enum intel_output_format output_format, 2248 + int pipe_bpp, int max_bpp_x16) 2249 + { 2250 + struct intel_display *display = to_intel_display(connector); 2251 + int link_bpp_x16 = intel_dp_output_format_link_bpp_x16(output_format, pipe_bpp); 2252 + int bpp_step_x16 = intel_dp_dsc_bpp_step_x16(connector); 2253 + 2254 + max_bpp_x16 = min(max_bpp_x16, link_bpp_x16 - bpp_step_x16); 2255 + 2256 + if (DISPLAY_VER(display) >= 13) { 2257 + drm_WARN_ON(display->drm, !is_power_of_2(bpp_step_x16)); 2258 + 2259 + return round_down(max_bpp_x16, bpp_step_x16); 2260 + } else { 2261 + return align_max_vesa_compressed_bpp_x16(max_bpp_x16); 2262 + } 2177 2263 } 2178 2264 2179 2265 /* ··· 2213 2241 struct intel_crtc_state *pipe_config, 2214 2242 struct drm_connector_state *conn_state, 2215 2243 const struct link_config_limits *limits, 2216 - int pipe_bpp, 2217 - int timeslots) 2244 + int pipe_bpp) 2218 2245 { 2219 2246 struct intel_display *display = to_intel_display(intel_dp); 2220 2247 const struct intel_connector *connector = to_intel_connector(conn_state->connector); 2221 2248 int min_bpp_x16, max_bpp_x16, bpp_step_x16; 2222 - int link_bpp_x16; 2223 2249 int bpp_x16; 2224 2250 int ret; 2225 2251 2252 + min_bpp_x16 = limits->link.min_bpp_x16; 2226 2253 max_bpp_x16 = limits->link.max_bpp_x16; 2227 2254 bpp_step_x16 = intel_dp_dsc_bpp_step_x16(connector); 2228 2255 2229 - /* Compressed BPP should be less than the Input DSC bpp */ 2230 - link_bpp_x16 = intel_dp_output_format_link_bpp_x16(pipe_config->output_format, pipe_bpp); 2231 - max_bpp_x16 = min(max_bpp_x16, link_bpp_x16 - bpp_step_x16); 2256 + max_bpp_x16 = align_max_compressed_bpp_x16(connector, pipe_config->output_format, 2257 + pipe_bpp, max_bpp_x16); 2258 + if (intel_dp_is_edp(intel_dp)) { 2259 + pipe_config->port_clock = limits->max_rate; 2260 + pipe_config->lane_count = limits->max_lane_count; 2232 2261 2233 - drm_WARN_ON(display->drm, !is_power_of_2(bpp_step_x16)); 2234 - min_bpp_x16 = round_up(limits->link.min_bpp_x16, bpp_step_x16); 2235 - max_bpp_x16 = round_down(max_bpp_x16, bpp_step_x16); 2262 + pipe_config->dsc.compressed_bpp_x16 = max_bpp_x16; 2263 + 2264 + return 0; 2265 + } 2236 2266 2237 2267 for (bpp_x16 = max_bpp_x16; bpp_x16 >= min_bpp_x16; bpp_x16 -= bpp_step_x16) { 2238 2268 if (!intel_dp_dsc_valid_compressed_bpp(intel_dp, bpp_x16)) ··· 2244 2270 pipe_config, 2245 2271 conn_state, 2246 2272 limits, 2247 - bpp_x16, 2248 - timeslots); 2273 + bpp_x16); 2249 2274 if (ret == 0) { 2250 2275 pipe_config->dsc.compressed_bpp_x16 = bpp_x16; 2251 2276 if (intel_dp->force_dsc_fractional_bpp_en && ··· 2301 2328 static int intel_dp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp, 2302 2329 struct intel_crtc_state *pipe_config, 2303 2330 struct drm_connector_state *conn_state, 2304 - const struct link_config_limits *limits, 2305 - int timeslots) 2331 + const struct link_config_limits *limits) 2306 2332 { 2307 - const struct intel_connector *connector = 2308 - to_intel_connector(conn_state->connector); 2309 - u8 dsc_bpc[3] = {}; 2310 2333 int forced_bpp, pipe_bpp; 2311 - int num_bpc, i, ret; 2334 + int ret; 2312 2335 2313 2336 forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp, limits); 2314 - 2315 - if (forced_bpp) { 2316 - ret = dsc_compute_compressed_bpp(intel_dp, pipe_config, conn_state, 2317 - limits, forced_bpp, timeslots); 2318 - if (ret == 0) { 2319 - pipe_config->pipe_bpp = forced_bpp; 2320 - return 0; 2321 - } 2322 - } 2323 - 2324 - /* 2325 - * Get the maximum DSC bpc that will be supported by any valid 2326 - * link configuration and compressed bpp. 2327 - */ 2328 - num_bpc = drm_dp_dsc_sink_supported_input_bpcs(connector->dp.dsc_dpcd, dsc_bpc); 2329 - for (i = 0; i < num_bpc; i++) { 2330 - pipe_bpp = dsc_bpc[i] * 3; 2331 - if (pipe_bpp < limits->pipe.min_bpp || pipe_bpp > limits->pipe.max_bpp) 2332 - continue; 2333 - 2334 - ret = dsc_compute_compressed_bpp(intel_dp, pipe_config, conn_state, 2335 - limits, pipe_bpp, timeslots); 2336 - if (ret == 0) { 2337 - pipe_config->pipe_bpp = pipe_bpp; 2338 - return 0; 2339 - } 2340 - } 2341 - 2342 - return -EINVAL; 2343 - } 2344 - 2345 - static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp, 2346 - struct intel_crtc_state *pipe_config, 2347 - struct drm_connector_state *conn_state, 2348 - const struct link_config_limits *limits) 2349 - { 2350 - struct intel_display *display = to_intel_display(intel_dp); 2351 - struct intel_connector *connector = 2352 - to_intel_connector(conn_state->connector); 2353 - int pipe_bpp, forced_bpp; 2354 - int dsc_min_bpp; 2355 - int dsc_max_bpp; 2356 - 2357 - forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp, limits); 2358 - 2359 - if (forced_bpp) { 2337 + if (forced_bpp) 2360 2338 pipe_bpp = forced_bpp; 2361 - } else { 2362 - int max_bpc = limits->pipe.max_bpp / 3; 2339 + else 2340 + pipe_bpp = limits->pipe.max_bpp; 2363 2341 2364 - /* For eDP use max bpp that can be supported with DSC. */ 2365 - pipe_bpp = intel_dp_dsc_compute_max_bpp(connector, max_bpc); 2366 - if (!is_dsc_pipe_bpp_sufficient(limits, pipe_bpp)) { 2367 - drm_dbg_kms(display->drm, 2368 - "Computed BPC is not in DSC BPC limits\n"); 2369 - return -EINVAL; 2370 - } 2371 - } 2372 - pipe_config->port_clock = limits->max_rate; 2373 - pipe_config->lane_count = limits->max_lane_count; 2374 - 2375 - dsc_min_bpp = fxp_q4_to_int_roundup(limits->link.min_bpp_x16); 2376 - 2377 - dsc_max_bpp = fxp_q4_to_int(limits->link.max_bpp_x16); 2378 - 2379 - /* Compressed BPP should be less than the Input DSC bpp */ 2380 - dsc_max_bpp = min(dsc_max_bpp, pipe_bpp - 1); 2381 - 2382 - pipe_config->dsc.compressed_bpp_x16 = 2383 - fxp_q4_from_int(max(dsc_min_bpp, dsc_max_bpp)); 2342 + ret = dsc_compute_compressed_bpp(intel_dp, pipe_config, conn_state, 2343 + limits, pipe_bpp); 2344 + if (ret) 2345 + return -EINVAL; 2384 2346 2385 2347 pipe_config->pipe_bpp = pipe_bpp; 2386 2348 ··· 2373 2465 * figured out for DP MST DSC. 2374 2466 */ 2375 2467 if (!is_mst) { 2376 - if (intel_dp_is_edp(intel_dp)) 2377 - ret = intel_edp_dsc_compute_pipe_bpp(intel_dp, pipe_config, 2378 - conn_state, limits); 2379 - else 2380 - ret = intel_dp_dsc_compute_pipe_bpp(intel_dp, pipe_config, 2381 - conn_state, limits, timeslots); 2468 + ret = intel_dp_dsc_compute_pipe_bpp(intel_dp, pipe_config, 2469 + conn_state, limits); 2382 2470 if (ret) { 2383 2471 drm_dbg_kms(display->drm, 2384 2472 "No Valid pipe bpp for given mode ret = %d\n", ret); ··· 2447 2543 2448 2544 static int 2449 2545 dsc_throughput_quirk_max_bpp_x16(const struct intel_connector *connector, 2450 - const struct intel_crtc_state *crtc_state) 2546 + int mode_clock) 2451 2547 { 2452 - const struct drm_display_mode *adjusted_mode = 2453 - &crtc_state->hw.adjusted_mode; 2454 - 2455 2548 if (!connector->dp.dsc_throughput_quirk) 2456 2549 return INT_MAX; 2457 2550 ··· 2468 2567 * smaller than the YUV422/420 value, but let's not depend on this 2469 2568 * assumption. 2470 2569 */ 2471 - if (adjusted_mode->crtc_clock < 2570 + if (mode_clock < 2472 2571 min(connector->dp.dsc_branch_caps.overall_throughput.rgb_yuv444, 2473 2572 connector->dp.dsc_branch_caps.overall_throughput.yuv422_420) / 2) 2474 2573 return INT_MAX; ··· 2476 2575 return fxp_q4_from_int(12); 2477 2576 } 2478 2577 2578 + static int compute_min_compressed_bpp_x16(struct intel_connector *connector, 2579 + enum intel_output_format output_format) 2580 + { 2581 + int dsc_src_min_bpp, dsc_sink_min_bpp, dsc_min_bpp; 2582 + int min_bpp_x16; 2583 + 2584 + dsc_src_min_bpp = intel_dp_dsc_min_src_compressed_bpp(); 2585 + dsc_sink_min_bpp = intel_dp_dsc_sink_min_compressed_bpp(output_format); 2586 + dsc_min_bpp = max(dsc_src_min_bpp, dsc_sink_min_bpp); 2587 + 2588 + min_bpp_x16 = fxp_q4_from_int(dsc_min_bpp); 2589 + 2590 + min_bpp_x16 = align_min_compressed_bpp_x16(connector, min_bpp_x16); 2591 + 2592 + return min_bpp_x16; 2593 + } 2594 + 2595 + static int compute_max_compressed_bpp_x16(struct intel_connector *connector, 2596 + int mode_clock, int mode_hdisplay, 2597 + int num_joined_pipes, 2598 + enum intel_output_format output_format, 2599 + int pipe_max_bpp, int max_link_bpp_x16) 2600 + { 2601 + struct intel_display *display = to_intel_display(connector); 2602 + struct intel_dp *intel_dp = intel_attached_dp(connector); 2603 + int dsc_src_max_bpp, dsc_sink_max_bpp, dsc_max_bpp; 2604 + int throughput_max_bpp_x16; 2605 + int joiner_max_bpp; 2606 + 2607 + dsc_src_max_bpp = dsc_src_max_compressed_bpp(intel_dp); 2608 + joiner_max_bpp = get_max_compressed_bpp_with_joiner(display, 2609 + mode_clock, 2610 + mode_hdisplay, 2611 + num_joined_pipes); 2612 + dsc_sink_max_bpp = intel_dp_dsc_sink_max_compressed_bpp(connector, 2613 + output_format, 2614 + pipe_max_bpp / 3); 2615 + dsc_max_bpp = min(dsc_sink_max_bpp, dsc_src_max_bpp); 2616 + dsc_max_bpp = min(dsc_max_bpp, joiner_max_bpp); 2617 + 2618 + max_link_bpp_x16 = min(max_link_bpp_x16, fxp_q4_from_int(dsc_max_bpp)); 2619 + 2620 + throughput_max_bpp_x16 = dsc_throughput_quirk_max_bpp_x16(connector, 2621 + mode_clock); 2622 + if (throughput_max_bpp_x16 < max_link_bpp_x16) { 2623 + max_link_bpp_x16 = throughput_max_bpp_x16; 2624 + 2625 + drm_dbg_kms(display->drm, 2626 + "[CONNECTOR:%d:%s] Decreasing link max bpp to " FXP_Q4_FMT " due to DSC throughput quirk\n", 2627 + connector->base.base.id, connector->base.name, 2628 + FXP_Q4_ARGS(max_link_bpp_x16)); 2629 + } 2630 + 2631 + max_link_bpp_x16 = align_max_compressed_bpp_x16(connector, output_format, 2632 + pipe_max_bpp, max_link_bpp_x16); 2633 + 2634 + return max_link_bpp_x16; 2635 + } 2636 + 2637 + bool intel_dp_mode_valid_with_dsc(struct intel_connector *connector, 2638 + int link_clock, int lane_count, 2639 + int mode_clock, int mode_hdisplay, 2640 + int num_joined_pipes, 2641 + enum intel_output_format output_format, 2642 + int pipe_bpp, unsigned long bw_overhead_flags) 2643 + { 2644 + struct intel_dp *intel_dp = intel_attached_dp(connector); 2645 + int min_bpp_x16 = compute_min_compressed_bpp_x16(connector, output_format); 2646 + int max_bpp_x16 = compute_max_compressed_bpp_x16(connector, 2647 + mode_clock, mode_hdisplay, 2648 + num_joined_pipes, 2649 + output_format, 2650 + pipe_bpp, INT_MAX); 2651 + int dsc_slice_count = intel_dp_dsc_get_slice_count(connector, 2652 + mode_clock, 2653 + mode_hdisplay, 2654 + num_joined_pipes); 2655 + 2656 + if (min_bpp_x16 <= 0 || min_bpp_x16 > max_bpp_x16) 2657 + return false; 2658 + 2659 + return is_bw_sufficient_for_dsc_config(intel_dp, 2660 + link_clock, lane_count, 2661 + mode_clock, mode_hdisplay, 2662 + dsc_slice_count, min_bpp_x16, 2663 + bw_overhead_flags); 2664 + } 2665 + 2479 2666 /* 2480 2667 * Calculate the output link min, max bpp values in limits based on the pipe bpp 2481 2668 * range, crtc_state and dsc mode. Return true on success. 2482 2669 */ 2483 2670 static bool 2484 - intel_dp_compute_config_link_bpp_limits(struct intel_dp *intel_dp, 2485 - const struct intel_connector *connector, 2671 + intel_dp_compute_config_link_bpp_limits(struct intel_connector *connector, 2486 2672 const struct intel_crtc_state *crtc_state, 2487 2673 bool dsc, 2488 2674 struct link_config_limits *limits) 2489 2675 { 2490 - struct intel_display *display = to_intel_display(intel_dp); 2676 + struct intel_display *display = to_intel_display(connector); 2677 + struct intel_dp *intel_dp = intel_attached_dp(connector); 2491 2678 const struct drm_display_mode *adjusted_mode = 2492 2679 &crtc_state->hw.adjusted_mode; 2493 2680 const struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); ··· 2593 2604 2594 2605 limits->link.min_bpp_x16 = fxp_q4_from_int(limits->pipe.min_bpp); 2595 2606 } else { 2596 - int dsc_src_min_bpp, dsc_sink_min_bpp, dsc_min_bpp; 2597 - int dsc_src_max_bpp, dsc_sink_max_bpp, dsc_max_bpp; 2598 - int throughput_max_bpp_x16; 2599 - int joiner_max_bpp; 2607 + limits->link.min_bpp_x16 = 2608 + compute_min_compressed_bpp_x16(connector, crtc_state->output_format); 2600 2609 2601 - dsc_src_min_bpp = intel_dp_dsc_min_src_compressed_bpp(); 2602 - dsc_sink_min_bpp = intel_dp_dsc_sink_min_compressed_bpp(crtc_state); 2603 - dsc_min_bpp = max(dsc_src_min_bpp, dsc_sink_min_bpp); 2604 - limits->link.min_bpp_x16 = fxp_q4_from_int(dsc_min_bpp); 2605 - 2606 - dsc_src_max_bpp = dsc_src_max_compressed_bpp(intel_dp); 2607 - joiner_max_bpp = 2608 - get_max_compressed_bpp_with_joiner(display, 2609 - adjusted_mode->crtc_clock, 2610 - adjusted_mode->hdisplay, 2611 - intel_crtc_num_joined_pipes(crtc_state)); 2612 - dsc_sink_max_bpp = intel_dp_dsc_sink_max_compressed_bpp(connector, 2613 - crtc_state, 2614 - limits->pipe.max_bpp / 3); 2615 - dsc_max_bpp = min(dsc_sink_max_bpp, dsc_src_max_bpp); 2616 - dsc_max_bpp = min(dsc_max_bpp, joiner_max_bpp); 2617 - 2618 - max_link_bpp_x16 = min(max_link_bpp_x16, fxp_q4_from_int(dsc_max_bpp)); 2619 - 2620 - throughput_max_bpp_x16 = dsc_throughput_quirk_max_bpp_x16(connector, crtc_state); 2621 - if (throughput_max_bpp_x16 < max_link_bpp_x16) { 2622 - max_link_bpp_x16 = throughput_max_bpp_x16; 2623 - 2624 - drm_dbg_kms(display->drm, 2625 - "[CRTC:%d:%s][CONNECTOR:%d:%s] Decreasing link max bpp to " FXP_Q4_FMT " due to DSC throughput quirk\n", 2626 - crtc->base.base.id, crtc->base.name, 2627 - connector->base.base.id, connector->base.name, 2628 - FXP_Q4_ARGS(max_link_bpp_x16)); 2629 - } 2610 + max_link_bpp_x16 = 2611 + compute_max_compressed_bpp_x16(connector, 2612 + adjusted_mode->crtc_clock, 2613 + adjusted_mode->hdisplay, 2614 + intel_crtc_num_joined_pipes(crtc_state), 2615 + crtc_state->output_format, 2616 + limits->pipe.max_bpp, 2617 + max_link_bpp_x16); 2630 2618 } 2631 2619 2632 2620 limits->link.max_bpp_x16 = max_link_bpp_x16; ··· 2637 2671 int dsc_max_bpc = intel_dp_dsc_max_src_input_bpc(display); 2638 2672 2639 2673 limits->pipe.min_bpp = max(limits->pipe.min_bpp, dsc_min_bpc * 3); 2674 + limits->pipe.min_bpp = align_min_sink_dsc_input_bpp(connector, limits->pipe.min_bpp); 2675 + 2640 2676 limits->pipe.max_bpp = min(limits->pipe.max_bpp, dsc_max_bpc * 3); 2677 + limits->pipe.max_bpp = align_max_sink_dsc_input_bpp(connector, limits->pipe.max_bpp); 2641 2678 2642 2679 if (limits->pipe.min_bpp <= 0 || 2643 2680 limits->pipe.min_bpp > limits->pipe.max_bpp) { 2644 2681 drm_dbg_kms(display->drm, 2645 - "[CONNECTOR:%d:%s] Invalid DSC src/sink input BPP (src:%d-%d pipe:%d-%d)\n", 2682 + "[CONNECTOR:%d:%s] Invalid DSC src/sink input BPP (src:%d-%d pipe:%d-%d sink-align:%d-%d)\n", 2646 2683 connector->base.base.id, connector->base.name, 2647 2684 dsc_min_bpc * 3, dsc_max_bpc * 3, 2648 - orig_limits.pipe.min_bpp, orig_limits.pipe.max_bpp); 2685 + orig_limits.pipe.min_bpp, orig_limits.pipe.max_bpp, 2686 + limits->pipe.min_bpp, limits->pipe.max_bpp); 2649 2687 2650 2688 return false; 2651 2689 } ··· 2715 2745 2716 2746 intel_dp_test_compute_config(intel_dp, crtc_state, limits); 2717 2747 2718 - return intel_dp_compute_config_link_bpp_limits(intel_dp, 2719 - connector, 2748 + return intel_dp_compute_config_link_bpp_limits(connector, 2720 2749 crtc_state, 2721 2750 dsc, 2722 2751 limits);
+6 -11
drivers/gpu/drm/i915/display/intel_dp.h
··· 143 143 bool intel_digital_port_connected_locked(struct intel_encoder *encoder); 144 144 int intel_dp_dsc_compute_max_bpp(const struct intel_connector *connector, 145 145 u8 dsc_max_bpc); 146 - u16 intel_dp_dsc_get_max_compressed_bpp(struct intel_display *display, 147 - u32 link_clock, u32 lane_count, 148 - u32 mode_clock, u32 mode_hdisplay, 149 - int num_joined_pipes, 150 - enum intel_output_format output_format, 151 - u32 pipe_bpp, 152 - u32 timeslots); 153 - int intel_dp_dsc_sink_min_compressed_bpp(const struct intel_crtc_state *pipe_config); 154 - int intel_dp_dsc_sink_max_compressed_bpp(const struct intel_connector *connector, 155 - const struct intel_crtc_state *pipe_config, 156 - int bpc); 146 + bool intel_dp_mode_valid_with_dsc(struct intel_connector *connector, 147 + int link_clock, int lane_count, 148 + int mode_clock, int mode_hdisplay, 149 + int num_joined_pipes, 150 + enum intel_output_format output_format, 151 + int pipe_bpp, unsigned long bw_overhead_flags); 157 152 bool intel_dp_dsc_valid_compressed_bpp(struct intel_dp *intel_dp, int bpp_x16); 158 153 u8 intel_dp_dsc_get_slice_count(const struct intel_connector *connector, 159 154 int mode_clock, int mode_hdisplay,
+15 -62
drivers/gpu/drm/i915/display/intel_dp_mst.c
··· 463 463 { 464 464 struct intel_display *display = to_intel_display(intel_dp); 465 465 struct intel_connector *connector = to_intel_connector(conn_state->connector); 466 - int num_bpc; 467 - u8 dsc_bpc[3] = {}; 468 - int min_bpp, max_bpp, sink_min_bpp, sink_max_bpp; 469 - int min_compressed_bpp_x16, max_compressed_bpp_x16; 470 - int bpp_step_x16; 471 466 472 - max_bpp = limits->pipe.max_bpp; 473 - min_bpp = limits->pipe.min_bpp; 474 - 475 - num_bpc = drm_dp_dsc_sink_supported_input_bpcs(connector->dp.dsc_dpcd, 476 - dsc_bpc); 477 - 478 - drm_dbg_kms(display->drm, "DSC Source supported min bpp %d max bpp %d\n", 479 - min_bpp, max_bpp); 480 - 481 - sink_min_bpp = min_array(dsc_bpc, num_bpc) * 3; 482 - sink_max_bpp = max_array(dsc_bpc, num_bpc) * 3; 483 - 484 - drm_dbg_kms(display->drm, "DSC Sink supported min bpp %d max bpp %d\n", 485 - sink_min_bpp, sink_max_bpp); 486 - 487 - if (min_bpp < sink_min_bpp) 488 - min_bpp = sink_min_bpp; 489 - 490 - if (max_bpp > sink_max_bpp) 491 - max_bpp = sink_max_bpp; 492 - 493 - crtc_state->pipe_bpp = max_bpp; 494 - 495 - min_compressed_bpp_x16 = limits->link.min_bpp_x16; 496 - max_compressed_bpp_x16 = limits->link.max_bpp_x16; 467 + crtc_state->pipe_bpp = limits->pipe.max_bpp; 497 468 498 469 drm_dbg_kms(display->drm, 499 470 "DSC Sink supported compressed min bpp " FXP_Q4_FMT " compressed max bpp " FXP_Q4_FMT "\n", 500 - FXP_Q4_ARGS(min_compressed_bpp_x16), FXP_Q4_ARGS(max_compressed_bpp_x16)); 501 - 502 - bpp_step_x16 = intel_dp_dsc_bpp_step_x16(connector); 503 - 504 - max_compressed_bpp_x16 = min(max_compressed_bpp_x16, fxp_q4_from_int(crtc_state->pipe_bpp) - bpp_step_x16); 505 - 506 - drm_WARN_ON(display->drm, !is_power_of_2(bpp_step_x16)); 507 - min_compressed_bpp_x16 = round_up(min_compressed_bpp_x16, bpp_step_x16); 508 - max_compressed_bpp_x16 = round_down(max_compressed_bpp_x16, bpp_step_x16); 471 + FXP_Q4_ARGS(limits->link.min_bpp_x16), FXP_Q4_ARGS(limits->link.max_bpp_x16)); 509 472 510 473 crtc_state->lane_count = limits->max_lane_count; 511 474 crtc_state->port_clock = limits->max_rate; 512 475 513 476 return intel_dp_mtp_tu_compute_config(intel_dp, crtc_state, conn_state, 514 - min_compressed_bpp_x16, 515 - max_compressed_bpp_x16, 516 - bpp_step_x16, true); 477 + limits->link.min_bpp_x16, 478 + limits->link.max_bpp_x16, 479 + intel_dp_dsc_bpp_step_x16(connector), 480 + true); 517 481 } 518 482 519 483 static int mode_hblank_period_ns(const struct drm_display_mode *mode) ··· 1426 1462 DRM_DP_BW_OVERHEAD_MST | DRM_DP_BW_OVERHEAD_SSC_REF_CLK; 1427 1463 int ret; 1428 1464 bool dsc = false; 1429 - u16 dsc_max_compressed_bpp = 0; 1430 - u8 dsc_slice_count = 0; 1431 1465 int target_clock = mode->clock; 1432 1466 int num_joined_pipes; 1433 1467 ··· 1484 1522 return 0; 1485 1523 } 1486 1524 1487 - if (intel_dp_has_dsc(connector)) { 1525 + if (intel_dp_has_dsc(connector) && drm_dp_sink_supports_fec(connector->dp.fec_capability)) { 1488 1526 /* 1489 1527 * TBD pass the connector BPC, 1490 1528 * for now U8_MAX so that max BPC on that platform would be picked 1491 1529 */ 1492 1530 int pipe_bpp = intel_dp_dsc_compute_max_bpp(connector, U8_MAX); 1493 1531 1494 - if (drm_dp_sink_supports_fec(connector->dp.fec_capability)) { 1495 - dsc_max_compressed_bpp = 1496 - intel_dp_dsc_get_max_compressed_bpp(display, 1497 - max_link_clock, 1498 - max_lanes, 1499 - target_clock, 1500 - mode->hdisplay, 1501 - num_joined_pipes, 1502 - INTEL_OUTPUT_FORMAT_RGB, 1503 - pipe_bpp, 64); 1504 - dsc_slice_count = 1505 - intel_dp_dsc_get_slice_count(connector, 1506 - target_clock, 1507 - mode->hdisplay, 1508 - num_joined_pipes); 1509 - } 1532 + if (!drm_dp_is_uhbr_rate(max_link_clock)) 1533 + bw_overhead_flags |= DRM_DP_BW_OVERHEAD_FEC; 1510 1534 1511 - dsc = dsc_max_compressed_bpp && dsc_slice_count; 1535 + dsc = intel_dp_mode_valid_with_dsc(connector, 1536 + max_link_clock, max_lanes, 1537 + target_clock, mode->hdisplay, 1538 + num_joined_pipes, 1539 + INTEL_OUTPUT_FORMAT_RGB, pipe_bpp, 1540 + bw_overhead_flags); 1512 1541 } 1513 1542 1514 1543 if (intel_dp_joiner_needs_dsc(display, num_joined_pipes) && !dsc) {
+19 -23
drivers/gpu/drm/i915/display/intel_dram.c
··· 8 8 #include <drm/drm_managed.h> 9 9 #include <drm/drm_print.h> 10 10 11 - #include "i915_drv.h" 12 11 #include "i915_reg.h" 13 12 #include "intel_display_core.h" 14 13 #include "intel_display_utils.h" ··· 57 58 58 59 static enum intel_dram_type pnv_dram_type(struct intel_display *display) 59 60 { 60 - struct drm_i915_private *i915 = to_i915(display->drm); 61 + struct intel_uncore *uncore = to_intel_uncore(display->drm); 61 62 62 - return intel_uncore_read(&i915->uncore, CSHRDDR3CTL) & CSHRDDR3CTL_DDR3 ? 63 + return intel_uncore_read(uncore, CSHRDDR3CTL) & CSHRDDR3CTL_DDR3 ? 63 64 INTEL_DRAM_DDR3 : INTEL_DRAM_DDR2; 64 65 } 65 66 66 67 static unsigned int pnv_mem_freq(struct intel_display *display) 67 68 { 68 - struct drm_i915_private *dev_priv = to_i915(display->drm); 69 + struct intel_uncore *uncore = to_intel_uncore(display->drm); 69 70 u32 tmp; 70 71 71 - tmp = intel_uncore_read(&dev_priv->uncore, CLKCFG); 72 + tmp = intel_uncore_read(uncore, CLKCFG); 72 73 73 74 switch (tmp & CLKCFG_MEM_MASK) { 74 75 case CLKCFG_MEM_533: ··· 84 85 85 86 static unsigned int ilk_mem_freq(struct intel_display *display) 86 87 { 87 - struct drm_i915_private *dev_priv = to_i915(display->drm); 88 + struct intel_uncore *uncore = to_intel_uncore(display->drm); 88 89 u16 ddrpll; 89 90 90 - ddrpll = intel_uncore_read16(&dev_priv->uncore, DDRMPLL1); 91 + ddrpll = intel_uncore_read16(uncore, DDRMPLL1); 91 92 switch (ddrpll & 0xff) { 92 93 case 0xc: 93 94 return 800000; ··· 157 158 158 159 static unsigned int i9xx_fsb_freq(struct intel_display *display) 159 160 { 160 - struct drm_i915_private *i915 = to_i915(display->drm); 161 + struct intel_uncore *uncore = to_intel_uncore(display->drm); 161 162 u32 fsb; 162 163 163 164 /* ··· 168 169 * don't know which registers have that information, 169 170 * and all the relevant docs have gone to bit heaven :( 170 171 */ 171 - fsb = intel_uncore_read(&i915->uncore, CLKCFG) & CLKCFG_FSB_MASK; 172 + fsb = intel_uncore_read(uncore, CLKCFG) & CLKCFG_FSB_MASK; 172 173 173 174 if (display->platform.pineview || display->platform.mobile) { 174 175 switch (fsb) { ··· 213 214 214 215 static unsigned int ilk_fsb_freq(struct intel_display *display) 215 216 { 216 - struct drm_i915_private *dev_priv = to_i915(display->drm); 217 + struct intel_uncore *uncore = to_intel_uncore(display->drm); 217 218 u16 fsb; 218 219 219 - fsb = intel_uncore_read16(&dev_priv->uncore, CSIPLL0) & 0x3ff; 220 + fsb = intel_uncore_read16(uncore, CSIPLL0) & 0x3ff; 220 221 221 222 switch (fsb) { 222 223 case 0x00c: ··· 483 484 static int 484 485 skl_dram_get_channels_info(struct intel_display *display, struct dram_info *dram_info) 485 486 { 486 - struct drm_i915_private *i915 = to_i915(display->drm); 487 + struct intel_uncore *uncore = to_intel_uncore(display->drm); 487 488 struct dram_channel_info ch0 = {}, ch1 = {}; 488 489 u32 val; 489 490 int ret; ··· 491 492 /* Assume 16Gb+ DIMMs are present until proven otherwise */ 492 493 dram_info->has_16gb_dimms = true; 493 494 494 - val = intel_uncore_read(&i915->uncore, 495 - SKL_MAD_DIMM_CH0_0_0_0_MCHBAR_MCMAIN); 495 + val = intel_uncore_read(uncore, SKL_MAD_DIMM_CH0_0_0_0_MCHBAR_MCMAIN); 496 496 ret = skl_dram_get_channel_info(display, &ch0, 0, val); 497 497 if (ret == 0) 498 498 dram_info->num_channels++; 499 499 500 - val = intel_uncore_read(&i915->uncore, 501 - SKL_MAD_DIMM_CH1_0_0_0_MCHBAR_MCMAIN); 500 + val = intel_uncore_read(uncore, SKL_MAD_DIMM_CH1_0_0_0_MCHBAR_MCMAIN); 502 501 ret = skl_dram_get_channel_info(display, &ch1, 1, val); 503 502 if (ret == 0) 504 503 dram_info->num_channels++; ··· 527 530 static enum intel_dram_type 528 531 skl_get_dram_type(struct intel_display *display) 529 532 { 530 - struct drm_i915_private *i915 = to_i915(display->drm); 533 + struct intel_uncore *uncore = to_intel_uncore(display->drm); 531 534 u32 val; 532 535 533 - val = intel_uncore_read(&i915->uncore, 534 - SKL_MAD_INTER_CHANNEL_0_0_0_MCHBAR_MCMAIN); 536 + val = intel_uncore_read(uncore, SKL_MAD_INTER_CHANNEL_0_0_0_MCHBAR_MCMAIN); 535 537 536 538 switch (val & SKL_DRAM_DDR_TYPE_MASK) { 537 539 case SKL_DRAM_DDR_TYPE_DDR3: ··· 641 645 642 646 static int bxt_get_dram_info(struct intel_display *display, struct dram_info *dram_info) 643 647 { 644 - struct drm_i915_private *i915 = to_i915(display->drm); 648 + struct intel_uncore *uncore = to_intel_uncore(display->drm); 645 649 u32 val; 646 650 u8 valid_ranks = 0; 647 651 int i; ··· 653 657 struct dram_dimm_info dimm; 654 658 enum intel_dram_type type; 655 659 656 - val = intel_uncore_read(&i915->uncore, BXT_D_CR_DRP0_DUNIT(i)); 660 + val = intel_uncore_read(uncore, BXT_D_CR_DRP0_DUNIT(i)); 657 661 if (val == 0xFFFFFFFF) 658 662 continue; 659 663 ··· 766 770 767 771 static int xelpdp_get_dram_info(struct intel_display *display, struct dram_info *dram_info) 768 772 { 769 - struct drm_i915_private *i915 = to_i915(display->drm); 770 - u32 val = intel_uncore_read(&i915->uncore, MTL_MEM_SS_INFO_GLOBAL); 773 + struct intel_uncore *uncore = to_intel_uncore(display->drm); 774 + u32 val = intel_uncore_read(uncore, MTL_MEM_SS_INFO_GLOBAL); 771 775 772 776 switch (REG_FIELD_GET(MTL_DDR_TYPE_MASK, val)) { 773 777 case 0:
+30 -1
drivers/gpu/drm/i915/display/intel_dsb.c
··· 704 704 if (crtc_state->has_psr) 705 705 intel_dsb_emit_wait_dsl(dsb, DSB_OPCODE_WAIT_DSL_OUT, 0, 0); 706 706 707 - if (pre_commit_is_vrr_active(state, crtc)) { 707 + if (pre_commit_is_vrr_active(state, crtc) && crtc_state->vrr.dc_balance.enable) { 708 + int vblank_delay = crtc_state->set_context_latency; 709 + int vmin_vblank_start, vmax_vblank_start; 710 + 711 + vmin_vblank_start = intel_vrr_dcb_vmin_vblank_start_next(crtc_state); 712 + 713 + if (vmin_vblank_start >= 0) { 714 + end = vmin_vblank_start; 715 + start = end - vblank_delay - latency; 716 + intel_dsb_wait_scanline_out(state, dsb, start, end); 717 + } 718 + 719 + vmax_vblank_start = intel_vrr_dcb_vmax_vblank_start_next(crtc_state); 720 + 721 + if (vmax_vblank_start >= 0) { 722 + end = vmax_vblank_start; 723 + start = end - vblank_delay - latency; 724 + intel_dsb_wait_scanline_out(state, dsb, start, end); 725 + } 726 + 727 + vmin_vblank_start = intel_vrr_dcb_vmin_vblank_start_final(crtc_state); 728 + end = vmin_vblank_start; 729 + start = end - vblank_delay - latency; 730 + intel_dsb_wait_scanline_out(state, dsb, start, end); 731 + 732 + vmax_vblank_start = intel_vrr_dcb_vmax_vblank_start_final(crtc_state); 733 + end = vmax_vblank_start; 734 + start = end - vblank_delay - latency; 735 + intel_dsb_wait_scanline_out(state, dsb, start, end); 736 + } else if (pre_commit_is_vrr_active(state, crtc)) { 708 737 int vblank_delay = crtc_state->set_context_latency; 709 738 710 739 end = intel_vrr_vmin_vblank_start(crtc_state);
+2 -2
drivers/gpu/drm/i915/display/intel_dsb.h
··· 1 - /* SPDX-License-Identifier: MIT 2 - * 1 + /* SPDX-License-Identifier: MIT */ 2 + /* 3 3 * Copyright © 2019 Intel Corporation 4 4 */ 5 5
+2 -2
drivers/gpu/drm/i915/display/intel_dsb_buffer.h
··· 1 - /* SPDX-License-Identifier: MIT 2 - * 1 + /* SPDX-License-Identifier: MIT */ 2 + /* 3 3 * Copyright © 2023 Intel Corporation 4 4 */ 5 5
+43
drivers/gpu/drm/i915/display/intel_gvt_api.c
··· 1 + // SPDX-License-Identifier: MIT 2 + /* 3 + * Copyright © 2025 Intel Corporation 4 + */ 5 + 6 + #include <linux/types.h> 7 + 8 + #include "intel_display_core.h" 9 + #include "intel_display_regs.h" 10 + #include "intel_gvt_api.h" 11 + 12 + u32 intel_display_device_pipe_offset(struct intel_display *display, enum pipe pipe) 13 + { 14 + return INTEL_DISPLAY_DEVICE_PIPE_OFFSET(display, pipe); 15 + } 16 + EXPORT_SYMBOL_NS_GPL(intel_display_device_pipe_offset, "I915_GVT"); 17 + 18 + u32 intel_display_device_trans_offset(struct intel_display *display, enum transcoder trans) 19 + { 20 + return INTEL_DISPLAY_DEVICE_TRANS_OFFSET(display, trans); 21 + } 22 + EXPORT_SYMBOL_NS_GPL(intel_display_device_trans_offset, "I915_GVT"); 23 + 24 + u32 intel_display_device_cursor_offset(struct intel_display *display, enum pipe pipe) 25 + { 26 + return INTEL_DISPLAY_DEVICE_CURSOR_OFFSET(display, pipe); 27 + } 28 + EXPORT_SYMBOL_NS_GPL(intel_display_device_cursor_offset, "I915_GVT"); 29 + 30 + u32 intel_display_device_mmio_base(struct intel_display *display) 31 + { 32 + return DISPLAY_MMIO_BASE(display); 33 + } 34 + EXPORT_SYMBOL_NS_GPL(intel_display_device_mmio_base, "I915_GVT"); 35 + 36 + bool intel_display_device_pipe_valid(struct intel_display *display, enum pipe pipe) 37 + { 38 + if (pipe < PIPE_A || pipe >= I915_MAX_PIPES) 39 + return false; 40 + 41 + return DISPLAY_RUNTIME_INFO(display)->pipe_mask & BIT(pipe); 42 + } 43 + EXPORT_SYMBOL_NS_GPL(intel_display_device_pipe_valid, "I915_GVT");
+21
drivers/gpu/drm/i915/display/intel_gvt_api.h
··· 1 + /* SPDX-License-Identifier: MIT */ 2 + /* 3 + * Copyright © 2025 Intel Corporation 4 + */ 5 + 6 + #ifndef __INTEL_GVT_API_H__ 7 + #define __INTEL_GVT_API_H__ 8 + 9 + #include <linux/types.h> 10 + 11 + enum pipe; 12 + enum transcoder; 13 + struct intel_display; 14 + 15 + u32 intel_display_device_pipe_offset(struct intel_display *display, enum pipe pipe); 16 + u32 intel_display_device_trans_offset(struct intel_display *display, enum transcoder trans); 17 + u32 intel_display_device_cursor_offset(struct intel_display *display, enum pipe pipe); 18 + u32 intel_display_device_mmio_base(struct intel_display *display); 19 + bool intel_display_device_pipe_valid(struct intel_display *display, enum pipe pipe); 20 + 21 + #endif /* __INTEL_GVT_API_H__ */
+193
drivers/gpu/drm/i915/display/intel_initial_plane.c
··· 1 + // SPDX-License-Identifier: MIT 2 + /* Copyright © 2025 Intel Corporation */ 3 + 4 + #include <drm/drm_print.h> 5 + #include <drm/intel/display_parent_interface.h> 6 + 7 + #include "intel_display_core.h" 8 + #include "intel_display_types.h" 9 + #include "intel_fb.h" 10 + #include "intel_frontbuffer.h" 11 + #include "intel_initial_plane.h" 12 + #include "intel_plane.h" 13 + 14 + void intel_initial_plane_vblank_wait(struct intel_crtc *crtc) 15 + { 16 + struct intel_display *display = to_intel_display(crtc); 17 + 18 + display->parent->initial_plane->vblank_wait(&crtc->base); 19 + } 20 + 21 + static const struct intel_plane_state * 22 + intel_reuse_initial_plane_obj(struct intel_crtc *this, 23 + const struct intel_initial_plane_config plane_configs[]) 24 + { 25 + struct intel_display *display = to_intel_display(this); 26 + struct intel_crtc *crtc; 27 + 28 + for_each_intel_crtc(display->drm, crtc) { 29 + struct intel_plane *plane = 30 + to_intel_plane(crtc->base.primary); 31 + const struct intel_plane_state *plane_state = 32 + to_intel_plane_state(plane->base.state); 33 + const struct intel_crtc_state *crtc_state = 34 + to_intel_crtc_state(crtc->base.state); 35 + 36 + if (!crtc_state->hw.active) 37 + continue; 38 + 39 + if (!plane_state->ggtt_vma) 40 + continue; 41 + 42 + if (plane_configs[this->pipe].base == plane_configs[crtc->pipe].base) 43 + return plane_state; 44 + } 45 + 46 + return NULL; 47 + } 48 + 49 + static struct drm_gem_object * 50 + intel_alloc_initial_plane_obj(struct intel_display *display, 51 + struct intel_initial_plane_config *plane_config) 52 + { 53 + struct intel_framebuffer *fb = plane_config->fb; 54 + 55 + switch (fb->base.modifier) { 56 + case DRM_FORMAT_MOD_LINEAR: 57 + case I915_FORMAT_MOD_X_TILED: 58 + case I915_FORMAT_MOD_Y_TILED: 59 + case I915_FORMAT_MOD_4_TILED: 60 + break; 61 + default: 62 + drm_dbg_kms(display->drm, "Unsupported modifier for initial FB: 0x%llx\n", 63 + fb->base.modifier); 64 + return NULL; 65 + } 66 + 67 + return display->parent->initial_plane->alloc_obj(display->drm, plane_config); 68 + } 69 + 70 + static void 71 + intel_find_initial_plane_obj(struct intel_crtc *crtc, 72 + struct intel_initial_plane_config plane_configs[]) 73 + { 74 + struct intel_display *display = to_intel_display(crtc); 75 + struct intel_initial_plane_config *plane_config = &plane_configs[crtc->pipe]; 76 + struct intel_plane *plane = to_intel_plane(crtc->base.primary); 77 + struct intel_plane_state *plane_state = to_intel_plane_state(plane->base.state); 78 + struct drm_framebuffer *fb; 79 + struct i915_vma *vma; 80 + int ret; 81 + 82 + /* 83 + * TODO: 84 + * Disable planes if get_initial_plane_config() failed. 85 + * Make sure things work if the surface base is not page aligned. 86 + */ 87 + if (!plane_config->fb) 88 + return; 89 + 90 + if (intel_alloc_initial_plane_obj(display, plane_config)) { 91 + fb = &plane_config->fb->base; 92 + vma = plane_config->vma; 93 + } else { 94 + const struct intel_plane_state *other_plane_state; 95 + 96 + other_plane_state = intel_reuse_initial_plane_obj(crtc, plane_configs); 97 + if (!other_plane_state) 98 + goto nofb; 99 + 100 + fb = other_plane_state->hw.fb; 101 + vma = other_plane_state->ggtt_vma; 102 + } 103 + 104 + plane_state->uapi.rotation = plane_config->rotation; 105 + intel_fb_fill_view(to_intel_framebuffer(fb), 106 + plane_state->uapi.rotation, &plane_state->view); 107 + 108 + ret = display->parent->initial_plane->setup(plane->base.state, plane_config, fb, vma); 109 + if (ret) 110 + goto nofb; 111 + 112 + plane_state->uapi.src_x = 0; 113 + plane_state->uapi.src_y = 0; 114 + plane_state->uapi.src_w = fb->width << 16; 115 + plane_state->uapi.src_h = fb->height << 16; 116 + 117 + plane_state->uapi.crtc_x = 0; 118 + plane_state->uapi.crtc_y = 0; 119 + plane_state->uapi.crtc_w = fb->width; 120 + plane_state->uapi.crtc_h = fb->height; 121 + 122 + plane_state->uapi.fb = fb; 123 + drm_framebuffer_get(fb); 124 + 125 + plane_state->uapi.crtc = &crtc->base; 126 + intel_plane_copy_uapi_to_hw_state(plane_state, plane_state, crtc); 127 + 128 + atomic_or(plane->frontbuffer_bit, &to_intel_frontbuffer(fb)->bits); 129 + 130 + return; 131 + 132 + nofb: 133 + /* 134 + * We've failed to reconstruct the BIOS FB. Current display state 135 + * indicates that the primary plane is visible, but has a NULL FB, 136 + * which will lead to problems later if we don't fix it up. The 137 + * simplest solution is to just disable the primary plane now and 138 + * pretend the BIOS never had it enabled. 139 + */ 140 + intel_plane_disable_noatomic(crtc, plane); 141 + } 142 + 143 + static void plane_config_fini(struct intel_display *display, 144 + struct intel_initial_plane_config *plane_config) 145 + { 146 + if (plane_config->fb) { 147 + struct drm_framebuffer *fb = &plane_config->fb->base; 148 + 149 + /* We may only have the stub and not a full framebuffer */ 150 + if (drm_framebuffer_read_refcount(fb)) 151 + drm_framebuffer_put(fb); 152 + else 153 + kfree(fb); 154 + } 155 + 156 + display->parent->initial_plane->config_fini(plane_config); 157 + } 158 + 159 + void intel_initial_plane_config(struct intel_display *display) 160 + { 161 + struct intel_initial_plane_config plane_configs[I915_MAX_PIPES] = {}; 162 + struct intel_crtc *crtc; 163 + 164 + for_each_intel_crtc(display->drm, crtc) { 165 + const struct intel_crtc_state *crtc_state = 166 + to_intel_crtc_state(crtc->base.state); 167 + struct intel_initial_plane_config *plane_config = 168 + &plane_configs[crtc->pipe]; 169 + 170 + if (!crtc_state->hw.active) 171 + continue; 172 + 173 + /* 174 + * Note that reserving the BIOS fb up front prevents us 175 + * from stuffing other stolen allocations like the ring 176 + * on top. This prevents some ugliness at boot time, and 177 + * can even allow for smooth boot transitions if the BIOS 178 + * fb is large enough for the active pipe configuration. 179 + */ 180 + display->funcs.display->get_initial_plane_config(crtc, plane_config); 181 + 182 + /* 183 + * If the fb is shared between multiple heads, we'll 184 + * just get the first one. 185 + */ 186 + intel_find_initial_plane_obj(crtc, plane_configs); 187 + 188 + if (display->funcs.display->fixup_initial_plane_config(crtc, plane_config)) 189 + intel_initial_plane_vblank_wait(crtc); 190 + 191 + plane_config_fini(display, plane_config); 192 + } 193 + }
+24 -30
drivers/gpu/drm/i915/display/intel_lt_phy.c
··· 31 31 #define INTEL_LT_PHY_BOTH_LANES (INTEL_LT_PHY_LANE1 |\ 32 32 INTEL_LT_PHY_LANE0) 33 33 #define MODE_DP 3 34 + #define MODE_HDMI_20 4 34 35 #define Q32_TO_INT(x) ((x) >> 32) 35 36 #define Q32_TO_FRAC(x) ((x) & 0xFFFFFFFF) 36 37 #define DCO_MIN_FREQ_MHZ 11850 ··· 1752 1751 intel_lt_phy_calc_port_clock(struct intel_encoder *encoder, 1753 1752 const struct intel_crtc_state *crtc_state) 1754 1753 { 1754 + struct intel_display *display = to_intel_display(encoder); 1755 1755 int clk; 1756 1756 const struct intel_lt_phy_pll_state *lt_state = 1757 1757 &crtc_state->dpll_hw_state.ltpll; ··· 1770 1768 rate = REG_FIELD_GET8(LT_PHY_VDR_RATE_ENCODING_MASK, 1771 1769 lt_state->config[0]); 1772 1770 clk = intel_lt_phy_get_dp_clock(rate); 1773 - } else { 1771 + } else if (mode == MODE_HDMI_20) { 1774 1772 clk = intel_lt_phy_calc_hdmi_port_clock(crtc_state); 1773 + } else { 1774 + drm_WARN_ON(display->drm, "Unsupported LT PHY Mode!\n"); 1775 + clk = xe3plpd_lt_hdmi_252.clock; 1775 1776 } 1776 1777 1777 1778 return clk; ··· 2212 2207 intel_lt_phy_pll_compare_hw_state(const struct intel_lt_phy_pll_state *a, 2213 2208 const struct intel_lt_phy_pll_state *b) 2214 2209 { 2215 - if (memcmp(&a->config, &b->config, sizeof(a->config)) != 0) 2216 - return false; 2210 + /* 2211 + * With LT PHY values other than VDR0_CONFIG and VDR2_CONFIG are 2212 + * unreliable. They cannot always be read back since internally 2213 + * after power gating values are not restored back to the 2214 + * shadow VDR registers. Thus we do not compare the whole state 2215 + * just the two VDR registers. 2216 + */ 2217 + if (a->config[0] == b->config[0] && 2218 + a->config[2] == b->config[2]) 2219 + return true; 2217 2220 2218 - if (memcmp(&a->data, &b->data, sizeof(a->data)) != 0) 2219 - return false; 2220 - 2221 - return true; 2221 + return false; 2222 2222 } 2223 2223 2224 2224 void intel_lt_phy_pll_readout_hw_state(struct intel_encoder *encoder, ··· 2269 2259 struct intel_encoder *encoder; 2270 2260 struct intel_lt_phy_pll_state pll_hw_state = {}; 2271 2261 const struct intel_lt_phy_pll_state *pll_sw_state = &new_crtc_state->dpll_hw_state.ltpll; 2272 - int clock; 2273 - int i, j; 2274 2262 2275 2263 if (DISPLAY_VER(display) < 35) 2276 2264 return; ··· 2283 2275 2284 2276 encoder = intel_get_crtc_new_encoder(state, new_crtc_state); 2285 2277 intel_lt_phy_pll_readout_hw_state(encoder, new_crtc_state, &pll_hw_state); 2286 - clock = intel_lt_phy_calc_port_clock(encoder, new_crtc_state); 2287 2278 2288 2279 dig_port = enc_to_dig_port(encoder); 2289 2280 if (intel_tc_port_in_tbt_alt_mode(dig_port)) 2290 2281 return; 2291 2282 2292 - INTEL_DISPLAY_STATE_WARN(display, pll_hw_state.clock != clock, 2293 - "[CRTC:%d:%s] mismatch in LT PHY: Register CLOCK (expected %d, found %d)", 2283 + INTEL_DISPLAY_STATE_WARN(display, pll_hw_state.config[0] != pll_sw_state->config[0], 2284 + "[CRTC:%d:%s] mismatch in LT PHY PLL CONFIG 0: (expected 0x%04x, found 0x%04x)", 2294 2285 crtc->base.base.id, crtc->base.name, 2295 - pll_sw_state->clock, pll_hw_state.clock); 2296 - 2297 - for (i = 0; i < 3; i++) { 2298 - INTEL_DISPLAY_STATE_WARN(display, pll_hw_state.config[i] != pll_sw_state->config[i], 2299 - "[CRTC:%d:%s] mismatch in LT PHY PLL CONFIG%d: (expected 0x%04x, found 0x%04x)", 2300 - crtc->base.base.id, crtc->base.name, i, 2301 - pll_sw_state->config[i], pll_hw_state.config[i]); 2302 - } 2303 - 2304 - for (i = 0; i <= 12; i++) { 2305 - for (j = 3; j >= 0; j--) 2306 - INTEL_DISPLAY_STATE_WARN(display, 2307 - pll_hw_state.data[i][j] != 2308 - pll_sw_state->data[i][j], 2309 - "[CRTC:%d:%s] mismatch in LT PHY PLL DATA[%d][%d]: (expected 0x%04x, found 0x%04x)", 2310 - crtc->base.base.id, crtc->base.name, i, j, 2311 - pll_sw_state->data[i][j], pll_hw_state.data[i][j]); 2312 - } 2286 + pll_sw_state->config[0], pll_hw_state.config[0]); 2287 + INTEL_DISPLAY_STATE_WARN(display, pll_hw_state.config[2] != pll_sw_state->config[2], 2288 + "[CRTC:%d:%s] mismatch in LT PHY PLL CONFIG 2: (expected 0x%04x, found 0x%04x)", 2289 + crtc->base.base.id, crtc->base.name, 2290 + pll_sw_state->config[2], pll_hw_state.config[2]); 2313 2291 } 2314 2292 2315 2293 void intel_xe3plpd_pll_enable(struct intel_encoder *encoder,
+2 -2
drivers/gpu/drm/i915/display/intel_lt_phy.h
··· 1 - /* SPDX-License-Identifier: MIT 2 - * 1 + /* SPDX-License-Identifier: MIT */ 2 + /* 3 3 * Copyright © 2025 Intel Corporation 4 4 */ 5 5
+2 -2
drivers/gpu/drm/i915/display/intel_lt_phy_regs.h
··· 1 - /* SPDX-License-Identifier: MIT 2 - * 1 + /* SPDX-License-Identifier: MIT */ 2 + /* 3 3 * Copyright © 2025 Intel Corporation 4 4 */ 5 5
-442
drivers/gpu/drm/i915/display/intel_plane_initial.c
··· 1 - // SPDX-License-Identifier: MIT 2 - /* 3 - * Copyright © 2021 Intel Corporation 4 - */ 5 - 6 - #include <drm/drm_print.h> 7 - 8 - #include "gem/i915_gem_lmem.h" 9 - #include "gem/i915_gem_region.h" 10 - #include "i915_drv.h" 11 - #include "intel_crtc.h" 12 - #include "intel_display.h" 13 - #include "intel_display_core.h" 14 - #include "intel_display_types.h" 15 - #include "intel_fb.h" 16 - #include "intel_frontbuffer.h" 17 - #include "intel_plane.h" 18 - #include "intel_plane_initial.h" 19 - 20 - void intel_plane_initial_vblank_wait(struct intel_crtc *crtc) 21 - { 22 - intel_crtc_wait_for_next_vblank(crtc); 23 - } 24 - 25 - static bool 26 - intel_reuse_initial_plane_obj(struct intel_crtc *this, 27 - const struct intel_initial_plane_config plane_configs[], 28 - struct drm_framebuffer **fb, 29 - struct i915_vma **vma) 30 - { 31 - struct intel_display *display = to_intel_display(this); 32 - struct intel_crtc *crtc; 33 - 34 - for_each_intel_crtc(display->drm, crtc) { 35 - struct intel_plane *plane = 36 - to_intel_plane(crtc->base.primary); 37 - const struct intel_plane_state *plane_state = 38 - to_intel_plane_state(plane->base.state); 39 - const struct intel_crtc_state *crtc_state = 40 - to_intel_crtc_state(crtc->base.state); 41 - 42 - if (!crtc_state->hw.active) 43 - continue; 44 - 45 - if (!plane_state->ggtt_vma) 46 - continue; 47 - 48 - if (plane_configs[this->pipe].base == plane_configs[crtc->pipe].base) { 49 - *fb = plane_state->hw.fb; 50 - *vma = plane_state->ggtt_vma; 51 - return true; 52 - } 53 - } 54 - 55 - return false; 56 - } 57 - 58 - static enum intel_memory_type 59 - initial_plane_memory_type(struct intel_display *display) 60 - { 61 - struct drm_i915_private *i915 = to_i915(display->drm); 62 - 63 - if (display->platform.dgfx) 64 - return INTEL_MEMORY_LOCAL; 65 - else if (HAS_LMEMBAR_SMEM_STOLEN(i915)) 66 - return INTEL_MEMORY_STOLEN_LOCAL; 67 - else 68 - return INTEL_MEMORY_STOLEN_SYSTEM; 69 - } 70 - 71 - static bool 72 - initial_plane_phys(struct intel_display *display, 73 - struct intel_initial_plane_config *plane_config) 74 - { 75 - struct drm_i915_private *i915 = to_i915(display->drm); 76 - struct i915_ggtt *ggtt = to_gt(i915)->ggtt; 77 - struct intel_memory_region *mem; 78 - enum intel_memory_type mem_type; 79 - bool is_present, is_local; 80 - dma_addr_t dma_addr; 81 - u32 base; 82 - 83 - mem_type = initial_plane_memory_type(display); 84 - mem = intel_memory_region_by_type(i915, mem_type); 85 - if (!mem) { 86 - drm_dbg_kms(display->drm, 87 - "Initial plane memory region (type %s) not initialized\n", 88 - intel_memory_type_str(mem_type)); 89 - return false; 90 - } 91 - 92 - base = round_down(plane_config->base, I915_GTT_MIN_ALIGNMENT); 93 - 94 - dma_addr = intel_ggtt_read_entry(&ggtt->vm, base, &is_present, &is_local); 95 - 96 - if (!is_present) { 97 - drm_err(display->drm, 98 - "Initial plane FB PTE not present\n"); 99 - return false; 100 - } 101 - 102 - if (intel_memory_type_is_local(mem->type) != is_local) { 103 - drm_err(display->drm, 104 - "Initial plane FB PTE unsuitable for %s\n", 105 - mem->region.name); 106 - return false; 107 - } 108 - 109 - if (dma_addr < mem->region.start || dma_addr > mem->region.end) { 110 - drm_err(display->drm, 111 - "Initial plane programming using invalid range, dma_addr=%pa (%s [%pa-%pa])\n", 112 - &dma_addr, mem->region.name, &mem->region.start, &mem->region.end); 113 - return false; 114 - } 115 - 116 - drm_dbg(display->drm, 117 - "Using dma_addr=%pa, based on initial plane programming\n", 118 - &dma_addr); 119 - 120 - plane_config->phys_base = dma_addr - mem->region.start; 121 - plane_config->mem = mem; 122 - 123 - return true; 124 - } 125 - 126 - static struct i915_vma * 127 - initial_plane_vma(struct intel_display *display, 128 - struct intel_initial_plane_config *plane_config) 129 - { 130 - struct drm_i915_private *i915 = to_i915(display->drm); 131 - struct intel_memory_region *mem; 132 - struct drm_i915_gem_object *obj; 133 - struct drm_mm_node orig_mm = {}; 134 - struct i915_vma *vma; 135 - resource_size_t phys_base; 136 - unsigned int tiling; 137 - u32 base, size; 138 - u64 pinctl; 139 - 140 - if (plane_config->size == 0) 141 - return NULL; 142 - 143 - if (!initial_plane_phys(display, plane_config)) 144 - return NULL; 145 - 146 - phys_base = plane_config->phys_base; 147 - mem = plane_config->mem; 148 - 149 - base = round_down(plane_config->base, I915_GTT_MIN_ALIGNMENT); 150 - size = round_up(plane_config->base + plane_config->size, 151 - mem->min_page_size); 152 - size -= base; 153 - 154 - /* 155 - * If the FB is too big, just don't use it since fbdev is not very 156 - * important and we should probably use that space with FBC or other 157 - * features. 158 - */ 159 - if (IS_ENABLED(CONFIG_FRAMEBUFFER_CONSOLE) && 160 - mem == i915->mm.stolen_region && 161 - size * 2 > i915->dsm.usable_size) { 162 - drm_dbg_kms(display->drm, "Initial FB size exceeds half of stolen, discarding\n"); 163 - return NULL; 164 - } 165 - 166 - obj = i915_gem_object_create_region_at(mem, phys_base, size, 167 - I915_BO_ALLOC_USER | 168 - I915_BO_PREALLOC); 169 - if (IS_ERR(obj)) { 170 - drm_dbg_kms(display->drm, "Failed to preallocate initial FB in %s\n", 171 - mem->region.name); 172 - return NULL; 173 - } 174 - 175 - /* 176 - * Mark it WT ahead of time to avoid changing the 177 - * cache_level during fbdev initialization. The 178 - * unbind there would get stuck waiting for rcu. 179 - */ 180 - i915_gem_object_set_cache_coherency(obj, HAS_WT(i915) ? 181 - I915_CACHE_WT : I915_CACHE_NONE); 182 - 183 - tiling = intel_fb_modifier_to_tiling(plane_config->fb->base.modifier); 184 - 185 - switch (tiling) { 186 - case I915_TILING_NONE: 187 - break; 188 - case I915_TILING_X: 189 - case I915_TILING_Y: 190 - obj->tiling_and_stride = 191 - plane_config->fb->base.pitches[0] | 192 - tiling; 193 - break; 194 - default: 195 - MISSING_CASE(tiling); 196 - goto err_obj; 197 - } 198 - 199 - /* 200 - * MTL GOP likes to place the framebuffer high up in ggtt, 201 - * which can cause problems for ggtt_reserve_guc_top(). 202 - * Try to pin it to a low ggtt address instead to avoid that. 203 - */ 204 - base = 0; 205 - 206 - if (base != plane_config->base) { 207 - struct i915_ggtt *ggtt = to_gt(i915)->ggtt; 208 - int ret; 209 - 210 - /* 211 - * Make sure the original and new locations 212 - * can't overlap. That would corrupt the original 213 - * PTEs which are still being used for scanout. 214 - */ 215 - ret = i915_gem_gtt_reserve(&ggtt->vm, NULL, &orig_mm, 216 - size, plane_config->base, 217 - I915_COLOR_UNEVICTABLE, PIN_NOEVICT); 218 - if (ret) 219 - goto err_obj; 220 - } 221 - 222 - vma = i915_vma_instance(obj, &to_gt(i915)->ggtt->vm, NULL); 223 - if (IS_ERR(vma)) 224 - goto err_obj; 225 - 226 - retry: 227 - pinctl = PIN_GLOBAL | PIN_OFFSET_FIXED | base; 228 - if (!i915_gem_object_is_lmem(obj)) 229 - pinctl |= PIN_MAPPABLE; 230 - if (i915_vma_pin(vma, 0, 0, pinctl)) { 231 - if (drm_mm_node_allocated(&orig_mm)) { 232 - drm_mm_remove_node(&orig_mm); 233 - /* 234 - * Try again, but this time pin 235 - * it to its original location. 236 - */ 237 - base = plane_config->base; 238 - goto retry; 239 - } 240 - goto err_obj; 241 - } 242 - 243 - if (i915_gem_object_is_tiled(obj) && 244 - !i915_vma_is_map_and_fenceable(vma)) 245 - goto err_obj; 246 - 247 - if (drm_mm_node_allocated(&orig_mm)) 248 - drm_mm_remove_node(&orig_mm); 249 - 250 - drm_dbg_kms(display->drm, 251 - "Initial plane fb bound to 0x%x in the ggtt (original 0x%x)\n", 252 - i915_ggtt_offset(vma), plane_config->base); 253 - 254 - return vma; 255 - 256 - err_obj: 257 - if (drm_mm_node_allocated(&orig_mm)) 258 - drm_mm_remove_node(&orig_mm); 259 - i915_gem_object_put(obj); 260 - return NULL; 261 - } 262 - 263 - static bool 264 - intel_alloc_initial_plane_obj(struct intel_crtc *crtc, 265 - struct intel_initial_plane_config *plane_config) 266 - { 267 - struct intel_display *display = to_intel_display(crtc); 268 - struct drm_mode_fb_cmd2 mode_cmd = {}; 269 - struct drm_framebuffer *fb = &plane_config->fb->base; 270 - struct i915_vma *vma; 271 - 272 - switch (fb->modifier) { 273 - case DRM_FORMAT_MOD_LINEAR: 274 - case I915_FORMAT_MOD_X_TILED: 275 - case I915_FORMAT_MOD_Y_TILED: 276 - case I915_FORMAT_MOD_4_TILED: 277 - break; 278 - default: 279 - drm_dbg(display->drm, 280 - "Unsupported modifier for initial FB: 0x%llx\n", 281 - fb->modifier); 282 - return false; 283 - } 284 - 285 - vma = initial_plane_vma(display, plane_config); 286 - if (!vma) 287 - return false; 288 - 289 - mode_cmd.pixel_format = fb->format->format; 290 - mode_cmd.width = fb->width; 291 - mode_cmd.height = fb->height; 292 - mode_cmd.pitches[0] = fb->pitches[0]; 293 - mode_cmd.modifier[0] = fb->modifier; 294 - mode_cmd.flags = DRM_MODE_FB_MODIFIERS; 295 - 296 - if (intel_framebuffer_init(to_intel_framebuffer(fb), 297 - intel_bo_to_drm_bo(vma->obj), 298 - fb->format, &mode_cmd)) { 299 - drm_dbg_kms(display->drm, "intel fb init failed\n"); 300 - goto err_vma; 301 - } 302 - 303 - plane_config->vma = vma; 304 - return true; 305 - 306 - err_vma: 307 - i915_vma_put(vma); 308 - return false; 309 - } 310 - 311 - static void 312 - intel_find_initial_plane_obj(struct intel_crtc *crtc, 313 - struct intel_initial_plane_config plane_configs[]) 314 - { 315 - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 316 - struct intel_initial_plane_config *plane_config = 317 - &plane_configs[crtc->pipe]; 318 - struct intel_plane *plane = 319 - to_intel_plane(crtc->base.primary); 320 - struct intel_plane_state *plane_state = 321 - to_intel_plane_state(plane->base.state); 322 - struct drm_framebuffer *fb; 323 - struct i915_vma *vma; 324 - 325 - /* 326 - * TODO: 327 - * Disable planes if get_initial_plane_config() failed. 328 - * Make sure things work if the surface base is not page aligned. 329 - */ 330 - if (!plane_config->fb) 331 - return; 332 - 333 - if (intel_alloc_initial_plane_obj(crtc, plane_config)) { 334 - fb = &plane_config->fb->base; 335 - vma = plane_config->vma; 336 - goto valid_fb; 337 - } 338 - 339 - /* 340 - * Failed to alloc the obj, check to see if we should share 341 - * an fb with another CRTC instead 342 - */ 343 - if (intel_reuse_initial_plane_obj(crtc, plane_configs, &fb, &vma)) 344 - goto valid_fb; 345 - 346 - /* 347 - * We've failed to reconstruct the BIOS FB. Current display state 348 - * indicates that the primary plane is visible, but has a NULL FB, 349 - * which will lead to problems later if we don't fix it up. The 350 - * simplest solution is to just disable the primary plane now and 351 - * pretend the BIOS never had it enabled. 352 - */ 353 - intel_plane_disable_noatomic(crtc, plane); 354 - 355 - return; 356 - 357 - valid_fb: 358 - plane_state->uapi.rotation = plane_config->rotation; 359 - intel_fb_fill_view(to_intel_framebuffer(fb), 360 - plane_state->uapi.rotation, &plane_state->view); 361 - 362 - __i915_vma_pin(vma); 363 - plane_state->ggtt_vma = i915_vma_get(vma); 364 - if (intel_plane_uses_fence(plane_state) && 365 - i915_vma_pin_fence(vma) == 0 && vma->fence) 366 - plane_state->flags |= PLANE_HAS_FENCE; 367 - 368 - plane_state->surf = i915_ggtt_offset(plane_state->ggtt_vma); 369 - 370 - plane_state->uapi.src_x = 0; 371 - plane_state->uapi.src_y = 0; 372 - plane_state->uapi.src_w = fb->width << 16; 373 - plane_state->uapi.src_h = fb->height << 16; 374 - 375 - plane_state->uapi.crtc_x = 0; 376 - plane_state->uapi.crtc_y = 0; 377 - plane_state->uapi.crtc_w = fb->width; 378 - plane_state->uapi.crtc_h = fb->height; 379 - 380 - if (fb->modifier != DRM_FORMAT_MOD_LINEAR) 381 - dev_priv->preserve_bios_swizzle = true; 382 - 383 - plane_state->uapi.fb = fb; 384 - drm_framebuffer_get(fb); 385 - 386 - plane_state->uapi.crtc = &crtc->base; 387 - intel_plane_copy_uapi_to_hw_state(plane_state, plane_state, crtc); 388 - 389 - atomic_or(plane->frontbuffer_bit, &to_intel_frontbuffer(fb)->bits); 390 - } 391 - 392 - static void plane_config_fini(struct intel_initial_plane_config *plane_config) 393 - { 394 - if (plane_config->fb) { 395 - struct drm_framebuffer *fb = &plane_config->fb->base; 396 - 397 - /* We may only have the stub and not a full framebuffer */ 398 - if (drm_framebuffer_read_refcount(fb)) 399 - drm_framebuffer_put(fb); 400 - else 401 - kfree(fb); 402 - } 403 - 404 - if (plane_config->vma) 405 - i915_vma_put(plane_config->vma); 406 - } 407 - 408 - void intel_initial_plane_config(struct intel_display *display) 409 - { 410 - struct intel_initial_plane_config plane_configs[I915_MAX_PIPES] = {}; 411 - struct intel_crtc *crtc; 412 - 413 - for_each_intel_crtc(display->drm, crtc) { 414 - const struct intel_crtc_state *crtc_state = 415 - to_intel_crtc_state(crtc->base.state); 416 - struct intel_initial_plane_config *plane_config = 417 - &plane_configs[crtc->pipe]; 418 - 419 - if (!crtc_state->hw.active) 420 - continue; 421 - 422 - /* 423 - * Note that reserving the BIOS fb up front prevents us 424 - * from stuffing other stolen allocations like the ring 425 - * on top. This prevents some ugliness at boot time, and 426 - * can even allow for smooth boot transitions if the BIOS 427 - * fb is large enough for the active pipe configuration. 428 - */ 429 - display->funcs.display->get_initial_plane_config(crtc, plane_config); 430 - 431 - /* 432 - * If the fb is shared between multiple heads, we'll 433 - * just get the first one. 434 - */ 435 - intel_find_initial_plane_obj(crtc, plane_configs); 436 - 437 - if (display->funcs.display->fixup_initial_plane_config(crtc, plane_config)) 438 - intel_plane_initial_vblank_wait(crtc); 439 - 440 - plane_config_fini(plane_config); 441 - } 442 - }
+3 -3
drivers/gpu/drm/i915/display/intel_plane_initial.h drivers/gpu/drm/i915/display/intel_initial_plane.h
··· 3 3 * Copyright © 2021 Intel Corporation 4 4 */ 5 5 6 - #ifndef __INTEL_PLANE_INITIAL_H__ 7 - #define __INTEL_PLANE_INITIAL_H__ 6 + #ifndef __INTEL_INITIAL_PLANE_H__ 7 + #define __INTEL_INITIAL_PLANE_H__ 8 8 9 9 struct intel_crtc; 10 10 struct intel_display; 11 11 12 12 void intel_initial_plane_config(struct intel_display *display); 13 - void intel_plane_initial_vblank_wait(struct intel_crtc *crtc); 13 + void intel_initial_plane_vblank_wait(struct intel_crtc *crtc); 14 14 15 15 #endif
+5 -3
drivers/gpu/drm/i915/display/intel_rom.c
··· 3 3 * Copyright © 2024 Intel Corporation 4 4 */ 5 5 6 - #include "i915_drv.h" 6 + #include <linux/pci.h> 7 + 8 + #include <drm/drm_device.h> 9 + 7 10 #include "i915_reg.h" 8 11 9 12 #include "intel_rom.h" ··· 44 41 45 42 struct intel_rom *intel_rom_spi(struct drm_device *drm) 46 43 { 47 - struct drm_i915_private *i915 = to_i915(drm); 48 44 struct intel_rom *rom; 49 45 u32 static_region; 50 46 ··· 51 49 if (!rom) 52 50 return NULL; 53 51 54 - rom->uncore = &i915->uncore; 52 + rom->uncore = to_intel_uncore(drm); 55 53 56 54 static_region = intel_uncore_read(rom->uncore, SPI_STATIC_REGIONS); 57 55 static_region &= OPTIONROM_SPI_REGIONID_MASK;
+35 -11
drivers/gpu/drm/i915/display/intel_vblank.c
··· 8 8 #include <drm/drm_print.h> 9 9 #include <drm/drm_vblank.h> 10 10 11 - #include "i915_drv.h" 12 11 #include "intel_color.h" 13 12 #include "intel_crtc.h" 14 13 #include "intel_de.h" ··· 304 305 */ 305 306 #ifdef I915 306 307 static void intel_vblank_section_enter(struct intel_display *display) 307 - __acquires(i915->uncore.lock) 308 + __acquires(uncore->lock) 308 309 { 309 - struct drm_i915_private *i915 = to_i915(display->drm); 310 - spin_lock(&i915->uncore.lock); 310 + struct intel_uncore *uncore = to_intel_uncore(display->drm); 311 + spin_lock(&uncore->lock); 311 312 } 312 313 313 314 static void intel_vblank_section_exit(struct intel_display *display) 314 - __releases(i915->uncore.lock) 315 + __releases(uncore->lock) 315 316 { 316 - struct drm_i915_private *i915 = to_i915(display->drm); 317 - spin_unlock(&i915->uncore.lock); 317 + struct intel_uncore *uncore = to_intel_uncore(display->drm); 318 + spin_unlock(&uncore->lock); 318 319 } 319 320 #else 320 321 static void intel_vblank_section_enter(struct intel_display *display) ··· 651 652 return pre_commit_crtc_state(old_crtc_state, new_crtc_state); 652 653 } 653 654 655 + static int vrr_vblank_start(const struct intel_crtc_state *crtc_state) 656 + { 657 + bool is_push_sent = intel_vrr_is_push_sent(crtc_state); 658 + int vblank_start; 659 + 660 + if (!crtc_state->vrr.dc_balance.enable) { 661 + if (is_push_sent) 662 + return intel_vrr_vmin_vblank_start(crtc_state); 663 + else 664 + return intel_vrr_vmax_vblank_start(crtc_state); 665 + } 666 + 667 + if (is_push_sent) 668 + vblank_start = intel_vrr_dcb_vmin_vblank_start_next(crtc_state); 669 + else 670 + vblank_start = intel_vrr_dcb_vmax_vblank_start_next(crtc_state); 671 + 672 + if (vblank_start >= 0) 673 + return vblank_start; 674 + 675 + if (is_push_sent) 676 + vblank_start = intel_vrr_dcb_vmin_vblank_start_final(crtc_state); 677 + else 678 + vblank_start = intel_vrr_dcb_vmax_vblank_start_final(crtc_state); 679 + 680 + return vblank_start; 681 + } 682 + 654 683 void intel_vblank_evade_init(const struct intel_crtc_state *old_crtc_state, 655 684 const struct intel_crtc_state *new_crtc_state, 656 685 struct intel_vblank_evade_ctx *evade) ··· 705 678 drm_WARN_ON(crtc->base.dev, intel_crtc_needs_modeset(new_crtc_state) || 706 679 new_crtc_state->update_m_n || new_crtc_state->update_lrr); 707 680 708 - if (intel_vrr_is_push_sent(crtc_state)) 709 - evade->vblank_start = intel_vrr_vmin_vblank_start(crtc_state); 710 - else 711 - evade->vblank_start = intel_vrr_vmax_vblank_start(crtc_state); 681 + evade->vblank_start = vrr_vblank_start(crtc_state); 712 682 713 683 vblank_delay = crtc_state->set_context_latency; 714 684 } else {
+31 -4
drivers/gpu/drm/i915/display/intel_vdsc.c
··· 1050 1050 drm_dsc_dump_config(p, indent, &crtc_state->dsc.config); 1051 1051 } 1052 1052 1053 + static 1054 + int intel_dsc_get_pixel_rate_with_dsc_bubbles(struct intel_display *display, 1055 + int pixel_rate, int htotal, 1056 + int dsc_horizontal_slices) 1057 + { 1058 + int dsc_slice_bubbles; 1059 + u64 num; 1060 + 1061 + if (drm_WARN_ON(display->drm, !htotal)) 1062 + return pixel_rate; 1063 + 1064 + dsc_slice_bubbles = 14 * dsc_horizontal_slices; 1065 + num = mul_u32_u32(pixel_rate, (htotal + dsc_slice_bubbles)); 1066 + 1067 + return DIV_ROUND_UP_ULL(num, htotal); 1068 + } 1069 + 1053 1070 int intel_vdsc_min_cdclk(const struct intel_crtc_state *crtc_state) 1054 1071 { 1055 1072 struct intel_display *display = to_intel_display(crtc_state); 1056 1073 int num_vdsc_instances = intel_dsc_get_num_vdsc_instances(crtc_state); 1074 + int htotal = crtc_state->hw.adjusted_mode.crtc_htotal; 1075 + int dsc_slices = crtc_state->dsc.slice_count; 1076 + int pixel_rate; 1057 1077 int min_cdclk; 1058 1078 1059 1079 if (!crtc_state->dsc.compression_enable) 1060 1080 return 0; 1081 + 1082 + pixel_rate = intel_dsc_get_pixel_rate_with_dsc_bubbles(display, 1083 + crtc_state->pixel_rate, 1084 + htotal, 1085 + dsc_slices); 1061 1086 1062 1087 /* 1063 1088 * When we decide to use only one VDSC engine, since ··· 1091 1066 * If there 2 VDSC engines, then pixel clock can't be higher than 1092 1067 * VDSC clock(cdclk) * 2 and so on. 1093 1068 */ 1094 - min_cdclk = DIV_ROUND_UP(crtc_state->pixel_rate, num_vdsc_instances); 1069 + min_cdclk = DIV_ROUND_UP(pixel_rate, num_vdsc_instances); 1095 1070 1096 1071 if (crtc_state->joiner_pipes) { 1097 1072 int pixel_clock = intel_dp_mode_to_fec_clock(crtc_state->hw.adjusted_mode.clock); ··· 1109 1084 * => CDCLK >= compressed_bpp * Pixel clock / 2 * Bigjoiner Interface bits 1110 1085 */ 1111 1086 int bigjoiner_interface_bits = DISPLAY_VER(display) >= 14 ? 36 : 24; 1112 - int min_cdclk_bj = 1113 - (fxp_q4_to_int_roundup(crtc_state->dsc.compressed_bpp_x16) * 1114 - pixel_clock) / (2 * bigjoiner_interface_bits); 1087 + int adjusted_pixel_rate = 1088 + intel_dsc_get_pixel_rate_with_dsc_bubbles(display, pixel_clock, 1089 + htotal, dsc_slices); 1090 + int min_cdclk_bj = (fxp_q4_to_int_roundup(crtc_state->dsc.compressed_bpp_x16) * 1091 + adjusted_pixel_rate) / (2 * bigjoiner_interface_bits); 1115 1092 1116 1093 min_cdclk = max(min_cdclk, min_cdclk_bj); 1117 1094 }
+279 -2
drivers/gpu/drm/i915/display/intel_vrr.c
··· 6 6 7 7 #include <drm/drm_print.h> 8 8 9 + #include "intel_crtc.h" 9 10 #include "intel_de.h" 10 11 #include "intel_display_regs.h" 11 12 #include "intel_display_types.h" 13 + #include "intel_dmc.h" 14 + #include "intel_dmc_regs.h" 12 15 #include "intel_dp.h" 13 16 #include "intel_psr.h" 14 17 #include "intel_vrr.h" ··· 21 18 22 19 #define FIXED_POINT_PRECISION 100 23 20 #define CMRR_PRECISION_TOLERANCE 10 21 + 22 + /* 23 + * Tunable parameters for DC Balance correction. 24 + * These are captured based on experimentations. 25 + */ 26 + #define DCB_CORRECTION_SENSITIVITY 30 27 + #define DCB_CORRECTION_AGGRESSIVENESS 1000 /* ms × 100; 10 ms */ 28 + #define DCB_BLANK_TARGET 50 24 29 25 30 bool intel_vrr_is_capable(struct intel_connector *connector) 26 31 { ··· 272 261 return value - crtc_state->set_context_latency; 273 262 } 274 263 264 + static int intel_vrr_vblank_start(const struct intel_crtc_state *crtc_state, 265 + int vmin_vmax) 266 + { 267 + return intel_vrr_hw_value(crtc_state, vmin_vmax) - crtc_state->vrr.guardband; 268 + } 269 + 275 270 /* 276 271 * For fixed refresh rate mode Vmin, Vmax and Flipline all are set to 277 272 * Vtotal value. ··· 352 335 return vmax; 353 336 } 354 337 338 + static bool intel_vrr_dc_balance_possible(const struct intel_crtc_state *crtc_state) 339 + { 340 + struct intel_display *display = to_intel_display(crtc_state); 341 + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 342 + enum pipe pipe = crtc->pipe; 343 + 344 + /* 345 + * FIXME: Currently Firmware supports DC Balancing on PIPE A 346 + * and PIPE B. Account those limitation while computing DC 347 + * Balance parameters. 348 + */ 349 + return (HAS_VRR_DC_BALANCE(display) && 350 + ((pipe == PIPE_A) || (pipe == PIPE_B))); 351 + } 352 + 353 + static void 354 + intel_vrr_dc_balance_compute_config(struct intel_crtc_state *crtc_state) 355 + { 356 + int guardband_usec, adjustment_usec; 357 + struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; 358 + 359 + if (!intel_vrr_dc_balance_possible(crtc_state) || !crtc_state->vrr.enable) 360 + return; 361 + 362 + crtc_state->vrr.dc_balance.vmax = crtc_state->vrr.vmax; 363 + crtc_state->vrr.dc_balance.vmin = crtc_state->vrr.vmin; 364 + crtc_state->vrr.dc_balance.max_increase = 365 + crtc_state->vrr.vmax - crtc_state->vrr.vmin; 366 + crtc_state->vrr.dc_balance.max_decrease = 367 + crtc_state->vrr.vmax - crtc_state->vrr.vmin; 368 + crtc_state->vrr.dc_balance.guardband = 369 + DIV_ROUND_UP(crtc_state->vrr.dc_balance.vmax * 370 + DCB_CORRECTION_SENSITIVITY, 100); 371 + guardband_usec = 372 + intel_scanlines_to_usecs(adjusted_mode, 373 + crtc_state->vrr.dc_balance.guardband); 374 + /* 375 + * The correction_aggressiveness/100 is the number of milliseconds to 376 + * adjust by when the balance is at twice the guardband. 377 + * guardband_slope = correction_aggressiveness / (guardband * 100) 378 + */ 379 + adjustment_usec = DCB_CORRECTION_AGGRESSIVENESS * 10; 380 + crtc_state->vrr.dc_balance.slope = 381 + DIV_ROUND_UP(adjustment_usec, guardband_usec); 382 + crtc_state->vrr.dc_balance.vblank_target = 383 + DIV_ROUND_UP((crtc_state->vrr.vmax - crtc_state->vrr.vmin) * 384 + DCB_BLANK_TARGET, 100); 385 + crtc_state->vrr.dc_balance.enable = true; 386 + } 387 + 355 388 void 356 389 intel_vrr_compute_config(struct intel_crtc_state *crtc_state, 357 390 struct drm_connector_state *conn_state) ··· 459 392 (crtc_state->hw.adjusted_mode.crtc_vtotal - 460 393 crtc_state->hw.adjusted_mode.crtc_vsync_end); 461 394 } 395 + 396 + intel_vrr_dc_balance_compute_config(crtc_state); 462 397 } 463 398 464 399 static int ··· 648 579 EMP_AS_SDP_DB_TL(crtc_state->vrr.vsync_start)); 649 580 } 650 581 582 + void 583 + intel_vrr_dcb_increment_flip_count(struct intel_crtc_state *crtc_state, 584 + struct intel_crtc *crtc) 585 + { 586 + struct intel_display *display = to_intel_display(crtc_state); 587 + enum pipe pipe = crtc->pipe; 588 + 589 + if (!crtc_state->vrr.dc_balance.enable) 590 + return; 591 + 592 + intel_de_write(display, PIPEDMC_DCB_FLIP_COUNT(pipe), 593 + ++crtc->dc_balance.flip_count); 594 + } 595 + 596 + void 597 + intel_vrr_dcb_reset(const struct intel_crtc_state *old_crtc_state, 598 + struct intel_crtc *crtc) 599 + { 600 + struct intel_display *display = to_intel_display(old_crtc_state); 601 + enum pipe pipe = crtc->pipe; 602 + 603 + if (!old_crtc_state->vrr.dc_balance.enable) 604 + return; 605 + 606 + intel_de_write(display, PIPEDMC_DCB_FLIP_COUNT(pipe), 0); 607 + intel_de_write(display, PIPEDMC_DCB_BALANCE_RESET(pipe), 0); 608 + } 609 + 651 610 void intel_vrr_send_push(struct intel_dsb *dsb, 652 611 const struct intel_crtc_state *crtc_state) 653 612 { ··· 783 686 intel_vrr_hw_flipline(crtc_state) - 1); 784 687 } 785 688 689 + static void 690 + intel_vrr_enable_dc_balancing(const struct intel_crtc_state *crtc_state) 691 + { 692 + struct intel_display *display = to_intel_display(crtc_state); 693 + enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; 694 + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 695 + enum pipe pipe = crtc->pipe; 696 + u32 vrr_ctl = intel_de_read(display, TRANS_VRR_CTL(display, cpu_transcoder)); 697 + 698 + if (!crtc_state->vrr.dc_balance.enable) 699 + return; 700 + 701 + intel_de_write(display, TRANS_VRR_DCB_ADJ_VMAX_CFG(cpu_transcoder), 702 + VRR_DCB_ADJ_VMAX(crtc_state->vrr.vmax - 1)); 703 + intel_de_write(display, TRANS_VRR_DCB_ADJ_VMAX_CFG_LIVE(cpu_transcoder), 704 + VRR_DCB_ADJ_VMAX(crtc_state->vrr.vmax - 1)); 705 + intel_de_write(display, TRANS_VRR_DCB_VMAX(cpu_transcoder), 706 + VRR_DCB_VMAX(crtc_state->vrr.vmax - 1)); 707 + intel_de_write(display, TRANS_VRR_DCB_VMAX_LIVE(cpu_transcoder), 708 + VRR_DCB_VMAX(crtc_state->vrr.vmax - 1)); 709 + intel_de_write(display, TRANS_VRR_DCB_FLIPLINE(cpu_transcoder), 710 + VRR_DCB_FLIPLINE(crtc_state->vrr.flipline - 1)); 711 + intel_de_write(display, TRANS_VRR_DCB_FLIPLINE_LIVE(cpu_transcoder), 712 + VRR_DCB_FLIPLINE(crtc_state->vrr.flipline - 1)); 713 + intel_de_write(display, TRANS_VRR_DCB_ADJ_FLIPLINE_CFG_LIVE(cpu_transcoder), 714 + VRR_DCB_ADJ_FLIPLINE(crtc_state->vrr.flipline - 1)); 715 + intel_de_write(display, TRANS_VRR_DCB_ADJ_FLIPLINE_CFG(cpu_transcoder), 716 + VRR_DCB_ADJ_FLIPLINE(crtc_state->vrr.flipline - 1)); 717 + intel_de_write(display, PIPEDMC_DCB_VMIN(pipe), 718 + crtc_state->vrr.dc_balance.vmin - 1); 719 + intel_de_write(display, PIPEDMC_DCB_VMAX(pipe), 720 + crtc_state->vrr.dc_balance.vmax - 1); 721 + intel_de_write(display, PIPEDMC_DCB_MAX_INCREASE(pipe), 722 + crtc_state->vrr.dc_balance.max_increase); 723 + intel_de_write(display, PIPEDMC_DCB_MAX_DECREASE(pipe), 724 + crtc_state->vrr.dc_balance.max_decrease); 725 + intel_de_write(display, PIPEDMC_DCB_GUARDBAND(pipe), 726 + crtc_state->vrr.dc_balance.guardband); 727 + intel_de_write(display, PIPEDMC_DCB_SLOPE(pipe), 728 + crtc_state->vrr.dc_balance.slope); 729 + intel_de_write(display, PIPEDMC_DCB_VBLANK(pipe), 730 + crtc_state->vrr.dc_balance.vblank_target); 731 + intel_dmc_configure_dc_balance_event(display, pipe, true); 732 + intel_de_write(display, TRANS_ADAPTIVE_SYNC_DCB_CTL(cpu_transcoder), 733 + ADAPTIVE_SYNC_COUNTER_EN); 734 + intel_pipedmc_dcb_enable(NULL, crtc); 735 + 736 + vrr_ctl |= VRR_CTL_DCB_ADJ_ENABLE; 737 + intel_de_write(display, TRANS_VRR_CTL(display, cpu_transcoder), vrr_ctl); 738 + } 739 + 740 + static void 741 + intel_vrr_disable_dc_balancing(const struct intel_crtc_state *old_crtc_state) 742 + { 743 + struct intel_display *display = to_intel_display(old_crtc_state); 744 + enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder; 745 + struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc); 746 + enum pipe pipe = crtc->pipe; 747 + u32 vrr_ctl = intel_de_read(display, TRANS_VRR_CTL(display, cpu_transcoder)); 748 + 749 + if (!old_crtc_state->vrr.dc_balance.enable) 750 + return; 751 + 752 + intel_pipedmc_dcb_disable(NULL, crtc); 753 + intel_dmc_configure_dc_balance_event(display, pipe, false); 754 + intel_de_write(display, TRANS_ADAPTIVE_SYNC_DCB_CTL(cpu_transcoder), 0); 755 + intel_de_write(display, PIPEDMC_DCB_VMIN(pipe), 0); 756 + intel_de_write(display, PIPEDMC_DCB_VMAX(pipe), 0); 757 + intel_de_write(display, PIPEDMC_DCB_MAX_INCREASE(pipe), 0); 758 + intel_de_write(display, PIPEDMC_DCB_MAX_DECREASE(pipe), 0); 759 + intel_de_write(display, PIPEDMC_DCB_GUARDBAND(pipe), 0); 760 + intel_de_write(display, PIPEDMC_DCB_SLOPE(pipe), 0); 761 + intel_de_write(display, PIPEDMC_DCB_VBLANK(pipe), 0); 762 + intel_de_write(display, TRANS_VRR_DCB_ADJ_VMAX_CFG_LIVE(cpu_transcoder), 0); 763 + intel_de_write(display, TRANS_VRR_DCB_ADJ_FLIPLINE_CFG_LIVE(cpu_transcoder), 0); 764 + intel_de_write(display, TRANS_VRR_DCB_VMAX_LIVE(cpu_transcoder), 0); 765 + intel_de_write(display, TRANS_VRR_DCB_FLIPLINE_LIVE(cpu_transcoder), 0); 766 + intel_de_write(display, TRANS_VRR_DCB_ADJ_VMAX_CFG(cpu_transcoder), 0); 767 + intel_de_write(display, TRANS_VRR_DCB_ADJ_FLIPLINE_CFG(cpu_transcoder), 0); 768 + intel_de_write(display, TRANS_VRR_DCB_VMAX(cpu_transcoder), 0); 769 + intel_de_write(display, TRANS_VRR_DCB_FLIPLINE(cpu_transcoder), 0); 770 + 771 + vrr_ctl &= ~VRR_CTL_DCB_ADJ_ENABLE; 772 + intel_de_write(display, TRANS_VRR_CTL(display, cpu_transcoder), vrr_ctl); 773 + } 774 + 786 775 static void intel_vrr_tg_enable(const struct intel_crtc_state *crtc_state, 787 776 bool cmrr_enable) 788 777 { ··· 915 732 return; 916 733 917 734 intel_vrr_set_vrr_timings(crtc_state); 735 + intel_vrr_enable_dc_balancing(crtc_state); 918 736 919 737 if (!intel_vrr_always_use_vrr_tg(display)) 920 738 intel_vrr_tg_enable(crtc_state, crtc_state->cmrr.enable); ··· 931 747 if (!intel_vrr_always_use_vrr_tg(display)) 932 748 intel_vrr_tg_disable(old_crtc_state); 933 749 750 + intel_vrr_disable_dc_balancing(old_crtc_state); 934 751 intel_vrr_set_fixed_rr_timings(old_crtc_state); 935 752 } 936 753 ··· 962 777 return crtc_state->vrr.flipline && 963 778 crtc_state->vrr.flipline == crtc_state->vrr.vmax && 964 779 crtc_state->vrr.flipline == crtc_state->vrr.vmin; 780 + } 781 + 782 + static 783 + void intel_vrr_get_dc_balance_config(struct intel_crtc_state *crtc_state) 784 + { 785 + u32 reg_val; 786 + struct intel_display *display = to_intel_display(crtc_state); 787 + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 788 + enum pipe pipe = crtc->pipe; 789 + 790 + if (!intel_vrr_dc_balance_possible(crtc_state)) 791 + return; 792 + 793 + reg_val = intel_de_read(display, PIPEDMC_DCB_VMIN(pipe)); 794 + crtc_state->vrr.dc_balance.vmin = reg_val ? reg_val + 1 : 0; 795 + 796 + reg_val = intel_de_read(display, PIPEDMC_DCB_VMAX(pipe)); 797 + crtc_state->vrr.dc_balance.vmax = reg_val ? reg_val + 1 : 0; 798 + 799 + crtc_state->vrr.dc_balance.guardband = 800 + intel_de_read(display, PIPEDMC_DCB_GUARDBAND(pipe)); 801 + crtc_state->vrr.dc_balance.max_increase = 802 + intel_de_read(display, PIPEDMC_DCB_MAX_INCREASE(pipe)); 803 + crtc_state->vrr.dc_balance.max_decrease = 804 + intel_de_read(display, PIPEDMC_DCB_MAX_DECREASE(pipe)); 805 + crtc_state->vrr.dc_balance.slope = 806 + intel_de_read(display, PIPEDMC_DCB_SLOPE(pipe)); 807 + crtc_state->vrr.dc_balance.vblank_target = 808 + intel_de_read(display, PIPEDMC_DCB_VBLANK(pipe)); 965 809 } 966 810 967 811 void intel_vrr_get_config(struct intel_crtc_state *crtc_state) ··· 1074 860 else 1075 861 crtc_state->vrr.enable = vrr_enable; 1076 862 863 + intel_vrr_get_dc_balance_config(crtc_state); 864 + 1077 865 /* 1078 866 * #TODO: For Both VRR and CMRR the flag I915_MODE_FLAG_VRR is set for mode_flags. 1079 867 * Since CMRR is currently disabled, set this flag for VRR for now. ··· 1109 893 return crtc_state->hw.adjusted_mode.crtc_vdisplay; 1110 894 } 1111 895 896 + static int 897 + intel_vrr_dcb_vmin_vblank_start(const struct intel_crtc_state *crtc_state) 898 + { 899 + return (intel_vrr_dcb_vmin_vblank_start_next(crtc_state) < 0) ? 900 + intel_vrr_dcb_vmin_vblank_start_final(crtc_state) : 901 + intel_vrr_dcb_vmin_vblank_start_next(crtc_state); 902 + } 903 + 1112 904 int intel_vrr_vmin_safe_window_end(const struct intel_crtc_state *crtc_state) 1113 905 { 1114 - return intel_vrr_vmin_vblank_start(crtc_state) - 1115 - crtc_state->set_context_latency; 906 + int vmin_vblank_start = crtc_state->vrr.dc_balance.enable ? 907 + intel_vrr_dcb_vmin_vblank_start(crtc_state) : 908 + intel_vrr_vmin_vblank_start(crtc_state); 909 + 910 + return vmin_vblank_start - crtc_state->set_context_latency; 911 + } 912 + 913 + int intel_vrr_dcb_vmin_vblank_start_next(const struct intel_crtc_state *crtc_state) 914 + { 915 + struct intel_display *display = to_intel_display(crtc_state); 916 + enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; 917 + u32 tmp = 0; 918 + 919 + tmp = intel_de_read(display, TRANS_VRR_DCB_ADJ_FLIPLINE_CFG_LIVE(cpu_transcoder)); 920 + 921 + if (REG_FIELD_GET(VRR_DCB_ADJ_FLIPLINE_CNT_MASK, tmp) == 0) 922 + return -EINVAL; 923 + 924 + return intel_vrr_vblank_start(crtc_state, VRR_DCB_ADJ_FLIPLINE(tmp) + 1); 925 + } 926 + 927 + int intel_vrr_dcb_vmax_vblank_start_next(const struct intel_crtc_state *crtc_state) 928 + { 929 + struct intel_display *display = to_intel_display(crtc_state); 930 + enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; 931 + u32 tmp = 0; 932 + 933 + tmp = intel_de_read(display, TRANS_VRR_DCB_ADJ_VMAX_CFG_LIVE(cpu_transcoder)); 934 + 935 + if (REG_FIELD_GET(VRR_DCB_ADJ_VMAX_CNT_MASK, tmp) == 0) 936 + return -EINVAL; 937 + 938 + return intel_vrr_vblank_start(crtc_state, VRR_DCB_ADJ_VMAX(tmp) + 1); 939 + } 940 + 941 + int intel_vrr_dcb_vmin_vblank_start_final(const struct intel_crtc_state *crtc_state) 942 + { 943 + struct intel_display *display = to_intel_display(crtc_state); 944 + enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; 945 + u32 tmp = 0; 946 + 947 + tmp = intel_de_read(display, TRANS_VRR_DCB_FLIPLINE_LIVE(cpu_transcoder)); 948 + 949 + return intel_vrr_vblank_start(crtc_state, VRR_DCB_FLIPLINE(tmp) + 1); 950 + } 951 + 952 + int intel_vrr_dcb_vmax_vblank_start_final(const struct intel_crtc_state *crtc_state) 953 + { 954 + struct intel_display *display = to_intel_display(crtc_state); 955 + enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; 956 + u32 tmp = 0; 957 + 958 + tmp = intel_de_read(display, TRANS_VRR_DCB_VMAX_LIVE(cpu_transcoder)); 959 + 960 + return intel_vrr_vblank_start(crtc_state, VRR_DCB_VMAX(tmp) + 1); 1116 961 }
+10
drivers/gpu/drm/i915/display/intel_vrr.h
··· 11 11 struct drm_connector_state; 12 12 struct intel_atomic_state; 13 13 struct intel_connector; 14 + struct intel_crtc; 14 15 struct intel_crtc_state; 15 16 struct intel_dsb; 16 17 struct intel_display; ··· 29 28 const struct intel_crtc_state *crtc_state); 30 29 void intel_vrr_check_push_sent(struct intel_dsb *dsb, 31 30 const struct intel_crtc_state *crtc_state); 31 + void intel_vrr_dcb_increment_flip_count(struct intel_crtc_state *crtc_state, 32 + struct intel_crtc *crtc); 32 33 bool intel_vrr_is_push_sent(const struct intel_crtc_state *crtc_state); 33 34 void intel_vrr_disable(const struct intel_crtc_state *old_crtc_state); 34 35 void intel_vrr_get_config(struct intel_crtc_state *crtc_state); ··· 42 39 void intel_vrr_transcoder_enable(const struct intel_crtc_state *crtc_state); 43 40 void intel_vrr_transcoder_disable(const struct intel_crtc_state *crtc_state); 44 41 void intel_vrr_set_fixed_rr_timings(const struct intel_crtc_state *crtc_state); 42 + void intel_vrr_dcb_reset(const struct intel_crtc_state *old_crtc_state, 43 + struct intel_crtc *crtc); 45 44 bool intel_vrr_always_use_vrr_tg(struct intel_display *display); 46 45 int intel_vrr_safe_window_start(const struct intel_crtc_state *crtc_state); 47 46 int intel_vrr_vmin_safe_window_end(const struct intel_crtc_state *crtc_state); 47 + 48 + int intel_vrr_dcb_vmin_vblank_start_next(const struct intel_crtc_state *crtc_state); 49 + int intel_vrr_dcb_vmax_vblank_start_next(const struct intel_crtc_state *crtc_state); 50 + int intel_vrr_dcb_vmin_vblank_start_final(const struct intel_crtc_state *crtc_state); 51 + int intel_vrr_dcb_vmax_vblank_start_final(const struct intel_crtc_state *crtc_state); 48 52 49 53 #endif /* __INTEL_VRR_H__ */
+68
drivers/gpu/drm/i915/display/intel_vrr_regs.h
··· 8 8 9 9 #include "intel_display_reg_defs.h" 10 10 11 + #define _TRANS_VRR_DCB_ADJ_FLIPLINE_CFG_A 0x604d4 12 + #define _TRANS_VRR_DCB_ADJ_FLIPLINE_CFG_B 0x614d4 13 + #define TRANS_VRR_DCB_ADJ_FLIPLINE_CFG(trans) _MMIO_TRANS(trans, \ 14 + _TRANS_VRR_DCB_ADJ_FLIPLINE_CFG_A, \ 15 + _TRANS_VRR_DCB_ADJ_FLIPLINE_CFG_B) 16 + #define VRR_DCB_ADJ_FLIPLINE_CNT_MASK REG_GENMASK(31, 24) 17 + #define VRR_DCB_ADJ_FLIPLINE_MASK REG_GENMASK(19, 0) 18 + #define VRR_DCB_ADJ_FLIPLINE(flipline) REG_FIELD_PREP(VRR_DCB_ADJ_FLIPLINE_MASK, \ 19 + (flipline)) 20 + 21 + #define _TRANS_VRR_DCB_ADJ_FLIPLINE_CFG_LIVE_A 0x90700 22 + #define _TRANS_VRR_DCB_ADJ_FLIPLINE_CFG_LIVE_B 0x98700 23 + #define TRANS_VRR_DCB_ADJ_FLIPLINE_CFG_LIVE(trans) _MMIO_TRANS(trans, \ 24 + _TRANS_VRR_DCB_ADJ_FLIPLINE_CFG_LIVE_A, \ 25 + _TRANS_VRR_DCB_ADJ_FLIPLINE_CFG_LIVE_B) 26 + 27 + #define _TRANS_VRR_DCB_ADJ_VMAX_CFG_A 0x604d8 28 + #define _TRANS_VRR_DCB_ADJ_VMAX_CFG_B 0x614d8 29 + #define TRANS_VRR_DCB_ADJ_VMAX_CFG(trans) _MMIO_TRANS(trans, \ 30 + _TRANS_VRR_DCB_ADJ_VMAX_CFG_A, \ 31 + _TRANS_VRR_DCB_ADJ_VMAX_CFG_B) 32 + #define VRR_DCB_ADJ_VMAX_CNT_MASK REG_GENMASK(31, 24) 33 + #define VRR_DCB_ADJ_VMAX_MASK REG_GENMASK(19, 0) 34 + #define VRR_DCB_ADJ_VMAX(vmax) REG_FIELD_PREP(VRR_DCB_ADJ_VMAX_MASK, (vmax)) 35 + 36 + #define _TRANS_VRR_DCB_ADJ_VMAX_CFG_LIVE_A 0x906f8 37 + #define _TRANS_VRR_DCB_ADJ_VMAX_CFG_LIVE_B 0x986f8 38 + #define TRANS_VRR_DCB_ADJ_VMAX_CFG_LIVE(trans) _MMIO_TRANS(trans, \ 39 + _TRANS_VRR_DCB_ADJ_VMAX_CFG_LIVE_A, \ 40 + _TRANS_VRR_DCB_ADJ_VMAX_CFG_LIVE_B) 41 + 42 + #define _TRANS_VRR_DCB_FLIPLINE_A 0x60418 43 + #define _TRANS_VRR_DCB_FLIPLINE_B 0x61418 44 + #define TRANS_VRR_DCB_FLIPLINE(trans) _MMIO_TRANS(trans, \ 45 + _TRANS_VRR_DCB_FLIPLINE_A, \ 46 + _TRANS_VRR_DCB_FLIPLINE_B) 47 + #define VRR_DCB_FLIPLINE_MASK REG_GENMASK(19, 0) 48 + #define VRR_DCB_FLIPLINE(flipline) REG_FIELD_PREP(VRR_DCB_FLIPLINE_MASK, \ 49 + (flipline)) 50 + 51 + #define _TRANS_VRR_DCB_FLIPLINE_LIVE_A 0x906fc 52 + #define _TRANS_VRR_DCB_FLIPLINE_LIVE_B 0x986fc 53 + #define TRANS_VRR_DCB_FLIPLINE_LIVE(trans) _MMIO_TRANS(trans, \ 54 + _TRANS_VRR_DCB_FLIPLINE_LIVE_A, \ 55 + _TRANS_VRR_DCB_FLIPLINE_LIVE_B) 56 + 57 + #define _TRANS_VRR_DCB_VMAX_A 0x60414 58 + #define _TRANS_VRR_DCB_VMAX_B 0x61414 59 + #define TRANS_VRR_DCB_VMAX(trans) _MMIO_TRANS(trans, \ 60 + _TRANS_VRR_DCB_VMAX_A, \ 61 + _TRANS_VRR_DCB_VMAX_B) 62 + #define VRR_DCB_VMAX_MASK REG_GENMASK(19, 0) 63 + #define VRR_DCB_VMAX(vmax) REG_FIELD_PREP(VRR_DCB_VMAX_MASK, (vmax)) 64 + 65 + #define _TRANS_VRR_DCB_VMAX_LIVE_A 0x906f4 66 + #define _TRANS_VRR_DCB_VMAX_LIVE_B 0x986f4 67 + #define TRANS_VRR_DCB_VMAX_LIVE(trans) _MMIO_TRANS(trans, \ 68 + _TRANS_VRR_DCB_VMAX_LIVE_A, \ 69 + _TRANS_VRR_DCB_VMAX_LIVE_B) 70 + 71 + #define _TRANS_ADAPTIVE_SYNC_DCB_CTL_A 0x604c0 72 + #define _TRANS_ADAPTIVE_SYNC_DCB_CTL_B 0x614c0 73 + #define TRANS_ADAPTIVE_SYNC_DCB_CTL(trans) _MMIO_TRANS(trans, \ 74 + _TRANS_ADAPTIVE_SYNC_DCB_CTL_A, \ 75 + _TRANS_ADAPTIVE_SYNC_DCB_CTL_B) 76 + #define ADAPTIVE_SYNC_COUNTER_EN REG_BIT(31) 77 + 11 78 #define _TRANS_VRR_CTL_A 0x60420 12 79 #define _TRANS_VRR_CTL_B 0x61420 13 80 #define _TRANS_VRR_CTL_C 0x62420 ··· 86 19 #define VRR_CTL_CMRR_ENABLE REG_BIT(27) 87 20 #define VRR_CTL_PIPELINE_FULL_MASK REG_GENMASK(10, 3) 88 21 #define VRR_CTL_PIPELINE_FULL(x) REG_FIELD_PREP(VRR_CTL_PIPELINE_FULL_MASK, (x)) 22 + #define VRR_CTL_DCB_ADJ_ENABLE REG_BIT(28) 89 23 #define VRR_CTL_PIPELINE_FULL_OVERRIDE REG_BIT(0) 90 24 #define XELPD_VRR_CTL_VRR_GUARDBAND_MASK REG_GENMASK(15, 0) 91 25 #define XELPD_VRR_CTL_VRR_GUARDBAND(x) REG_FIELD_PREP(XELPD_VRR_CTL_VRR_GUARDBAND_MASK, (x))
+1 -1
drivers/gpu/drm/i915/gem/i915_gem_clflush.c
··· 113 113 if (clflush) { 114 114 i915_sw_fence_await_reservation(&clflush->base.chain, 115 115 obj->base.resv, true, 116 - i915_fence_timeout(i915), 116 + i915_fence_timeout(), 117 117 I915_FENCE_GFP); 118 118 dma_resv_add_fence(obj->base.resv, &clflush->base.dma, 119 119 DMA_RESV_USAGE_KERNEL);
+3 -2
drivers/gpu/drm/i915/gvt/aperture_gm.c
··· 36 36 37 37 #include <drm/drm_print.h> 38 38 39 + #include "gt/intel_ggtt_fencing.h" 40 + 41 + #include "gvt.h" 39 42 #include "i915_drv.h" 40 43 #include "i915_reg.h" 41 - #include "gt/intel_ggtt_fencing.h" 42 - #include "gvt.h" 43 44 44 45 static int alloc_gm(struct intel_vgpu *vgpu, bool high_gm) 45 46 {
+1 -1
drivers/gpu/drm/i915/gvt/cfg_space.c
··· 33 33 34 34 #include <drm/drm_print.h> 35 35 36 - #include "i915_drv.h" 37 36 #include "gvt.h" 37 + #include "i915_drv.h" 38 38 #include "intel_pci_config.h" 39 39 40 40 enum {
+14 -12
drivers/gpu/drm/i915/gvt/cmd_parser.c
··· 38 38 39 39 #include <drm/drm_print.h> 40 40 41 - #include "i915_drv.h" 42 - #include "i915_reg.h" 41 + #include "display/i9xx_plane_regs.h" 43 42 #include "display/intel_display_regs.h" 43 + #include "display/intel_sprite_regs.h" 44 + 45 + #include "gem/i915_gem_context.h" 46 + #include "gem/i915_gem_pm.h" 47 + 48 + #include "gt/intel_context.h" 44 49 #include "gt/intel_engine_regs.h" 45 50 #include "gt/intel_gpu_commands.h" 46 51 #include "gt/intel_gt_regs.h" 52 + #include "gt/intel_gt_requests.h" 47 53 #include "gt/intel_lrc.h" 48 54 #include "gt/intel_ring.h" 49 - #include "gt/intel_gt_requests.h" 50 55 #include "gt/shmem_utils.h" 51 - #include "gvt.h" 52 - #include "i915_pvinfo.h" 53 - #include "trace.h" 54 56 55 - #include "display/i9xx_plane_regs.h" 56 - #include "display/intel_display_core.h" 57 - #include "display/intel_sprite_regs.h" 58 - #include "gem/i915_gem_context.h" 59 - #include "gem/i915_gem_pm.h" 60 - #include "gt/intel_context.h" 57 + #include "display_helpers.h" 58 + #include "gvt.h" 59 + #include "i915_drv.h" 60 + #include "i915_pvinfo.h" 61 + #include "i915_reg.h" 62 + #include "trace.h" 61 63 62 64 #define INVALID_OP (~0U) 63 65
+3 -1
drivers/gpu/drm/i915/gvt/debugfs.c
··· 20 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 21 * SOFTWARE. 22 22 */ 23 + 23 24 #include <linux/debugfs.h> 24 25 #include <linux/list_sort.h> 25 - #include "i915_drv.h" 26 + 26 27 #include "gvt.h" 28 + #include "i915_drv.h" 27 29 28 30 struct mmio_diff_param { 29 31 struct intel_vgpu *vgpu;
+12 -11
drivers/gpu/drm/i915/gvt/display.c
··· 35 35 #include <drm/display/drm_dp.h> 36 36 #include <drm/drm_print.h> 37 37 38 - #include "i915_drv.h" 39 - #include "i915_reg.h" 40 - #include "display/intel_display_regs.h" 41 - #include "gvt.h" 42 - 43 38 #include "display/bxt_dpio_phy_regs.h" 44 39 #include "display/i9xx_plane_regs.h" 45 40 #include "display/intel_crt_regs.h" 46 41 #include "display/intel_cursor_regs.h" 47 42 #include "display/intel_display.h" 48 - #include "display/intel_display_core.h" 43 + #include "display/intel_display_regs.h" 49 44 #include "display/intel_dpio_phy.h" 45 + #include "display/intel_dpll_mgr.h" 50 46 #include "display/intel_sprite_regs.h" 47 + 48 + #include "display_helpers.h" 49 + #include "gvt.h" 50 + #include "i915_drv.h" 51 + #include "i915_reg.h" 51 52 52 53 static int get_edp_pipe(struct intel_vgpu *vgpu) 53 54 { ··· 188 187 { 189 188 struct drm_i915_private *dev_priv = vgpu->gvt->gt->i915; 190 189 struct intel_display *display = dev_priv->display; 191 - int pipe; 190 + enum pipe pipe; 192 191 193 192 if (IS_BROXTON(dev_priv)) { 194 193 enum transcoder trans; ··· 200 199 GEN8_DE_PORT_HOTPLUG(HPD_PORT_B) | 201 200 GEN8_DE_PORT_HOTPLUG(HPD_PORT_C)); 202 201 203 - for_each_pipe(display, pipe) { 202 + gvt_for_each_pipe(display, pipe) { 204 203 vgpu_vreg_t(vgpu, TRANSCONF(display, pipe)) &= 205 204 ~(TRANSCONF_ENABLE | TRANSCONF_STATE_ENABLE); 206 205 vgpu_vreg_t(vgpu, DSPCNTR(display, pipe)) &= ~DISP_ENABLE; ··· 516 515 vgpu_vreg_t(vgpu, PCH_ADPA) &= ~ADPA_CRT_HOTPLUG_MONITOR_MASK; 517 516 518 517 /* Disable Primary/Sprite/Cursor plane */ 519 - for_each_pipe(display, pipe) { 518 + gvt_for_each_pipe(display, pipe) { 520 519 vgpu_vreg_t(vgpu, DSPCNTR(display, pipe)) &= ~DISP_ENABLE; 521 520 vgpu_vreg_t(vgpu, SPRCTL(pipe)) &= ~SPRITE_ENABLE; 522 521 vgpu_vreg_t(vgpu, CURCNTR(display, pipe)) &= ~MCURSOR_MODE_MASK; ··· 669 668 { 670 669 struct drm_i915_private *i915 = vgpu->gvt->gt->i915; 671 670 struct intel_display *display = i915->display; 672 - int pipe; 671 + enum pipe pipe; 673 672 674 673 mutex_lock(&vgpu->vgpu_lock); 675 - for_each_pipe(display, pipe) 674 + gvt_for_each_pipe(display, pipe) 676 675 emulate_vblank_on_pipe(vgpu, pipe); 677 676 mutex_unlock(&vgpu->vgpu_lock); 678 677 }
+1 -1
drivers/gpu/drm/i915/gvt/display.h
··· 35 35 #ifndef _GVT_DISPLAY_H_ 36 36 #define _GVT_DISPLAY_H_ 37 37 38 - #include <linux/types.h> 39 38 #include <linux/hrtimer.h> 39 + #include <linux/types.h> 40 40 41 41 struct intel_gvt; 42 42 struct intel_vgpu;
+37
drivers/gpu/drm/i915/gvt/display_helpers.h
··· 1 + /* SPDX-License-Identifier: MIT 2 + * 3 + * Copyright © 2025 Intel Corporation 4 + */ 5 + 6 + #ifndef __DISPLAY_HELPERS_H__ 7 + #define __DISPLAY_HELPERS_H__ 8 + 9 + #include "display/intel_gvt_api.h" 10 + 11 + #define DISPLAY_MMIO_BASE(display) \ 12 + intel_display_device_mmio_base((display)) 13 + 14 + /* 15 + * #FIXME: 16 + * TRANSCONF() uses pipe-based addressing via _MMIO_PIPE2(). 17 + * Some GVT call sites pass enum transcoder instead of enum pipe. 18 + * Cast the argument to enum pipe for now since TRANSCODER_A..D map 19 + * 1:1 to PIPE_A..D. 20 + * TRANSCODER_EDP is an exception, the cast preserves the existing 21 + * behaviour but this needs to be handled later either by using the 22 + * correct pipe or by switching TRANSCONF() to use _MMIO_TRANS2(). 23 + */ 24 + #define INTEL_DISPLAY_DEVICE_PIPE_OFFSET(display, idx) \ 25 + intel_display_device_pipe_offset((display), (enum pipe)(idx)) 26 + 27 + #define INTEL_DISPLAY_DEVICE_TRANS_OFFSET(display, trans) \ 28 + intel_display_device_trans_offset((display), (trans)) 29 + 30 + #define INTEL_DISPLAY_DEVICE_CURSOR_OFFSET(display, pipe) \ 31 + intel_display_device_cursor_offset((display), (pipe)) 32 + 33 + #define gvt_for_each_pipe(display, __p) \ 34 + for ((__p) = PIPE_A; (__p) < I915_MAX_PIPES; (__p)++) \ 35 + for_each_if(intel_display_device_pipe_valid((display), (__p))) 36 + 37 + #endif /* __DISPLAY_HELPERS_H__ */
+3 -3
drivers/gpu/drm/i915/gvt/dmabuf.c
··· 35 35 #include <drm/drm_plane.h> 36 36 #include <drm/drm_print.h> 37 37 38 + #include "display/skl_universal_plane_regs.h" 39 + 38 40 #include "gem/i915_gem_dmabuf.h" 39 41 40 - #include "i915_drv.h" 41 42 #include "gvt.h" 42 - 43 - #include "display/skl_universal_plane_regs.h" 43 + #include "i915_drv.h" 44 44 45 45 #define GEN8_DECODE_PTE(pte) (pte & GENMASK_ULL(63, 12)) 46 46
+6 -1
drivers/gpu/drm/i915/gvt/dmabuf.h
··· 30 30 31 31 #ifndef _GVT_DMABUF_H_ 32 32 #define _GVT_DMABUF_H_ 33 - #include <linux/vfio.h> 33 + 34 + #include <linux/kref.h> 35 + #include <linux/types.h> 36 + 37 + struct intel_vgpu; 38 + struct intel_vgpu_dmabuf_obj; 34 39 35 40 struct intel_vgpu_fb_info { 36 41 __u64 start;
+1
drivers/gpu/drm/i915/gvt/edid.c
··· 38 38 #include "display/intel_dp_aux_regs.h" 39 39 #include "display/intel_gmbus.h" 40 40 #include "display/intel_gmbus_regs.h" 41 + 41 42 #include "gvt.h" 42 43 #include "i915_drv.h" 43 44 #include "i915_reg.h"
+1 -1
drivers/gpu/drm/i915/gvt/execlist.c
··· 32 32 * 33 33 */ 34 34 35 - #include "i915_drv.h" 36 35 #include "gvt.h" 36 + #include "i915_drv.h" 37 37 38 38 #define _EL_OFFSET_STATUS 0x234 39 39 #define _EL_OFFSET_STATUS_BUF 0x370
+7 -7
drivers/gpu/drm/i915/gvt/fb_decoder.c
··· 35 35 36 36 #include <uapi/drm/drm_fourcc.h> 37 37 38 + #include "display/i9xx_plane_regs.h" 39 + #include "display/intel_cursor_regs.h" 40 + #include "display/intel_display_regs.h" 41 + #include "display/intel_sprite_regs.h" 42 + #include "display/skl_universal_plane_regs.h" 43 + 44 + #include "display_helpers.h" 38 45 #include "gvt.h" 39 46 #include "i915_drv.h" 40 47 #include "i915_pvinfo.h" 41 48 #include "i915_reg.h" 42 - #include "display/intel_display_regs.h" 43 - 44 - #include "display/i9xx_plane_regs.h" 45 - #include "display/intel_cursor_regs.h" 46 - #include "display/intel_display_core.h" 47 - #include "display/intel_sprite_regs.h" 48 - #include "display/skl_universal_plane_regs.h" 49 49 50 50 #define PRIMARY_FORMAT_NUM 16 51 51 struct pixel_format {
-2
drivers/gpu/drm/i915/gvt/fb_decoder.h
··· 38 38 39 39 #include <linux/types.h> 40 40 41 - #include "display/intel_display_limits.h" 42 - 43 41 struct intel_vgpu; 44 42 45 43 #define _PLANE_CTL_FORMAT_SHIFT 24
+2 -2
drivers/gpu/drm/i915/gvt/firmware.c
··· 28 28 * 29 29 */ 30 30 31 - #include <linux/firmware.h> 32 31 #include <linux/crc32.h> 32 + #include <linux/firmware.h> 33 33 #include <linux/vmalloc.h> 34 34 35 - #include "i915_drv.h" 36 35 #include "gvt.h" 36 + #include "i915_drv.h" 37 37 #include "i915_pvinfo.h" 38 38 39 39 #define FIRMWARE_VERSION (0x0)
+5 -4
drivers/gpu/drm/i915/gvt/gtt.c
··· 33 33 * 34 34 */ 35 35 36 + #include <linux/vmalloc.h> 37 + 36 38 #include <drm/drm_print.h> 37 39 38 - #include "i915_drv.h" 40 + #include "gt/intel_gt_regs.h" 41 + 39 42 #include "gvt.h" 43 + #include "i915_drv.h" 40 44 #include "i915_pvinfo.h" 41 45 #include "trace.h" 42 - 43 - #include "gt/intel_gt_regs.h" 44 - #include <linux/vmalloc.h> 45 46 46 47 #if defined(VERBOSE_DEBUG) 47 48 #define gvt_vdbg_mm(fmt, args...) gvt_dbg_mm(fmt, ##args)
+13 -13
drivers/gpu/drm/i915/gvt/gvt.h
··· 34 34 #define _GVT_H_ 35 35 36 36 #include <uapi/linux/pci_regs.h> 37 - #include <linux/vfio.h> 38 37 #include <linux/mdev.h> 39 - 38 + #include <linux/vfio.h> 40 39 #include <asm/kvm_page_track.h> 41 40 42 - #include "gt/intel_gt.h" 43 - #include "intel_gvt.h" 41 + #include "display/intel_display_limits.h" 44 42 43 + #include "gt/intel_gt.h" 44 + 45 + #include "cmd_parser.h" 45 46 #include "debug.h" 46 - #include "mmio.h" 47 - #include "reg.h" 48 - #include "interrupt.h" 49 - #include "gtt.h" 50 47 #include "display.h" 48 + #include "dmabuf.h" 51 49 #include "edid.h" 52 50 #include "execlist.h" 53 - #include "scheduler.h" 54 - #include "sched_policy.h" 55 - #include "mmio_context.h" 56 - #include "cmd_parser.h" 57 51 #include "fb_decoder.h" 58 - #include "dmabuf.h" 52 + #include "gtt.h" 53 + #include "intel_gvt.h" 54 + #include "interrupt.h" 55 + #include "mmio.h" 56 + #include "mmio_context.h" 59 57 #include "page_track.h" 58 + #include "reg.h" 59 + #include "scheduler.h" 60 60 61 61 #define GVT_MAX_VGPU 8 62 62
+13 -8
drivers/gpu/drm/i915/gvt/handlers.c
··· 36 36 37 37 */ 38 38 39 + #include <linux/vmalloc.h> 40 + 39 41 #include <drm/display/drm_dp.h> 40 42 #include <drm/drm_print.h> 41 43 42 - #include "i915_drv.h" 43 - #include "i915_reg.h" 44 - #include "display/intel_display_regs.h" 45 - #include "gvt.h" 46 - #include "i915_pvinfo.h" 47 - #include "intel_mchbar_regs.h" 48 44 #include "display/bxt_dpio_phy_regs.h" 49 45 #include "display/i9xx_plane_regs.h" 50 46 #include "display/intel_crt_regs.h" 51 47 #include "display/intel_cursor_regs.h" 52 - #include "display/intel_display_core.h" 48 + #include "display/intel_display_regs.h" 53 49 #include "display/intel_display_types.h" 54 50 #include "display/intel_dmc_regs.h" 55 51 #include "display/intel_dp_aux_regs.h" ··· 60 64 #include "display/skl_universal_plane_regs.h" 61 65 #include "display/skl_watermark_regs.h" 62 66 #include "display/vlv_dsi_pll_regs.h" 67 + 68 + #include "gt/intel_engine_regs.h" 63 69 #include "gt/intel_gt_regs.h" 64 - #include <linux/vmalloc.h> 70 + 71 + #include "display_helpers.h" 72 + #include "gvt.h" 73 + #include "i915_drv.h" 74 + #include "i915_pvinfo.h" 75 + #include "i915_reg.h" 76 + #include "intel_mchbar_regs.h" 77 + #include "sched_policy.h" 65 78 66 79 /* XXX FIXME i915 has changed PP_XXX definition */ 67 80 #define PCH_PP_STATUS _MMIO(0xc7200)
+3 -2
drivers/gpu/drm/i915/gvt/interrupt.c
··· 33 33 34 34 #include <drm/drm_print.h> 35 35 36 + #include "display/intel_display_regs.h" 37 + 38 + #include "gvt.h" 36 39 #include "i915_drv.h" 37 40 #include "i915_reg.h" 38 - #include "display/intel_display_regs.h" 39 - #include "gvt.h" 40 41 #include "trace.h" 41 42 42 43 struct intel_gvt_irq_info {
+12 -12
drivers/gpu/drm/i915/gvt/kvmgt.c
··· 33 33 * Zhi Wang <zhi.a.wang@intel.com> 34 34 */ 35 35 36 - #include <linux/init.h> 37 - #include <linux/mm.h> 38 - #include <linux/kthread.h> 39 - #include <linux/sched/mm.h> 40 - #include <linux/types.h> 41 - #include <linux/list.h> 42 - #include <linux/rbtree.h> 43 - #include <linux/spinlock.h> 44 - #include <linux/eventfd.h> 45 - #include <linux/mdev.h> 46 36 #include <linux/debugfs.h> 47 - 37 + #include <linux/eventfd.h> 38 + #include <linux/init.h> 39 + #include <linux/kthread.h> 40 + #include <linux/list.h> 41 + #include <linux/mdev.h> 42 + #include <linux/mm.h> 48 43 #include <linux/nospec.h> 44 + #include <linux/rbtree.h> 45 + #include <linux/sched/mm.h> 46 + #include <linux/spinlock.h> 47 + #include <linux/types.h> 49 48 50 49 #include <drm/drm_edid.h> 51 50 #include <drm/drm_print.h> 52 51 52 + #include "gvt.h" 53 53 #include "i915_drv.h" 54 54 #include "intel_gvt.h" 55 - #include "gvt.h" 55 + #include "sched_policy.h" 56 56 57 57 MODULE_IMPORT_NS("DMA_BUF"); 58 58 MODULE_IMPORT_NS("I915_GVT");
+7 -6
drivers/gpu/drm/i915/gvt/mmio.c
··· 37 37 38 38 #include <drm/drm_print.h> 39 39 40 + #include "display/bxt_dpio_phy_regs.h" 41 + #include "display/intel_display_regs.h" 42 + #include "display/intel_dpio_phy.h" 43 + 44 + #include "gt/intel_gt_regs.h" 45 + 46 + #include "gvt.h" 40 47 #include "i915_drv.h" 41 48 #include "i915_reg.h" 42 - #include "display/intel_display_regs.h" 43 - #include "gvt.h" 44 - 45 - #include "display/bxt_dpio_phy_regs.h" 46 - #include "display/intel_dpio_phy.h" 47 - #include "gt/intel_gt_regs.h" 48 49 49 50 /** 50 51 * intel_vgpu_gpa_to_mmio_offset - translate a GPA to MMIO offset
-5
drivers/gpu/drm/i915/gvt/mmio_context.h
··· 38 38 39 39 #include <linux/types.h> 40 40 41 - #include "gt/intel_engine_regs.h" 42 - 43 41 struct i915_request; 44 42 struct intel_context; 45 43 struct intel_engine_cs; ··· 54 56 55 57 int intel_vgpu_restore_inhibit_context(struct intel_vgpu *vgpu, 56 58 struct i915_request *req); 57 - 58 - #define IS_RESTORE_INHIBIT(a) \ 59 - IS_MASKED_BITS_ENABLED(a, CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT) 60 59 61 60 #endif
+2 -1
drivers/gpu/drm/i915/gvt/opregion.c
··· 22 22 */ 23 23 24 24 #include <linux/acpi.h> 25 - #include "i915_drv.h" 25 + 26 26 #include "gvt.h" 27 + #include "i915_drv.h" 27 28 28 29 /* 29 30 * Note: Only for GVT-g virtual VBT generation, other usage must
+2 -1
drivers/gpu/drm/i915/gvt/page_track.c
··· 20 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 21 * SOFTWARE. 22 22 */ 23 - #include "i915_drv.h" 23 + 24 24 #include "gvt.h" 25 + #include "i915_drv.h" 25 26 26 27 /** 27 28 * intel_vgpu_find_page_track - find page track rcord of guest page
+2 -1
drivers/gpu/drm/i915/gvt/sched_policy.c
··· 31 31 * 32 32 */ 33 33 34 - #include "i915_drv.h" 35 34 #include "gvt.h" 35 + #include "i915_drv.h" 36 + #include "sched_policy.h" 36 37 37 38 static bool vgpu_has_pending_workload(struct intel_vgpu *vgpu) 38 39 {
+7 -1
drivers/gpu/drm/i915/gvt/scheduler.c
··· 38 38 #include <drm/drm_print.h> 39 39 40 40 #include "gem/i915_gem_pm.h" 41 + 41 42 #include "gt/intel_context.h" 43 + #include "gt/intel_engine_regs.h" 42 44 #include "gt/intel_execlists_submission.h" 43 45 #include "gt/intel_gt_regs.h" 44 46 #include "gt/intel_lrc.h" 45 47 #include "gt/intel_ring.h" 46 48 49 + #include "gvt.h" 47 50 #include "i915_drv.h" 48 51 #include "i915_gem_gtt.h" 49 52 #include "i915_perf_oa_regs.h" 50 - #include "gvt.h" 53 + #include "sched_policy.h" 51 54 52 55 #define RING_CTX_OFF(x) \ 53 56 offsetof(struct execlist_ring_context, x) 57 + 58 + #define IS_RESTORE_INHIBIT(a) \ 59 + IS_MASKED_BITS_ENABLED(a, CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT) 54 60 55 61 static void set_context_pdp_root_pointer( 56 62 struct execlist_ring_context *ring_context,
+1 -1
drivers/gpu/drm/i915/gvt/trace.h
··· 31 31 #if !defined(_GVT_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ) 32 32 #define _GVT_TRACE_H_ 33 33 34 - #include <linux/types.h> 35 34 #include <linux/stringify.h> 36 35 #include <linux/tracepoint.h> 36 + #include <linux/types.h> 37 37 #include <asm/tsc.h> 38 38 39 39 #undef TRACE_SYSTEM
+2
drivers/gpu/drm/i915/gvt/trace_points.c
··· 30 30 31 31 #ifndef __CHECKER__ 32 32 #define CREATE_TRACE_POINTS 33 + 33 34 #include "trace.h" 35 + 34 36 #endif
+4 -2
drivers/gpu/drm/i915/gvt/vgpu.c
··· 31 31 * 32 32 */ 33 33 34 + #include <linux/vmalloc.h> 35 + 34 36 #include <drm/drm_print.h> 35 37 36 - #include "i915_drv.h" 37 38 #include "gvt.h" 39 + #include "i915_drv.h" 38 40 #include "i915_pvinfo.h" 39 - #include <linux/vmalloc.h> 41 + #include "sched_policy.h" 40 42 41 43 void populate_pvinfo_page(struct intel_vgpu *vgpu) 42 44 {
+1 -2
drivers/gpu/drm/i915/i915_config.c
··· 8 8 #include "i915_config.h" 9 9 #include "i915_jiffies.h" 10 10 11 - unsigned long 12 - i915_fence_context_timeout(const struct drm_i915_private *i915, u64 context) 11 + unsigned long i915_fence_context_timeout(u64 context) 13 12 { 14 13 if (CONFIG_DRM_I915_FENCE_TIMEOUT && context) 15 14 return msecs_to_jiffies_timeout(CONFIG_DRM_I915_FENCE_TIMEOUT);
+3 -7
drivers/gpu/drm/i915/i915_config.h
··· 9 9 #include <linux/types.h> 10 10 #include <linux/limits.h> 11 11 12 - struct drm_i915_private; 12 + unsigned long i915_fence_context_timeout(u64 context); 13 13 14 - unsigned long i915_fence_context_timeout(const struct drm_i915_private *i915, 15 - u64 context); 16 - 17 - static inline unsigned long 18 - i915_fence_timeout(const struct drm_i915_private *i915) 14 + static inline unsigned long i915_fence_timeout(void) 19 15 { 20 - return i915_fence_context_timeout(i915, U64_MAX); 16 + return i915_fence_context_timeout(U64_MAX); 21 17 } 22 18 23 19 #endif /* __I915_CONFIG_H__ */
+2
drivers/gpu/drm/i915/i915_driver.c
··· 99 99 #include "i915_gmch.h" 100 100 #include "i915_hdcp_gsc.h" 101 101 #include "i915_hwmon.h" 102 + #include "i915_initial_plane.h" 102 103 #include "i915_ioc32.h" 103 104 #include "i915_ioctl.h" 104 105 #include "i915_irq.h" ··· 765 764 766 765 static const struct intel_display_parent_interface parent = { 767 766 .hdcp = &i915_display_hdcp_interface, 767 + .initial_plane = &i915_display_initial_plane_interface, 768 768 .irq = &i915_display_irq_interface, 769 769 .panic = &i915_display_panic_interface, 770 770 .pc8 = &i915_display_pc8_interface,
+1 -1
drivers/gpu/drm/i915/i915_gpu_error.c
··· 686 686 } 687 687 688 688 /* This list includes registers that are useful in debugging GuC hangs. */ 689 - const struct { 689 + static const struct { 690 690 u32 start; 691 691 u32 count; 692 692 } guc_hw_reg_state[] = {
+290
drivers/gpu/drm/i915/i915_initial_plane.c
··· 1 + // SPDX-License-Identifier: MIT 2 + /* 3 + * Copyright © 2021 Intel Corporation 4 + */ 5 + 6 + #include <drm/drm_print.h> 7 + #include <drm/intel/display_parent_interface.h> 8 + 9 + #include "display/intel_crtc.h" 10 + #include "display/intel_display_types.h" 11 + #include "display/intel_fb.h" 12 + #include "gem/i915_gem_lmem.h" 13 + #include "gem/i915_gem_region.h" 14 + 15 + #include "i915_drv.h" 16 + #include "i915_initial_plane.h" 17 + 18 + static void i915_initial_plane_vblank_wait(struct drm_crtc *crtc) 19 + { 20 + intel_crtc_wait_for_next_vblank(to_intel_crtc(crtc)); 21 + } 22 + 23 + static enum intel_memory_type 24 + initial_plane_memory_type(struct drm_i915_private *i915) 25 + { 26 + if (IS_DGFX(i915)) 27 + return INTEL_MEMORY_LOCAL; 28 + else if (HAS_LMEMBAR_SMEM_STOLEN(i915)) 29 + return INTEL_MEMORY_STOLEN_LOCAL; 30 + else 31 + return INTEL_MEMORY_STOLEN_SYSTEM; 32 + } 33 + 34 + static bool 35 + initial_plane_phys(struct drm_i915_private *i915, 36 + struct intel_initial_plane_config *plane_config) 37 + { 38 + struct i915_ggtt *ggtt = to_gt(i915)->ggtt; 39 + struct intel_memory_region *mem; 40 + enum intel_memory_type mem_type; 41 + bool is_present, is_local; 42 + dma_addr_t dma_addr; 43 + u32 base; 44 + 45 + mem_type = initial_plane_memory_type(i915); 46 + mem = intel_memory_region_by_type(i915, mem_type); 47 + if (!mem) { 48 + drm_dbg_kms(&i915->drm, 49 + "Initial plane memory region (type %s) not initialized\n", 50 + intel_memory_type_str(mem_type)); 51 + return false; 52 + } 53 + 54 + base = round_down(plane_config->base, I915_GTT_MIN_ALIGNMENT); 55 + 56 + dma_addr = intel_ggtt_read_entry(&ggtt->vm, base, &is_present, &is_local); 57 + 58 + if (!is_present) { 59 + drm_err(&i915->drm, "Initial plane FB PTE not present\n"); 60 + return false; 61 + } 62 + 63 + if (intel_memory_type_is_local(mem->type) != is_local) { 64 + drm_err(&i915->drm, "Initial plane FB PTE unsuitable for %s\n", 65 + mem->region.name); 66 + return false; 67 + } 68 + 69 + if (dma_addr < mem->region.start || dma_addr > mem->region.end) { 70 + drm_err(&i915->drm, 71 + "Initial plane programming using invalid range, dma_addr=%pa (%s [%pa-%pa])\n", 72 + &dma_addr, mem->region.name, &mem->region.start, &mem->region.end); 73 + return false; 74 + } 75 + 76 + drm_dbg(&i915->drm, "Using dma_addr=%pa, based on initial plane programming\n", 77 + &dma_addr); 78 + 79 + plane_config->phys_base = dma_addr - mem->region.start; 80 + plane_config->mem = mem; 81 + 82 + return true; 83 + } 84 + 85 + static struct i915_vma * 86 + initial_plane_vma(struct drm_i915_private *i915, 87 + struct intel_initial_plane_config *plane_config) 88 + { 89 + struct intel_memory_region *mem; 90 + struct drm_i915_gem_object *obj; 91 + struct drm_mm_node orig_mm = {}; 92 + struct i915_vma *vma; 93 + resource_size_t phys_base; 94 + unsigned int tiling; 95 + u32 base, size; 96 + u64 pinctl; 97 + 98 + if (plane_config->size == 0) 99 + return NULL; 100 + 101 + if (!initial_plane_phys(i915, plane_config)) 102 + return NULL; 103 + 104 + phys_base = plane_config->phys_base; 105 + mem = plane_config->mem; 106 + 107 + base = round_down(plane_config->base, I915_GTT_MIN_ALIGNMENT); 108 + size = round_up(plane_config->base + plane_config->size, 109 + mem->min_page_size); 110 + size -= base; 111 + 112 + /* 113 + * If the FB is too big, just don't use it since fbdev is not very 114 + * important and we should probably use that space with FBC or other 115 + * features. 116 + */ 117 + if (IS_ENABLED(CONFIG_FRAMEBUFFER_CONSOLE) && 118 + mem == i915->mm.stolen_region && 119 + size * 2 > i915->dsm.usable_size) { 120 + drm_dbg_kms(&i915->drm, "Initial FB size exceeds half of stolen, discarding\n"); 121 + return NULL; 122 + } 123 + 124 + obj = i915_gem_object_create_region_at(mem, phys_base, size, 125 + I915_BO_ALLOC_USER | 126 + I915_BO_PREALLOC); 127 + if (IS_ERR(obj)) { 128 + drm_dbg_kms(&i915->drm, "Failed to preallocate initial FB in %s\n", 129 + mem->region.name); 130 + return NULL; 131 + } 132 + 133 + /* 134 + * Mark it WT ahead of time to avoid changing the 135 + * cache_level during fbdev initialization. The 136 + * unbind there would get stuck waiting for rcu. 137 + */ 138 + i915_gem_object_set_cache_coherency(obj, HAS_WT(i915) ? 139 + I915_CACHE_WT : I915_CACHE_NONE); 140 + 141 + tiling = intel_fb_modifier_to_tiling(plane_config->fb->base.modifier); 142 + 143 + switch (tiling) { 144 + case I915_TILING_NONE: 145 + break; 146 + case I915_TILING_X: 147 + case I915_TILING_Y: 148 + obj->tiling_and_stride = 149 + plane_config->fb->base.pitches[0] | 150 + tiling; 151 + break; 152 + default: 153 + MISSING_CASE(tiling); 154 + goto err_obj; 155 + } 156 + 157 + /* 158 + * MTL GOP likes to place the framebuffer high up in ggtt, 159 + * which can cause problems for ggtt_reserve_guc_top(). 160 + * Try to pin it to a low ggtt address instead to avoid that. 161 + */ 162 + base = 0; 163 + 164 + if (base != plane_config->base) { 165 + struct i915_ggtt *ggtt = to_gt(i915)->ggtt; 166 + int ret; 167 + 168 + /* 169 + * Make sure the original and new locations 170 + * can't overlap. That would corrupt the original 171 + * PTEs which are still being used for scanout. 172 + */ 173 + ret = i915_gem_gtt_reserve(&ggtt->vm, NULL, &orig_mm, 174 + size, plane_config->base, 175 + I915_COLOR_UNEVICTABLE, PIN_NOEVICT); 176 + if (ret) 177 + goto err_obj; 178 + } 179 + 180 + vma = i915_vma_instance(obj, &to_gt(i915)->ggtt->vm, NULL); 181 + if (IS_ERR(vma)) 182 + goto err_obj; 183 + 184 + retry: 185 + pinctl = PIN_GLOBAL | PIN_OFFSET_FIXED | base; 186 + if (!i915_gem_object_is_lmem(obj)) 187 + pinctl |= PIN_MAPPABLE; 188 + if (i915_vma_pin(vma, 0, 0, pinctl)) { 189 + if (drm_mm_node_allocated(&orig_mm)) { 190 + drm_mm_remove_node(&orig_mm); 191 + /* 192 + * Try again, but this time pin 193 + * it to its original location. 194 + */ 195 + base = plane_config->base; 196 + goto retry; 197 + } 198 + goto err_obj; 199 + } 200 + 201 + if (i915_gem_object_is_tiled(obj) && 202 + !i915_vma_is_map_and_fenceable(vma)) 203 + goto err_obj; 204 + 205 + if (drm_mm_node_allocated(&orig_mm)) 206 + drm_mm_remove_node(&orig_mm); 207 + 208 + drm_dbg_kms(&i915->drm, 209 + "Initial plane fb bound to 0x%x in the ggtt (original 0x%x)\n", 210 + i915_ggtt_offset(vma), plane_config->base); 211 + 212 + return vma; 213 + 214 + err_obj: 215 + if (drm_mm_node_allocated(&orig_mm)) 216 + drm_mm_remove_node(&orig_mm); 217 + i915_gem_object_put(obj); 218 + return NULL; 219 + } 220 + 221 + static struct drm_gem_object * 222 + i915_alloc_initial_plane_obj(struct drm_device *drm, 223 + struct intel_initial_plane_config *plane_config) 224 + { 225 + struct drm_i915_private *i915 = to_i915(drm); 226 + struct drm_mode_fb_cmd2 mode_cmd = {}; 227 + struct drm_framebuffer *fb = &plane_config->fb->base; 228 + struct i915_vma *vma; 229 + 230 + vma = initial_plane_vma(i915, plane_config); 231 + if (!vma) 232 + return NULL; 233 + 234 + mode_cmd.pixel_format = fb->format->format; 235 + mode_cmd.width = fb->width; 236 + mode_cmd.height = fb->height; 237 + mode_cmd.pitches[0] = fb->pitches[0]; 238 + mode_cmd.modifier[0] = fb->modifier; 239 + mode_cmd.flags = DRM_MODE_FB_MODIFIERS; 240 + 241 + if (intel_framebuffer_init(to_intel_framebuffer(fb), 242 + intel_bo_to_drm_bo(vma->obj), 243 + fb->format, &mode_cmd)) { 244 + drm_dbg_kms(&i915->drm, "intel fb init failed\n"); 245 + goto err_vma; 246 + } 247 + 248 + plane_config->vma = vma; 249 + return intel_bo_to_drm_bo(vma->obj); 250 + 251 + err_vma: 252 + i915_vma_put(vma); 253 + return NULL; 254 + } 255 + 256 + static int 257 + i915_initial_plane_setup(struct drm_plane_state *_plane_state, 258 + struct intel_initial_plane_config *plane_config, 259 + struct drm_framebuffer *fb, 260 + struct i915_vma *vma) 261 + { 262 + struct intel_plane_state *plane_state = to_intel_plane_state(_plane_state); 263 + struct drm_i915_private *dev_priv = to_i915(_plane_state->plane->dev); 264 + 265 + __i915_vma_pin(vma); 266 + plane_state->ggtt_vma = i915_vma_get(vma); 267 + if (intel_plane_uses_fence(plane_state) && 268 + i915_vma_pin_fence(vma) == 0 && vma->fence) 269 + plane_state->flags |= PLANE_HAS_FENCE; 270 + 271 + plane_state->surf = i915_ggtt_offset(plane_state->ggtt_vma); 272 + 273 + if (fb->modifier != DRM_FORMAT_MOD_LINEAR) 274 + dev_priv->preserve_bios_swizzle = true; 275 + 276 + return 0; 277 + } 278 + 279 + static void i915_plane_config_fini(struct intel_initial_plane_config *plane_config) 280 + { 281 + if (plane_config->vma) 282 + i915_vma_put(plane_config->vma); 283 + } 284 + 285 + const struct intel_display_initial_plane_interface i915_display_initial_plane_interface = { 286 + .vblank_wait = i915_initial_plane_vblank_wait, 287 + .alloc_obj = i915_alloc_initial_plane_obj, 288 + .setup = i915_initial_plane_setup, 289 + .config_fini = i915_plane_config_fini, 290 + };
+9
drivers/gpu/drm/i915/i915_initial_plane.h
··· 1 + /* SPDX-License-Identifier: MIT */ 2 + /* Copyright © 2025 Intel Corporation */ 3 + 4 + #ifndef __I915_INITIAL_PLANE_H__ 5 + #define __I915_INITIAL_PLANE_H__ 6 + 7 + extern const struct intel_display_initial_plane_interface i915_display_initial_plane_interface; 8 + 9 + #endif
+1 -2
drivers/gpu/drm/i915/i915_request.c
··· 1351 1351 { 1352 1352 mark_external(rq); 1353 1353 return i915_sw_fence_await_dma_fence(&rq->submit, fence, 1354 - i915_fence_context_timeout(rq->i915, 1355 - fence->context), 1354 + i915_fence_context_timeout(fence->context), 1356 1355 I915_FENCE_GFP); 1357 1356 } 1358 1357
-4
drivers/gpu/drm/i915/i915_utils.h
··· 38 38 39 39 struct drm_i915_private; 40 40 41 - #ifndef MISSING_CASE 42 41 #define MISSING_CASE(x) WARN(1, "Missing case (%s == %ld)\n", \ 43 42 __stringify(x), (long)(x)) 44 - #endif 45 43 46 44 #define i915_probe_error(i915, fmt, ...) ({ \ 47 45 drm_err(&(i915)->drm, fmt, ##__VA_ARGS__); \ 48 46 }) 49 47 50 - #ifndef fetch_and_zero 51 48 #define fetch_and_zero(ptr) ({ \ 52 49 typeof(*ptr) __T = *(ptr); \ 53 50 *(ptr) = (typeof(*ptr))0; \ 54 51 __T; \ 55 52 }) 56 - #endif 57 53 58 54 /* 59 55 * check_user_mbz: Check that a user value exists and is zero
+8 -5
drivers/gpu/drm/i915/intel_gvt.c
··· 21 21 * SOFTWARE. 22 22 */ 23 23 24 + #include <linux/vmalloc.h> 25 + 24 26 #include <drm/drm_print.h> 27 + 28 + #include "gem/i915_gem_dmabuf.h" 29 + 30 + #include "gt/intel_context.h" 31 + #include "gt/intel_ring.h" 32 + #include "gt/shmem_utils.h" 25 33 26 34 #include "i915_drv.h" 27 35 #include "i915_vgpu.h" 28 36 #include "intel_gvt.h" 29 - #include "gem/i915_gem_dmabuf.h" 30 - #include "gt/intel_context.h" 31 - #include "gt/intel_ring.h" 32 - #include "gt/shmem_utils.h" 33 - #include <linux/vmalloc.h> 34 37 35 38 /** 36 39 * DOC: Intel GVT-g host support
+3 -1
drivers/gpu/drm/i915/intel_gvt_mmio_table.c
··· 12 12 #include "display/intel_crt_regs.h" 13 13 #include "display/intel_cursor_regs.h" 14 14 #include "display/intel_display_core.h" 15 + #include "display/intel_display_regs.h" 15 16 #include "display/intel_display_types.h" 16 17 #include "display/intel_dmc_regs.h" 17 18 #include "display/intel_dp_aux_regs.h" ··· 28 27 #include "display/skl_universal_plane_regs.h" 29 28 #include "display/skl_watermark_regs.h" 30 29 #include "display/vlv_dsi_pll_regs.h" 30 + 31 31 #include "gt/intel_engine_regs.h" 32 32 #include "gt/intel_gt_regs.h" 33 + 33 34 #include "gvt/reg.h" 34 35 35 36 #include "i915_drv.h" 36 37 #include "i915_pvinfo.h" 37 38 #include "i915_reg.h" 38 - #include "display/intel_display_regs.h" 39 39 #include "intel_gvt.h" 40 40 #include "intel_mchbar_regs.h" 41 41
+3 -3
drivers/gpu/drm/xe/Makefile
··· 200 200 # i915 Display compat #defines and #includes 201 201 subdir-ccflags-$(CONFIG_DRM_XE_DISPLAY) += \ 202 202 -I$(src)/compat-i915-headers \ 203 - -I$(srctree)/drivers/gpu/drm/i915/display/ \ 204 - -Ddrm_i915_private=xe_device 203 + -I$(srctree)/drivers/gpu/drm/i915/display/ 205 204 206 205 # Rule to build display code shared with i915 207 206 $(obj)/i915-display/%.o: $(srctree)/drivers/gpu/drm/i915/display/%.c FORCE ··· 218 219 display/xe_dsb_buffer.o \ 219 220 display/xe_fb_pin.o \ 220 221 display/xe_hdcp_gsc.o \ 222 + display/xe_initial_plane.o \ 221 223 display/xe_panic.o \ 222 - display/xe_plane_initial.o \ 223 224 display/xe_stolen.o \ 224 225 display/xe_tdf.o 225 226 ··· 295 296 i915-display/intel_hotplug.o \ 296 297 i915-display/intel_hotplug_irq.o \ 297 298 i915-display/intel_hti.o \ 299 + i915-display/intel_initial_plane.o \ 298 300 i915-display/intel_link_bw.o \ 299 301 i915-display/intel_lspcon.o \ 300 302 i915-display/intel_lt_phy.o \
+1 -4
drivers/gpu/drm/xe/compat-i915-headers/i915_config.h
··· 8 8 9 9 #include <linux/sched.h> 10 10 11 - struct drm_i915_private; 12 - 13 - static inline unsigned long 14 - i915_fence_timeout(const struct drm_i915_private *i915) 11 + static inline unsigned long i915_fence_timeout(void) 15 12 { 16 13 return MAX_SCHEDULE_TIMEOUT; 17 14 }
-22
drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h
··· 1 - /* SPDX-License-Identifier: MIT */ 2 - /* 3 - * Copyright © 2023 Intel Corporation 4 - */ 5 - #ifndef _XE_I915_DRV_H_ 6 - #define _XE_I915_DRV_H_ 7 - 8 - /* 9 - * "Adaptation header" to allow i915 display to also build for xe driver. 10 - * TODO: refactor i915 and xe so this can cease to exist 11 - */ 12 - 13 - #include <drm/drm_drv.h> 14 - 15 - #include "xe_device_types.h" 16 - 17 - static inline struct drm_i915_private *to_i915(const struct drm_device *dev) 18 - { 19 - return container_of(dev, struct drm_i915_private, drm); 20 - } 21 - 22 - #endif
-7
drivers/gpu/drm/xe/compat-i915-headers/i915_utils.h
··· 1 - /* SPDX-License-Identifier: MIT */ 2 - /* 3 - * Copyright © 2023 Intel Corporation 4 - */ 5 - 6 - /* for a couple of users under i915/display */ 7 - #define i915_inject_probe_failure(unused) ((unused) && 0)
+5 -6
drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h
··· 10 10 #include "xe_device_types.h" 11 11 #include "xe_mmio.h" 12 12 13 - #define FORCEWAKE_ALL XE_FORCEWAKE_ALL 14 - 15 13 static inline struct intel_uncore *to_intel_uncore(struct drm_device *drm) 16 14 { 17 15 return &to_xe_device(drm)->uncore; ··· 152 154 xe_mmio_write32(__compat_uncore_to_mmio(uncore), reg, val); 153 155 } 154 156 155 - #define intel_uncore_forcewake_get(x, y) do { } while (0) 156 - #define intel_uncore_forcewake_put(x, y) do { } while (0) 157 - 158 - #define intel_uncore_arm_unclaimed_mmio_detection(x) do { } while (0) 157 + static inline bool 158 + intel_uncore_arm_unclaimed_mmio_detection(struct intel_uncore *uncore) 159 + { 160 + return false; 161 + } 159 162 160 163 #endif /* __INTEL_UNCORE_H__ */
+2
drivers/gpu/drm/xe/display/xe_display.c
··· 37 37 #include "skl_watermark.h" 38 38 #include "xe_display_rpm.h" 39 39 #include "xe_hdcp_gsc.h" 40 + #include "xe_initial_plane.h" 40 41 #include "xe_module.h" 41 42 #include "xe_panic.h" 42 43 #include "xe_stolen.h" ··· 539 538 540 539 static const struct intel_display_parent_interface parent = { 541 540 .hdcp = &xe_display_hdcp_interface, 541 + .initial_plane = &xe_display_initial_plane_interface, 542 542 .irq = &xe_display_irq_interface, 543 543 .panic = &xe_display_panic_interface, 544 544 .rpm = &xe_display_rpm_interface,
+1 -1
drivers/gpu/drm/xe/display/xe_fb_pin.c
··· 373 373 { 374 374 *out_flags = 0; 375 375 376 - return __xe_pin_fb_vma(to_intel_framebuffer(fb), view, phys_alignment); 376 + return __xe_pin_fb_vma(to_intel_framebuffer(fb), view, alignment); 377 377 } 378 378 379 379 void intel_fb_unpin_vma(struct i915_vma *vma, unsigned long flags)
+189
drivers/gpu/drm/xe/display/xe_initial_plane.c
··· 1 + // SPDX-License-Identifier: MIT 2 + /* 3 + * Copyright © 2021 Intel Corporation 4 + */ 5 + 6 + /* for ioread64 */ 7 + #include <linux/io-64-nonatomic-lo-hi.h> 8 + 9 + #include <drm/intel/display_parent_interface.h> 10 + 11 + #include "regs/xe_gtt_defs.h" 12 + #include "xe_ggtt.h" 13 + #include "xe_mmio.h" 14 + 15 + #include "i915_vma.h" 16 + #include "intel_crtc.h" 17 + #include "intel_display_regs.h" 18 + #include "intel_display_types.h" 19 + #include "intel_fb.h" 20 + #include "intel_fb_pin.h" 21 + #include "xe_bo.h" 22 + #include "xe_vram_types.h" 23 + #include "xe_wa.h" 24 + 25 + #include <generated/xe_device_wa_oob.h> 26 + 27 + /* Early xe has no irq */ 28 + static void xe_initial_plane_vblank_wait(struct drm_crtc *_crtc) 29 + { 30 + struct intel_crtc *crtc = to_intel_crtc(_crtc); 31 + struct xe_device *xe = to_xe_device(crtc->base.dev); 32 + struct xe_reg pipe_frmtmstmp = XE_REG(i915_mmio_reg_offset(PIPE_FRMTMSTMP(crtc->pipe))); 33 + u32 timestamp; 34 + int ret; 35 + 36 + timestamp = xe_mmio_read32(xe_root_tile_mmio(xe), pipe_frmtmstmp); 37 + 38 + ret = xe_mmio_wait32_not(xe_root_tile_mmio(xe), pipe_frmtmstmp, ~0U, timestamp, 40000U, &timestamp, false); 39 + if (ret < 0) 40 + drm_warn(&xe->drm, "waiting for early vblank failed with %i\n", ret); 41 + } 42 + 43 + static struct xe_bo * 44 + initial_plane_bo(struct xe_device *xe, 45 + struct intel_initial_plane_config *plane_config) 46 + { 47 + struct xe_tile *tile0 = xe_device_get_root_tile(xe); 48 + struct xe_bo *bo; 49 + resource_size_t phys_base; 50 + u32 base, size, flags; 51 + u64 page_size = xe->info.vram_flags & XE_VRAM_FLAGS_NEED64K ? SZ_64K : SZ_4K; 52 + 53 + if (plane_config->size == 0) 54 + return NULL; 55 + 56 + flags = XE_BO_FLAG_SCANOUT | XE_BO_FLAG_GGTT; 57 + 58 + base = round_down(plane_config->base, page_size); 59 + if (IS_DGFX(xe)) { 60 + u64 pte = xe_ggtt_read_pte(tile0->mem.ggtt, base); 61 + 62 + if (!(pte & XE_GGTT_PTE_DM)) { 63 + drm_err(&xe->drm, 64 + "Initial plane programming missing DM bit\n"); 65 + return NULL; 66 + } 67 + 68 + phys_base = pte & ~(page_size - 1); 69 + flags |= XE_BO_FLAG_VRAM0; 70 + 71 + /* 72 + * We don't currently expect this to ever be placed in the 73 + * stolen portion. 74 + */ 75 + if (phys_base >= xe_vram_region_usable_size(tile0->mem.vram)) { 76 + drm_err(&xe->drm, 77 + "Initial plane programming using invalid range, phys_base=%pa\n", 78 + &phys_base); 79 + return NULL; 80 + } 81 + 82 + drm_dbg(&xe->drm, 83 + "Using phys_base=%pa, based on initial plane programming\n", 84 + &phys_base); 85 + } else { 86 + struct ttm_resource_manager *stolen = ttm_manager_type(&xe->ttm, XE_PL_STOLEN); 87 + 88 + if (!stolen) 89 + return NULL; 90 + phys_base = base; 91 + flags |= XE_BO_FLAG_STOLEN; 92 + 93 + if (XE_DEVICE_WA(xe, 22019338487_display)) 94 + return NULL; 95 + 96 + /* 97 + * If the FB is too big, just don't use it since fbdev is not very 98 + * important and we should probably use that space with FBC or other 99 + * features. 100 + */ 101 + if (IS_ENABLED(CONFIG_FRAMEBUFFER_CONSOLE) && 102 + plane_config->size * 2 >> PAGE_SHIFT >= stolen->size) 103 + return NULL; 104 + } 105 + 106 + size = round_up(plane_config->base + plane_config->size, 107 + page_size); 108 + size -= base; 109 + 110 + bo = xe_bo_create_pin_map_at_novm(xe, tile0, size, phys_base, 111 + ttm_bo_type_kernel, flags, 0, false); 112 + if (IS_ERR(bo)) { 113 + drm_dbg(&xe->drm, 114 + "Failed to create bo phys_base=%pa size %u with flags %x: %li\n", 115 + &phys_base, size, flags, PTR_ERR(bo)); 116 + return NULL; 117 + } 118 + 119 + return bo; 120 + } 121 + 122 + static struct drm_gem_object * 123 + xe_alloc_initial_plane_obj(struct drm_device *drm, 124 + struct intel_initial_plane_config *plane_config) 125 + { 126 + struct xe_device *xe = to_xe_device(drm); 127 + struct drm_mode_fb_cmd2 mode_cmd = { 0 }; 128 + struct drm_framebuffer *fb = &plane_config->fb->base; 129 + struct xe_bo *bo; 130 + 131 + mode_cmd.pixel_format = fb->format->format; 132 + mode_cmd.width = fb->width; 133 + mode_cmd.height = fb->height; 134 + mode_cmd.pitches[0] = fb->pitches[0]; 135 + mode_cmd.modifier[0] = fb->modifier; 136 + mode_cmd.flags = DRM_MODE_FB_MODIFIERS; 137 + 138 + bo = initial_plane_bo(xe, plane_config); 139 + if (!bo) 140 + return NULL; 141 + 142 + if (intel_framebuffer_init(to_intel_framebuffer(fb), 143 + &bo->ttm.base, fb->format, &mode_cmd)) { 144 + drm_dbg_kms(&xe->drm, "intel fb init failed\n"); 145 + goto err_bo; 146 + } 147 + /* Reference handed over to fb */ 148 + xe_bo_put(bo); 149 + 150 + return &bo->ttm.base; 151 + 152 + err_bo: 153 + xe_bo_unpin_map_no_vm(bo); 154 + return NULL; 155 + } 156 + 157 + static int 158 + xe_initial_plane_setup(struct drm_plane_state *_plane_state, 159 + struct intel_initial_plane_config *plane_config, 160 + struct drm_framebuffer *fb, 161 + struct i915_vma *_unused) 162 + { 163 + struct intel_plane_state *plane_state = to_intel_plane_state(_plane_state); 164 + struct i915_vma *vma; 165 + 166 + vma = intel_fb_pin_to_ggtt(fb, &plane_state->view.gtt, 167 + 0, 0, 0, false, &plane_state->flags); 168 + if (IS_ERR(vma)) 169 + return PTR_ERR(vma); 170 + 171 + plane_state->ggtt_vma = vma; 172 + 173 + plane_state->surf = i915_ggtt_offset(plane_state->ggtt_vma); 174 + 175 + plane_config->vma = vma; 176 + 177 + return 0; 178 + } 179 + 180 + static void xe_plane_config_fini(struct intel_initial_plane_config *plane_config) 181 + { 182 + } 183 + 184 + const struct intel_display_initial_plane_interface xe_display_initial_plane_interface = { 185 + .vblank_wait = xe_initial_plane_vblank_wait, 186 + .alloc_obj = xe_alloc_initial_plane_obj, 187 + .setup = xe_initial_plane_setup, 188 + .config_fini = xe_plane_config_fini, 189 + };
+9
drivers/gpu/drm/xe/display/xe_initial_plane.h
··· 1 + /* SPDX-License-Identifier: MIT */ 2 + /* Copyright © 2025 Intel Corporation */ 3 + 4 + #ifndef __XE_INITIAL_PLANE_H__ 5 + #define __XE_INITIAL_PLANE_H__ 6 + 7 + extern const struct intel_display_initial_plane_interface xe_display_initial_plane_interface; 8 + 9 + #endif
-321
drivers/gpu/drm/xe/display/xe_plane_initial.c
··· 1 - // SPDX-License-Identifier: MIT 2 - /* 3 - * Copyright © 2021 Intel Corporation 4 - */ 5 - 6 - /* for ioread64 */ 7 - #include <linux/io-64-nonatomic-lo-hi.h> 8 - 9 - #include "regs/xe_gtt_defs.h" 10 - #include "xe_ggtt.h" 11 - #include "xe_mmio.h" 12 - 13 - #include "i915_vma.h" 14 - #include "intel_crtc.h" 15 - #include "intel_display.h" 16 - #include "intel_display_core.h" 17 - #include "intel_display_regs.h" 18 - #include "intel_display_types.h" 19 - #include "intel_fb.h" 20 - #include "intel_fb_pin.h" 21 - #include "intel_frontbuffer.h" 22 - #include "intel_plane.h" 23 - #include "intel_plane_initial.h" 24 - #include "xe_bo.h" 25 - #include "xe_vram_types.h" 26 - #include "xe_wa.h" 27 - 28 - #include <generated/xe_device_wa_oob.h> 29 - 30 - void intel_plane_initial_vblank_wait(struct intel_crtc *crtc) 31 - { 32 - /* Early xe has no irq */ 33 - struct xe_device *xe = to_xe_device(crtc->base.dev); 34 - struct xe_reg pipe_frmtmstmp = XE_REG(i915_mmio_reg_offset(PIPE_FRMTMSTMP(crtc->pipe))); 35 - u32 timestamp; 36 - int ret; 37 - 38 - timestamp = xe_mmio_read32(xe_root_tile_mmio(xe), pipe_frmtmstmp); 39 - 40 - ret = xe_mmio_wait32_not(xe_root_tile_mmio(xe), pipe_frmtmstmp, ~0U, timestamp, 40000U, &timestamp, false); 41 - if (ret < 0) 42 - drm_warn(&xe->drm, "waiting for early vblank failed with %i\n", ret); 43 - } 44 - 45 - static bool 46 - intel_reuse_initial_plane_obj(struct intel_crtc *this, 47 - const struct intel_initial_plane_config plane_configs[], 48 - struct drm_framebuffer **fb) 49 - { 50 - struct xe_device *xe = to_xe_device(this->base.dev); 51 - struct intel_crtc *crtc; 52 - 53 - for_each_intel_crtc(&xe->drm, crtc) { 54 - struct intel_plane *plane = 55 - to_intel_plane(crtc->base.primary); 56 - const struct intel_plane_state *plane_state = 57 - to_intel_plane_state(plane->base.state); 58 - const struct intel_crtc_state *crtc_state = 59 - to_intel_crtc_state(crtc->base.state); 60 - 61 - if (!crtc_state->hw.active) 62 - continue; 63 - 64 - if (!plane_state->ggtt_vma) 65 - continue; 66 - 67 - if (plane_configs[this->pipe].base == plane_configs[crtc->pipe].base) { 68 - *fb = plane_state->hw.fb; 69 - return true; 70 - } 71 - } 72 - 73 - return false; 74 - } 75 - 76 - static struct xe_bo * 77 - initial_plane_bo(struct xe_device *xe, 78 - struct intel_initial_plane_config *plane_config) 79 - { 80 - struct xe_tile *tile0 = xe_device_get_root_tile(xe); 81 - struct xe_bo *bo; 82 - resource_size_t phys_base; 83 - u32 base, size, flags; 84 - u64 page_size = xe->info.vram_flags & XE_VRAM_FLAGS_NEED64K ? SZ_64K : SZ_4K; 85 - 86 - if (plane_config->size == 0) 87 - return NULL; 88 - 89 - flags = XE_BO_FLAG_SCANOUT | XE_BO_FLAG_GGTT; 90 - 91 - base = round_down(plane_config->base, page_size); 92 - if (IS_DGFX(xe)) { 93 - u64 pte = xe_ggtt_read_pte(tile0->mem.ggtt, base); 94 - 95 - if (!(pte & XE_GGTT_PTE_DM)) { 96 - drm_err(&xe->drm, 97 - "Initial plane programming missing DM bit\n"); 98 - return NULL; 99 - } 100 - 101 - phys_base = pte & ~(page_size - 1); 102 - flags |= XE_BO_FLAG_VRAM0; 103 - 104 - /* 105 - * We don't currently expect this to ever be placed in the 106 - * stolen portion. 107 - */ 108 - if (phys_base >= xe_vram_region_usable_size(tile0->mem.vram)) { 109 - drm_err(&xe->drm, 110 - "Initial plane programming using invalid range, phys_base=%pa\n", 111 - &phys_base); 112 - return NULL; 113 - } 114 - 115 - drm_dbg(&xe->drm, 116 - "Using phys_base=%pa, based on initial plane programming\n", 117 - &phys_base); 118 - } else { 119 - struct ttm_resource_manager *stolen = ttm_manager_type(&xe->ttm, XE_PL_STOLEN); 120 - 121 - if (!stolen) 122 - return NULL; 123 - phys_base = base; 124 - flags |= XE_BO_FLAG_STOLEN; 125 - 126 - if (XE_DEVICE_WA(xe, 22019338487_display)) 127 - return NULL; 128 - 129 - /* 130 - * If the FB is too big, just don't use it since fbdev is not very 131 - * important and we should probably use that space with FBC or other 132 - * features. 133 - */ 134 - if (IS_ENABLED(CONFIG_FRAMEBUFFER_CONSOLE) && 135 - plane_config->size * 2 >> PAGE_SHIFT >= stolen->size) 136 - return NULL; 137 - } 138 - 139 - size = round_up(plane_config->base + plane_config->size, 140 - page_size); 141 - size -= base; 142 - 143 - bo = xe_bo_create_pin_map_at_novm(xe, tile0, size, phys_base, 144 - ttm_bo_type_kernel, flags, 0, false); 145 - if (IS_ERR(bo)) { 146 - drm_dbg(&xe->drm, 147 - "Failed to create bo phys_base=%pa size %u with flags %x: %li\n", 148 - &phys_base, size, flags, PTR_ERR(bo)); 149 - return NULL; 150 - } 151 - 152 - return bo; 153 - } 154 - 155 - static bool 156 - intel_alloc_initial_plane_obj(struct intel_crtc *crtc, 157 - struct intel_initial_plane_config *plane_config) 158 - { 159 - struct xe_device *xe = to_xe_device(crtc->base.dev); 160 - struct drm_mode_fb_cmd2 mode_cmd = { 0 }; 161 - struct drm_framebuffer *fb = &plane_config->fb->base; 162 - struct xe_bo *bo; 163 - 164 - switch (fb->modifier) { 165 - case DRM_FORMAT_MOD_LINEAR: 166 - case I915_FORMAT_MOD_X_TILED: 167 - case I915_FORMAT_MOD_Y_TILED: 168 - case I915_FORMAT_MOD_4_TILED: 169 - break; 170 - default: 171 - drm_dbg_kms(&xe->drm, 172 - "Unsupported modifier for initial FB: 0x%llx\n", 173 - fb->modifier); 174 - return false; 175 - } 176 - 177 - mode_cmd.pixel_format = fb->format->format; 178 - mode_cmd.width = fb->width; 179 - mode_cmd.height = fb->height; 180 - mode_cmd.pitches[0] = fb->pitches[0]; 181 - mode_cmd.modifier[0] = fb->modifier; 182 - mode_cmd.flags = DRM_MODE_FB_MODIFIERS; 183 - 184 - bo = initial_plane_bo(xe, plane_config); 185 - if (!bo) 186 - return false; 187 - 188 - if (intel_framebuffer_init(to_intel_framebuffer(fb), 189 - &bo->ttm.base, fb->format, &mode_cmd)) { 190 - drm_dbg_kms(&xe->drm, "intel fb init failed\n"); 191 - goto err_bo; 192 - } 193 - /* Reference handed over to fb */ 194 - xe_bo_put(bo); 195 - 196 - return true; 197 - 198 - err_bo: 199 - xe_bo_unpin_map_no_vm(bo); 200 - return false; 201 - } 202 - 203 - static void 204 - intel_find_initial_plane_obj(struct intel_crtc *crtc, 205 - struct intel_initial_plane_config plane_configs[]) 206 - { 207 - struct intel_initial_plane_config *plane_config = 208 - &plane_configs[crtc->pipe]; 209 - struct intel_plane *plane = 210 - to_intel_plane(crtc->base.primary); 211 - struct intel_plane_state *plane_state = 212 - to_intel_plane_state(plane->base.state); 213 - struct drm_framebuffer *fb; 214 - struct i915_vma *vma; 215 - 216 - /* 217 - * TODO: 218 - * Disable planes if get_initial_plane_config() failed. 219 - * Make sure things work if the surface base is not page aligned. 220 - */ 221 - if (!plane_config->fb) 222 - return; 223 - 224 - if (intel_alloc_initial_plane_obj(crtc, plane_config)) 225 - fb = &plane_config->fb->base; 226 - else if (!intel_reuse_initial_plane_obj(crtc, plane_configs, &fb)) 227 - goto nofb; 228 - 229 - plane_state->uapi.rotation = plane_config->rotation; 230 - intel_fb_fill_view(to_intel_framebuffer(fb), 231 - plane_state->uapi.rotation, &plane_state->view); 232 - 233 - vma = intel_fb_pin_to_ggtt(fb, &plane_state->view.gtt, 234 - 0, 0, 0, false, &plane_state->flags); 235 - if (IS_ERR(vma)) 236 - goto nofb; 237 - 238 - plane_state->ggtt_vma = vma; 239 - 240 - plane_state->surf = i915_ggtt_offset(plane_state->ggtt_vma); 241 - 242 - plane_state->uapi.src_x = 0; 243 - plane_state->uapi.src_y = 0; 244 - plane_state->uapi.src_w = fb->width << 16; 245 - plane_state->uapi.src_h = fb->height << 16; 246 - 247 - plane_state->uapi.crtc_x = 0; 248 - plane_state->uapi.crtc_y = 0; 249 - plane_state->uapi.crtc_w = fb->width; 250 - plane_state->uapi.crtc_h = fb->height; 251 - 252 - plane_state->uapi.fb = fb; 253 - drm_framebuffer_get(fb); 254 - 255 - plane_state->uapi.crtc = &crtc->base; 256 - intel_plane_copy_uapi_to_hw_state(plane_state, plane_state, crtc); 257 - 258 - atomic_or(plane->frontbuffer_bit, &to_intel_frontbuffer(fb)->bits); 259 - 260 - plane_config->vma = vma; 261 - return; 262 - 263 - nofb: 264 - /* 265 - * We've failed to reconstruct the BIOS FB. Current display state 266 - * indicates that the primary plane is visible, but has a NULL FB, 267 - * which will lead to problems later if we don't fix it up. The 268 - * simplest solution is to just disable the primary plane now and 269 - * pretend the BIOS never had it enabled. 270 - */ 271 - intel_plane_disable_noatomic(crtc, plane); 272 - } 273 - 274 - static void plane_config_fini(struct intel_initial_plane_config *plane_config) 275 - { 276 - if (plane_config->fb) { 277 - struct drm_framebuffer *fb = &plane_config->fb->base; 278 - 279 - /* We may only have the stub and not a full framebuffer */ 280 - if (drm_framebuffer_read_refcount(fb)) 281 - drm_framebuffer_put(fb); 282 - else 283 - kfree(fb); 284 - } 285 - } 286 - 287 - void intel_initial_plane_config(struct intel_display *display) 288 - { 289 - struct intel_initial_plane_config plane_configs[I915_MAX_PIPES] = {}; 290 - struct intel_crtc *crtc; 291 - 292 - for_each_intel_crtc(display->drm, crtc) { 293 - const struct intel_crtc_state *crtc_state = 294 - to_intel_crtc_state(crtc->base.state); 295 - struct intel_initial_plane_config *plane_config = 296 - &plane_configs[crtc->pipe]; 297 - 298 - if (!crtc_state->hw.active) 299 - continue; 300 - 301 - /* 302 - * Note that reserving the BIOS fb up front prevents us 303 - * from stuffing other stolen allocations like the ring 304 - * on top. This prevents some ugliness at boot time, and 305 - * can even allow for smooth boot transitions if the BIOS 306 - * fb is large enough for the active pipe configuration. 307 - */ 308 - display->funcs.display->get_initial_plane_config(crtc, plane_config); 309 - 310 - /* 311 - * If the fb is shared between multiple heads, we'll 312 - * just get the first one. 313 - */ 314 - intel_find_initial_plane_obj(crtc, plane_configs); 315 - 316 - if (display->funcs.display->fixup_initial_plane_config(crtc, plane_config)) 317 - intel_plane_initial_vblank_wait(crtc); 318 - 319 - plane_config_fini(plane_config); 320 - } 321 - }
+17
include/drm/intel/display_parent_interface.h
··· 7 7 #include <linux/types.h> 8 8 9 9 struct dma_fence; 10 + struct drm_crtc; 10 11 struct drm_device; 12 + struct drm_framebuffer; 13 + struct drm_gem_object; 14 + struct drm_plane_state; 11 15 struct drm_scanout_buffer; 16 + struct i915_vma; 12 17 struct intel_hdcp_gsc_context; 18 + struct intel_initial_plane_config; 13 19 struct intel_panic; 14 20 struct intel_stolen_node; 15 21 struct ref_tracker; ··· 29 23 bool (*gsc_check_status)(struct drm_device *drm); 30 24 struct intel_hdcp_gsc_context *(*gsc_context_alloc)(struct drm_device *drm); 31 25 void (*gsc_context_free)(struct intel_hdcp_gsc_context *gsc_context); 26 + }; 27 + 28 + struct intel_display_initial_plane_interface { 29 + void (*vblank_wait)(struct drm_crtc *crtc); 30 + struct drm_gem_object *(*alloc_obj)(struct drm_device *drm, struct intel_initial_plane_config *plane_config); 31 + int (*setup)(struct drm_plane_state *plane_state, struct intel_initial_plane_config *plane_config, 32 + struct drm_framebuffer *fb, struct i915_vma *vma); 33 + void (*config_fini)(struct intel_initial_plane_config *plane_configs); 32 34 }; 33 35 34 36 struct intel_display_irq_interface { ··· 108 94 struct intel_display_parent_interface { 109 95 /** @hdcp: HDCP GSC interface */ 110 96 const struct intel_display_hdcp_interface *hdcp; 97 + 98 + /** @initial_plane: Initial plane interface */ 99 + const struct intel_display_initial_plane_interface *initial_plane; 111 100 112 101 /** @irq: IRQ interface */ 113 102 const struct intel_display_irq_interface *irq;
+2 -1
include/drm/intel/intel_lb_mei_interface.h
··· 53 53 */ 54 54 struct intel_lb_component_ops { 55 55 /** 56 - * push_payload - Sends a payload to the authentication firmware 56 + * @push_payload: Sends a payload to the authentication firmware 57 + * 57 58 * @dev: Device struct corresponding to the mei device 58 59 * @type: Payload type (see &enum intel_lb_type) 59 60 * @flags: Payload flags bitmap (e.g. %INTEL_LB_FLAGS_IS_PERSISTENT)