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-2025-07-04' of https://gitlab.freedesktop.org/drm/i915/kernel into drm-next

drm/i915 feature pull #2 for v6.17:

Features and functionality:
- Add drm_panic support for both i915 and xe drivers (Jocelyn Falempe)
- Add initial flip queue implementation, disabled by default, for LNL and PTL
(Ville)
- Add support for Wildcat Lake (WCL) display, version 30.02 (Matt Roper, Matt
Atwood, Dnyaneshwar)
- Extend drm_panel and follower support to DDI eDP (Arun)

Refactoring and cleanups:
- Make all global state objects opaque (Jani)
- Move display works to display specific unordered workqueue (Luca)
- Add and use struct drm_device based pcode interface (Jani, Lucas)
- Use clamp() instead of max()+min() combo (Ankit)
- Simplify wait for power well disable (Jani)
- Various stylistics cleanups and renames (Jani)

Fixes:
- Deal with loss of pipe DMC state (Ville)
- Fix PTL HDCP2 stream status check (Suraj)
- Add workaround for ADL-P DKL PHY DP and HDMI (Nemesa)
- Fix skl_print_wm_changes() stack usage with KMSAN (Arnd Bergmann)
- Fix PCON capability reads on non-branch devices (Chaitanya)
- Fix which platforms have ultra joiner (Ankit)

DRM core changes:
- Add ttm_bo_kmap_try_from_panic() for xe drm_panic support (Jocelyn Falempe)
- Add private pointer to struct drm_scanout buffer for xe/i915 drm_panic support
(Jocelyn Falempe)

Merges:
- Backmerge drm-next for drm_panel and xe changes (Jani)

Signed-off-by: Simona Vetter <simona.vetter@ffwll.ch>
From: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/6d728bf6ef23681b00dfbc7da9aeae41042dee02@intel.com

+2638 -904
+8 -2
Documentation/gpu/i915.rst
··· 112 112 Atomic Plane Helpers 113 113 -------------------- 114 114 115 - .. kernel-doc:: drivers/gpu/drm/i915/display/intel_atomic_plane.c 115 + .. kernel-doc:: drivers/gpu/drm/i915/display/intel_plane.c 116 116 :doc: atomic plane helpers 117 117 118 - .. kernel-doc:: drivers/gpu/drm/i915/display/intel_atomic_plane.c 118 + .. kernel-doc:: drivers/gpu/drm/i915/display/intel_plane.c 119 119 :internal: 120 120 121 121 Asynchronous Page Flip ··· 203 203 204 204 .. kernel-doc:: drivers/gpu/drm/i915/display/intel_dmc.c 205 205 :internal: 206 + 207 + DMC Flip Queue 208 + -------------------- 209 + 210 + .. kernel-doc:: drivers/gpu/drm/i915/display/intel_flipq.c 211 + :doc: DMC Flip Queue 206 212 207 213 DMC wakelock support 208 214 --------------------
+3 -2
drivers/gpu/drm/i915/Makefile
··· 218 218 # modesetting core code 219 219 i915-y += \ 220 220 display/hsw_ips.o \ 221 - display/i9xx_plane.o \ 222 221 display/i9xx_display_sr.o \ 222 + display/i9xx_plane.o \ 223 223 display/i9xx_wm.o \ 224 224 display/intel_alpm.o \ 225 225 display/intel_atomic.o \ 226 - display/intel_atomic_plane.o \ 227 226 display/intel_audio.o \ 228 227 display/intel_bios.o \ 229 228 display/intel_bo.o \ ··· 264 265 display/intel_fbc.o \ 265 266 display/intel_fdi.o \ 266 267 display/intel_fifo_underrun.o \ 268 + display/intel_flipq.o \ 267 269 display/intel_frontbuffer.o \ 268 270 display/intel_global_state.o \ 269 271 display/intel_hdcp.o \ ··· 283 283 display/intel_pch.o \ 284 284 display/intel_pch_display.o \ 285 285 display/intel_pch_refclk.o \ 286 + display/intel_plane.o \ 286 287 display/intel_plane_initial.o \ 287 288 display/intel_pmdemand.o \ 288 289 display/intel_psr.o \
+6 -9
drivers/gpu/drm/i915/display/hsw_ips.c
··· 5 5 6 6 #include <linux/debugfs.h> 7 7 8 + #include <drm/drm_print.h> 9 + 8 10 #include "hsw_ips.h" 9 - #include "i915_drv.h" 10 11 #include "i915_reg.h" 11 12 #include "intel_color_regs.h" 12 13 #include "intel_de.h" ··· 19 18 static void hsw_ips_enable(const struct intel_crtc_state *crtc_state) 20 19 { 21 20 struct intel_display *display = to_intel_display(crtc_state); 22 - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 23 - struct drm_i915_private *i915 = to_i915(crtc->base.dev); 24 21 u32 val; 25 22 26 23 if (!crtc_state->ips_enabled) ··· 39 40 40 41 if (display->platform.broadwell) { 41 42 drm_WARN_ON(display->drm, 42 - snb_pcode_write(&i915->uncore, DISPLAY_IPS_CONTROL, 43 - val | IPS_PCODE_CONTROL)); 43 + intel_pcode_write(display->drm, DISPLAY_IPS_CONTROL, 44 + val | IPS_PCODE_CONTROL)); 44 45 /* 45 46 * Quoting Art Runyan: "its not safe to expect any particular 46 47 * value in IPS_CTL bit 31 after enabling IPS through the ··· 65 66 bool hsw_ips_disable(const struct intel_crtc_state *crtc_state) 66 67 { 67 68 struct intel_display *display = to_intel_display(crtc_state); 68 - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 69 - struct drm_i915_private *i915 = to_i915(crtc->base.dev); 70 69 bool need_vblank_wait = false; 71 70 72 71 if (!crtc_state->ips_enabled) ··· 72 75 73 76 if (display->platform.broadwell) { 74 77 drm_WARN_ON(display->drm, 75 - snb_pcode_write(&i915->uncore, DISPLAY_IPS_CONTROL, 0)); 78 + intel_pcode_write(display->drm, DISPLAY_IPS_CONTROL, 0)); 76 79 /* 77 80 * Wait for PCODE to finish disabling IPS. The BSpec specified 78 81 * 42ms timeout value leads to occasional timeouts so use 100ms ··· 265 268 return PTR_ERR(cdclk_state); 266 269 267 270 /* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */ 268 - if (crtc_state->pixel_rate > cdclk_state->logical.cdclk * 95 / 100) 271 + if (crtc_state->pixel_rate > intel_cdclk_logical(cdclk_state) * 95 / 100) 269 272 return 0; 270 273 } 271 274
+30 -6
drivers/gpu/drm/i915/display/i9xx_plane.c
··· 15 15 #include "i9xx_plane.h" 16 16 #include "i9xx_plane_regs.h" 17 17 #include "intel_atomic.h" 18 - #include "intel_atomic_plane.h" 18 + #include "intel_bo.h" 19 19 #include "intel_de.h" 20 20 #include "intel_display_irq.h" 21 21 #include "intel_display_regs.h" ··· 23 23 #include "intel_fb.h" 24 24 #include "intel_fbc.h" 25 25 #include "intel_frontbuffer.h" 26 + #include "intel_plane.h" 26 27 #include "intel_sprite.h" 27 28 28 29 /* Primary plane formats for gen <= 3 */ ··· 337 336 if (ret) 338 337 return ret; 339 338 340 - ret = intel_atomic_plane_check_clipping(plane_state, crtc_state, 341 - DRM_PLANE_NO_SCALING, 342 - DRM_PLANE_NO_SCALING, 343 - i9xx_plane_has_windowing(plane)); 339 + ret = intel_plane_check_clipping(plane_state, crtc_state, 340 + DRM_PLANE_NO_SCALING, 341 + DRM_PLANE_NO_SCALING, 342 + i9xx_plane_has_windowing(plane)); 344 343 if (ret) 345 344 return ret; 346 345 ··· 906 905 .format_mod_supported_async = intel_plane_format_mod_supported_async, 907 906 }; 908 907 908 + static void i9xx_disable_tiling(struct intel_plane *plane) 909 + { 910 + struct intel_display *display = to_intel_display(plane); 911 + enum i9xx_plane_id i9xx_plane = plane->i9xx_plane; 912 + u32 dspcntr; 913 + u32 reg; 914 + 915 + dspcntr = intel_de_read_fw(display, DSPCNTR(display, i9xx_plane)); 916 + dspcntr &= ~DISP_TILED; 917 + intel_de_write_fw(display, DSPCNTR(display, i9xx_plane), dspcntr); 918 + 919 + if (DISPLAY_VER(display) >= 4) { 920 + reg = intel_de_read_fw(display, DSPSURF(display, i9xx_plane)); 921 + intel_de_write_fw(display, DSPSURF(display, i9xx_plane), reg); 922 + 923 + } else { 924 + reg = intel_de_read_fw(display, DSPADDR(display, i9xx_plane)); 925 + intel_de_write_fw(display, DSPADDR(display, i9xx_plane), reg); 926 + } 927 + } 928 + 909 929 struct intel_plane * 910 930 intel_primary_plane_create(struct intel_display *display, enum pipe pipe) 911 931 { ··· 1069 1047 } 1070 1048 } 1071 1049 1050 + plane->disable_tiling = i9xx_disable_tiling; 1051 + 1072 1052 modifiers = intel_fb_plane_get_modifiers(display, INTEL_PLANE_CAP_TILING_X); 1073 1053 1074 1054 if (DISPLAY_VER(display) >= 5 || display->platform.g4x) ··· 1175 1151 1176 1152 drm_WARN_ON(display->drm, pipe != crtc->pipe); 1177 1153 1178 - intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); 1154 + intel_fb = intel_bo_alloc_framebuffer(); 1179 1155 if (!intel_fb) { 1180 1156 drm_dbg_kms(display->drm, "failed to alloc fb\n"); 1181 1157 return;
+1 -1
drivers/gpu/drm/i915/display/intel_atomic.c
··· 26 26 * 27 27 * The functions here implement the state management and hardware programming 28 28 * dispatch required by the atomic modeset infrastructure. 29 - * See intel_atomic_plane.c for the plane-specific atomic functionality. 29 + * See intel_plane.c for the plane-specific atomic functionality. 30 30 */ 31 31 32 32 #include <drm/display/drm_dp_tunnel.h>
+184 -15
drivers/gpu/drm/i915/display/intel_atomic_plane.c drivers/gpu/drm/i915/display/intel_plane.c
··· 33 33 34 34 #include <linux/dma-fence-chain.h> 35 35 #include <linux/dma-resv.h> 36 + #include <linux/iosys-map.h> 36 37 37 38 #include <drm/drm_atomic_helper.h> 38 39 #include <drm/drm_blend.h> 40 + #include <drm/drm_cache.h> 39 41 #include <drm/drm_damage_helper.h> 40 42 #include <drm/drm_fourcc.h> 41 43 #include <drm/drm_gem.h> 42 44 #include <drm/drm_gem_atomic_helper.h> 45 + #include <drm/drm_panic.h> 43 46 44 47 #include "gem/i915_gem_object.h" 45 48 #include "i915_scheduler_types.h" 46 49 #include "i915_vma.h" 47 50 #include "i9xx_plane_regs.h" 48 - #include "intel_atomic_plane.h" 51 + #include "intel_bo.h" 49 52 #include "intel_cdclk.h" 50 53 #include "intel_cursor.h" 51 54 #include "intel_display_rps.h" ··· 56 53 #include "intel_display_types.h" 57 54 #include "intel_fb.h" 58 55 #include "intel_fb_pin.h" 56 + #include "intel_fbdev.h" 57 + #include "intel_plane.h" 58 + #include "intel_psr.h" 59 59 #include "skl_scaler.h" 60 60 #include "skl_universal_plane.h" 61 61 #include "skl_watermark.h" ··· 339 333 * display blinking due to constant cdclk changes. 340 334 */ 341 335 if (new_crtc_state->min_cdclk[plane->id] <= 342 - cdclk_state->min_cdclk[crtc->pipe]) 336 + intel_cdclk_min_cdclk(cdclk_state, crtc->pipe)) 343 337 return 0; 344 338 345 339 drm_dbg_kms(display->drm, ··· 347 341 plane->base.base.id, plane->base.name, 348 342 new_crtc_state->min_cdclk[plane->id], 349 343 crtc->base.base.id, crtc->base.name, 350 - cdclk_state->min_cdclk[crtc->pipe]); 344 + intel_cdclk_min_cdclk(cdclk_state, crtc->pipe)); 351 345 *need_cdclk_calc = true; 352 346 353 347 return 0; ··· 740 734 return NULL; 741 735 } 742 736 743 - int intel_plane_atomic_check(struct intel_atomic_state *state, 744 - struct intel_plane *plane) 737 + static int plane_atomic_check(struct intel_atomic_state *state, 738 + struct intel_plane *plane) 745 739 { 746 740 struct intel_display *display = to_intel_display(state); 747 741 struct intel_plane_state *new_plane_state = ··· 989 983 i9xx_crtc_planes_update_arm(dsb, state, crtc); 990 984 } 991 985 992 - int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state, 993 - struct intel_crtc_state *crtc_state, 994 - int min_scale, int max_scale, 995 - bool can_position) 986 + int intel_plane_check_clipping(struct intel_plane_state *plane_state, 987 + struct intel_crtc_state *crtc_state, 988 + int min_scale, int max_scale, 989 + bool can_position) 996 990 { 997 991 struct intel_display *display = to_intel_display(plane_state); 998 992 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); ··· 1091 1085 1092 1086 /* Wa_16023981245 */ 1093 1087 if ((DISPLAY_VERx100(display) == 2000 || 1094 - DISPLAY_VERx100(display) == 3000) && 1088 + DISPLAY_VERx100(display) == 3000 || 1089 + DISPLAY_VERx100(display) == 3002) && 1095 1090 src_x % 2 != 0) 1096 1091 hsub = 2; 1097 1092 } else { ··· 1273 1266 intel_plane_unpin_fb(old_plane_state); 1274 1267 } 1275 1268 1269 + /* Handle Y-tiling, only if DPT is enabled (otherwise disabling tiling is easier) 1270 + * All DPT hardware have 128-bytes width tiling, so Y-tile dimension is 32x32 1271 + * pixels for 32bits pixels. 1272 + */ 1273 + #define YTILE_WIDTH 32 1274 + #define YTILE_HEIGHT 32 1275 + #define YTILE_SIZE (YTILE_WIDTH * YTILE_HEIGHT * 4) 1276 + 1277 + static unsigned int intel_ytile_get_offset(unsigned int width, unsigned int x, unsigned int y) 1278 + { 1279 + u32 offset; 1280 + unsigned int swizzle; 1281 + unsigned int width_in_blocks = DIV_ROUND_UP(width, 32); 1282 + 1283 + /* Block offset */ 1284 + offset = ((y / YTILE_HEIGHT) * width_in_blocks + (x / YTILE_WIDTH)) * YTILE_SIZE; 1285 + 1286 + x = x % YTILE_WIDTH; 1287 + y = y % YTILE_HEIGHT; 1288 + 1289 + /* bit order inside a block is x4 x3 x2 y4 y3 y2 y1 y0 x1 x0 */ 1290 + swizzle = (x & 3) | ((y & 0x1f) << 2) | ((x & 0x1c) << 5); 1291 + offset += swizzle * 4; 1292 + return offset; 1293 + } 1294 + 1295 + static unsigned int intel_4tile_get_offset(unsigned int width, unsigned int x, unsigned int y) 1296 + { 1297 + u32 offset; 1298 + unsigned int swizzle; 1299 + unsigned int width_in_blocks = DIV_ROUND_UP(width, 32); 1300 + 1301 + /* Block offset */ 1302 + offset = ((y / YTILE_HEIGHT) * width_in_blocks + (x / YTILE_WIDTH)) * YTILE_SIZE; 1303 + 1304 + x = x % YTILE_WIDTH; 1305 + y = y % YTILE_HEIGHT; 1306 + 1307 + /* bit order inside a block is y4 y3 x4 y2 x3 x2 y1 y0 x1 x0 */ 1308 + swizzle = (x & 3) | ((y & 3) << 2) | ((x & 0xc) << 2) | (y & 4) << 4 | 1309 + ((x & 0x10) << 3) | ((y & 0x18) << 5); 1310 + offset += swizzle * 4; 1311 + return offset; 1312 + } 1313 + 1314 + static void intel_panic_flush(struct drm_plane *plane) 1315 + { 1316 + struct intel_plane_state *plane_state = to_intel_plane_state(plane->state); 1317 + struct intel_crtc_state *crtc_state = to_intel_crtc_state(plane->state->crtc->state); 1318 + struct intel_plane *iplane = to_intel_plane(plane); 1319 + struct intel_display *display = to_intel_display(iplane); 1320 + struct drm_framebuffer *fb = plane_state->hw.fb; 1321 + struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); 1322 + 1323 + intel_bo_panic_finish(intel_fb); 1324 + 1325 + if (crtc_state->enable_psr2_sel_fetch) { 1326 + /* Force a full update for psr2 */ 1327 + intel_psr2_panic_force_full_update(display, crtc_state); 1328 + } 1329 + 1330 + /* Flush the cache and don't disable tiling if it's the fbdev framebuffer.*/ 1331 + if (intel_fb == intel_fbdev_framebuffer(display->fbdev.fbdev)) { 1332 + struct iosys_map map; 1333 + 1334 + intel_fbdev_get_map(display->fbdev.fbdev, &map); 1335 + drm_clflush_virt_range(map.vaddr, fb->pitches[0] * fb->height); 1336 + return; 1337 + } 1338 + 1339 + if (fb->modifier && iplane->disable_tiling) 1340 + iplane->disable_tiling(iplane); 1341 + } 1342 + 1343 + static unsigned int (*intel_get_tiling_func(u64 fb_modifier))(unsigned int width, 1344 + unsigned int x, 1345 + unsigned int y) 1346 + { 1347 + switch (fb_modifier) { 1348 + case I915_FORMAT_MOD_Y_TILED: 1349 + case I915_FORMAT_MOD_Y_TILED_CCS: 1350 + case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC: 1351 + case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS: 1352 + case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS: 1353 + return intel_ytile_get_offset; 1354 + case I915_FORMAT_MOD_4_TILED: 1355 + case I915_FORMAT_MOD_4_TILED_DG2_RC_CCS: 1356 + case I915_FORMAT_MOD_4_TILED_DG2_MC_CCS: 1357 + case I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC: 1358 + case I915_FORMAT_MOD_4_TILED_MTL_RC_CCS: 1359 + case I915_FORMAT_MOD_4_TILED_MTL_RC_CCS_CC: 1360 + case I915_FORMAT_MOD_4_TILED_MTL_MC_CCS: 1361 + case I915_FORMAT_MOD_4_TILED_BMG_CCS: 1362 + case I915_FORMAT_MOD_4_TILED_LNL_CCS: 1363 + return intel_4tile_get_offset; 1364 + case I915_FORMAT_MOD_X_TILED: 1365 + case I915_FORMAT_MOD_Yf_TILED: 1366 + case I915_FORMAT_MOD_Yf_TILED_CCS: 1367 + default: 1368 + /* Not supported yet */ 1369 + return NULL; 1370 + } 1371 + } 1372 + 1373 + static int intel_get_scanout_buffer(struct drm_plane *plane, 1374 + struct drm_scanout_buffer *sb) 1375 + { 1376 + struct intel_plane_state *plane_state; 1377 + struct drm_gem_object *obj; 1378 + struct drm_framebuffer *fb; 1379 + struct intel_framebuffer *intel_fb; 1380 + struct intel_display *display = to_intel_display(plane->dev); 1381 + 1382 + if (!plane->state || !plane->state->fb || !plane->state->visible) 1383 + return -ENODEV; 1384 + 1385 + plane_state = to_intel_plane_state(plane->state); 1386 + fb = plane_state->hw.fb; 1387 + intel_fb = to_intel_framebuffer(fb); 1388 + 1389 + obj = intel_fb_bo(fb); 1390 + if (!obj) 1391 + return -ENODEV; 1392 + 1393 + if (intel_fb == intel_fbdev_framebuffer(display->fbdev.fbdev)) { 1394 + intel_fbdev_get_map(display->fbdev.fbdev, &sb->map[0]); 1395 + } else { 1396 + int ret; 1397 + /* Can't disable tiling if DPT is in use */ 1398 + if (intel_fb_uses_dpt(fb)) { 1399 + if (fb->format->cpp[0] != 4) 1400 + return -EOPNOTSUPP; 1401 + intel_fb->panic_tiling = intel_get_tiling_func(fb->modifier); 1402 + if (!intel_fb->panic_tiling) 1403 + return -EOPNOTSUPP; 1404 + } 1405 + sb->private = intel_fb; 1406 + ret = intel_bo_panic_setup(sb); 1407 + if (ret) 1408 + return ret; 1409 + } 1410 + sb->width = fb->width; 1411 + sb->height = fb->height; 1412 + /* Use the generic linear format, because tiling, RC, CCS, CC 1413 + * will be disabled in disable_tiling() 1414 + */ 1415 + sb->format = drm_format_info(fb->format->format); 1416 + sb->pitch[0] = fb->pitches[0]; 1417 + 1418 + return 0; 1419 + } 1420 + 1276 1421 static const struct drm_plane_helper_funcs intel_plane_helper_funcs = { 1277 1422 .prepare_fb = intel_prepare_plane_fb, 1278 1423 .cleanup_fb = intel_cleanup_plane_fb, 1279 1424 }; 1280 1425 1426 + static const struct drm_plane_helper_funcs intel_primary_plane_helper_funcs = { 1427 + .prepare_fb = intel_prepare_plane_fb, 1428 + .cleanup_fb = intel_cleanup_plane_fb, 1429 + .get_scanout_buffer = intel_get_scanout_buffer, 1430 + .panic_flush = intel_panic_flush, 1431 + }; 1432 + 1281 1433 void intel_plane_helper_add(struct intel_plane *plane) 1282 1434 { 1283 - drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs); 1435 + if (plane->base.type == DRM_PLANE_TYPE_PRIMARY) 1436 + drm_plane_helper_add(&plane->base, &intel_primary_plane_helper_funcs); 1437 + else 1438 + drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs); 1284 1439 } 1285 1440 1286 1441 void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state, ··· 1602 1433 return 0; 1603 1434 } 1604 1435 1605 - int intel_atomic_add_affected_planes(struct intel_atomic_state *state, 1606 - struct intel_crtc *crtc) 1436 + int intel_plane_add_affected(struct intel_atomic_state *state, 1437 + struct intel_crtc *crtc) 1607 1438 { 1608 1439 const struct intel_crtc_state *old_crtc_state = 1609 1440 intel_atomic_get_old_crtc_state(state, crtc); ··· 1697 1528 return 0; 1698 1529 } 1699 1530 1700 - int intel_atomic_check_planes(struct intel_atomic_state *state) 1531 + int intel_plane_atomic_check(struct intel_atomic_state *state) 1701 1532 { 1702 1533 struct intel_display *display = to_intel_display(state); 1703 1534 struct intel_crtc_state *old_crtc_state, *new_crtc_state; ··· 1711 1542 return ret; 1712 1543 1713 1544 for_each_new_intel_plane_in_state(state, plane, plane_state, i) { 1714 - ret = intel_plane_atomic_check(state, plane); 1545 + ret = plane_atomic_check(state, plane); 1715 1546 if (ret) { 1716 1547 drm_dbg_atomic(display->drm, 1717 1548 "[PLANE:%d:%s] atomic driver check failed\n",
+10 -12
drivers/gpu/drm/i915/display/intel_atomic_plane.h drivers/gpu/drm/i915/display/intel_plane.h
··· 3 3 * Copyright © 2019 Intel Corporation 4 4 */ 5 5 6 - #ifndef __INTEL_ATOMIC_PLANE_H__ 7 - #define __INTEL_ATOMIC_PLANE_H__ 6 + #ifndef __INTEL_PLANE_H__ 7 + #define __INTEL_PLANE_H__ 8 8 9 9 #include <linux/types.h> 10 10 ··· 69 69 struct intel_crtc_state *crtc_state, 70 70 const struct intel_plane_state *old_plane_state, 71 71 struct intel_plane_state *intel_state); 72 - int intel_plane_atomic_check(struct intel_atomic_state *state, 73 - struct intel_plane *plane); 74 72 int intel_plane_calc_min_cdclk(struct intel_atomic_state *state, 75 73 struct intel_plane *plane, 76 74 bool *need_cdclk_calc); 77 - int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state, 78 - struct intel_crtc_state *crtc_state, 79 - int min_scale, int max_scale, 80 - bool can_position); 75 + int intel_plane_check_clipping(struct intel_plane_state *plane_state, 76 + struct intel_crtc_state *crtc_state, 77 + int min_scale, int max_scale, 78 + bool can_position); 81 79 int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state); 82 80 void intel_plane_set_invisible(struct intel_crtc_state *crtc_state, 83 81 struct intel_plane_state *plane_state); ··· 83 85 bool intel_plane_needs_physical(struct intel_plane *plane); 84 86 void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state, 85 87 struct intel_plane_state *new_plane_state); 86 - int intel_atomic_add_affected_planes(struct intel_atomic_state *state, 87 - struct intel_crtc *crtc); 88 - int intel_atomic_check_planes(struct intel_atomic_state *state); 88 + int intel_plane_add_affected(struct intel_atomic_state *state, 89 + struct intel_crtc *crtc); 90 + int intel_plane_atomic_check(struct intel_atomic_state *state); 89 91 90 92 u32 intel_plane_ggtt_offset(const struct intel_plane_state *plane_state); 91 93 bool intel_plane_format_mod_supported_async(struct drm_plane *plane, 92 94 u32 format, 93 95 u64 modifier); 94 96 95 - #endif /* __INTEL_ATOMIC_PLANE_H__ */ 97 + #endif /* __INTEL_PLANE_H__ */
+1 -1
drivers/gpu/drm/i915/display/intel_audio.c
··· 951 951 if (IS_ERR(cdclk_state)) 952 952 return PTR_ERR(cdclk_state); 953 953 954 - cdclk_state->force_min_cdclk = enable ? 2 * 96000 : 0; 954 + intel_cdclk_force_min_cdclk(cdclk_state, enable ? 2 * 96000 : 0); 955 955 956 956 return drm_atomic_commit(&state->base); 957 957 }
+17
drivers/gpu/drm/i915/display/intel_bo.c
··· 1 1 // SPDX-License-Identifier: MIT 2 2 /* Copyright © 2024 Intel Corporation */ 3 3 4 + #include <drm/drm_panic.h> 5 + #include "display/intel_display_types.h" 4 6 #include "gem/i915_gem_mman.h" 5 7 #include "gem/i915_gem_object.h" 6 8 #include "gem/i915_gem_object_frontbuffer.h" ··· 58 56 void intel_bo_describe(struct seq_file *m, struct drm_gem_object *obj) 59 57 { 60 58 i915_debugfs_describe_obj(m, to_intel_bo(obj)); 59 + } 60 + 61 + struct intel_framebuffer *intel_bo_alloc_framebuffer(void) 62 + { 63 + return i915_gem_object_alloc_framebuffer(); 64 + } 65 + 66 + int intel_bo_panic_setup(struct drm_scanout_buffer *sb) 67 + { 68 + return i915_gem_object_panic_setup(sb); 69 + } 70 + 71 + void intel_bo_panic_finish(struct intel_framebuffer *fb) 72 + { 73 + return i915_gem_object_panic_finish(fb); 61 74 }
+5
drivers/gpu/drm/i915/display/intel_bo.h
··· 7 7 #include <linux/types.h> 8 8 9 9 struct drm_gem_object; 10 + struct drm_scanout_buffer; 11 + struct intel_framebuffer; 10 12 struct seq_file; 11 13 struct vm_area_struct; 12 14 ··· 25 23 struct intel_frontbuffer *front); 26 24 27 25 void intel_bo_describe(struct seq_file *m, struct drm_gem_object *obj); 26 + struct intel_framebuffer *intel_bo_alloc_framebuffer(void); 27 + int intel_bo_panic_setup(struct drm_scanout_buffer *sb); 28 + void intel_bo_panic_finish(struct intel_framebuffer *fb); 28 29 29 30 #endif /* __INTEL_BO__ */
+164 -24
drivers/gpu/drm/i915/display/intel_bw.c
··· 18 18 #include "intel_display_types.h" 19 19 #include "intel_mchbar_regs.h" 20 20 #include "intel_pcode.h" 21 + #include "intel_uncore.h" 21 22 #include "skl_watermark.h" 23 + 24 + struct intel_dbuf_bw { 25 + unsigned int max_bw[I915_MAX_DBUF_SLICES]; 26 + u8 active_planes[I915_MAX_DBUF_SLICES]; 27 + }; 28 + 29 + struct intel_bw_state { 30 + struct intel_global_state base; 31 + struct intel_dbuf_bw dbuf_bw[I915_MAX_PIPES]; 32 + 33 + /* 34 + * Contains a bit mask, used to determine, whether correspondent 35 + * pipe allows SAGV or not. 36 + */ 37 + u8 pipe_sagv_reject; 38 + 39 + /* bitmask of active pipes */ 40 + u8 active_pipes; 41 + 42 + /* 43 + * From MTL onwards, to lock a QGV point, punit expects the peak BW of 44 + * the selected QGV point as the parameter in multiples of 100MB/s 45 + */ 46 + u16 qgv_point_peakbw; 47 + 48 + /* 49 + * Current QGV points mask, which restricts 50 + * some particular SAGV states, not to confuse 51 + * with pipe_sagv_mask. 52 + */ 53 + u16 qgv_points_mask; 54 + 55 + unsigned int data_rate[I915_MAX_PIPES]; 56 + u8 num_active_planes[I915_MAX_PIPES]; 57 + }; 22 58 23 59 /* Parameters for Qclk Geyserville (QGV) */ 24 60 struct intel_qgv_point { ··· 118 82 struct intel_qgv_point *sp, 119 83 int point) 120 84 { 121 - struct drm_i915_private *i915 = to_i915(display->drm); 122 85 u32 val = 0, val2 = 0; 123 86 u16 dclk; 124 87 int ret; 125 88 126 - ret = snb_pcode_read(&i915->uncore, ICL_PCODE_MEM_SUBSYSYSTEM_INFO | 127 - ICL_PCODE_MEM_SS_READ_QGV_POINT_INFO(point), 128 - &val, &val2); 89 + ret = intel_pcode_read(display->drm, ICL_PCODE_MEM_SUBSYSYSTEM_INFO | 90 + ICL_PCODE_MEM_SS_READ_QGV_POINT_INFO(point), 91 + &val, &val2); 129 92 if (ret) 130 93 return ret; 131 94 ··· 145 110 static int adls_pcode_read_psf_gv_point_info(struct intel_display *display, 146 111 struct intel_psf_gv_point *points) 147 112 { 148 - struct drm_i915_private *i915 = to_i915(display->drm); 149 113 u32 val = 0; 150 114 int ret; 151 115 int i; 152 116 153 - ret = snb_pcode_read(&i915->uncore, ICL_PCODE_MEM_SUBSYSYSTEM_INFO | 154 - ADL_PCODE_MEM_SS_READ_PSF_GV_INFO, &val, NULL); 117 + ret = intel_pcode_read(display->drm, ICL_PCODE_MEM_SUBSYSYSTEM_INFO | 118 + ADL_PCODE_MEM_SS_READ_PSF_GV_INFO, &val, NULL); 155 119 if (ret) 156 120 return ret; 157 121 ··· 188 154 ICL_PCODE_REQ_QGV_PT_MASK); 189 155 } 190 156 191 - int icl_pcode_restrict_qgv_points(struct intel_display *display, 192 - u32 points_mask) 157 + static int icl_pcode_restrict_qgv_points(struct intel_display *display, 158 + u32 points_mask) 193 159 { 194 - struct drm_i915_private *i915 = to_i915(display->drm); 195 160 int ret; 196 161 197 162 if (DISPLAY_VER(display) >= 14) 198 163 return 0; 199 164 200 165 /* bspec says to keep retrying for at least 1 ms */ 201 - ret = skl_pcode_request(&i915->uncore, ICL_PCODE_SAGV_DE_MEM_SS_CONFIG, 202 - points_mask, 203 - ICL_PCODE_REP_QGV_MASK | ADLS_PCODE_REP_PSF_MASK, 204 - ICL_PCODE_REP_QGV_SAFE | ADLS_PCODE_REP_PSF_SAFE, 205 - 1); 166 + ret = intel_pcode_request(display->drm, ICL_PCODE_SAGV_DE_MEM_SS_CONFIG, 167 + points_mask, 168 + ICL_PCODE_REP_QGV_MASK | ADLS_PCODE_REP_PSF_MASK, 169 + ICL_PCODE_REP_QGV_SAFE | ADLS_PCODE_REP_PSF_SAFE, 170 + 1); 206 171 207 172 if (ret < 0) { 208 173 drm_err(display->drm, ··· 449 416 static const struct intel_sa_info xe3lpd_sa_info = { 450 417 .deburst = 32, 451 418 .deprogbwlimit = 65, /* GB/s */ 419 + .displayrtids = 256, 420 + .derating = 10, 421 + }; 422 + 423 + static const struct intel_sa_info xe3lpd_3002_sa_info = { 424 + .deburst = 32, 425 + .deprogbwlimit = 22, /* GB/s */ 452 426 .displayrtids = 256, 453 427 .derating = 10, 454 428 }; ··· 811 771 if (!HAS_DISPLAY(display)) 812 772 return; 813 773 814 - if (DISPLAY_VER(display) >= 30) 774 + if (DISPLAY_VERx100(display) >= 3002) 775 + tgl_get_bw_info(display, dram_info, &xe3lpd_3002_sa_info); 776 + else if (DISPLAY_VER(display) >= 30) 815 777 tgl_get_bw_info(display, dram_info, &xe3lpd_sa_info); 816 778 else if (DISPLAY_VERx100(display) >= 1401 && display->platform.dgfx && 817 779 dram_info->type == INTEL_DRAM_GDDR_ECC) ··· 905 863 data_rate = DIV_ROUND_UP(data_rate * 105, 100); 906 864 907 865 return data_rate; 866 + } 867 + 868 + struct intel_bw_state *to_intel_bw_state(struct intel_global_state *obj_state) 869 + { 870 + return container_of(obj_state, struct intel_bw_state, base); 908 871 } 909 872 910 873 struct intel_bw_state * ··· 1021 974 icl_pcode_restrict_qgv_points(display, bw_state->qgv_points_mask); 1022 975 } 1023 976 977 + void icl_sagv_pre_plane_update(struct intel_atomic_state *state) 978 + { 979 + struct intel_display *display = to_intel_display(state); 980 + const struct intel_bw_state *old_bw_state = 981 + intel_atomic_get_old_bw_state(state); 982 + const struct intel_bw_state *new_bw_state = 983 + intel_atomic_get_new_bw_state(state); 984 + u16 old_mask, new_mask; 985 + 986 + if (!new_bw_state) 987 + return; 988 + 989 + old_mask = old_bw_state->qgv_points_mask; 990 + new_mask = old_bw_state->qgv_points_mask | new_bw_state->qgv_points_mask; 991 + 992 + if (old_mask == new_mask) 993 + return; 994 + 995 + WARN_ON(!new_bw_state->base.changed); 996 + 997 + drm_dbg_kms(display->drm, "Restricting QGV points: 0x%x -> 0x%x\n", 998 + old_mask, new_mask); 999 + 1000 + /* 1001 + * Restrict required qgv points before updating the configuration. 1002 + * According to BSpec we can't mask and unmask qgv points at the same 1003 + * time. Also masking should be done before updating the configuration 1004 + * and unmasking afterwards. 1005 + */ 1006 + icl_pcode_restrict_qgv_points(display, new_mask); 1007 + } 1008 + 1009 + void icl_sagv_post_plane_update(struct intel_atomic_state *state) 1010 + { 1011 + struct intel_display *display = to_intel_display(state); 1012 + const struct intel_bw_state *old_bw_state = 1013 + intel_atomic_get_old_bw_state(state); 1014 + const struct intel_bw_state *new_bw_state = 1015 + intel_atomic_get_new_bw_state(state); 1016 + u16 old_mask, new_mask; 1017 + 1018 + if (!new_bw_state) 1019 + return; 1020 + 1021 + old_mask = old_bw_state->qgv_points_mask | new_bw_state->qgv_points_mask; 1022 + new_mask = new_bw_state->qgv_points_mask; 1023 + 1024 + if (old_mask == new_mask) 1025 + return; 1026 + 1027 + WARN_ON(!new_bw_state->base.changed); 1028 + 1029 + drm_dbg_kms(display->drm, "Relaxing QGV points: 0x%x -> 0x%x\n", 1030 + old_mask, new_mask); 1031 + 1032 + /* 1033 + * Allow required qgv points after updating the configuration. 1034 + * According to BSpec we can't mask and unmask qgv points at the same 1035 + * time. Also masking should be done before updating the configuration 1036 + * and unmasking afterwards. 1037 + */ 1038 + icl_pcode_restrict_qgv_points(display, new_mask); 1039 + } 1040 + 1024 1041 static int mtl_find_qgv_points(struct intel_display *display, 1025 1042 unsigned int data_rate, 1026 1043 unsigned int num_active_planes, ··· 1105 994 * for qgv peak bw in PM Demand request. So assign UINT_MAX if SAGV is 1106 995 * not enabled. PM Demand code will clamp the value for the register 1107 996 */ 1108 - if (!intel_can_enable_sagv(display, new_bw_state)) { 997 + if (!intel_bw_can_enable_sagv(display, new_bw_state)) { 1109 998 new_bw_state->qgv_point_peakbw = U16_MAX; 1110 999 drm_dbg_kms(display->drm, "No SAGV, use UINT_MAX as peak bw."); 1111 1000 return 0; ··· 1218 1107 * we can't enable SAGV due to the increased memory latency it may 1219 1108 * cause. 1220 1109 */ 1221 - if (!intel_can_enable_sagv(display, new_bw_state)) { 1110 + if (!intel_bw_can_enable_sagv(display, new_bw_state)) { 1222 1111 qgv_points = icl_max_bw_qgv_point_mask(display, num_active_planes); 1223 1112 drm_dbg_kms(display->drm, "No SAGV, using single QGV point mask 0x%x\n", 1224 1113 qgv_points); ··· 1468 1357 * requirements. This can reduce back and forth 1469 1358 * display blinking due to constant cdclk changes. 1470 1359 */ 1471 - if (new_min_cdclk <= cdclk_state->bw_min_cdclk) 1360 + if (new_min_cdclk <= intel_cdclk_bw_min_cdclk(cdclk_state)) 1472 1361 return 0; 1473 1362 1474 1363 drm_dbg_kms(display->drm, 1475 1364 "new bandwidth min cdclk (%d kHz) > old min cdclk (%d kHz)\n", 1476 - new_min_cdclk, cdclk_state->bw_min_cdclk); 1365 + new_min_cdclk, intel_cdclk_bw_min_cdclk(cdclk_state)); 1477 1366 *need_cdclk_calc = true; 1478 1367 1479 1368 return 0; ··· 1585 1474 if (!new_bw_state) 1586 1475 return 0; 1587 1476 1588 - if (intel_can_enable_sagv(display, new_bw_state) != 1589 - intel_can_enable_sagv(display, old_bw_state)) { 1477 + if (intel_bw_can_enable_sagv(display, new_bw_state) != 1478 + intel_bw_can_enable_sagv(display, old_bw_state)) { 1590 1479 ret = intel_atomic_serialize_global_state(&new_bw_state->base); 1591 1480 if (ret) 1592 1481 return ret; ··· 1632 1521 new_bw_state = intel_atomic_get_new_bw_state(state); 1633 1522 1634 1523 if (new_bw_state && 1635 - intel_can_enable_sagv(display, old_bw_state) != 1636 - intel_can_enable_sagv(display, new_bw_state)) 1524 + intel_bw_can_enable_sagv(display, old_bw_state) != 1525 + intel_bw_can_enable_sagv(display, new_bw_state)) 1637 1526 changed = true; 1638 1527 1639 1528 /* ··· 1754 1643 icl_force_disable_sagv(display, state); 1755 1644 1756 1645 return 0; 1646 + } 1647 + 1648 + bool intel_bw_pmdemand_needs_update(struct intel_atomic_state *state) 1649 + { 1650 + const struct intel_bw_state *new_bw_state, *old_bw_state; 1651 + 1652 + new_bw_state = intel_atomic_get_new_bw_state(state); 1653 + old_bw_state = intel_atomic_get_old_bw_state(state); 1654 + 1655 + if (new_bw_state && 1656 + new_bw_state->qgv_point_peakbw != old_bw_state->qgv_point_peakbw) 1657 + return true; 1658 + 1659 + return false; 1660 + } 1661 + 1662 + bool intel_bw_can_enable_sagv(struct intel_display *display, 1663 + const struct intel_bw_state *bw_state) 1664 + { 1665 + if (DISPLAY_VER(display) < 11 && 1666 + bw_state->active_pipes && !is_power_of_2(bw_state->active_pipes)) 1667 + return false; 1668 + 1669 + return bw_state->pipe_sagv_reject == 0; 1670 + } 1671 + 1672 + int intel_bw_qgv_point_peakbw(const struct intel_bw_state *bw_state) 1673 + { 1674 + return bw_state->qgv_point_peakbw; 1757 1675 }
+10 -43
drivers/gpu/drm/i915/display/intel_bw.h
··· 8 8 9 9 #include <drm/drm_atomic.h> 10 10 11 - #include "intel_display_limits.h" 12 - #include "intel_display_power.h" 13 - #include "intel_global_state.h" 14 - 15 11 struct intel_atomic_state; 12 + struct intel_bw_state; 16 13 struct intel_crtc; 17 14 struct intel_crtc_state; 18 15 struct intel_display; 16 + struct intel_global_state; 19 17 20 - struct intel_dbuf_bw { 21 - unsigned int max_bw[I915_MAX_DBUF_SLICES]; 22 - u8 active_planes[I915_MAX_DBUF_SLICES]; 23 - }; 24 - 25 - struct intel_bw_state { 26 - struct intel_global_state base; 27 - struct intel_dbuf_bw dbuf_bw[I915_MAX_PIPES]; 28 - 29 - /* 30 - * Contains a bit mask, used to determine, whether correspondent 31 - * pipe allows SAGV or not. 32 - */ 33 - u8 pipe_sagv_reject; 34 - 35 - /* bitmask of active pipes */ 36 - u8 active_pipes; 37 - 38 - /* 39 - * From MTL onwards, to lock a QGV point, punit expects the peak BW of 40 - * the selected QGV point as the parameter in multiples of 100MB/s 41 - */ 42 - u16 qgv_point_peakbw; 43 - 44 - /* 45 - * Current QGV points mask, which restricts 46 - * some particular SAGV states, not to confuse 47 - * with pipe_sagv_mask. 48 - */ 49 - u16 qgv_points_mask; 50 - 51 - unsigned int data_rate[I915_MAX_PIPES]; 52 - u8 num_active_planes[I915_MAX_PIPES]; 53 - }; 54 - 55 - #define to_intel_bw_state(global_state) \ 56 - container_of_const((global_state), struct intel_bw_state, base) 18 + struct intel_bw_state *to_intel_bw_state(struct intel_global_state *obj_state); 57 19 58 20 struct intel_bw_state * 59 21 intel_atomic_get_old_bw_state(struct intel_atomic_state *state); ··· 29 67 void intel_bw_init_hw(struct intel_display *display); 30 68 int intel_bw_init(struct intel_display *display); 31 69 int intel_bw_atomic_check(struct intel_atomic_state *state, bool any_ms); 32 - int icl_pcode_restrict_qgv_points(struct intel_display *display, 33 - u32 points_mask); 34 70 int intel_bw_calc_min_cdclk(struct intel_atomic_state *state, 35 71 bool *need_cdclk_calc); 36 72 int intel_bw_min_cdclk(struct intel_display *display, 37 73 const struct intel_bw_state *bw_state); 38 74 void intel_bw_update_hw_state(struct intel_display *display); 39 75 void intel_bw_crtc_disable_noatomic(struct intel_crtc *crtc); 76 + 77 + bool intel_bw_pmdemand_needs_update(struct intel_atomic_state *state); 78 + bool intel_bw_can_enable_sagv(struct intel_display *display, 79 + const struct intel_bw_state *bw_state); 80 + void icl_sagv_pre_plane_update(struct intel_atomic_state *state); 81 + void icl_sagv_post_plane_update(struct intel_atomic_state *state); 82 + int intel_bw_qgv_point_peakbw(const struct intel_bw_state *bw_state); 40 83 41 84 #endif /* __INTEL_BW_H__ */
+123 -33
drivers/gpu/drm/i915/display/intel_cdclk.c
··· 32 32 #include "i915_drv.h" 33 33 #include "i915_reg.h" 34 34 #include "intel_atomic.h" 35 - #include "intel_atomic_plane.h" 36 35 #include "intel_audio.h" 37 36 #include "intel_bw.h" 38 37 #include "intel_cdclk.h" ··· 42 43 #include "intel_mchbar_regs.h" 43 44 #include "intel_pci_config.h" 44 45 #include "intel_pcode.h" 46 + #include "intel_plane.h" 45 47 #include "intel_psr.h" 46 48 #include "intel_vdsc.h" 47 49 #include "skl_watermark.h" ··· 113 113 * really need to know about RAWCLK is its frequency so that various 114 114 * dividers can be programmed correctly. 115 115 */ 116 + 117 + struct intel_cdclk_state { 118 + struct intel_global_state base; 119 + 120 + /* 121 + * Logical configuration of cdclk (used for all scaling, 122 + * watermark, etc. calculations and checks). This is 123 + * computed as if all enabled crtcs were active. 124 + */ 125 + struct intel_cdclk_config logical; 126 + 127 + /* 128 + * Actual configuration of cdclk, can be different from the 129 + * logical configuration only when all crtc's are DPMS off. 130 + */ 131 + struct intel_cdclk_config actual; 132 + 133 + /* minimum acceptable cdclk to satisfy bandwidth requirements */ 134 + int bw_min_cdclk; 135 + /* minimum acceptable cdclk for each pipe */ 136 + int min_cdclk[I915_MAX_PIPES]; 137 + /* minimum acceptable voltage level for each pipe */ 138 + u8 min_voltage_level[I915_MAX_PIPES]; 139 + 140 + /* pipe to which cd2x update is synchronized */ 141 + enum pipe pipe; 142 + 143 + /* forced minimum cdclk for glk+ audio w/a */ 144 + int force_min_cdclk; 145 + 146 + /* bitmask of active pipes */ 147 + u8 active_pipes; 148 + 149 + /* update cdclk with pipes disabled */ 150 + bool disable_pipes; 151 + }; 116 152 117 153 struct intel_cdclk_funcs { 118 154 void (*get_cdclk)(struct intel_display *display, ··· 877 841 const struct intel_cdclk_config *cdclk_config, 878 842 enum pipe pipe) 879 843 { 880 - struct drm_i915_private *dev_priv = to_i915(display->drm); 881 844 int cdclk = cdclk_config->cdclk; 882 845 int ret; 883 846 ··· 889 854 "trying to change cdclk frequency with cdclk not enabled\n")) 890 855 return; 891 856 892 - ret = snb_pcode_write(&dev_priv->uncore, BDW_PCODE_DISPLAY_FREQ_CHANGE_REQ, 0x0); 857 + ret = intel_pcode_write(display->drm, BDW_PCODE_DISPLAY_FREQ_CHANGE_REQ, 0x0); 893 858 if (ret) { 894 859 drm_err(display->drm, 895 860 "failed to inform pcode about cdclk change\n"); ··· 917 882 LCPLL_CD_SOURCE_FCLK_DONE) == 0, 1)) 918 883 drm_err(display->drm, "Switching back to LCPLL failed\n"); 919 884 920 - snb_pcode_write(&dev_priv->uncore, HSW_PCODE_DE_WRITE_FREQ_REQ, 921 - cdclk_config->voltage_level); 885 + intel_pcode_write(display->drm, HSW_PCODE_DE_WRITE_FREQ_REQ, 886 + cdclk_config->voltage_level); 922 887 923 888 intel_de_write(display, CDCLK_FREQ, 924 889 DIV_ROUND_CLOSEST(cdclk, 1000) - 1); ··· 1158 1123 const struct intel_cdclk_config *cdclk_config, 1159 1124 enum pipe pipe) 1160 1125 { 1161 - struct drm_i915_private *dev_priv = to_i915(display->drm); 1162 1126 int cdclk = cdclk_config->cdclk; 1163 1127 int vco = cdclk_config->vco; 1164 1128 u32 freq_select, cdclk_ctl; ··· 1174 1140 drm_WARN_ON_ONCE(display->drm, 1175 1141 display->platform.skylake && vco == 8640000); 1176 1142 1177 - ret = skl_pcode_request(&dev_priv->uncore, SKL_PCODE_CDCLK_CONTROL, 1178 - SKL_CDCLK_PREPARE_FOR_CHANGE, 1179 - SKL_CDCLK_READY_FOR_CHANGE, 1180 - SKL_CDCLK_READY_FOR_CHANGE, 3); 1143 + ret = intel_pcode_request(display->drm, SKL_PCODE_CDCLK_CONTROL, 1144 + SKL_CDCLK_PREPARE_FOR_CHANGE, 1145 + SKL_CDCLK_READY_FOR_CHANGE, 1146 + SKL_CDCLK_READY_FOR_CHANGE, 3); 1181 1147 if (ret) { 1182 1148 drm_err(display->drm, 1183 1149 "Failed to inform PCU about cdclk change (%d)\n", ret); ··· 1220 1186 intel_de_posting_read(display, CDCLK_CTL); 1221 1187 1222 1188 /* inform PCU of the change */ 1223 - snb_pcode_write(&dev_priv->uncore, SKL_PCODE_CDCLK_CONTROL, 1224 - cdclk_config->voltage_level); 1189 + intel_pcode_write(display->drm, SKL_PCODE_CDCLK_CONTROL, 1190 + cdclk_config->voltage_level); 1225 1191 1226 1192 intel_update_cdclk(display); 1227 1193 } ··· 2157 2123 const struct intel_cdclk_config *cdclk_config, 2158 2124 enum pipe pipe) 2159 2125 { 2160 - struct drm_i915_private *dev_priv = to_i915(display->drm); 2161 2126 struct intel_cdclk_config mid_cdclk_config; 2162 2127 int cdclk = cdclk_config->cdclk; 2163 2128 int ret = 0; ··· 2170 2137 if (DISPLAY_VER(display) >= 14 || display->platform.dg2) 2171 2138 ; /* NOOP */ 2172 2139 else if (DISPLAY_VER(display) >= 11) 2173 - ret = skl_pcode_request(&dev_priv->uncore, SKL_PCODE_CDCLK_CONTROL, 2174 - SKL_CDCLK_PREPARE_FOR_CHANGE, 2175 - SKL_CDCLK_READY_FOR_CHANGE, 2176 - SKL_CDCLK_READY_FOR_CHANGE, 3); 2140 + ret = intel_pcode_request(display->drm, SKL_PCODE_CDCLK_CONTROL, 2141 + SKL_CDCLK_PREPARE_FOR_CHANGE, 2142 + SKL_CDCLK_READY_FOR_CHANGE, 2143 + SKL_CDCLK_READY_FOR_CHANGE, 3); 2177 2144 else 2178 2145 /* 2179 2146 * BSpec requires us to wait up to 150usec, but that leads to 2180 2147 * timeouts; the 2ms used here is based on experiment. 2181 2148 */ 2182 - ret = snb_pcode_write_timeout(&dev_priv->uncore, 2183 - HSW_PCODE_DE_WRITE_FREQ_REQ, 2184 - 0x80000000, 150, 2); 2149 + ret = intel_pcode_write_timeout(display->drm, 2150 + HSW_PCODE_DE_WRITE_FREQ_REQ, 2151 + 0x80000000, 2); 2185 2152 2186 2153 if (ret) { 2187 2154 drm_err(display->drm, ··· 2210 2177 * Display versions 14 and beyond 2211 2178 */; 2212 2179 else if (DISPLAY_VER(display) >= 11 && !display->platform.dg2) 2213 - ret = snb_pcode_write(&dev_priv->uncore, SKL_PCODE_CDCLK_CONTROL, 2214 - cdclk_config->voltage_level); 2180 + ret = intel_pcode_write(display->drm, SKL_PCODE_CDCLK_CONTROL, 2181 + cdclk_config->voltage_level); 2215 2182 if (DISPLAY_VER(display) < 11) { 2216 2183 /* 2217 2184 * The timeout isn't specified, the 2ms used here is based on ··· 2219 2186 * FIXME: Waiting for the request completion could be delayed 2220 2187 * until the next PCODE request based on BSpec. 2221 2188 */ 2222 - ret = snb_pcode_write_timeout(&dev_priv->uncore, 2223 - HSW_PCODE_DE_WRITE_FREQ_REQ, 2224 - cdclk_config->voltage_level, 2225 - 150, 2); 2189 + ret = intel_pcode_write_timeout(display->drm, 2190 + HSW_PCODE_DE_WRITE_FREQ_REQ, 2191 + cdclk_config->voltage_level, 2); 2226 2192 } 2227 2193 if (ret) { 2228 2194 drm_err(display->drm, ··· 2507 2475 bool cdclk_update_valid, 2508 2476 bool pipe_count_update_valid) 2509 2477 { 2510 - struct drm_i915_private *i915 = to_i915(display->drm); 2511 2478 int ret; 2512 2479 u32 update_mask = 0; 2513 2480 ··· 2521 2490 if (pipe_count_update_valid) 2522 2491 update_mask |= DISPLAY_TO_PCODE_PIPE_COUNT_VALID; 2523 2492 2524 - ret = skl_pcode_request(&i915->uncore, SKL_PCODE_CDCLK_CONTROL, 2525 - SKL_CDCLK_PREPARE_FOR_CHANGE | 2526 - update_mask, 2527 - SKL_CDCLK_READY_FOR_CHANGE, 2528 - SKL_CDCLK_READY_FOR_CHANGE, 3); 2493 + ret = intel_pcode_request(display->drm, SKL_PCODE_CDCLK_CONTROL, 2494 + SKL_CDCLK_PREPARE_FOR_CHANGE | 2495 + update_mask, 2496 + SKL_CDCLK_READY_FOR_CHANGE, 2497 + SKL_CDCLK_READY_FOR_CHANGE, 3); 2529 2498 if (ret) 2530 2499 drm_err(display->drm, 2531 2500 "Failed to inform PCU about display config (err %d)\n", ··· 3417 3386 */ 3418 3387 void intel_update_max_cdclk(struct intel_display *display) 3419 3388 { 3420 - if (DISPLAY_VER(display) >= 30) { 3389 + if (DISPLAY_VERx100(display) >= 3002) { 3390 + display->cdclk.max_cdclk_freq = 480000; 3391 + } else if (DISPLAY_VER(display) >= 30) { 3421 3392 display->cdclk.max_cdclk_freq = 691200; 3422 3393 } else if (display->platform.jasperlake || display->platform.elkhartlake) { 3423 3394 if (display->cdclk.hw.ref == 24000) ··· 3869 3836 if (drm_WARN(display->drm, !display->funcs.cdclk, 3870 3837 "Unknown platform. Assuming i830\n")) 3871 3838 display->funcs.cdclk = &i830_cdclk_funcs; 3839 + } 3840 + 3841 + int intel_cdclk_logical(const struct intel_cdclk_state *cdclk_state) 3842 + { 3843 + return cdclk_state->logical.cdclk; 3844 + } 3845 + 3846 + int intel_cdclk_actual(const struct intel_cdclk_state *cdclk_state) 3847 + { 3848 + return cdclk_state->actual.cdclk; 3849 + } 3850 + 3851 + int intel_cdclk_actual_voltage_level(const struct intel_cdclk_state *cdclk_state) 3852 + { 3853 + return cdclk_state->actual.voltage_level; 3854 + } 3855 + 3856 + int intel_cdclk_min_cdclk(const struct intel_cdclk_state *cdclk_state, enum pipe pipe) 3857 + { 3858 + return cdclk_state->min_cdclk[pipe]; 3859 + } 3860 + 3861 + int intel_cdclk_bw_min_cdclk(const struct intel_cdclk_state *cdclk_state) 3862 + { 3863 + return cdclk_state->bw_min_cdclk; 3864 + } 3865 + 3866 + bool intel_cdclk_pmdemand_needs_update(struct intel_atomic_state *state) 3867 + { 3868 + const struct intel_cdclk_state *new_cdclk_state, *old_cdclk_state; 3869 + 3870 + new_cdclk_state = intel_atomic_get_new_cdclk_state(state); 3871 + old_cdclk_state = intel_atomic_get_old_cdclk_state(state); 3872 + 3873 + if (new_cdclk_state && 3874 + (new_cdclk_state->actual.cdclk != old_cdclk_state->actual.cdclk || 3875 + new_cdclk_state->actual.voltage_level != old_cdclk_state->actual.voltage_level)) 3876 + return true; 3877 + 3878 + return false; 3879 + } 3880 + 3881 + void intel_cdclk_force_min_cdclk(struct intel_cdclk_state *cdclk_state, int force_min_cdclk) 3882 + { 3883 + cdclk_state->force_min_cdclk = force_min_cdclk; 3884 + } 3885 + 3886 + void intel_cdclk_read_hw(struct intel_display *display) 3887 + { 3888 + struct intel_cdclk_state *cdclk_state; 3889 + 3890 + cdclk_state = to_intel_cdclk_state(display->cdclk.obj.state); 3891 + 3892 + intel_update_cdclk(display); 3893 + intel_cdclk_dump_config(display, &display->cdclk.hw, "Current CDCLK"); 3894 + cdclk_state->actual = display->cdclk.hw; 3895 + cdclk_state->logical = display->cdclk.hw; 3872 3896 }
+11 -39
drivers/gpu/drm/i915/display/intel_cdclk.h
··· 8 8 9 9 #include <linux/types.h> 10 10 11 - #include "intel_display_limits.h" 12 - #include "intel_global_state.h" 13 - 11 + enum pipe; 14 12 struct intel_atomic_state; 13 + struct intel_cdclk_state; 15 14 struct intel_crtc; 16 15 struct intel_crtc_state; 17 16 struct intel_display; ··· 20 21 u8 voltage_level; 21 22 /* This field is only valid for Xe2LPD and above. */ 22 23 bool joined_mbus; 23 - }; 24 - 25 - struct intel_cdclk_state { 26 - struct intel_global_state base; 27 - 28 - /* 29 - * Logical configuration of cdclk (used for all scaling, 30 - * watermark, etc. calculations and checks). This is 31 - * computed as if all enabled crtcs were active. 32 - */ 33 - struct intel_cdclk_config logical; 34 - 35 - /* 36 - * Actual configuration of cdclk, can be different from the 37 - * logical configuration only when all crtc's are DPMS off. 38 - */ 39 - struct intel_cdclk_config actual; 40 - 41 - /* minimum acceptable cdclk to satisfy bandwidth requirements */ 42 - int bw_min_cdclk; 43 - /* minimum acceptable cdclk for each pipe */ 44 - int min_cdclk[I915_MAX_PIPES]; 45 - /* minimum acceptable voltage level for each pipe */ 46 - u8 min_voltage_level[I915_MAX_PIPES]; 47 - 48 - /* pipe to which cd2x update is synchronized */ 49 - enum pipe pipe; 50 - 51 - /* forced minimum cdclk for glk+ audio w/a */ 52 - int force_min_cdclk; 53 - 54 - /* bitmask of active pipes */ 55 - u8 active_pipes; 56 - 57 - /* update cdclk with pipes disabled */ 58 - bool disable_pipes; 59 24 }; 60 25 61 26 void intel_cdclk_init_hw(struct intel_display *display); ··· 59 96 60 97 int intel_cdclk_init(struct intel_display *display); 61 98 void intel_cdclk_debugfs_register(struct intel_display *display); 99 + 100 + int intel_cdclk_logical(const struct intel_cdclk_state *cdclk_state); 101 + int intel_cdclk_actual(const struct intel_cdclk_state *cdclk_state); 102 + int intel_cdclk_actual_voltage_level(const struct intel_cdclk_state *cdclk_state); 103 + int intel_cdclk_min_cdclk(const struct intel_cdclk_state *cdclk_state, enum pipe pipe); 104 + int intel_cdclk_bw_min_cdclk(const struct intel_cdclk_state *cdclk_state); 105 + bool intel_cdclk_pmdemand_needs_update(struct intel_atomic_state *state); 106 + void intel_cdclk_force_min_cdclk(struct intel_cdclk_state *cdclk_state, int force_min_cdclk); 107 + void intel_cdclk_read_hw(struct intel_display *display); 62 108 63 109 #endif /* __INTEL_CDCLK_H__ */
+2 -2
drivers/gpu/drm/i915/display/intel_connector.c
··· 64 64 65 65 void intel_connector_queue_modeset_retry_work(struct intel_connector *connector) 66 66 { 67 - struct drm_i915_private *i915 = to_i915(connector->base.dev); 67 + struct intel_display *display = to_intel_display(connector); 68 68 69 69 drm_connector_get(&connector->base); 70 - if (!queue_work(i915->unordered_wq, &connector->modeset_retry_work)) 70 + if (!queue_work(display->wq.unordered, &connector->modeset_retry_work)) 71 71 drm_connector_put(&connector->base); 72 72 } 73 73
+1 -1
drivers/gpu/drm/i915/display/intel_crtc.c
··· 17 17 #include "i9xx_plane.h" 18 18 #include "icl_dsi.h" 19 19 #include "intel_atomic.h" 20 - #include "intel_atomic_plane.h" 21 20 #include "intel_color.h" 22 21 #include "intel_crtc.h" 23 22 #include "intel_cursor.h" ··· 28 29 #include "intel_dsi.h" 29 30 #include "intel_fifo_underrun.h" 30 31 #include "intel_pipe_crc.h" 32 + #include "intel_plane.h" 31 33 #include "intel_psr.h" 32 34 #include "intel_sprite.h" 33 35 #include "intel_vblank.h"
+5 -5
drivers/gpu/drm/i915/display/intel_cursor.c
··· 14 14 15 15 #include "i915_utils.h" 16 16 #include "intel_atomic.h" 17 - #include "intel_atomic_plane.h" 18 17 #include "intel_cursor.h" 19 18 #include "intel_cursor_regs.h" 20 19 #include "intel_de.h" ··· 22 23 #include "intel_fb.h" 23 24 #include "intel_fb_pin.h" 24 25 #include "intel_frontbuffer.h" 26 + #include "intel_plane.h" 25 27 #include "intel_psr.h" 26 28 #include "intel_psr_regs.h" 27 29 #include "intel_vblank.h" ··· 158 158 return -EINVAL; 159 159 } 160 160 161 - ret = intel_atomic_plane_check_clipping(plane_state, crtc_state, 162 - DRM_PLANE_NO_SCALING, 163 - DRM_PLANE_NO_SCALING, 164 - true); 161 + ret = intel_plane_check_clipping(plane_state, crtc_state, 162 + DRM_PLANE_NO_SCALING, 163 + DRM_PLANE_NO_SCALING, 164 + true); 165 165 if (ret) 166 166 return ret; 167 167
+7 -1
drivers/gpu/drm/i915/display/intel_cx0_phy.c
··· 39 39 struct intel_display *display = to_intel_display(encoder); 40 40 enum phy phy = intel_encoder_to_phy(encoder); 41 41 42 - if (display->platform.pantherlake && phy == PHY_A) 42 + /* PTL doesn't have a PHY connected to PORT B; as such, 43 + * there will never be a case where PTL uses PHY B. 44 + * WCL uses PORT A and B with the C10 PHY. 45 + * Reusing the condition for WCL and extending it for PORT B 46 + * should not cause any issues for PTL. 47 + */ 48 + if (display->platform.pantherlake && phy < PHY_C) 43 49 return true; 44 50 45 51 if ((display->platform.lunarlake || display->platform.meteorlake) && phy < PHY_C)
+20
drivers/gpu/drm/i915/display/intel_ddi.c
··· 73 73 #include "intel_lspcon.h" 74 74 #include "intel_mg_phy_regs.h" 75 75 #include "intel_modeset_lock.h" 76 + #include "intel_panel.h" 76 77 #include "intel_pfit.h" 77 78 #include "intel_pps.h" 78 79 #include "intel_psr.h" 79 80 #include "intel_quirks.h" 80 81 #include "intel_snps_phy.h" 82 + #include "intel_step.h" 81 83 #include "intel_tc.h" 82 84 #include "intel_vdsc.h" 83 85 #include "intel_vdsc_regs.h" ··· 1395 1393 1396 1394 for (ln = 0; ln < 2; ln++) { 1397 1395 int level; 1396 + 1397 + /* Wa_16011342517:adl-p */ 1398 + if (display->platform.alderlake_p && 1399 + IS_DISPLAY_STEP(display, STEP_A0, STEP_D0)) { 1400 + if ((intel_encoder_is_hdmi(encoder) && 1401 + crtc_state->port_clock == 594000) || 1402 + (intel_encoder_is_dp(encoder) && 1403 + crtc_state->port_clock == 162000)) { 1404 + intel_dkl_phy_rmw(display, DKL_TX_DPCNTL2(tc_port, ln), 1405 + LOADGEN_SHARING_PMD_DISABLE, 1); 1406 + } else { 1407 + intel_dkl_phy_rmw(display, DKL_TX_DPCNTL2(tc_port, ln), 1408 + LOADGEN_SHARING_PMD_DISABLE, 0); 1409 + } 1410 + } 1398 1411 1399 1412 intel_dkl_phy_write(display, DKL_TX_PMD_LANE_SUS(tc_port, ln), 0); 1400 1413 ··· 3372 3355 drm_connector_update_privacy_screen(conn_state); 3373 3356 intel_edp_backlight_on(crtc_state, conn_state); 3374 3357 3358 + intel_panel_prepare(crtc_state, conn_state); 3359 + 3375 3360 if (!intel_lspcon_active(dig_port) || intel_dp_has_hdmi_sink(&dig_port->dp)) 3376 3361 intel_dp_set_infoframes(encoder, true, crtc_state, conn_state); 3377 3362 ··· 3571 3552 3572 3553 intel_dp->link.active = false; 3573 3554 3555 + intel_panel_unprepare(old_conn_state); 3574 3556 intel_psr_disable(intel_dp, old_crtc_state); 3575 3557 intel_alpm_disable(intel_dp); 3576 3558 intel_edp_backlight_off(old_conn_state);
+61 -18
drivers/gpu/drm/i915/display/intel_display.c
··· 57 57 #include "i9xx_wm.h" 58 58 #include "intel_alpm.h" 59 59 #include "intel_atomic.h" 60 - #include "intel_atomic_plane.h" 61 60 #include "intel_audio.h" 62 61 #include "intel_bo.h" 63 62 #include "intel_bw.h" ··· 93 94 #include "intel_fbc.h" 94 95 #include "intel_fdi.h" 95 96 #include "intel_fifo_underrun.h" 97 + #include "intel_flipq.h" 96 98 #include "intel_frontbuffer.h" 97 99 #include "intel_hdmi.h" 98 100 #include "intel_hotplug.h" ··· 108 108 #include "intel_pch_refclk.h" 109 109 #include "intel_pfit.h" 110 110 #include "intel_pipe_crc.h" 111 + #include "intel_plane.h" 111 112 #include "intel_plane_initial.h" 112 113 #include "intel_pmdemand.h" 113 114 #include "intel_pps.h" ··· 1660 1659 1661 1660 if (drm_WARN_ON(display->drm, crtc->active)) 1662 1661 return; 1663 - for_each_pipe_crtc_modeset_enable(display, pipe_crtc, new_crtc_state, i) 1664 - intel_dmc_enable_pipe(display, pipe_crtc->pipe); 1662 + for_each_pipe_crtc_modeset_enable(display, pipe_crtc, new_crtc_state, i) { 1663 + const struct intel_crtc_state *new_pipe_crtc_state = 1664 + intel_atomic_get_new_crtc_state(state, pipe_crtc); 1665 + 1666 + intel_dmc_enable_pipe(new_pipe_crtc_state); 1667 + } 1665 1668 1666 1669 intel_encoders_pre_pll_enable(state, crtc); 1667 1670 ··· 1803 1798 1804 1799 intel_encoders_post_pll_disable(state, crtc); 1805 1800 1806 - for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state, i) 1807 - intel_dmc_disable_pipe(display, pipe_crtc->pipe); 1801 + for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state, i) { 1802 + const struct intel_crtc_state *old_pipe_crtc_state = 1803 + intel_atomic_get_old_crtc_state(state, pipe_crtc); 1804 + 1805 + intel_dmc_disable_pipe(old_pipe_crtc_state); 1806 + } 1808 1807 } 1809 1808 1810 1809 /* Prefer intel_encoder_is_combo() */ ··· 4169 4160 return 0; 4170 4161 4171 4162 linetime_wm = DIV_ROUND_CLOSEST(pipe_mode->crtc_htotal * 1000 * 8, 4172 - cdclk_state->logical.cdclk); 4163 + intel_cdclk_logical(cdclk_state)); 4173 4164 4174 4165 return min(linetime_wm, 0x1ff); 4175 4166 } ··· 5488 5479 if (ret) 5489 5480 return ret; 5490 5481 5491 - ret = intel_atomic_add_affected_planes(state, crtc); 5482 + ret = intel_plane_add_affected(state, crtc); 5492 5483 if (ret) 5493 5484 return ret; 5494 5485 ··· 6204 6195 if (ret) 6205 6196 return ret; 6206 6197 6207 - ret = intel_atomic_add_affected_planes(state, crtc); 6198 + ret = intel_plane_add_affected(state, crtc); 6208 6199 if (ret) 6209 6200 return ret; 6210 6201 } ··· 6456 6447 goto fail; 6457 6448 } 6458 6449 6459 - ret = intel_atomic_check_planes(state); 6450 + ret = intel_plane_atomic_check(state); 6460 6451 if (ret) 6461 6452 goto fail; 6462 6453 ··· 6620 6611 intel_atomic_get_new_crtc_state(state, crtc); 6621 6612 bool modeset = intel_crtc_needs_modeset(new_crtc_state); 6622 6613 6623 - drm_WARN_ON(display->drm, new_crtc_state->use_dsb); 6614 + drm_WARN_ON(display->drm, new_crtc_state->use_dsb || new_crtc_state->use_flipq); 6624 6615 6625 6616 /* 6626 6617 * During modesets pipe configuration was programmed as the ··· 6650 6641 intel_atomic_get_new_crtc_state(state, crtc); 6651 6642 bool modeset = intel_crtc_needs_modeset(new_crtc_state); 6652 6643 6653 - drm_WARN_ON(display->drm, new_crtc_state->use_dsb); 6644 + drm_WARN_ON(display->drm, new_crtc_state->use_dsb || new_crtc_state->use_flipq); 6654 6645 6655 6646 /* 6656 6647 * Disable the scaler(s) after the plane(s) so that we don't ··· 6739 6730 6740 6731 if (!modeset && 6741 6732 intel_crtc_needs_color_update(new_crtc_state) && 6742 - !new_crtc_state->use_dsb) 6733 + !new_crtc_state->use_dsb && !new_crtc_state->use_flipq) 6743 6734 intel_color_commit_noarm(NULL, new_crtc_state); 6744 6735 6745 - if (!new_crtc_state->use_dsb) 6736 + if (!new_crtc_state->use_dsb && !new_crtc_state->use_flipq) 6746 6737 intel_crtc_planes_update_noarm(NULL, state, crtc); 6747 6738 } 6748 6739 ··· 6754 6745 struct intel_crtc_state *new_crtc_state = 6755 6746 intel_atomic_get_new_crtc_state(state, crtc); 6756 6747 6757 - if (new_crtc_state->use_dsb) { 6748 + if (new_crtc_state->use_flipq) { 6749 + intel_flipq_enable(new_crtc_state); 6750 + 6751 + intel_crtc_prepare_vblank_event(new_crtc_state, &crtc->flipq_event); 6752 + 6753 + intel_flipq_add(crtc, INTEL_FLIPQ_PLANE_1, 0, INTEL_DSB_0, 6754 + new_crtc_state->dsb_commit); 6755 + } else if (new_crtc_state->use_dsb) { 6758 6756 intel_crtc_prepare_vblank_event(new_crtc_state, &crtc->dsb_event); 6759 6757 6760 6758 intel_dsb_commit(new_crtc_state->dsb_commit); ··· 7199 7183 return; 7200 7184 7201 7185 /* FIXME deal with everything */ 7186 + new_crtc_state->use_flipq = 7187 + intel_flipq_supported(display) && 7188 + !new_crtc_state->do_async_flip && 7189 + !new_crtc_state->vrr.enable && 7190 + !new_crtc_state->has_psr && 7191 + !intel_crtc_needs_modeset(new_crtc_state) && 7192 + !intel_crtc_needs_fastset(new_crtc_state) && 7193 + !intel_crtc_needs_color_update(new_crtc_state); 7194 + 7202 7195 new_crtc_state->use_dsb = 7196 + !new_crtc_state->use_flipq && 7203 7197 !new_crtc_state->do_async_flip && 7204 7198 (DISPLAY_VER(display) >= 20 || !new_crtc_state->has_psr) && 7205 7199 !intel_crtc_needs_modeset(new_crtc_state) && ··· 7225 7199 struct intel_crtc_state *new_crtc_state = 7226 7200 intel_atomic_get_new_crtc_state(state, crtc); 7227 7201 7228 - if (!new_crtc_state->use_dsb && !new_crtc_state->dsb_color) 7202 + if (!new_crtc_state->use_flipq && 7203 + !new_crtc_state->use_dsb && 7204 + !new_crtc_state->dsb_color) 7229 7205 return; 7230 7206 7231 7207 /* ··· 7236 7208 * Double that for pipe stuff and other overhead. 7237 7209 */ 7238 7210 new_crtc_state->dsb_commit = intel_dsb_prepare(state, crtc, INTEL_DSB_0, 7239 - new_crtc_state->use_dsb ? 1024 : 16); 7211 + new_crtc_state->use_dsb || 7212 + new_crtc_state->use_flipq ? 1024 : 16); 7240 7213 if (!new_crtc_state->dsb_commit) { 7214 + new_crtc_state->use_flipq = false; 7241 7215 new_crtc_state->use_dsb = false; 7242 7216 intel_color_cleanup_commit(new_crtc_state); 7243 7217 return; 7244 7218 } 7245 7219 7246 - if (new_crtc_state->use_dsb) { 7220 + if (new_crtc_state->use_flipq || new_crtc_state->use_dsb) { 7221 + /* Wa_18034343758 */ 7222 + if (new_crtc_state->use_flipq) 7223 + intel_flipq_wait_dmc_halt(new_crtc_state->dsb_commit, crtc); 7224 + 7247 7225 if (intel_crtc_needs_color_update(new_crtc_state)) 7248 7226 intel_color_commit_noarm(new_crtc_state->dsb_commit, 7249 7227 new_crtc_state); ··· 7264 7230 intel_psr_trigger_frame_change_event(new_crtc_state->dsb_commit, 7265 7231 state, crtc); 7266 7232 7267 - intel_dsb_vblank_evade(state, new_crtc_state->dsb_commit); 7233 + if (new_crtc_state->use_dsb) 7234 + intel_dsb_vblank_evade(state, new_crtc_state->dsb_commit); 7268 7235 7269 7236 if (intel_crtc_needs_color_update(new_crtc_state)) 7270 7237 intel_color_commit_arm(new_crtc_state->dsb_commit, ··· 7280 7245 if (DISPLAY_VER(display) >= 9) 7281 7246 skl_detach_scalers(new_crtc_state->dsb_commit, 7282 7247 new_crtc_state); 7248 + 7249 + /* Wa_18034343758 */ 7250 + if (new_crtc_state->use_flipq) 7251 + intel_flipq_unhalt_dmc(new_crtc_state->dsb_commit, crtc); 7283 7252 } 7284 7253 7285 7254 if (intel_color_uses_chained_dsb(new_crtc_state)) ··· 7424 7385 /* Now enable the clocks, plane, pipe, and connectors that we set up. */ 7425 7386 display->funcs.display->commit_modeset_enables(state); 7426 7387 7388 + /* FIXME probably need to sequence this properly */ 7427 7389 intel_program_dpkgc_latency(state); 7428 7390 7429 7391 intel_wait_for_vblank_workers(state); ··· 7448 7408 7449 7409 if (!state->base.legacy_cursor_update && !new_crtc_state->use_dsb) 7450 7410 intel_vrr_check_push_sent(NULL, new_crtc_state); 7411 + 7412 + if (new_crtc_state->use_flipq) 7413 + intel_flipq_disable(new_crtc_state); 7451 7414 } 7452 7415 7453 7416 /*
+9
drivers/gpu/drm/i915/display/intel_display_core.h
··· 480 480 } irq; 481 481 482 482 struct { 483 + /* protected by wm.wm_mutex */ 484 + u16 linetime[I915_MAX_PIPES]; 485 + bool disable[I915_MAX_PIPES]; 486 + } pkgc; 487 + 488 + struct { 483 489 wait_queue_head_t waitqueue; 484 490 485 491 /* mutex to protect pmdemand programming sequence */ ··· 576 570 577 571 /* hipri wq for commit cleanups */ 578 572 struct workqueue_struct *cleanup; 573 + 574 + /* unordered workqueue for all display unordered work */ 575 + struct workqueue_struct *unordered; 579 576 } wq; 580 577 581 578 /* Grouping using named structs. Keep sorted. */
+1
drivers/gpu/drm/i915/display/intel_display_device.c
··· 1480 1480 { 14, 1, &xe2_hpd_display }, 1481 1481 { 20, 0, &xe2_lpd_display }, 1482 1482 { 30, 0, &xe2_lpd_display }, 1483 + { 30, 2, &xe2_lpd_display }, 1483 1484 }; 1484 1485 1485 1486 static const struct intel_display_device_info *
+2 -3
drivers/gpu/drm/i915/display/intel_display_device.h
··· 192 192 #define HAS_TRANSCODER(__display, trans) ((DISPLAY_RUNTIME_INFO(__display)->cpu_transcoder_mask & \ 193 193 BIT(trans)) != 0) 194 194 #define HAS_UNCOMPRESSED_JOINER(__display) (DISPLAY_VER(__display) >= 13) 195 - #define HAS_ULTRAJOINER(__display) ((DISPLAY_VER(__display) >= 20 || \ 196 - ((__display)->platform.dgfx && DISPLAY_VER(__display) == 14)) && \ 197 - HAS_DSC(__display)) 195 + #define HAS_ULTRAJOINER(__display) (((__display)->platform.dgfx && \ 196 + DISPLAY_VER(__display) == 14) && HAS_DSC(__display)) 198 197 #define HAS_VRR(__display) (DISPLAY_VER(__display) >= 11) 199 198 #define INTEL_NUM_PIPES(__display) (hweight8(DISPLAY_RUNTIME_INFO(__display)->pipe_mask)) 200 199 #define OVERLAY_NEEDS_PHYSICAL(__display) (DISPLAY_INFO(__display)->overlay_needs_physical)
+22 -17
drivers/gpu/drm/i915/display/intel_display_driver.c
··· 44 44 #include "intel_fbc.h" 45 45 #include "intel_fbdev.h" 46 46 #include "intel_fdi.h" 47 + #include "intel_flipq.h" 47 48 #include "intel_gmbus.h" 48 49 #include "intel_hdcp.h" 49 50 #include "intel_hotplug.h" ··· 85 84 86 85 void intel_display_driver_init_hw(struct intel_display *display) 87 86 { 88 - struct intel_cdclk_state *cdclk_state; 89 - 90 87 if (!HAS_DISPLAY(display)) 91 88 return; 92 89 93 - cdclk_state = to_intel_cdclk_state(display->cdclk.obj.state); 94 - 95 - intel_update_cdclk(display); 96 - intel_cdclk_dump_config(display, &display->cdclk.hw, "Current CDCLK"); 97 - cdclk_state->logical = cdclk_state->actual = display->cdclk.hw; 90 + intel_cdclk_read_hw(display); 98 91 99 92 intel_display_wa_apply(display); 100 93 } ··· 237 242 if (!HAS_DISPLAY(display)) 238 243 return 0; 239 244 240 - intel_dmc_init(display); 241 - 242 245 display->hotplug.dp_wq = alloc_ordered_workqueue("intel-dp", 0); 243 246 if (!display->hotplug.dp_wq) { 244 247 ret = -ENOMEM; ··· 262 269 goto cleanup_wq_flip; 263 270 } 264 271 272 + display->wq.unordered = alloc_workqueue("display_unordered", 0, 0); 273 + if (!display->wq.unordered) { 274 + ret = -ENOMEM; 275 + goto cleanup_wq_cleanup; 276 + } 277 + 278 + intel_dmc_init(display); 279 + 265 280 intel_mode_config_init(display); 266 281 267 282 ret = intel_cdclk_init(display); 268 283 if (ret) 269 - goto cleanup_wq_cleanup; 284 + goto cleanup_wq_unordered; 270 285 271 286 ret = intel_color_init(display); 272 287 if (ret) 273 - goto cleanup_wq_cleanup; 288 + goto cleanup_wq_unordered; 274 289 275 290 ret = intel_dbuf_init(display); 276 291 if (ret) 277 - goto cleanup_wq_cleanup; 292 + goto cleanup_wq_unordered; 278 293 279 294 ret = intel_bw_init(display); 280 295 if (ret) 281 - goto cleanup_wq_cleanup; 296 + goto cleanup_wq_unordered; 282 297 283 298 ret = intel_pmdemand_init(display); 284 299 if (ret) 285 - goto cleanup_wq_cleanup; 300 + goto cleanup_wq_unordered; 286 301 287 302 intel_init_quirks(display); 288 303 ··· 298 297 299 298 return 0; 300 299 300 + cleanup_wq_unordered: 301 + destroy_workqueue(display->wq.unordered); 301 302 cleanup_wq_cleanup: 302 303 destroy_workqueue(display->wq.cleanup); 303 304 cleanup_wq_flip: ··· 538 535 */ 539 536 intel_hdcp_component_init(display); 540 537 538 + intel_flipq_init(display); 539 + 541 540 /* 542 541 * Force all active planes to recompute their states. So that on 543 542 * mode_setcrtc after probe, all the intel_plane_state variables ··· 605 600 flush_workqueue(display->wq.flip); 606 601 flush_workqueue(display->wq.modeset); 607 602 flush_workqueue(display->wq.cleanup); 603 + flush_workqueue(display->wq.unordered); 608 604 609 605 /* 610 606 * MST topology needs to be suspended so we don't have any calls to ··· 618 612 /* part #2: call after irq uninstall */ 619 613 void intel_display_driver_remove_noirq(struct intel_display *display) 620 614 { 621 - struct drm_i915_private *i915 = to_i915(display->drm); 622 - 623 615 if (!HAS_DISPLAY(display)) 624 616 return; 625 617 ··· 632 628 intel_unregister_dsm_handler(); 633 629 634 630 /* flush any delayed tasks or pending work */ 635 - flush_workqueue(i915->unordered_wq); 631 + flush_workqueue(display->wq.unordered); 636 632 637 633 intel_hdcp_component_fini(display); 638 634 ··· 648 644 destroy_workqueue(display->wq.flip); 649 645 destroy_workqueue(display->wq.modeset); 650 646 destroy_workqueue(display->wq.cleanup); 647 + destroy_workqueue(display->wq.unordered); 651 648 652 649 intel_fbc_cleanup(display); 653 650 }
+1 -1
drivers/gpu/drm/i915/display/intel_display_irq.c
··· 9 9 #include "i915_irq.h" 10 10 #include "i915_reg.h" 11 11 #include "icl_dsi_regs.h" 12 - #include "intel_atomic_plane.h" 13 12 #include "intel_crtc.h" 14 13 #include "intel_de.h" 15 14 #include "intel_display_irq.h" ··· 26 27 #include "intel_gmbus.h" 27 28 #include "intel_hotplug_irq.h" 28 29 #include "intel_pipe_crc_regs.h" 30 + #include "intel_plane.h" 29 31 #include "intel_pmdemand.h" 30 32 #include "intel_psr.h" 31 33 #include "intel_psr_regs.h"
+3
drivers/gpu/drm/i915/display/intel_display_params.c
··· 62 62 intel_display_param_named_unsafe(enable_dsb, bool, 0400, 63 63 "Enable display state buffer (DSB) (default: true)"); 64 64 65 + intel_display_param_named_unsafe(enable_flipq, bool, 0400, 66 + "Enable DMC flip queue (default: false)"); 67 + 65 68 intel_display_param_named_unsafe(enable_sagv, bool, 0400, 66 69 "Enable system agent voltage/frequency scaling (SAGV) (default: true)"); 67 70
+1
drivers/gpu/drm/i915/display/intel_display_params.h
··· 31 31 param(int, enable_dc, -1, 0400) \ 32 32 param(bool, enable_dpt, true, 0400) \ 33 33 param(bool, enable_dsb, true, 0600) \ 34 + param(bool, enable_flipq, false, 0600) \ 34 35 param(bool, enable_sagv, true, 0600) \ 35 36 param(int, disable_power_well, -1, 0400) \ 36 37 param(bool, enable_ips, true, 0600) \
+1 -3
drivers/gpu/drm/i915/display/intel_display_power.c
··· 1257 1257 1258 1258 static void hsw_write_dcomp(struct intel_display *display, u32 val) 1259 1259 { 1260 - struct drm_i915_private *dev_priv = to_i915(display->drm); 1261 - 1262 1260 if (display->platform.haswell) { 1263 - if (snb_pcode_write(&dev_priv->uncore, GEN6_PCODE_WRITE_D_COMP, val)) 1261 + if (intel_pcode_write(display->drm, GEN6_PCODE_WRITE_D_COMP, val)) 1264 1262 drm_dbg_kms(display->drm, "Failed to write to D_COMP\n"); 1265 1263 } else { 1266 1264 intel_de_write(display, D_COMP_BDW, val);
+30 -14
drivers/gpu/drm/i915/display/intel_display_power_well.c
··· 34 34 #include "vlv_iosf_sb_reg.h" 35 35 #include "vlv_sideband.h" 36 36 37 + /* 38 + * PG0 is HW controlled, so doesn't have a corresponding power well control knob 39 + * 40 + * {ICL,SKL}_DISP_PW1_IDX..{ICL,SKL}_DISP_PW4_IDX -> PG1..PG4 41 + */ 42 + static enum skl_power_gate pw_idx_to_pg(struct intel_display *display, int pw_idx) 43 + { 44 + int pw1_idx = DISPLAY_VER(display) >= 11 ? ICL_PW_CTL_IDX_PW_1 : SKL_PW_CTL_IDX_PW_1; 45 + 46 + return pw_idx - pw1_idx + SKL_PG1; 47 + } 48 + 37 49 struct i915_power_well_regs { 38 50 i915_reg_t bios; 39 51 i915_reg_t driver; ··· 320 308 { 321 309 const struct i915_power_well_regs *regs = power_well->desc->ops->regs; 322 310 int pw_idx = i915_power_well_instance(power_well)->hsw.idx; 323 - bool disabled; 324 311 u32 reqs; 312 + int ret; 325 313 326 314 /* 327 315 * Bspec doesn't require waiting for PWs to get disabled, but still do ··· 332 320 * Skip the wait in case any of the request bits are set and print a 333 321 * diagnostic message. 334 322 */ 335 - wait_for((disabled = !(intel_de_read(display, regs->driver) & 336 - HSW_PWR_WELL_CTL_STATE(pw_idx))) || 337 - (reqs = hsw_power_well_requesters(display, regs, pw_idx)), 1); 338 - if (disabled) 323 + reqs = hsw_power_well_requesters(display, regs, pw_idx); 324 + 325 + ret = intel_de_wait_for_clear(display, regs->driver, 326 + HSW_PWR_WELL_CTL_STATE(pw_idx), 327 + reqs ? 0 : 1); 328 + if (!ret) 339 329 return; 330 + 331 + /* Refresh requesters in case they popped up during the wait. */ 332 + if (!reqs) 333 + reqs = hsw_power_well_requesters(display, regs, pw_idx); 340 334 341 335 drm_dbg_kms(display->drm, 342 336 "%s forced on (bios:%d driver:%d kvmr:%d debug:%d)\n", ··· 368 350 if (power_well->desc->has_fuses) { 369 351 enum skl_power_gate pg; 370 352 371 - pg = DISPLAY_VER(display) >= 11 ? ICL_PW_CTL_IDX_TO_PG(pw_idx) : 372 - SKL_PW_CTL_IDX_TO_PG(pw_idx); 353 + pg = pw_idx_to_pg(display, pw_idx); 373 354 374 355 /* Wa_16013190616:adlp */ 375 356 if (display->platform.alderlake_p && pg == SKL_PG1) ··· 392 375 if (power_well->desc->has_fuses) { 393 376 enum skl_power_gate pg; 394 377 395 - pg = DISPLAY_VER(display) >= 11 ? ICL_PW_CTL_IDX_TO_PG(pw_idx) : 396 - SKL_PW_CTL_IDX_TO_PG(pw_idx); 378 + pg = pw_idx_to_pg(display, pw_idx); 379 + 397 380 gen9_wait_for_power_well_fuses(display, pg); 398 381 } 399 382 ··· 503 486 int ret, tries = 0; 504 487 505 488 while (1) { 506 - ret = snb_pcode_write_timeout(&i915->uncore, ICL_PCODE_EXIT_TCCOLD, 0, 507 - 250, 1); 489 + ret = intel_pcode_write(display->drm, ICL_PCODE_EXIT_TCCOLD, 0); 508 490 if (ret != -EAGAIN || ++tries == 3) 509 491 break; 510 492 msleep(1); ··· 845 829 846 830 assert_display_rpm_held(display); 847 831 848 - assert_dmc_loaded(display); 832 + assert_main_dmc_loaded(display); 849 833 } 850 834 851 835 void gen9_enable_dc5(struct intel_display *display) ··· 876 860 DC_STATE_EN_UPTO_DC6), 877 861 "DC6 already programmed to be enabled.\n"); 878 862 879 - assert_dmc_loaded(display); 863 + assert_main_dmc_loaded(display); 880 864 } 881 865 882 866 void skl_enable_dc6(struct intel_display *display) ··· 1782 1766 * Spec states that we should timeout the request after 200us 1783 1767 * but the function below will timeout after 500us 1784 1768 */ 1785 - ret = snb_pcode_read(&i915->uncore, TGL_PCODE_TCCOLD, &low_val, &high_val); 1769 + ret = intel_pcode_read(display->drm, TGL_PCODE_TCCOLD, &low_val, &high_val); 1786 1770 if (ret == 0) { 1787 1771 if (block && 1788 1772 (low_val & TGL_PCODE_EXIT_TCCOLD_DATA_L_EXIT_FAILED))
+9 -12
drivers/gpu/drm/i915/display/intel_display_regs.h
··· 2195 2195 #define HSW_PWR_WELL_FORCE_ON (1 << 19) 2196 2196 #define HSW_PWR_WELL_CTL6 _MMIO(0x45414) 2197 2197 2198 + /* SKL Fuse Status */ 2199 + enum skl_power_gate { 2200 + SKL_PG0, 2201 + SKL_PG1, 2202 + SKL_PG2, 2203 + ICL_PG3, 2204 + ICL_PG4, 2205 + }; 2206 + 2198 2207 #define SKL_FUSE_STATUS _MMIO(0x42000) 2199 2208 #define SKL_FUSE_DOWNLOAD_STATUS (1 << 31) 2200 - /* 2201 - * PG0 is HW controlled, so doesn't have a corresponding power well control knob 2202 - * SKL_DISP_PW1_IDX..SKL_DISP_PW2_IDX -> PG1..PG2 2203 - */ 2204 - #define SKL_PW_CTL_IDX_TO_PG(pw_idx) \ 2205 - ((pw_idx) - SKL_PW_CTL_IDX_PW_1 + SKL_PG1) 2206 - /* 2207 - * PG0 is HW controlled, so doesn't have a corresponding power well control knob 2208 - * ICL_DISP_PW1_IDX..ICL_DISP_PW4_IDX -> PG1..PG4 2209 - */ 2210 - #define ICL_PW_CTL_IDX_TO_PG(pw_idx) \ 2211 - ((pw_idx) - ICL_PW_CTL_IDX_PW_1 + SKL_PG1) 2212 2209 #define SKL_FUSE_PG_DIST_STATUS(pg) (1 << (27 - (pg))) 2213 2210 2214 2211 /* Per-pipe DDI Function Control */
+24
drivers/gpu/drm/i915/display/intel_display_types.h
··· 146 146 147 147 unsigned int min_alignment; 148 148 unsigned int vtd_guard; 149 + 150 + unsigned int (*panic_tiling)(unsigned int x, unsigned int y, unsigned int width); 149 151 }; 150 152 151 153 enum intel_hotplug_state { ··· 1305 1303 /* For DSB based pipe updates */ 1306 1304 struct intel_dsb *dsb_color, *dsb_commit; 1307 1305 bool use_dsb; 1306 + bool use_flipq; 1308 1307 1309 1308 u32 psr2_man_track_ctl; 1310 1309 ··· 1372 1369 enum intel_pipe_crc_source source; 1373 1370 }; 1374 1371 1372 + enum intel_flipq_id { 1373 + INTEL_FLIPQ_PLANE_1, 1374 + INTEL_FLIPQ_PLANE_2, 1375 + INTEL_FLIPQ_PLANE_3, 1376 + INTEL_FLIPQ_GENERAL, 1377 + INTEL_FLIPQ_FAST, 1378 + MAX_INTEL_FLIPQ, 1379 + }; 1380 + 1381 + struct intel_flipq { 1382 + u32 start_mmioaddr; 1383 + enum intel_flipq_id flipq_id; 1384 + u8 tail; 1385 + }; 1386 + 1375 1387 struct intel_crtc { 1376 1388 struct drm_crtc base; 1377 1389 enum pipe pipe; ··· 1413 1395 struct drm_pending_vblank_event *flip_done_event; 1414 1396 /* armed event for DSB based updates */ 1415 1397 struct drm_pending_vblank_event *dsb_event; 1398 + /* armed event for flip queue based updates */ 1399 + struct drm_pending_vblank_event *flipq_event; 1416 1400 1417 1401 /* Access to these should be protected by display->irq.lock. */ 1418 1402 bool cpu_fifo_underrun_disabled; 1419 1403 bool pch_fifo_underrun_disabled; 1404 + 1405 + struct intel_flipq flipq[MAX_INTEL_FLIPQ]; 1420 1406 1421 1407 /* per-pipe watermark state */ 1422 1408 struct { ··· 1543 1521 bool async_flip); 1544 1522 void (*enable_flip_done)(struct intel_plane *plane); 1545 1523 void (*disable_flip_done)(struct intel_plane *plane); 1524 + /* For drm_panic */ 1525 + void (*disable_tiling)(struct intel_plane *plane); 1546 1526 }; 1547 1527 1548 1528 #define to_intel_atomic_state(x) container_of(x, struct intel_atomic_state, base)
+1
drivers/gpu/drm/i915/display/intel_dkl_phy_regs.h
··· 153 153 #define DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX1(val) REG_FIELD_PREP(DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX1_MASK, (val)) 154 154 #define DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2_MASK REG_GENMASK(6, 5) 155 155 #define DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2(val) REG_FIELD_PREP(DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2_MASK, (val)) 156 + #define LOADGEN_SHARING_PMD_DISABLE REG_BIT(12) 156 157 157 158 #define _DKL_TX_FW_CALIB_LN0 0x02F8 158 159 #define _DKL_TX_FW_CALIB_LN1 0x12F8
+328 -129
drivers/gpu/drm/i915/display/intel_dmc.c
··· 24 24 25 25 #include <linux/debugfs.h> 26 26 #include <linux/firmware.h> 27 + #include <drm/drm_vblank.h> 27 28 28 - #include "i915_drv.h" 29 + #include <drm/drm_file.h> 30 + #include <drm/drm_print.h> 31 + 29 32 #include "i915_reg.h" 33 + #include "i915_utils.h" 30 34 #include "intel_crtc.h" 31 35 #include "intel_de.h" 32 36 #include "intel_display_power_well.h" ··· 39 35 #include "intel_display_types.h" 40 36 #include "intel_dmc.h" 41 37 #include "intel_dmc_regs.h" 38 + #include "intel_flipq.h" 42 39 #include "intel_step.h" 43 40 44 41 /** ··· 184 179 const char *fw_path = NULL; 185 180 u32 max_fw_size = 0; 186 181 187 - if (DISPLAY_VERx100(display) == 3000) { 182 + if (DISPLAY_VERx100(display) == 3002 || 183 + DISPLAY_VERx100(display) == 3000) { 188 184 fw_path = XE3LPD_DMC_PATH; 189 185 max_fw_size = XE2LPD_DMC_MAX_FW_SIZE; 190 186 } else if (DISPLAY_VERx100(display) == 2000) { ··· 438 432 intel_de_write(display, htp_reg, 0); 439 433 } 440 434 441 - static void disable_all_event_handlers(struct intel_display *display) 435 + static void disable_all_event_handlers(struct intel_display *display, 436 + enum intel_dmc_id dmc_id) 442 437 { 443 - enum intel_dmc_id dmc_id; 438 + int handler; 444 439 445 440 /* TODO: disable the event handlers on pre-GEN12 platforms as well */ 446 441 if (DISPLAY_VER(display) < 12) 447 442 return; 448 443 449 - for_each_dmc_id(dmc_id) { 450 - int handler; 444 + if (!has_dmc_id_fw(display, dmc_id)) 445 + return; 451 446 452 - if (!has_dmc_id_fw(display, dmc_id)) 453 - continue; 454 - 455 - for (handler = 0; handler < DMC_EVENT_HANDLER_COUNT_GEN12; handler++) 456 - disable_event_handler(display, 457 - DMC_EVT_CTL(display, dmc_id, handler), 458 - DMC_EVT_HTP(display, dmc_id, handler)); 459 - } 447 + for (handler = 0; handler < DMC_EVENT_HANDLER_COUNT_GEN12; handler++) 448 + disable_event_handler(display, 449 + DMC_EVT_CTL(display, dmc_id, handler), 450 + DMC_EVT_HTP(display, dmc_id, handler)); 460 451 } 461 452 462 453 static void adlp_pipedmc_clock_gating_wa(struct intel_display *display, bool enable) ··· 485 482 * for pipe A and B. 486 483 */ 487 484 intel_de_rmw(display, GEN9_CLKGATE_DIS_0, 0, 488 - MTL_PIPEDMC_GATING_DIS_A | MTL_PIPEDMC_GATING_DIS_B); 485 + MTL_PIPEDMC_GATING_DIS(PIPE_A) | 486 + MTL_PIPEDMC_GATING_DIS(PIPE_B)); 489 487 } 490 488 491 489 static void pipedmc_clock_gating_wa(struct intel_display *display, bool enable) 492 490 { 493 - if (DISPLAY_VER(display) >= 14 && enable) 491 + if (display->platform.meteorlake && enable) 494 492 mtl_pipedmc_clock_gating_wa(display); 495 493 else if (DISPLAY_VER(display) == 13) 496 494 adlp_pipedmc_clock_gating_wa(display, enable); ··· 504 500 * triggering it during the first DC state transition. Figure 505 501 * out what is going on... 506 502 */ 507 - return PIPEDMC_GTT_FAULT | 503 + return PIPEDMC_FLIPQ_PROG_DONE | 504 + PIPEDMC_GTT_FAULT | 508 505 PIPEDMC_ATS_FAULT; 509 - } 510 - 511 - void intel_dmc_enable_pipe(struct intel_display *display, enum pipe pipe) 512 - { 513 - enum intel_dmc_id dmc_id = PIPE_TO_DMC_ID(pipe); 514 - 515 - if (!is_valid_dmc_id(dmc_id) || !has_dmc_id_fw(display, dmc_id)) 516 - return; 517 - 518 - if (DISPLAY_VER(display) >= 20) { 519 - intel_de_write(display, PIPEDMC_INTERRUPT(pipe), pipedmc_interrupt_mask(display)); 520 - intel_de_write(display, PIPEDMC_INTERRUPT_MASK(pipe), ~pipedmc_interrupt_mask(display)); 521 - } 522 - 523 - if (DISPLAY_VER(display) >= 14) 524 - intel_de_rmw(display, MTL_PIPEDMC_CONTROL, 0, PIPEDMC_ENABLE_MTL(pipe)); 525 - else 526 - intel_de_rmw(display, PIPEDMC_CONTROL(pipe), 0, PIPEDMC_ENABLE); 527 - } 528 - 529 - void intel_dmc_disable_pipe(struct intel_display *display, enum pipe pipe) 530 - { 531 - enum intel_dmc_id dmc_id = PIPE_TO_DMC_ID(pipe); 532 - 533 - if (!is_valid_dmc_id(dmc_id) || !has_dmc_id_fw(display, dmc_id)) 534 - return; 535 - 536 - if (DISPLAY_VER(display) >= 14) 537 - intel_de_rmw(display, MTL_PIPEDMC_CONTROL, PIPEDMC_ENABLE_MTL(pipe), 0); 538 - else 539 - intel_de_rmw(display, PIPEDMC_CONTROL(pipe), PIPEDMC_ENABLE, 0); 540 - 541 - if (DISPLAY_VER(display) >= 20) { 542 - intel_de_write(display, PIPEDMC_INTERRUPT_MASK(pipe), ~0); 543 - intel_de_write(display, PIPEDMC_INTERRUPT(pipe), pipedmc_interrupt_mask(display)); 544 - } 545 506 } 546 507 547 508 static u32 dmc_evt_ctl_disable(void) ··· 544 575 { 545 576 return is_dmc_evt_ctl_reg(display, dmc_id, reg) && 546 577 REG_FIELD_GET(DMC_EVT_CTL_EVENT_ID_MASK, data) == event_id; 578 + } 579 + 580 + static bool disable_dmc_evt(struct intel_display *display, 581 + enum intel_dmc_id dmc_id, 582 + i915_reg_t reg, u32 data) 583 + { 584 + if (!is_dmc_evt_ctl_reg(display, dmc_id, reg)) 585 + return false; 586 + 587 + /* keep all pipe DMC events disabled by default */ 588 + if (dmc_id != DMC_FW_MAIN) 589 + return true; 590 + 591 + /* also disable the flip queue event on the main DMC on TGL */ 592 + if (display->platform.tigerlake && 593 + is_event_handler(display, dmc_id, MAINDMC_EVENT_CLK_MSEC, reg, data)) 594 + return true; 595 + 596 + /* also disable the HRR event on the main DMC on TGL/ADLS */ 597 + if ((display->platform.tigerlake || display->platform.alderlake_s) && 598 + is_event_handler(display, dmc_id, MAINDMC_EVENT_VBLANK_A, reg, data)) 599 + return true; 600 + 601 + return false; 602 + } 603 + 604 + static u32 dmc_mmiodata(struct intel_display *display, 605 + struct intel_dmc *dmc, 606 + enum intel_dmc_id dmc_id, int i) 607 + { 608 + if (disable_dmc_evt(display, dmc_id, 609 + dmc->dmc_info[dmc_id].mmioaddr[i], 610 + dmc->dmc_info[dmc_id].mmiodata[i])) 611 + return dmc_evt_ctl_disable(); 612 + else 613 + return dmc->dmc_info[dmc_id].mmiodata[i]; 614 + } 615 + 616 + static void dmc_load_mmio(struct intel_display *display, enum intel_dmc_id dmc_id) 617 + { 618 + struct intel_dmc *dmc = display_to_dmc(display); 619 + int i; 620 + 621 + for (i = 0; i < dmc->dmc_info[dmc_id].mmio_count; i++) { 622 + intel_de_write(display, dmc->dmc_info[dmc_id].mmioaddr[i], 623 + dmc_mmiodata(display, dmc, dmc_id, i)); 624 + } 625 + } 626 + 627 + static void dmc_load_program(struct intel_display *display, enum intel_dmc_id dmc_id) 628 + { 629 + struct intel_dmc *dmc = display_to_dmc(display); 630 + int i; 631 + 632 + disable_all_event_handlers(display, dmc_id); 633 + 634 + preempt_disable(); 635 + 636 + for (i = 0; i < dmc->dmc_info[dmc_id].dmc_fw_size; i++) { 637 + intel_de_write_fw(display, 638 + DMC_PROGRAM(dmc->dmc_info[dmc_id].start_mmioaddr, i), 639 + dmc->dmc_info[dmc_id].payload[i]); 640 + } 641 + 642 + preempt_enable(); 643 + 644 + dmc_load_mmio(display, dmc_id); 645 + } 646 + 647 + static void assert_dmc_loaded(struct intel_display *display, 648 + enum intel_dmc_id dmc_id) 649 + { 650 + struct intel_dmc *dmc = display_to_dmc(display); 651 + u32 expected, found; 652 + int i; 653 + 654 + if (!is_valid_dmc_id(dmc_id) || !has_dmc_id_fw(display, dmc_id)) 655 + return; 656 + 657 + found = intel_de_read(display, DMC_PROGRAM(dmc->dmc_info[dmc_id].start_mmioaddr, 0)); 658 + expected = dmc->dmc_info[dmc_id].payload[0]; 659 + 660 + drm_WARN(display->drm, found != expected, 661 + "DMC %d program storage start incorrect (expected 0x%x, current 0x%x)\n", 662 + dmc_id, expected, found); 663 + 664 + for (i = 0; i < dmc->dmc_info[dmc_id].mmio_count; i++) { 665 + i915_reg_t reg = dmc->dmc_info[dmc_id].mmioaddr[i]; 666 + 667 + found = intel_de_read(display, reg); 668 + expected = dmc_mmiodata(display, dmc, dmc_id, i); 669 + 670 + /* once set DMC_EVT_CTL_ENABLE can't be cleared :/ */ 671 + if (is_dmc_evt_ctl_reg(display, dmc_id, reg)) { 672 + found &= ~DMC_EVT_CTL_ENABLE; 673 + expected &= ~DMC_EVT_CTL_ENABLE; 674 + } 675 + 676 + drm_WARN(display->drm, found != expected, 677 + "DMC %d mmio[%d]/0x%x incorrect (expected 0x%x, current 0x%x)\n", 678 + dmc_id, i, i915_mmio_reg_offset(reg), expected, found); 679 + } 680 + } 681 + 682 + void assert_main_dmc_loaded(struct intel_display *display) 683 + { 684 + assert_dmc_loaded(display, DMC_FW_MAIN); 685 + } 686 + 687 + static bool need_pipedmc_load_program(struct intel_display *display) 688 + { 689 + /* On TGL/derivatives pipe DMC state is lost when PG1 is disabled */ 690 + return DISPLAY_VER(display) == 12; 691 + } 692 + 693 + static bool need_pipedmc_load_mmio(struct intel_display *display, enum pipe pipe) 694 + { 695 + /* 696 + * PTL: 697 + * - pipe A/B DMC doesn't need save/restore 698 + * - pipe C/D DMC is in PG0, needs manual save/restore 699 + */ 700 + if (DISPLAY_VER(display) == 30) 701 + return pipe >= PIPE_C; 702 + 703 + /* 704 + * FIXME LNL unclear, main DMC firmware has the pipe DMC A/B PG0 705 + * save/restore, but so far unable to see the loss of pipe DMC state 706 + * in action. Are we just failing to turn off PG0 due to some other 707 + * SoC level stuff? 708 + */ 709 + if (DISPLAY_VER(display) == 20) 710 + return false; 711 + 712 + /* 713 + * FIXME BMG untested, main DMC firmware has the 714 + * pipe DMC A/B PG0 save/restore... 715 + */ 716 + if (display->platform.battlemage) 717 + return false; 718 + 719 + /* 720 + * DG2: 721 + * - Pipe DMCs presumably in PG0? 722 + * - No DC6, and even DC9 doesn't seem to result 723 + * in loss of DMC state for whatever reason 724 + */ 725 + if (display->platform.dg2) 726 + return false; 727 + 728 + /* 729 + * ADL/MTL: 730 + * - pipe A/B DMC is in PG0, saved/restored by the main DMC 731 + * - pipe C/D DMC is in PG0, needs manual save/restore 732 + */ 733 + if (IS_DISPLAY_VER(display, 13, 14)) 734 + return pipe >= PIPE_C; 735 + 736 + return false; 737 + } 738 + 739 + static bool can_enable_pipedmc(const struct intel_crtc_state *crtc_state) 740 + { 741 + struct intel_display *display = to_intel_display(crtc_state); 742 + 743 + /* 744 + * On TGL/derivatives pipe DMC state is lost when PG1 is disabled. 745 + * Do not even enable the pipe DMC when that can happen outside 746 + * of driver control (PSR+DC5/6). 747 + */ 748 + if (DISPLAY_VER(display) == 12 && crtc_state->has_psr) 749 + return false; 750 + 751 + return true; 752 + } 753 + 754 + void intel_dmc_enable_pipe(const struct intel_crtc_state *crtc_state) 755 + { 756 + struct intel_display *display = to_intel_display(crtc_state); 757 + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 758 + enum pipe pipe = crtc->pipe; 759 + enum intel_dmc_id dmc_id = PIPE_TO_DMC_ID(pipe); 760 + 761 + if (!is_valid_dmc_id(dmc_id) || !has_dmc_id_fw(display, dmc_id)) 762 + return; 763 + 764 + if (!can_enable_pipedmc(crtc_state)) { 765 + intel_dmc_disable_pipe(crtc_state); 766 + return; 767 + } 768 + 769 + if (need_pipedmc_load_program(display)) 770 + dmc_load_program(display, dmc_id); 771 + else if (need_pipedmc_load_mmio(display, pipe)) 772 + dmc_load_mmio(display, dmc_id); 773 + 774 + assert_dmc_loaded(display, dmc_id); 775 + 776 + if (DISPLAY_VER(display) >= 20) { 777 + intel_flipq_reset(display, pipe); 778 + 779 + intel_de_write(display, PIPEDMC_INTERRUPT(pipe), pipedmc_interrupt_mask(display)); 780 + intel_de_write(display, PIPEDMC_INTERRUPT_MASK(pipe), ~pipedmc_interrupt_mask(display)); 781 + } 782 + 783 + if (DISPLAY_VER(display) >= 14) 784 + intel_de_rmw(display, MTL_PIPEDMC_CONTROL, 0, PIPEDMC_ENABLE_MTL(pipe)); 785 + else 786 + intel_de_rmw(display, PIPEDMC_CONTROL(pipe), 0, PIPEDMC_ENABLE); 787 + } 788 + 789 + void intel_dmc_disable_pipe(const struct intel_crtc_state *crtc_state) 790 + { 791 + struct intel_display *display = to_intel_display(crtc_state); 792 + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 793 + enum pipe pipe = crtc->pipe; 794 + enum intel_dmc_id dmc_id = PIPE_TO_DMC_ID(pipe); 795 + 796 + if (!is_valid_dmc_id(dmc_id) || !has_dmc_id_fw(display, dmc_id)) 797 + return; 798 + 799 + if (DISPLAY_VER(display) >= 14) 800 + intel_de_rmw(display, MTL_PIPEDMC_CONTROL, PIPEDMC_ENABLE_MTL(pipe), 0); 801 + else 802 + intel_de_rmw(display, PIPEDMC_CONTROL(pipe), PIPEDMC_ENABLE, 0); 803 + 804 + if (DISPLAY_VER(display) >= 20) { 805 + intel_de_write(display, PIPEDMC_INTERRUPT_MASK(pipe), ~0); 806 + intel_de_write(display, PIPEDMC_INTERRUPT(pipe), pipedmc_interrupt_mask(display)); 807 + 808 + intel_flipq_reset(display, pipe); 809 + } 547 810 } 548 811 549 812 static void dmc_configure_event(struct intel_display *display, ··· 838 637 dmc_configure_event(display, dmc_id, PIPEDMC_EVENT_VBLANK, enable); 839 638 } 840 639 841 - static bool disable_dmc_evt(struct intel_display *display, 842 - enum intel_dmc_id dmc_id, 843 - i915_reg_t reg, u32 data) 844 - { 845 - if (!is_dmc_evt_ctl_reg(display, dmc_id, reg)) 846 - return false; 847 - 848 - /* keep all pipe DMC events disabled by default */ 849 - if (dmc_id != DMC_FW_MAIN) 850 - return true; 851 - 852 - /* also disable the flip queue event on the main DMC on TGL */ 853 - if (display->platform.tigerlake && 854 - is_event_handler(display, dmc_id, MAINDMC_EVENT_CLK_MSEC, reg, data)) 855 - return true; 856 - 857 - /* also disable the HRR event on the main DMC on TGL/ADLS */ 858 - if ((display->platform.tigerlake || display->platform.alderlake_s) && 859 - is_event_handler(display, dmc_id, MAINDMC_EVENT_VBLANK_A, reg, data)) 860 - return true; 861 - 862 - return false; 863 - } 864 - 865 - static u32 dmc_mmiodata(struct intel_display *display, 866 - struct intel_dmc *dmc, 867 - enum intel_dmc_id dmc_id, int i) 868 - { 869 - if (disable_dmc_evt(display, dmc_id, 870 - dmc->dmc_info[dmc_id].mmioaddr[i], 871 - dmc->dmc_info[dmc_id].mmiodata[i])) 872 - return dmc_evt_ctl_disable(); 873 - else 874 - return dmc->dmc_info[dmc_id].mmiodata[i]; 875 - } 876 - 877 640 /** 878 641 * intel_dmc_load_program() - write the firmware from memory to register. 879 642 * @display: display instance ··· 849 684 void intel_dmc_load_program(struct intel_display *display) 850 685 { 851 686 struct i915_power_domains *power_domains = &display->power.domains; 852 - struct intel_dmc *dmc = display_to_dmc(display); 853 687 enum intel_dmc_id dmc_id; 854 - u32 i; 855 688 856 689 if (!intel_dmc_has_payload(display)) 857 690 return; 858 691 859 - pipedmc_clock_gating_wa(display, true); 860 - 861 - disable_all_event_handlers(display); 862 - 863 692 assert_display_rpm_held(display); 864 693 865 - preempt_disable(); 694 + pipedmc_clock_gating_wa(display, true); 866 695 867 696 for_each_dmc_id(dmc_id) { 868 - for (i = 0; i < dmc->dmc_info[dmc_id].dmc_fw_size; i++) { 869 - intel_de_write_fw(display, 870 - DMC_PROGRAM(dmc->dmc_info[dmc_id].start_mmioaddr, i), 871 - dmc->dmc_info[dmc_id].payload[i]); 872 - } 697 + dmc_load_program(display, dmc_id); 698 + assert_dmc_loaded(display, dmc_id); 873 699 } 874 700 875 - preempt_enable(); 876 - 877 - for_each_dmc_id(dmc_id) { 878 - for (i = 0; i < dmc->dmc_info[dmc_id].mmio_count; i++) { 879 - intel_de_write(display, dmc->dmc_info[dmc_id].mmioaddr[i], 880 - dmc_mmiodata(display, dmc, dmc_id, i)); 881 - } 882 - } 701 + if (DISPLAY_VER(display) >= 20) 702 + intel_de_write(display, DMC_FQ_W2_PTS_CFG_SEL, 703 + PIPE_D_DMC_W2_PTS_CONFIG_SELECT(PIPE_D) | 704 + PIPE_C_DMC_W2_PTS_CONFIG_SELECT(PIPE_C) | 705 + PIPE_B_DMC_W2_PTS_CONFIG_SELECT(PIPE_B) | 706 + PIPE_A_DMC_W2_PTS_CONFIG_SELECT(PIPE_A)); 883 707 884 708 power_domains->dc_state = 0; 885 709 ··· 886 732 */ 887 733 void intel_dmc_disable_program(struct intel_display *display) 888 734 { 735 + enum intel_dmc_id dmc_id; 736 + 889 737 if (!intel_dmc_has_payload(display)) 890 738 return; 891 739 892 740 pipedmc_clock_gating_wa(display, true); 893 - disable_all_event_handlers(display); 741 + 742 + for_each_dmc_id(dmc_id) 743 + disable_all_event_handlers(display, dmc_id); 744 + 894 745 pipedmc_clock_gating_wa(display, false); 895 - } 896 - 897 - void assert_dmc_loaded(struct intel_display *display) 898 - { 899 - struct intel_dmc *dmc = display_to_dmc(display); 900 - 901 - drm_WARN_ONCE(display->drm, !dmc, "DMC not initialized\n"); 902 - drm_WARN_ONCE(display->drm, dmc && 903 - !intel_de_read(display, DMC_PROGRAM(dmc->dmc_info[DMC_FW_MAIN].start_mmioaddr, 0)), 904 - "DMC program storage start is NULL\n"); 905 - drm_WARN_ONCE(display->drm, !intel_de_read(display, DMC_SSP_BASE), 906 - "DMC SSP Base Not fine\n"); 907 - drm_WARN_ONCE(display->drm, !intel_de_read(display, DMC_HTP_SKL), 908 - "DMC HTP Not fine\n"); 909 746 } 910 747 911 748 static bool fw_info_matches_stepping(const struct intel_fw_info *fw_info, ··· 1315 1170 */ 1316 1171 void intel_dmc_init(struct intel_display *display) 1317 1172 { 1318 - struct drm_i915_private *i915 = to_i915(display->drm); 1319 1173 struct intel_dmc *dmc; 1320 1174 1321 1175 if (!HAS_DMC(display)) ··· 1357 1213 display->dmc.dmc = dmc; 1358 1214 1359 1215 drm_dbg_kms(display->drm, "Loading %s\n", dmc->fw_path); 1360 - queue_work(i915->unordered_wq, &dmc->work); 1216 + queue_work(display->wq.unordered, &dmc->work); 1361 1217 1362 1218 return; 1363 1219 ··· 1386 1242 /* Drop the reference held in case DMC isn't loaded. */ 1387 1243 if (!intel_dmc_has_payload(display)) 1388 1244 intel_dmc_runtime_pm_put(display); 1245 + } 1246 + 1247 + void intel_dmc_wait_fw_load(struct intel_display *display) 1248 + { 1249 + struct intel_dmc *dmc = display_to_dmc(display); 1250 + 1251 + if (!HAS_DMC(display)) 1252 + return; 1253 + 1254 + if (dmc) 1255 + flush_work(&dmc->work); 1389 1256 } 1390 1257 1391 1258 /** ··· 1612 1457 void intel_pipedmc_irq_handler(struct intel_display *display, enum pipe pipe) 1613 1458 { 1614 1459 struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe); 1615 - u32 tmp; 1460 + u32 tmp = 0, int_vector; 1616 1461 1617 1462 if (DISPLAY_VER(display) >= 20) { 1618 1463 tmp = intel_de_read(display, PIPEDMC_INTERRUPT(pipe)); 1619 1464 intel_de_write(display, PIPEDMC_INTERRUPT(pipe), tmp); 1465 + 1466 + if (tmp & PIPEDMC_FLIPQ_PROG_DONE) { 1467 + spin_lock(&display->drm->event_lock); 1468 + 1469 + if (crtc->flipq_event) { 1470 + /* 1471 + * Update vblank counter/timestamp in case it 1472 + * hasn't been done yet for this frame. 1473 + */ 1474 + drm_crtc_accurate_vblank_count(&crtc->base); 1475 + 1476 + drm_crtc_send_vblank_event(&crtc->base, crtc->flipq_event); 1477 + crtc->flipq_event = NULL; 1478 + } 1479 + 1480 + spin_unlock(&display->drm->event_lock); 1481 + } 1620 1482 1621 1483 if (tmp & PIPEDMC_ATS_FAULT) 1622 1484 drm_err_ratelimited(display->drm, "[CRTC:%d:%s] PIPEDMC ATS fault\n", ··· 1646 1474 crtc->base.base.id, crtc->base.name); 1647 1475 } 1648 1476 1649 - tmp = intel_de_read(display, PIPEDMC_STATUS(pipe)) & PIPEDMC_INT_VECTOR_MASK; 1650 - if (tmp) 1477 + int_vector = intel_de_read(display, PIPEDMC_STATUS(pipe)) & PIPEDMC_INT_VECTOR_MASK; 1478 + if (tmp == 0 && int_vector != 0) 1651 1479 drm_err(display->drm, "[CRTC:%d:%s]] PIPEDMC interrupt vector 0x%x\n", 1652 1480 crtc->base.base.id, crtc->base.name, tmp); 1481 + } 1482 + 1483 + void intel_pipedmc_enable_event(struct intel_crtc *crtc, 1484 + enum pipedmc_event_id event) 1485 + { 1486 + struct intel_display *display = to_intel_display(crtc); 1487 + enum intel_dmc_id dmc_id = PIPE_TO_DMC_ID(crtc->pipe); 1488 + 1489 + dmc_configure_event(display, dmc_id, event, true); 1490 + } 1491 + 1492 + void intel_pipedmc_disable_event(struct intel_crtc *crtc, 1493 + enum pipedmc_event_id event) 1494 + { 1495 + struct intel_display *display = to_intel_display(crtc); 1496 + enum intel_dmc_id dmc_id = PIPE_TO_DMC_ID(crtc->pipe); 1497 + 1498 + dmc_configure_event(display, dmc_id, event, false); 1499 + } 1500 + 1501 + u32 intel_pipedmc_start_mmioaddr(struct intel_crtc *crtc) 1502 + { 1503 + struct intel_display *display = to_intel_display(crtc); 1504 + struct intel_dmc *dmc = display_to_dmc(display); 1505 + enum intel_dmc_id dmc_id = PIPE_TO_DMC_ID(crtc->pipe); 1506 + 1507 + return dmc ? dmc->dmc_info[dmc_id].start_mmioaddr : 0; 1653 1508 }
+15 -3
drivers/gpu/drm/i915/display/intel_dmc.h
··· 9 9 #include <linux/types.h> 10 10 11 11 enum pipe; 12 + enum pipedmc_event_id; 12 13 struct drm_printer; 14 + struct intel_crtc; 15 + struct intel_crtc_state; 13 16 struct intel_display; 14 17 struct intel_dmc_snapshot; 15 18 16 19 void intel_dmc_init(struct intel_display *display); 17 20 void intel_dmc_load_program(struct intel_display *display); 21 + void intel_dmc_wait_fw_load(struct intel_display *display); 18 22 void intel_dmc_disable_program(struct intel_display *display); 19 - void intel_dmc_enable_pipe(struct intel_display *display, enum pipe pipe); 20 - void intel_dmc_disable_pipe(struct intel_display *display, enum pipe pipe); 23 + void intel_dmc_enable_pipe(const struct intel_crtc_state *crtc_state); 24 + void intel_dmc_disable_pipe(const struct intel_crtc_state *crtc_state); 21 25 void intel_dmc_block_pkgc(struct intel_display *display, enum pipe pipe, 22 26 bool block); 23 27 void intel_dmc_start_pkgc_exit_at_start_of_undelayed_vblank(struct intel_display *display, ··· 36 32 void intel_dmc_snapshot_print(const struct intel_dmc_snapshot *snapshot, struct drm_printer *p); 37 33 void intel_dmc_update_dc6_allowed_count(struct intel_display *display, bool start_tracking); 38 34 39 - void assert_dmc_loaded(struct intel_display *display); 35 + void assert_main_dmc_loaded(struct intel_display *display); 36 + 37 + void intel_pipedmc_irq_handler(struct intel_display *display, enum pipe pipe); 38 + 39 + u32 intel_pipedmc_start_mmioaddr(struct intel_crtc *crtc); 40 + void intel_pipedmc_enable_event(struct intel_crtc *crtc, 41 + enum pipedmc_event_id event); 42 + void intel_pipedmc_disable_event(struct intel_crtc *crtc, 43 + enum pipedmc_event_id event); 40 44 41 45 void intel_pipedmc_irq_handler(struct intel_display *display, enum pipe pipe); 42 46
+190
drivers/gpu/drm/i915/display/intel_dmc_regs.h
··· 287 287 #define MTL_PIPEDMC_CONTROL _MMIO(0x45250) 288 288 #define PIPEDMC_ENABLE_MTL(pipe) REG_BIT(((pipe) - PIPE_A) * 4) 289 289 290 + #define _PIPEDMC_LOAD_HTP_A 0x5f000 291 + #define _PIPEDMC_LOAD_HTP_B 0x5f400 292 + #define PIPEDMC_LOAD_HTP(pipe) _MMIO_PIPE((pipe), _PIPEDMC_LOAD_HTP_A, _PIPEDMC_LOAD_HTP_B) 293 + 294 + #define _PIPEDMC_CTL_A 0x5f064 295 + #define _PIPEDMC_CTL_B 0x5f464 296 + #define PIPEDMC_CTL(pipe) _MMIO_PIPE((pipe), _PIPEDMC_CTL_A, _PIPEDMC_CTL_B) 297 + #define PIPEDMC_HALT REG_BIT(31) 298 + #define PIPEDMC_STEP REG_BIT(27) 299 + #define PIPEDMC_CLOCKGATE REG_BIT(23) 300 + 290 301 #define _PIPEDMC_STATUS_A 0x5f06c 291 302 #define _PIPEDMC_STATUS_B 0x5f46c 292 303 #define PIPEDMC_STATUS(pipe) _MMIO_PIPE((pipe), _PIPEDMC_STATUS_A, _PIPEDMC_STATUS_B) ··· 308 297 #define PIPEDMC_INT_VECTOR_DC6V_FLIPQ_OVERLAP_ERROR REG_FIELD_PREP(PIPEDMC_INT_VECTOR_MASK, 0x2) 309 298 #define PIPEDMC_INT_VECTOR_FLIPQ_PROG_DONE REG_FIELD_PREP(PIPEDMC_INT_VECTOR_MASK, 0xff) /* Wa_16018781658:lnl[a0] */ 310 299 #define PIPEDMC_EVT_PENDING REG_GENMASK(7, 0) 300 + 301 + #define _PIPEDMC_FQ_CTRL_A 0x5f078 302 + #define _PIPEDMC_FQ_CTRL_B 0x5f478 303 + #define PIPEDMC_FQ_CTRL(pipe) _MMIO_PIPE((pipe), _PIPEDMC_FQ_CTRL_A, _PIPEDMC_FQ_CTRL_B) 304 + #define PIPEDMC_FQ_CTRL_ENABLE REG_BIT(31) 305 + #define PIPEDMC_FQ_CTRL_ASYNC REG_BIT(29) 306 + #define PIPEDMC_FQ_CTRL_PREEMPT REG_BIT(0) 307 + 308 + #define _PIPEDMC_FQ_STATUS_A 0x5f098 309 + #define _PIPEDMC_FQ_STATUS_B 0x5f498 310 + #define PIPEDMC_FQ_STATUS(pipe) _MMIO_PIPE((pipe), _PIPEDMC_FQ_STATUS_A, _PIPEDMC_FQ_STATUS_B) 311 + #define PIPEDMC_FQ_STATUS_BUSY REG_BIT(31) 312 + #define PIPEDMC_FQ_STATUS_W2_LIVE_STATUS REG_BIT(1) 313 + #define PIPEDMC_FQ_STATUS_W1_LIVE_STATUS REG_BIT(0) 314 + 315 + #define _PIPEDMC_FPQ_ATOMIC_TP_A 0x5f0a0 316 + #define _PIPEDMC_FPQ_ATOMIC_TP_B 0x5f4a0 317 + #define PIPEDMC_FPQ_ATOMIC_TP(pipe) _MMIO_PIPE((pipe), _PIPEDMC_FPQ_ATOMIC_TP_A, _PIPEDMC_FPQ_ATOMIC_TP_B) 318 + #define PIPEDMC_FPQ_PLANEQ_3_TP_MASK REG_GENMASK(31, 26) 319 + #define PIPEDMC_FPQ_PLANEQ_3_TP(tail) REG_FIELD_PREP(PIPEDMC_FPQ_PLANEQ_3_TP_MASK, (tail)) 320 + #define PIPEDMC_FPQ_PLANEQ_2_TP_MASK REG_GENMASK(24, 19) 321 + #define PIPEDMC_FPQ_PLANEQ_2_TP(tail) REG_FIELD_PREP(PIPEDMC_FPQ_PLANEQ_2_TP_MASK, (tail)) 322 + #define PIPEDMC_FPQ_PLANEQ_1_TP_MASK REG_GENMASK(17, 12) 323 + #define PIPEDMC_FPQ_PLANEQ_1_TP(tail) REG_FIELD_PREP(PIPEDMC_FPQ_PLANEQ_1_TP_MASK, (tail)) 324 + #define PIPEDMC_FPQ_FASTQ_TP_MASK REG_GENMASK(10, 6) 325 + #define PIPEDMC_FPQ_FASTQ_TP(tail) REG_FIELD_PREP(PIPEDMC_FPQ_FASTQ_TP_MASK, (tail)) 326 + #define PIPEDMC_FPQ_GENERALQ_TP_MASK REG_GENMASK(4, 0) 327 + #define PIPEDMC_FPQ_GENERALQ_TP(tail) REG_FIELD_PREP(PIPEDMC_FPQ_GENERALQ_TP_MASK, (tail)) 328 + 329 + #define _PIPEDMC_FPQ_LINES_TO_W1_A 0x5f0a4 330 + #define _PIPEDMC_FPQ_LINES_TO_W1_B 0x5f4a4 331 + #define PIPEDMC_FPQ_LINES_TO_W1 _MMIO_PIPE((pipe), _PIPEDMC_FPQ_LINES_TO_W1_A, _PIPEDMC_FPQ_LINES_TO_W1_B) 332 + 333 + #define _PIPEDMC_FPQ_LINES_TO_W2_A 0x5f0a8 334 + #define _PIPEDMC_FPQ_LINES_TO_W2_B 0x5f4a8 335 + #define PIPEDMC_FPQ_LINES_TO_W2 _MMIO_PIPE((pipe), _PIPEDMC_FPQ_LINES_TO_W2_A, _PIPEDMC_FPQ_LINES_TO_W2_B) 336 + 337 + #define _PIPEDMC_SCANLINECMP_A 0x5f11c 338 + #define _PIPEDMC_SCANLINECMP_B 0x5f51c 339 + #define PIPEDMC_SCANLINECMP(pipe) _MMIO_PIPE((pipe), _PIPEDMC_SCANLINECMP_A, _PIPEDMC_SCANLINECMP_B) 340 + #define PIPEDMC_SCANLINECMP_EN REG_BIT(31) 341 + #define PIPEDMC_SCANLINE_NUMBER REG_GENMASK(20, 0) 342 + 343 + #define _PIPEDMC_SCANLINECMPLOWER_A 0x5f120 344 + #define _PIPEDMC_SCANLINECMPLOWER_B 0x5f520 345 + #define PIPEDMC_SCANLINECMPLOWER(pipe) _MMIO_PIPE((pipe), _PIPEDMC_SCANLINECMPLOWER_A, _PIPEDMC_SCANLINECMPLOWER_B) 346 + #define PIPEDMC_SCANLINEINRANGECMP_EN REG_BIT(31) 347 + #define PIPEDMC_SCANLINEOUTRANGECMP_EN REG_BIT(30) 348 + #define PIPEDMC_SCANLINE_LOWER_MASK REG_GENMASK(20, 0) 349 + #define PIPEDMC_SCANLINE_LOWER(scanline) REG_FIELD_PREP(PIPEDMC_SCANLINE_LOWER_MASK, (scanline)) 350 + 351 + #define _PIPEDMC_SCANLINECMPUPPER_A 0x5f124 352 + #define _PIPEDMC_SCANLINECMPUPPER_B 0x5f524 353 + #define PIPEDMC_SCANLINECMPUPPER(pipe) _MMIO_PIPE((pipe), _PIPEDMC_SCANLINECMPUPPER_A, _PIPEDMC_SCANLINECMPUPPER_B) 354 + #define PIPEDMC_SCANLINE_UPPER_MASK REG_GENMASK(20, 0) 355 + #define PIPEDMC_SCANLINE_UPPER(scanline) REG_FIELD_PREP(PIPEDMC_SCANLINE_UPPER_MASK, (scanline)) 356 + 357 + #define _MMIO_PIPEDMC_FPQ(pipe, fq_id, \ 358 + reg_fpq1_a, reg_fpq2_a, reg_fpq3_a, reg_fpq4_a, \ 359 + reg_fpq1_b, reg_fpq2_b, reg_fpq3_b, reg_fpq4_b) \ 360 + _MMIO(_PICK_EVEN_2RANGES((fq_id), INTEL_FLIPQ_PLANE_3, \ 361 + _PIPE((pipe), (reg_fpq1_a), (reg_fpq1_b)), \ 362 + _PIPE((pipe), (reg_fpq2_a), (reg_fpq2_b)), \ 363 + _PIPE((pipe), (reg_fpq3_a), (reg_fpq3_b)), \ 364 + _PIPE((pipe), (reg_fpq4_a), (reg_fpq4_b)))) 365 + 366 + #define _PIPEDMC_FPQ1_HP_A 0x5f128 367 + #define _PIPEDMC_FPQ2_HP_A 0x5f138 368 + #define _PIPEDMC_FPQ3_HP_A 0x5f168 369 + #define _PIPEDMC_FPQ4_HP_A 0x5f174 370 + #define _PIPEDMC_FPQ5_HP_A 0x5f180 371 + #define _PIPEDMC_FPQ1_HP_B 0x5f528 372 + #define _PIPEDMC_FPQ2_HP_B 0x5f538 373 + #define _PIPEDMC_FPQ3_HP_B 0x5f568 374 + #define _PIPEDMC_FPQ4_HP_B 0x5f574 375 + #define _PIPEDMC_FPQ5_HP_B 0x5f580 376 + #define PIPEDMC_FPQ_HP(pipe, fq_id) _MMIO_PIPEDMC_FPQ((pipe), (fq_id), \ 377 + _PIPEDMC_FPQ1_HP_A, _PIPEDMC_FPQ2_HP_A, \ 378 + _PIPEDMC_FPQ3_HP_A, _PIPEDMC_FPQ4_HP_A, \ 379 + _PIPEDMC_FPQ1_HP_B, _PIPEDMC_FPQ2_HP_B, \ 380 + _PIPEDMC_FPQ3_HP_B, _PIPEDMC_FPQ4_HP_B) 381 + 382 + #define _PIPEDMC_FPQ1_TP_A 0x5f12c 383 + #define _PIPEDMC_FPQ2_TP_A 0x5f13c 384 + #define _PIPEDMC_FPQ3_TP_A 0x5f16c 385 + #define _PIPEDMC_FPQ4_TP_A 0x5f178 386 + #define _PIPEDMC_FPQ5_TP_A 0x5f184 387 + #define _PIPEDMC_FPQ1_TP_B 0x5f52c 388 + #define _PIPEDMC_FPQ2_TP_B 0x5f53c 389 + #define _PIPEDMC_FPQ3_TP_B 0x5f56c 390 + #define _PIPEDMC_FPQ4_TP_B 0x5f578 391 + #define _PIPEDMC_FPQ5_TP_B 0x5f584 392 + #define PIPEDMC_FPQ_TP(pipe, fq_id) _MMIO_PIPEDMC_FPQ((pipe), (fq_id), \ 393 + _PIPEDMC_FPQ1_TP_A, _PIPEDMC_FPQ2_TP_A, \ 394 + _PIPEDMC_FPQ3_TP_A, _PIPEDMC_FPQ4_TP_A, \ 395 + _PIPEDMC_FPQ1_TP_B, _PIPEDMC_FPQ2_TP_B, \ 396 + _PIPEDMC_FPQ3_TP_B, _PIPEDMC_FPQ4_TP_B) 397 + 398 + #define _PIPEDMC_FPQ1_CHP_A 0x5f130 399 + #define _PIPEDMC_FPQ2_CHP_A 0x5f140 400 + #define _PIPEDMC_FPQ3_CHP_A 0x5f170 401 + #define _PIPEDMC_FPQ4_CHP_A 0x5f17c 402 + #define _PIPEDMC_FPQ5_CHP_A 0x5f188 403 + #define _PIPEDMC_FPQ1_CHP_B 0x5f530 404 + #define _PIPEDMC_FPQ2_CHP_B 0x5f540 405 + #define _PIPEDMC_FPQ3_CHP_B 0x5f570 406 + #define _PIPEDMC_FPQ4_CHP_B 0x5f57c 407 + #define _PIPEDMC_FPQ5_CHP_B 0x5f588 408 + #define PIPEDMC_FPQ_CHP(pipe, fq_id) _MMIO_PIPEDMC_FPQ((pipe), (fq_id), \ 409 + _PIPEDMC_FPQ1_CHP_A, _PIPEDMC_FPQ2_CHP_A, \ 410 + _PIPEDMC_FPQ3_CHP_A, _PIPEDMC_FPQ4_CHP_A, \ 411 + _PIPEDMC_FPQ1_CHP_B, _PIPEDMC_FPQ2_CHP_B, \ 412 + _PIPEDMC_FPQ3_CHP_B, _PIPEDMC_FPQ4_CHP_B) 413 + 414 + #define _PIPEDMC_FPQ_TS_A 0x5f134 415 + #define _PIPEDMC_FPQ_TS_B 0x5f534 416 + #define PIPEDMC_FPQ_TS(pipe) _MMIO_PIPE((pipe), _PIPEDMC_FPQ_TS_A, _PIPEDMC_FPQ_TS_B) 417 + 418 + #define _PIPEDMC_SCANLINE_RO_A 0x5f144 419 + #define _PIPEDMC_SCANLINE_RO_B 0x5f544 420 + #define PIPEDMC_SCANLINE_RO(pipe) _MMIO_PIPE((pipe), _PIPEDMC_SCANLINE_RO_A, _PIPEDMC_SCANLINE_RO_B) 421 + 422 + #define _PIPEDMC_FPQ_CTL1_A 0x5f160 423 + #define _PIPEDMC_FPQ_CTL1_B 0x5f560 424 + #define PIPEDMC_FPQ_CTL1(pipe) _MMIO_PIPE((pipe), _PIPEDMC_FPQ_CTL1_A, _PIPEDMC_FPQ_CTL1_B) 425 + #define PIPEDMC_SW_DMC_WAKE REG_BIT(0) 426 + 427 + #define _PIPEDMC_FPQ_CTL2_A 0x5f164 428 + #define _PIPEDMC_FPQ_CTL2_B 0x5f564 429 + #define PIPEDMC_FPQ_CTL2(pipe) _MMIO_PIPE((pipe), _PIPEDMC_FPQ_CTL2_A, _PIPEDMC_FPQ_CTL2_B) 430 + #define PIPEDMC_DMC_INT_AT_DELAYED_VBLANK REG_BIT(1) 431 + #define PIPEDMC_W1_DMC_WAKE REG_BIT(0) 311 432 312 433 #define _PIPEDMC_INTERRUPT_A 0x5f190 /* lnl+ */ 313 434 #define _PIPEDMC_INTERRUPT_B 0x5f590 /* lnl+ */ ··· 536 393 #define DMC_WAKELOCK1_CTL _MMIO(0x8F140) 537 394 #define DMC_WAKELOCK_CTL_REQ REG_BIT(31) 538 395 #define DMC_WAKELOCK_CTL_ACK REG_BIT(15) 396 + 397 + #define DMC_FQ_W2_PTS_CFG_SEL _MMIO(0x8f240) 398 + #define PIPE_D_DMC_W2_PTS_CONFIG_SELECT_MASK REG_GENMASK(26, 24) 399 + #define PIPE_D_DMC_W2_PTS_CONFIG_SELECT(pipe) REG_FIELD_PREP(PIPE_D_DMC_W2_PTS_CONFIG_SELECT_MASK, (pipe)) 400 + #define PIPE_C_DMC_W2_PTS_CONFIG_SELECT_MASK REG_GENMASK(18, 16) 401 + #define PIPE_C_DMC_W2_PTS_CONFIG_SELECT(pipe) REG_FIELD_PREP(PIPE_C_DMC_W2_PTS_CONFIG_SELECT_MASK, (pipe)) 402 + #define PIPE_B_DMC_W2_PTS_CONFIG_SELECT_MASK REG_GENMASK(10, 8) 403 + #define PIPE_B_DMC_W2_PTS_CONFIG_SELECT(pipe) REG_FIELD_PREP(PIPE_B_DMC_W2_PTS_CONFIG_SELECT_MASK, (pipe)) 404 + #define PIPE_A_DMC_W2_PTS_CONFIG_SELECT_MASK REG_GENMASK(2, 0) 405 + #define PIPE_A_DMC_W2_PTS_CONFIG_SELECT(pipe) REG_FIELD_PREP(PIPE_A_DMC_W2_PTS_CONFIG_SELECT_MASK, (pipe)) 406 + 407 + /* plane/general flip queue entries */ 408 + #define PIPEDMC_FQ_RAM(start_mmioaddr, i) _MMIO((start_mmioaddr) + (i) * 4) 409 + /* LNL */ 410 + /* DW0 pts */ 411 + /* DW1 head */ 412 + /* DW2 size/etc. */ 413 + #define LNL_FQ_INTERRUPT REG_BIT(31) 414 + #define LNL_FQ_DSB_ID_MASK REG_GENMASK(30, 29) 415 + #define LNL_FQ_DSB_ID(dsb_id) REG_FIELD_PREP(LNL_FQ_DSB_ID_MASK, (dsb_id)) 416 + #define LNL_FQ_EXECUTED REG_BIT(28) 417 + #define LNL_FQ_DSB_SIZE_MASK REG_GENMASK(15, 0) 418 + #define LNL_FQ_DSB_SIZE(size) REG_FIELD_PREP(LNL_FQ_DSB_SIZE_MASK, (size)) 419 + /* DW3 reserved (plane queues) */ 420 + /* DW3 second DSB head (general queue) */ 421 + /* DW4 second DSB size/etc. (general queue) */ 422 + /* DW5 reserved (general queue) */ 423 + 424 + /* PTL+ */ 425 + /* DW0 pts */ 426 + /* DW1 reserved */ 427 + /* DW2 size/etc. */ 428 + #define PTL_FQ_INTERRUPT REG_BIT(31) 429 + #define PTL_FQ_NEED_PUSH REG_BIT(30) 430 + #define PTL_FQ_BLOCK_PUSH REG_BIT(29) 431 + #define PTL_FQ_EXECUTED REG_BIT(28) 432 + #define PTL_FQ_DSB_ID_MASK REG_GENMASK(25, 24) 433 + #define PTL_FQ_DSB_ID(dsb_id) REG_FIELD_PREP(PTL_FQ_DSB_ID_MASK, (dsb_id)) 434 + #define PTL_FQ_DSB_SIZE_MASK REG_GENMASK(15, 0) 435 + #define PTL_FQ_DSB_SIZE(size) REG_FIELD_PREP(PTL_FQ_DSB_SIZE_MASK, (size)) 436 + /* DW3 head */ 437 + /* DW4 second DSB size/etc. (general queue) */ 438 + /* DW5 second DSB head (general queue) */ 439 + 440 + /* undocumented magic DMC variables */ 441 + #define PTL_PIPEDMC_EXEC_TIME_LINES(start_mmioaddr) _MMIO((start_mmioaddr) + 0x6b8) 442 + #define PTL_PIPEDMC_END_OF_EXEC_GB(start_mmioaddr) _MMIO((start_mmioaddr) + 0x6c0) 539 443 540 444 #endif /* __INTEL_DMC_REGS_H__ */
+1 -3
drivers/gpu/drm/i915/display/intel_dmc_wl.c
··· 7 7 8 8 #include <drm/drm_print.h> 9 9 10 - #include "i915_drv.h" 11 10 #include "intel_de.h" 12 11 #include "intel_display_regs.h" 13 12 #include "intel_dmc_regs.h" ··· 154 155 155 156 static void __intel_dmc_wl_release(struct intel_display *display) 156 157 { 157 - struct drm_i915_private *i915 = to_i915(display->drm); 158 158 struct intel_dmc_wl *wl = &display->wl; 159 159 160 160 WARN_ON(refcount_read(&wl->refcount)); 161 161 162 - queue_delayed_work(i915->unordered_wq, &wl->work, 162 + queue_delayed_work(display->wq.unordered, &wl->work, 163 163 msecs_to_jiffies(DMC_WAKELOCK_HOLD_TIME)); 164 164 } 165 165
+3
drivers/gpu/drm/i915/display/intel_dp.c
··· 3726 3726 3727 3727 memset(intel_dp->pcon_dsc_dpcd, 0, sizeof(intel_dp->pcon_dsc_dpcd)); 3728 3728 3729 + if (!drm_dp_is_branch(intel_dp->dpcd)) 3730 + return; 3731 + 3729 3732 if (drm_dp_dpcd_read(&intel_dp->aux, DP_PCON_DSC_ENCODER, 3730 3733 intel_dp->pcon_dsc_dpcd, 3731 3734 sizeof(intel_dp->pcon_dsc_dpcd)) < 0)
+17 -3
drivers/gpu/drm/i915/display/intel_dp_hdcp.c
··· 805 805 enum pipe pipe = (enum pipe)cpu_transcoder; 806 806 enum port port = dig_port->base.port; 807 807 int ret; 808 + u32 val; 809 + u8 stream_type; 808 810 809 - drm_WARN_ON(display->drm, enable && 810 - !!(intel_de_read(display, HDCP2_AUTH_STREAM(display, cpu_transcoder, port)) 811 - & AUTH_STREAM_TYPE) != data->streams[0].stream_type); 811 + if (DISPLAY_VER(display) < 30) { 812 + val = intel_de_read(display, 813 + HDCP2_AUTH_STREAM(display, cpu_transcoder, port)); 814 + stream_type = REG_FIELD_GET(AUTH_STREAM_TYPE_MASK, val); 815 + drm_WARN_ON(display->drm, enable && 816 + stream_type != data->streams[0].stream_type); 817 + } 812 818 813 819 ret = intel_dp_mst_toggle_hdcp_stream_select(connector, enable); 814 820 if (ret) ··· 828 822 drm_err(display->drm, "Timed out waiting for transcoder: %s stream encryption %s\n", 829 823 transcoder_name(cpu_transcoder), str_enabled_disabled(enable)); 830 824 return -ETIMEDOUT; 825 + } 826 + 827 + if (DISPLAY_VER(display) >= 30) { 828 + val = intel_de_read(display, 829 + HDCP2_STREAM_STATUS(display, cpu_transcoder, port)); 830 + stream_type = REG_FIELD_GET(STREAM_TYPE_STATUS_MASK, val); 831 + drm_WARN_ON(display->drm, enable && 832 + stream_type != data->streams[0].stream_type); 831 833 } 832 834 833 835 return 0;
+4 -3
drivers/gpu/drm/i915/display/intel_drrs.c
··· 5 5 6 6 #include <linux/debugfs.h> 7 7 8 - #include "i915_drv.h" 8 + #include <drm/drm_print.h> 9 + 9 10 #include "intel_atomic.h" 10 11 #include "intel_de.h" 11 12 #include "intel_display_regs.h" ··· 124 123 125 124 static void intel_drrs_schedule_work(struct intel_crtc *crtc) 126 125 { 127 - struct drm_i915_private *i915 = to_i915(crtc->base.dev); 126 + struct intel_display *display = to_intel_display(crtc); 128 127 129 - mod_delayed_work(i915->unordered_wq, &crtc->drrs.work, msecs_to_jiffies(1000)); 128 + mod_delayed_work(display->wq.unordered, &crtc->drrs.work, msecs_to_jiffies(1000)); 130 129 } 131 130 132 131 static unsigned int intel_drrs_frontbuffer_bits(const struct intel_crtc_state *crtc_state)
+2 -3
drivers/gpu/drm/i915/display/intel_encoder.c
··· 5 5 6 6 #include <linux/workqueue.h> 7 7 8 - #include "i915_drv.h" 9 8 #include "intel_display_core.h" 10 9 #include "intel_display_types.h" 11 10 #include "intel_encoder.h" ··· 31 32 32 33 void intel_encoder_link_check_queue_work(struct intel_encoder *encoder, int delay_ms) 33 34 { 34 - struct drm_i915_private *i915 = to_i915(encoder->base.dev); 35 + struct intel_display *display = to_intel_display(encoder); 35 36 36 - mod_delayed_work(i915->unordered_wq, 37 + mod_delayed_work(display->wq.unordered, 37 38 &encoder->link_check_work, msecs_to_jiffies(delay_ms)); 38 39 } 39 40
+4 -4
drivers/gpu/drm/i915/display/intel_fb.c
··· 11 11 #include <drm/drm_modeset_helper.h> 12 12 13 13 #include "i915_drv.h" 14 - #include "intel_atomic_plane.h" 15 14 #include "intel_bo.h" 16 15 #include "intel_display.h" 17 16 #include "intel_display_core.h" ··· 19 20 #include "intel_fb.h" 20 21 #include "intel_fb_bo.h" 21 22 #include "intel_frontbuffer.h" 23 + #include "intel_plane.h" 22 24 23 25 #define check_array_bounds(display, a, i) drm_WARN_ON((display)->drm, (i) >= ARRAY_SIZE(a)) 24 26 ··· 1286 1286 1287 1287 bool intel_plane_uses_fence(const struct intel_plane_state *plane_state) 1288 1288 { 1289 + struct intel_display *display = to_intel_display(plane_state); 1289 1290 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); 1290 - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); 1291 1291 1292 - return DISPLAY_VER(dev_priv) < 4 || 1292 + return DISPLAY_VER(display) < 4 || 1293 1293 (plane->fbc && !plane_state->no_fbc_reason && 1294 1294 plane_state->view.gtt.type == I915_GTT_VIEW_NORMAL); 1295 1295 } ··· 2346 2346 struct intel_framebuffer *intel_fb; 2347 2347 int ret; 2348 2348 2349 - intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); 2349 + intel_fb = intel_bo_alloc_framebuffer(); 2350 2350 if (!intel_fb) 2351 2351 return ERR_PTR(-ENOMEM); 2352 2352
+6 -1
drivers/gpu/drm/i915/display/intel_fb_pin.c
··· 11 11 #include "gem/i915_gem_object.h" 12 12 13 13 #include "i915_drv.h" 14 - #include "intel_atomic_plane.h" 15 14 #include "intel_display_core.h" 16 15 #include "intel_display_rpm.h" 17 16 #include "intel_display_types.h" 18 17 #include "intel_dpt.h" 19 18 #include "intel_fb.h" 20 19 #include "intel_fb_pin.h" 20 + #include "intel_plane.h" 21 21 22 22 static struct i915_vma * 23 23 intel_fb_pin_to_dpt(const struct drm_framebuffer *fb, ··· 333 333 if (vma) 334 334 intel_dpt_unpin_from_ggtt(fb->dpt_vm); 335 335 } 336 + } 337 + 338 + void intel_fb_get_map(struct i915_vma *vma, struct iosys_map *map) 339 + { 340 + iosys_map_set_vaddr_iomem(map, i915_vma_get_iomap(vma)); 336 341 }
+2
drivers/gpu/drm/i915/display/intel_fb_pin.h
··· 12 12 struct i915_vma; 13 13 struct intel_plane_state; 14 14 struct i915_gtt_view; 15 + struct iosys_map; 15 16 16 17 struct i915_vma * 17 18 intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb, ··· 28 27 int intel_plane_pin_fb(struct intel_plane_state *new_plane_state, 29 28 const struct intel_plane_state *old_plane_state); 30 29 void intel_plane_unpin_fb(struct intel_plane_state *old_plane_state); 30 + void intel_fb_get_map(struct i915_vma *vma, struct iosys_map *map); 31 31 32 32 #endif
+3 -3
drivers/gpu/drm/i915/display/intel_fbc.c
··· 1576 1576 if (IS_ERR(cdclk_state)) 1577 1577 return PTR_ERR(cdclk_state); 1578 1578 1579 - if (crtc_state->pixel_rate >= cdclk_state->logical.cdclk * 95 / 100) { 1579 + if (crtc_state->pixel_rate >= intel_cdclk_logical(cdclk_state) * 95 / 100) { 1580 1580 plane_state->no_fbc_reason = "pixel rate too high"; 1581 1581 return 0; 1582 1582 } ··· 2011 2011 2012 2012 static void __intel_fbc_handle_fifo_underrun_irq(struct intel_fbc *fbc) 2013 2013 { 2014 - struct drm_i915_private *i915 = to_i915(fbc->display->drm); 2014 + struct intel_display *display = fbc->display; 2015 2015 2016 2016 /* 2017 2017 * There's no guarantee that underrun_detected won't be set to true ··· 2024 2024 if (READ_ONCE(fbc->underrun_detected)) 2025 2025 return; 2026 2026 2027 - queue_work(i915->unordered_wq, &fbc->underrun_work); 2027 + queue_work(display->wq.unordered, &fbc->underrun_work); 2028 2028 } 2029 2029 2030 2030 /**
+5
drivers/gpu/drm/i915/display/intel_fbdev.c
··· 512 512 { 513 513 return fbdev ? fbdev->vma : NULL; 514 514 } 515 + 516 + void intel_fbdev_get_map(struct intel_fbdev *fbdev, struct iosys_map *map) 517 + { 518 + intel_fb_get_map(fbdev->vma, map); 519 + }
+5 -1
drivers/gpu/drm/i915/display/intel_fbdev.h
··· 13 13 struct intel_display; 14 14 struct intel_fbdev; 15 15 struct intel_framebuffer; 16 + struct iosys_map; 16 17 17 18 #ifdef CONFIG_DRM_FBDEV_EMULATION 18 19 int intel_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper, ··· 23 22 void intel_fbdev_setup(struct intel_display *display); 24 23 struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev); 25 24 struct i915_vma *intel_fbdev_vma_pointer(struct intel_fbdev *fbdev); 26 - 25 + void intel_fbdev_get_map(struct intel_fbdev *fbdev, struct iosys_map *map); 27 26 #else 28 27 #define INTEL_FBDEV_DRIVER_OPS \ 29 28 .fbdev_probe = NULL ··· 40 39 return NULL; 41 40 } 42 41 42 + static inline void intel_fbdev_get_map(struct intel_fbdev *fbdev, struct iosys_map *map) 43 + { 44 + } 43 45 #endif 44 46 45 47 #endif /* __INTEL_FBDEV_H__ */
+472
drivers/gpu/drm/i915/display/intel_flipq.c
··· 1 + // SPDX-License-Identifier: MIT 2 + /* 3 + * Copyright © 2025 Intel Corporation 4 + */ 5 + 6 + #include <linux/pci.h> 7 + 8 + #include <drm/drm_print.h> 9 + 10 + #include "i915_utils.h" 11 + #include "intel_step.h" 12 + #include "intel_crtc.h" 13 + #include "intel_de.h" 14 + #include "intel_display_core.h" 15 + #include "intel_display_types.h" 16 + #include "intel_flipq.h" 17 + #include "intel_dmc.h" 18 + #include "intel_dmc_regs.h" 19 + #include "intel_dsb.h" 20 + #include "intel_vblank.h" 21 + #include "intel_vrr.h" 22 + 23 + /** 24 + * DOC: DMC Flip Queue 25 + * 26 + * A flip queue is a ring buffer implemented by the pipe DMC firmware. 27 + * The driver inserts entries into the queues to be executed by the 28 + * pipe DMC at a specified presentation timestamp (PTS). 29 + * 30 + * Each pipe DMC provides several queues: 31 + * 32 + * - 1 general queue (two DSB buffers executed per entry) 33 + * - 3 plane queues (one DSB buffer executed per entry) 34 + * - 1 fast queue (deprecated) 35 + */ 36 + 37 + #define for_each_flipq(flipq_id) \ 38 + for ((flipq_id) = INTEL_FLIPQ_PLANE_1; (flipq_id) < MAX_INTEL_FLIPQ; (flipq_id)++) 39 + 40 + static int intel_flipq_offset(enum intel_flipq_id flipq_id) 41 + { 42 + switch (flipq_id) { 43 + case INTEL_FLIPQ_PLANE_1: 44 + return 0x008; 45 + case INTEL_FLIPQ_PLANE_2: 46 + return 0x108; 47 + case INTEL_FLIPQ_PLANE_3: 48 + return 0x208; 49 + case INTEL_FLIPQ_GENERAL: 50 + return 0x308; 51 + case INTEL_FLIPQ_FAST: 52 + return 0x3c8; 53 + default: 54 + MISSING_CASE(flipq_id); 55 + return 0; 56 + } 57 + } 58 + 59 + static int intel_flipq_size_dw(enum intel_flipq_id flipq_id) 60 + { 61 + switch (flipq_id) { 62 + case INTEL_FLIPQ_PLANE_1: 63 + case INTEL_FLIPQ_PLANE_2: 64 + case INTEL_FLIPQ_PLANE_3: 65 + return 64; 66 + case INTEL_FLIPQ_GENERAL: 67 + case INTEL_FLIPQ_FAST: 68 + return 48; 69 + default: 70 + MISSING_CASE(flipq_id); 71 + return 1; 72 + } 73 + } 74 + 75 + static int intel_flipq_elem_size_dw(enum intel_flipq_id flipq_id) 76 + { 77 + switch (flipq_id) { 78 + case INTEL_FLIPQ_PLANE_1: 79 + case INTEL_FLIPQ_PLANE_2: 80 + case INTEL_FLIPQ_PLANE_3: 81 + return 4; 82 + case INTEL_FLIPQ_GENERAL: 83 + case INTEL_FLIPQ_FAST: 84 + return 6; 85 + default: 86 + MISSING_CASE(flipq_id); 87 + return 1; 88 + } 89 + } 90 + 91 + static int intel_flipq_size_entries(enum intel_flipq_id flipq_id) 92 + { 93 + return intel_flipq_size_dw(flipq_id) / intel_flipq_elem_size_dw(flipq_id); 94 + } 95 + 96 + static void intel_flipq_crtc_init(struct intel_crtc *crtc) 97 + { 98 + struct intel_display *display = to_intel_display(crtc); 99 + enum intel_flipq_id flipq_id; 100 + 101 + for_each_flipq(flipq_id) { 102 + struct intel_flipq *flipq = &crtc->flipq[flipq_id]; 103 + 104 + flipq->start_mmioaddr = intel_pipedmc_start_mmioaddr(crtc) + intel_flipq_offset(flipq_id); 105 + flipq->flipq_id = flipq_id; 106 + 107 + drm_dbg_kms(display->drm, "[CRTC:%d:%s] FQ %d: start 0x%x\n", 108 + crtc->base.base.id, crtc->base.name, 109 + flipq_id, flipq->start_mmioaddr); 110 + } 111 + } 112 + 113 + bool intel_flipq_supported(struct intel_display *display) 114 + { 115 + if (!display->params.enable_flipq) 116 + return false; 117 + 118 + if (!display->dmc.dmc) 119 + return false; 120 + 121 + if (DISPLAY_VER(display) == 20) 122 + return true; 123 + 124 + /* DMC firmware expects VRR timing generator to be used */ 125 + return DISPLAY_VER(display) >= 30 && intel_vrr_always_use_vrr_tg(display); 126 + } 127 + 128 + void intel_flipq_init(struct intel_display *display) 129 + { 130 + struct intel_crtc *crtc; 131 + 132 + intel_dmc_wait_fw_load(display); 133 + 134 + for_each_intel_crtc(display->drm, crtc) 135 + intel_flipq_crtc_init(crtc); 136 + } 137 + 138 + static int cdclk_factor(struct intel_display *display) 139 + { 140 + if (DISPLAY_VER(display) >= 30) 141 + return 120; 142 + else 143 + return 280; 144 + } 145 + 146 + int intel_flipq_exec_time_us(struct intel_display *display) 147 + { 148 + return intel_dsb_exec_time_us() + 149 + DIV_ROUND_UP(display->cdclk.hw.cdclk * cdclk_factor(display), 540000) + 150 + display->sagv.block_time_us; 151 + } 152 + 153 + static int intel_flipq_preempt_timeout_ms(struct intel_display *display) 154 + { 155 + return DIV_ROUND_UP(intel_flipq_exec_time_us(display), 1000); 156 + } 157 + 158 + static void intel_flipq_preempt(struct intel_crtc *crtc, bool preempt) 159 + { 160 + struct intel_display *display = to_intel_display(crtc); 161 + 162 + intel_de_rmw(display, PIPEDMC_FQ_CTRL(crtc->pipe), 163 + PIPEDMC_FQ_CTRL_PREEMPT, preempt ? PIPEDMC_FQ_CTRL_PREEMPT : 0); 164 + 165 + if (preempt && 166 + intel_de_wait_for_clear(display, 167 + PIPEDMC_FQ_STATUS(crtc->pipe), 168 + PIPEDMC_FQ_STATUS_BUSY, 169 + intel_flipq_preempt_timeout_ms(display))) 170 + drm_err(display->drm, "[CRTC:%d:%s] flip queue preempt timeout\n", 171 + crtc->base.base.id, crtc->base.name); 172 + } 173 + 174 + static int intel_flipq_current_head(struct intel_crtc *crtc, enum intel_flipq_id flipq_id) 175 + { 176 + struct intel_display *display = to_intel_display(crtc); 177 + 178 + return intel_de_read(display, PIPEDMC_FPQ_CHP(crtc->pipe, flipq_id)); 179 + } 180 + 181 + static void intel_flipq_write_tail(struct intel_crtc *crtc) 182 + { 183 + struct intel_display *display = to_intel_display(crtc); 184 + 185 + intel_de_write(display, PIPEDMC_FPQ_ATOMIC_TP(crtc->pipe), 186 + PIPEDMC_FPQ_PLANEQ_3_TP(crtc->flipq[INTEL_FLIPQ_PLANE_3].tail) | 187 + PIPEDMC_FPQ_PLANEQ_2_TP(crtc->flipq[INTEL_FLIPQ_PLANE_2].tail) | 188 + PIPEDMC_FPQ_PLANEQ_1_TP(crtc->flipq[INTEL_FLIPQ_PLANE_1].tail) | 189 + PIPEDMC_FPQ_FASTQ_TP(crtc->flipq[INTEL_FLIPQ_FAST].tail) | 190 + PIPEDMC_FPQ_GENERALQ_TP(crtc->flipq[INTEL_FLIPQ_GENERAL].tail)); 191 + } 192 + 193 + static void intel_flipq_sw_dmc_wake(struct intel_crtc *crtc) 194 + { 195 + struct intel_display *display = to_intel_display(crtc); 196 + 197 + intel_de_write(display, PIPEDMC_FPQ_CTL1(crtc->pipe), PIPEDMC_SW_DMC_WAKE); 198 + } 199 + 200 + static int intel_flipq_exec_time_lines(const struct intel_crtc_state *crtc_state) 201 + { 202 + struct intel_display *display = to_intel_display(crtc_state); 203 + 204 + return intel_usecs_to_scanlines(&crtc_state->hw.adjusted_mode, 205 + intel_flipq_exec_time_us(display)); 206 + } 207 + 208 + void intel_flipq_dump(struct intel_crtc *crtc, 209 + enum intel_flipq_id flipq_id) 210 + { 211 + struct intel_display *display = to_intel_display(crtc); 212 + struct intel_flipq *flipq = &crtc->flipq[flipq_id]; 213 + u32 tmp; 214 + 215 + drm_dbg_kms(display->drm, 216 + "[CRTC:%d:%s] FQ %d @ 0x%x: ", 217 + crtc->base.base.id, crtc->base.name, flipq_id, 218 + flipq->start_mmioaddr); 219 + for (int i = 0 ; i < intel_flipq_size_dw(flipq_id); i++) { 220 + printk(KERN_CONT " 0x%08x", 221 + intel_de_read(display, PIPEDMC_FQ_RAM(flipq->start_mmioaddr, i))); 222 + if (i % intel_flipq_elem_size_dw(flipq_id) == intel_flipq_elem_size_dw(flipq_id) - 1) 223 + printk(KERN_CONT "\n"); 224 + } 225 + 226 + drm_dbg_kms(display->drm, 227 + "[CRTC:%d:%s] FQ %d: chp=0x%x, hp=0x%x\n", 228 + crtc->base.base.id, crtc->base.name, flipq_id, 229 + intel_de_read(display, PIPEDMC_FPQ_CHP(crtc->pipe, flipq_id)), 230 + intel_de_read(display, PIPEDMC_FPQ_HP(crtc->pipe, flipq_id))); 231 + 232 + drm_dbg_kms(display->drm, 233 + "[CRTC:%d:%s] FQ %d: current head %d\n", 234 + crtc->base.base.id, crtc->base.name, flipq_id, 235 + intel_flipq_current_head(crtc, flipq_id)); 236 + 237 + drm_dbg_kms(display->drm, 238 + "[CRTC:%d:%s] flip queue timestamp: 0x%x\n", 239 + crtc->base.base.id, crtc->base.name, 240 + intel_de_read(display, PIPEDMC_FPQ_TS(crtc->pipe))); 241 + 242 + tmp = intel_de_read(display, PIPEDMC_FPQ_ATOMIC_TP(crtc->pipe)); 243 + 244 + drm_dbg_kms(display->drm, 245 + "[CRTC:%d:%s] flip queue atomic tails: P3 %d, P2 %d, P1 %d, G %d, F %d\n", 246 + crtc->base.base.id, crtc->base.name, 247 + REG_FIELD_GET(PIPEDMC_FPQ_PLANEQ_3_TP_MASK, tmp), 248 + REG_FIELD_GET(PIPEDMC_FPQ_PLANEQ_2_TP_MASK, tmp), 249 + REG_FIELD_GET(PIPEDMC_FPQ_PLANEQ_1_TP_MASK, tmp), 250 + REG_FIELD_GET(PIPEDMC_FPQ_GENERALQ_TP_MASK, tmp), 251 + REG_FIELD_GET(PIPEDMC_FPQ_FASTQ_TP_MASK, tmp)); 252 + } 253 + 254 + void intel_flipq_reset(struct intel_display *display, enum pipe pipe) 255 + { 256 + struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe); 257 + enum intel_flipq_id flipq_id; 258 + 259 + intel_de_write(display, PIPEDMC_FQ_CTRL(pipe), 0); 260 + 261 + intel_de_write(display, PIPEDMC_SCANLINECMPLOWER(pipe), 0); 262 + intel_de_write(display, PIPEDMC_SCANLINECMPUPPER(pipe), 0); 263 + 264 + for_each_flipq(flipq_id) { 265 + struct intel_flipq *flipq = &crtc->flipq[flipq_id]; 266 + 267 + intel_de_write(display, PIPEDMC_FPQ_HP(pipe, flipq_id), 0); 268 + intel_de_write(display, PIPEDMC_FPQ_CHP(pipe, flipq_id), 0); 269 + 270 + flipq->tail = 0; 271 + } 272 + 273 + intel_de_write(display, PIPEDMC_FPQ_ATOMIC_TP(pipe), 0); 274 + } 275 + 276 + static enum pipedmc_event_id flipq_event_id(struct intel_display *display) 277 + { 278 + if (DISPLAY_VER(display) >= 30) 279 + return PIPEDMC_EVENT_FULL_FQ_WAKE_TRIGGER; 280 + else 281 + return PIPEDMC_EVENT_SCANLINE_INRANGE_FQ_TRIGGER; 282 + } 283 + 284 + void intel_flipq_enable(const struct intel_crtc_state *crtc_state) 285 + { 286 + struct intel_display *display = to_intel_display(crtc_state); 287 + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 288 + /* FIXME what to do with VRR? */ 289 + int scanline = intel_mode_vblank_start(&crtc_state->hw.adjusted_mode) - 290 + intel_flipq_exec_time_lines(crtc_state); 291 + 292 + if (DISPLAY_VER(display) >= 30) { 293 + u32 start_mmioaddr = intel_pipedmc_start_mmioaddr(crtc); 294 + 295 + /* undocumented magic DMC variables */ 296 + intel_de_write(display, PTL_PIPEDMC_EXEC_TIME_LINES(start_mmioaddr), 297 + intel_flipq_exec_time_lines(crtc_state)); 298 + intel_de_write(display, PTL_PIPEDMC_END_OF_EXEC_GB(start_mmioaddr), 299 + 100); 300 + } 301 + 302 + intel_de_write(display, PIPEDMC_SCANLINECMPUPPER(crtc->pipe), 303 + PIPEDMC_SCANLINE_UPPER(scanline)); 304 + intel_de_write(display, PIPEDMC_SCANLINECMPLOWER(crtc->pipe), 305 + PIPEDMC_SCANLINEINRANGECMP_EN | 306 + PIPEDMC_SCANLINE_LOWER(scanline - 2)); 307 + 308 + intel_pipedmc_enable_event(crtc, flipq_event_id(display)); 309 + 310 + intel_de_write(display, PIPEDMC_FQ_CTRL(crtc->pipe), PIPEDMC_FQ_CTRL_ENABLE); 311 + } 312 + 313 + void intel_flipq_disable(const struct intel_crtc_state *crtc_state) 314 + { 315 + struct intel_display *display = to_intel_display(crtc_state); 316 + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 317 + 318 + intel_flipq_preempt(crtc, true); 319 + 320 + intel_de_write(display, PIPEDMC_FQ_CTRL(crtc->pipe), 0); 321 + 322 + intel_pipedmc_disable_event(crtc, flipq_event_id(display)); 323 + 324 + intel_de_write(display, PIPEDMC_SCANLINECMPLOWER(crtc->pipe), 0); 325 + intel_de_write(display, PIPEDMC_SCANLINECMPUPPER(crtc->pipe), 0); 326 + } 327 + 328 + static bool assert_flipq_has_room(struct intel_crtc *crtc, 329 + enum intel_flipq_id flipq_id) 330 + { 331 + struct intel_display *display = to_intel_display(crtc); 332 + struct intel_flipq *flipq = &crtc->flipq[flipq_id]; 333 + int head, size = intel_flipq_size_entries(flipq_id); 334 + 335 + head = intel_flipq_current_head(crtc, flipq_id); 336 + 337 + return !drm_WARN(display->drm, 338 + (flipq->tail + size - head) % size >= size - 1, 339 + "[CRTC:%d:%s] FQ %d overflow (head %d, tail %d, size %d)\n", 340 + crtc->base.base.id, crtc->base.name, flipq_id, 341 + head, flipq->tail, size); 342 + } 343 + 344 + static void intel_flipq_write(struct intel_display *display, 345 + struct intel_flipq *flipq, u32 data, int i) 346 + { 347 + intel_de_write(display, PIPEDMC_FQ_RAM(flipq->start_mmioaddr, flipq->tail * 348 + intel_flipq_elem_size_dw(flipq->flipq_id) + i), data); 349 + } 350 + 351 + static void lnl_flipq_add(struct intel_display *display, 352 + struct intel_flipq *flipq, 353 + unsigned int pts, 354 + enum intel_dsb_id dsb_id, 355 + struct intel_dsb *dsb) 356 + { 357 + int i = 0; 358 + 359 + switch (flipq->flipq_id) { 360 + case INTEL_FLIPQ_GENERAL: 361 + intel_flipq_write(display, flipq, pts, i++); 362 + intel_flipq_write(display, flipq, intel_dsb_head(dsb), i++); 363 + intel_flipq_write(display, flipq, LNL_FQ_INTERRUPT | 364 + LNL_FQ_DSB_ID(dsb_id) | 365 + LNL_FQ_DSB_SIZE(intel_dsb_size(dsb) / 64), i++); 366 + intel_flipq_write(display, flipq, 0, i++); 367 + intel_flipq_write(display, flipq, 0, i++); /* head for second DSB */ 368 + intel_flipq_write(display, flipq, 0, i++); /* DSB engine + size for second DSB */ 369 + break; 370 + case INTEL_FLIPQ_PLANE_1: 371 + case INTEL_FLIPQ_PLANE_2: 372 + case INTEL_FLIPQ_PLANE_3: 373 + intel_flipq_write(display, flipq, pts, i++); 374 + intel_flipq_write(display, flipq, intel_dsb_head(dsb), i++); 375 + intel_flipq_write(display, flipq, LNL_FQ_INTERRUPT | 376 + LNL_FQ_DSB_ID(dsb_id) | 377 + LNL_FQ_DSB_SIZE(intel_dsb_size(dsb) / 64), i++); 378 + intel_flipq_write(display, flipq, 0, i++); 379 + break; 380 + default: 381 + MISSING_CASE(flipq->flipq_id); 382 + return; 383 + } 384 + } 385 + 386 + static void ptl_flipq_add(struct intel_display *display, 387 + struct intel_flipq *flipq, 388 + unsigned int pts, 389 + enum intel_dsb_id dsb_id, 390 + struct intel_dsb *dsb) 391 + { 392 + int i = 0; 393 + 394 + switch (flipq->flipq_id) { 395 + case INTEL_FLIPQ_GENERAL: 396 + intel_flipq_write(display, flipq, pts, i++); 397 + intel_flipq_write(display, flipq, 0, i++); 398 + intel_flipq_write(display, flipq, PTL_FQ_INTERRUPT | 399 + PTL_FQ_DSB_ID(dsb_id) | 400 + PTL_FQ_DSB_SIZE(intel_dsb_size(dsb) / 64), i++); 401 + intel_flipq_write(display, flipq, intel_dsb_head(dsb), i++); 402 + intel_flipq_write(display, flipq, 0, i++); /* DSB engine + size for second DSB */ 403 + intel_flipq_write(display, flipq, 0, i++); /* head for second DSB */ 404 + break; 405 + case INTEL_FLIPQ_PLANE_1: 406 + case INTEL_FLIPQ_PLANE_2: 407 + case INTEL_FLIPQ_PLANE_3: 408 + intel_flipq_write(display, flipq, pts, i++); 409 + intel_flipq_write(display, flipq, 0, i++); 410 + intel_flipq_write(display, flipq, PTL_FQ_INTERRUPT | 411 + PTL_FQ_DSB_ID(dsb_id) | 412 + PTL_FQ_DSB_SIZE(intel_dsb_size(dsb) / 64), i++); 413 + intel_flipq_write(display, flipq, intel_dsb_head(dsb), i++); 414 + break; 415 + default: 416 + MISSING_CASE(flipq->flipq_id); 417 + return; 418 + } 419 + } 420 + 421 + void intel_flipq_add(struct intel_crtc *crtc, 422 + enum intel_flipq_id flipq_id, 423 + unsigned int pts, 424 + enum intel_dsb_id dsb_id, 425 + struct intel_dsb *dsb) 426 + { 427 + struct intel_display *display = to_intel_display(crtc); 428 + struct intel_flipq *flipq = &crtc->flipq[flipq_id]; 429 + 430 + if (!assert_flipq_has_room(crtc, flipq_id)) 431 + return; 432 + 433 + pts += intel_de_read(display, PIPEDMC_FPQ_TS(crtc->pipe)); 434 + 435 + intel_flipq_preempt(crtc, true); 436 + 437 + if (DISPLAY_VER(display) >= 30) 438 + ptl_flipq_add(display, flipq, pts, dsb_id, dsb); 439 + else 440 + lnl_flipq_add(display, flipq, pts, dsb_id, dsb); 441 + 442 + flipq->tail = (flipq->tail + 1) % intel_flipq_size_entries(flipq->flipq_id); 443 + intel_flipq_write_tail(crtc); 444 + 445 + intel_flipq_preempt(crtc, false); 446 + 447 + intel_flipq_sw_dmc_wake(crtc); 448 + } 449 + 450 + /* Wa_18034343758 */ 451 + static bool need_dmc_halt_wa(struct intel_display *display) 452 + { 453 + return DISPLAY_VER(display) == 20 || 454 + (display->platform.pantherlake && 455 + IS_DISPLAY_STEP(display, STEP_A0, STEP_B0)); 456 + } 457 + 458 + void intel_flipq_wait_dmc_halt(struct intel_dsb *dsb, struct intel_crtc *crtc) 459 + { 460 + struct intel_display *display = to_intel_display(crtc); 461 + 462 + if (need_dmc_halt_wa(display)) 463 + intel_dsb_wait_usec(dsb, 2); 464 + } 465 + 466 + void intel_flipq_unhalt_dmc(struct intel_dsb *dsb, struct intel_crtc *crtc) 467 + { 468 + struct intel_display *display = to_intel_display(crtc); 469 + 470 + if (need_dmc_halt_wa(display)) 471 + intel_dsb_reg_write(dsb, PIPEDMC_CTL(crtc->pipe), 0); 472 + }
+37
drivers/gpu/drm/i915/display/intel_flipq.h
··· 1 + /* SPDX-License-Identifier: MIT */ 2 + /* 3 + * Copyright © 2025 Intel Corporation 4 + */ 5 + 6 + #ifndef __INTEL_FLIPQ_H__ 7 + #define __INTEL_FLIPQ_H__ 8 + 9 + #include <linux/types.h> 10 + 11 + enum intel_dsb_id; 12 + enum intel_flipq_id; 13 + enum pipe; 14 + struct intel_crtc; 15 + struct intel_crtc_state; 16 + struct intel_display; 17 + struct intel_dsb; 18 + 19 + bool intel_flipq_supported(struct intel_display *display); 20 + void intel_flipq_init(struct intel_display *display); 21 + void intel_flipq_reset(struct intel_display *display, enum pipe pipe); 22 + 23 + void intel_flipq_enable(const struct intel_crtc_state *crtc_state); 24 + void intel_flipq_disable(const struct intel_crtc_state *old_crtc_state); 25 + 26 + void intel_flipq_add(struct intel_crtc *crtc, 27 + enum intel_flipq_id flip_queue_id, 28 + unsigned int pts, 29 + enum intel_dsb_id dsb_id, 30 + struct intel_dsb *dsb); 31 + int intel_flipq_exec_time_us(struct intel_display *display); 32 + void intel_flipq_wait_dmc_halt(struct intel_dsb *dsb, struct intel_crtc *crtc); 33 + void intel_flipq_unhalt_dmc(struct intel_dsb *dsb, struct intel_crtc *crtc); 34 + void intel_flipq_dump(struct intel_crtc *crtc, 35 + enum intel_flipq_id flip_queue_id); 36 + 37 + #endif /* __INTEL_FLIPQ_H__ */
+12 -15
drivers/gpu/drm/i915/display/intel_hdcp.c
··· 14 14 #include <linux/random.h> 15 15 16 16 #include <drm/display/drm_hdcp_helper.h> 17 + #include <drm/drm_print.h> 17 18 #include <drm/intel/i915_component.h> 18 19 19 - #include "i915_drv.h" 20 20 #include "i915_reg.h" 21 + #include "i915_utils.h" 21 22 #include "intel_connector.h" 22 23 #include "intel_de.h" 23 24 #include "intel_display_power.h" ··· 33 32 #include "intel_hdcp_regs.h" 34 33 #include "intel_hdcp_shim.h" 35 34 #include "intel_pcode.h" 35 + #include "intel_step.h" 36 36 37 37 #define USE_HDCP_GSC(__display) (DISPLAY_VER(__display) >= 14) 38 38 ··· 376 374 377 375 static int intel_hdcp_load_keys(struct intel_display *display) 378 376 { 379 - struct drm_i915_private *i915 = to_i915(display->drm); 380 377 int ret; 381 378 u32 val; 382 379 ··· 400 399 * Mailbox interface. 401 400 */ 402 401 if (DISPLAY_VER(display) == 9 && !display->platform.broxton) { 403 - ret = snb_pcode_write(&i915->uncore, SKL_PCODE_LOAD_HDCP_KEYS, 1); 402 + ret = intel_pcode_write(display->drm, SKL_PCODE_LOAD_HDCP_KEYS, 1); 404 403 if (ret) { 405 404 drm_err(display->drm, 406 405 "Failed to initiate HDCP key load (%d)\n", ··· 1090 1089 u64 value, bool update_property) 1091 1090 { 1092 1091 struct intel_display *display = to_intel_display(connector); 1093 - struct drm_i915_private *i915 = to_i915(display->drm); 1094 1092 struct intel_digital_port *dig_port = intel_attached_dig_port(connector); 1095 1093 struct intel_hdcp *hdcp = &connector->hdcp; 1096 1094 ··· 1110 1110 hdcp->value = value; 1111 1111 if (update_property) { 1112 1112 drm_connector_get(&connector->base); 1113 - if (!queue_work(i915->unordered_wq, &hdcp->prop_work)) 1113 + if (!queue_work(display->wq.unordered, &hdcp->prop_work)) 1114 1114 drm_connector_put(&connector->base); 1115 1115 } 1116 1116 } ··· 2237 2237 check_work); 2238 2238 struct intel_connector *connector = intel_hdcp_to_connector(hdcp); 2239 2239 struct intel_display *display = to_intel_display(connector); 2240 - struct drm_i915_private *i915 = to_i915(display->drm); 2241 2240 2242 2241 if (drm_connector_is_unregistered(&connector->base)) 2243 2242 return; 2244 2243 2245 2244 if (!intel_hdcp2_check_link(connector)) 2246 - queue_delayed_work(i915->unordered_wq, &hdcp->check_work, 2245 + queue_delayed_work(display->wq.unordered, &hdcp->check_work, 2247 2246 DRM_HDCP2_CHECK_PERIOD_MS); 2248 2247 else if (!intel_hdcp_check_link(connector)) 2249 - queue_delayed_work(i915->unordered_wq, &hdcp->check_work, 2248 + queue_delayed_work(display->wq.unordered, &hdcp->check_work, 2250 2249 DRM_HDCP_CHECK_PERIOD_MS); 2251 2250 } 2252 2251 ··· 2436 2437 const struct drm_connector_state *conn_state) 2437 2438 { 2438 2439 struct intel_display *display = to_intel_display(encoder); 2439 - struct drm_i915_private *i915 = to_i915(display->drm); 2440 2440 struct intel_connector *connector = 2441 2441 to_intel_connector(conn_state->connector); 2442 2442 struct intel_digital_port *dig_port = intel_attached_dig_port(connector); ··· 2494 2496 } 2495 2497 2496 2498 if (!ret) { 2497 - queue_delayed_work(i915->unordered_wq, &hdcp->check_work, 2499 + queue_delayed_work(display->wq.unordered, &hdcp->check_work, 2498 2500 check_link_interval); 2499 2501 intel_hdcp_update_value(connector, 2500 2502 DRM_MODE_CONTENT_PROTECTION_ENABLED, ··· 2565 2567 to_intel_connector(conn_state->connector); 2566 2568 struct intel_hdcp *hdcp = &connector->hdcp; 2567 2569 bool content_protection_type_changed, desired_and_not_enabled = false; 2568 - struct drm_i915_private *i915 = to_i915(connector->base.dev); 2570 + struct intel_display *display = to_intel_display(connector); 2569 2571 2570 2572 if (!connector->hdcp.shim) 2571 2573 return; ··· 2592 2594 mutex_lock(&hdcp->mutex); 2593 2595 hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED; 2594 2596 drm_connector_get(&connector->base); 2595 - if (!queue_work(i915->unordered_wq, &hdcp->prop_work)) 2597 + if (!queue_work(display->wq.unordered, &hdcp->prop_work)) 2596 2598 drm_connector_put(&connector->base); 2597 2599 mutex_unlock(&hdcp->mutex); 2598 2600 } ··· 2610 2612 */ 2611 2613 if (!desired_and_not_enabled && !content_protection_type_changed) { 2612 2614 drm_connector_get(&connector->base); 2613 - if (!queue_work(i915->unordered_wq, &hdcp->prop_work)) 2615 + if (!queue_work(display->wq.unordered, &hdcp->prop_work)) 2614 2616 drm_connector_put(&connector->base); 2615 2617 2616 2618 } ··· 2734 2736 { 2735 2737 struct intel_hdcp *hdcp = &connector->hdcp; 2736 2738 struct intel_display *display = to_intel_display(connector); 2737 - struct drm_i915_private *i915 = to_i915(display->drm); 2738 2739 2739 2740 if (!hdcp->shim) 2740 2741 return; ··· 2741 2744 atomic_inc(&connector->hdcp.cp_irq_count); 2742 2745 wake_up_all(&connector->hdcp.cp_irq_queue); 2743 2746 2744 - queue_delayed_work(i915->unordered_wq, &hdcp->check_work, 0); 2747 + queue_delayed_work(display->wq.unordered, &hdcp->check_work, 0); 2745 2748 } 2746 2749 2747 2750 static void __intel_hdcp_info(struct seq_file *m, struct intel_connector *connector,
+2 -2
drivers/gpu/drm/i915/display/intel_hdcp_regs.h
··· 247 247 _TRANSA_HDCP2_STREAM_STATUS, \ 248 248 _TRANSB_HDCP2_STREAM_STATUS) 249 249 #define STREAM_ENCRYPTION_STATUS REG_BIT(31) 250 - #define STREAM_TYPE_STATUS REG_BIT(30) 250 + #define STREAM_TYPE_STATUS_MASK REG_GENMASK(30, 30) 251 251 #define HDCP2_STREAM_STATUS(dev_priv, trans, port) \ 252 252 (TRANS_HDCP(dev_priv) ? \ 253 253 TRANS_HDCP2_STREAM_STATUS(trans) : \ ··· 263 263 #define TRANS_HDCP2_AUTH_STREAM(trans) _MMIO_TRANS(trans, \ 264 264 _TRANSA_HDCP2_AUTH_STREAM, \ 265 265 _TRANSB_HDCP2_AUTH_STREAM) 266 - #define AUTH_STREAM_TYPE REG_BIT(31) 266 + #define AUTH_STREAM_TYPE_MASK REG_GENMASK(31, 31) 267 267 #define HDCP2_AUTH_STREAM(dev_priv, trans, port) \ 268 268 (TRANS_HDCP(dev_priv) ? \ 269 269 TRANS_HDCP2_AUTH_STREAM(trans) : \
+3 -9
drivers/gpu/drm/i915/display/intel_hotplug.c
··· 193 193 static bool 194 194 mod_delayed_detection_work(struct intel_display *display, struct delayed_work *work, int delay) 195 195 { 196 - struct drm_i915_private *i915 = to_i915(display->drm); 197 - 198 196 lockdep_assert_held(&display->irq.lock); 199 197 200 198 if (!detection_work_enabled(display)) 201 199 return false; 202 200 203 - return mod_delayed_work(i915->unordered_wq, work, delay); 201 + return mod_delayed_work(display->wq.unordered, work, delay); 204 202 } 205 203 206 204 static bool 207 205 queue_delayed_detection_work(struct intel_display *display, struct delayed_work *work, int delay) 208 206 { 209 - struct drm_i915_private *i915 = to_i915(display->drm); 210 - 211 207 lockdep_assert_held(&display->irq.lock); 212 208 213 209 if (!detection_work_enabled(display)) 214 210 return false; 215 211 216 - return queue_delayed_work(i915->unordered_wq, work, delay); 212 + return queue_delayed_work(display->wq.unordered, work, delay); 217 213 } 218 214 219 215 static bool 220 216 queue_detection_work(struct intel_display *display, struct work_struct *work) 221 217 { 222 - struct drm_i915_private *i915 = to_i915(display->drm); 223 - 224 218 lockdep_assert_held(&display->irq.lock); 225 219 226 220 if (!detection_work_enabled(display)) 227 221 return false; 228 222 229 - return queue_work(i915->unordered_wq, work); 223 + return queue_work(display->wq.unordered, work); 230 224 } 231 225 232 226 static void
+1 -1
drivers/gpu/drm/i915/display/intel_modeset_setup.c
··· 961 961 drm_crtc_vblank_reset(&crtc->base); 962 962 963 963 if (crtc_state->hw.active) { 964 - intel_dmc_enable_pipe(display, crtc->pipe); 964 + intel_dmc_enable_pipe(crtc_state); 965 965 intel_crtc_vblank_on(crtc_state); 966 966 } 967 967 }
+4 -3
drivers/gpu/drm/i915/display/intel_opregion.c
··· 31 31 #include <acpi/video.h> 32 32 33 33 #include <drm/drm_edid.h> 34 + #include <drm/drm_file.h> 35 + #include <drm/drm_print.h> 34 36 35 - #include "i915_drv.h" 37 + #include "i915_utils.h" 36 38 #include "intel_acpi.h" 37 39 #include "intel_backlight.h" 38 40 #include "intel_display_core.h" ··· 667 665 668 666 void intel_opregion_asle_intr(struct intel_display *display) 669 667 { 670 - struct drm_i915_private *i915 = to_i915(display->drm); 671 668 struct intel_opregion *opregion = display->opregion; 672 669 673 670 if (opregion && opregion->asle) 674 - queue_work(i915->unordered_wq, &opregion->asle_work); 671 + queue_work(display->wq.unordered, &opregion->asle_work); 675 672 } 676 673 677 674 #define ACPI_EV_DISPLAY_SWITCH (1<<0)
+3 -2
drivers/gpu/drm/i915/display/intel_panel.c
··· 502 502 drm_modeset_unlock(&display->drm->mode_config.connection_mutex); 503 503 } 504 504 505 - const struct drm_panel_funcs dummy_panel_funcs = { 505 + static const struct drm_panel_funcs dummy_panel_funcs = { 506 506 }; 507 507 508 508 int intel_panel_register(struct intel_connector *connector) ··· 515 515 if (ret) 516 516 return ret; 517 517 518 - if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI) { 518 + if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI || 519 + connector->base.connector_type == DRM_MODE_CONNECTOR_eDP) { 519 520 struct device *dev = connector->base.kdev; 520 521 struct drm_panel *base; 521 522
+1 -1
drivers/gpu/drm/i915/display/intel_plane_initial.c
··· 6 6 #include "gem/i915_gem_lmem.h" 7 7 #include "gem/i915_gem_region.h" 8 8 #include "i915_drv.h" 9 - #include "intel_atomic_plane.h" 10 9 #include "intel_crtc.h" 11 10 #include "intel_display.h" 12 11 #include "intel_display_core.h" 13 12 #include "intel_display_types.h" 14 13 #include "intel_fb.h" 15 14 #include "intel_frontbuffer.h" 15 + #include "intel_plane.h" 16 16 #include "intel_plane_initial.h" 17 17 18 18 void intel_plane_initial_vblank_wait(struct intel_crtc *crtc)
+9 -32
drivers/gpu/drm/i915/display/intel_pmdemand.c
··· 294 294 295 295 static bool intel_pmdemand_needs_update(struct intel_atomic_state *state) 296 296 { 297 - struct intel_display *display = to_intel_display(state); 298 - const struct intel_bw_state *new_bw_state, *old_bw_state; 299 - const struct intel_cdclk_state *new_cdclk_state, *old_cdclk_state; 300 297 const struct intel_crtc_state *new_crtc_state, *old_crtc_state; 301 - const struct intel_dbuf_state *new_dbuf_state, *old_dbuf_state; 302 298 struct intel_crtc *crtc; 303 299 int i; 304 300 305 - new_bw_state = intel_atomic_get_new_bw_state(state); 306 - old_bw_state = intel_atomic_get_old_bw_state(state); 307 - if (new_bw_state && new_bw_state->qgv_point_peakbw != 308 - old_bw_state->qgv_point_peakbw) 301 + if (intel_bw_pmdemand_needs_update(state)) 309 302 return true; 310 303 311 - new_dbuf_state = intel_atomic_get_new_dbuf_state(state); 312 - old_dbuf_state = intel_atomic_get_old_dbuf_state(state); 313 - if (new_dbuf_state && 314 - new_dbuf_state->active_pipes != old_dbuf_state->active_pipes) 304 + if (intel_dbuf_pmdemand_needs_update(state)) 315 305 return true; 316 306 317 - if (DISPLAY_VER(display) < 30) { 318 - if (new_dbuf_state && 319 - new_dbuf_state->enabled_slices != 320 - old_dbuf_state->enabled_slices) 321 - return true; 322 - } 323 - 324 - new_cdclk_state = intel_atomic_get_new_cdclk_state(state); 325 - old_cdclk_state = intel_atomic_get_old_cdclk_state(state); 326 - if (new_cdclk_state && 327 - (new_cdclk_state->actual.cdclk != 328 - old_cdclk_state->actual.cdclk || 329 - new_cdclk_state->actual.voltage_level != 330 - old_cdclk_state->actual.voltage_level)) 307 + if (intel_cdclk_pmdemand_needs_update(state)) 331 308 return true; 332 309 333 310 for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, ··· 339 362 340 363 /* firmware will calculate the qclk_gv_index, requirement is set to 0 */ 341 364 new_pmdemand_state->params.qclk_gv_index = 0; 342 - new_pmdemand_state->params.qclk_gv_bw = new_bw_state->qgv_point_peakbw; 365 + new_pmdemand_state->params.qclk_gv_bw = intel_bw_qgv_point_peakbw(new_bw_state); 343 366 344 367 new_dbuf_state = intel_atomic_get_dbuf_state(state); 345 368 if (IS_ERR(new_dbuf_state)) ··· 347 370 348 371 if (DISPLAY_VER(display) < 30) { 349 372 new_pmdemand_state->params.active_dbufs = 350 - min_t(u8, hweight8(new_dbuf_state->enabled_slices), 3); 373 + min_t(u8, intel_dbuf_num_enabled_slices(new_dbuf_state), 3); 351 374 new_pmdemand_state->params.active_pipes = 352 - min_t(u8, hweight8(new_dbuf_state->active_pipes), 3); 375 + min_t(u8, intel_dbuf_num_active_pipes(new_dbuf_state), 3); 353 376 } else { 354 377 new_pmdemand_state->params.active_pipes = 355 - min_t(u8, hweight8(new_dbuf_state->active_pipes), INTEL_NUM_PIPES(display)); 378 + min_t(u8, intel_dbuf_num_active_pipes(new_dbuf_state), INTEL_NUM_PIPES(display)); 356 379 } 357 380 358 381 new_cdclk_state = intel_atomic_get_cdclk_state(state); ··· 360 383 return PTR_ERR(new_cdclk_state); 361 384 362 385 new_pmdemand_state->params.voltage_index = 363 - new_cdclk_state->actual.voltage_level; 386 + intel_cdclk_actual_voltage_level(new_cdclk_state); 364 387 new_pmdemand_state->params.cdclk_freq_mhz = 365 - DIV_ROUND_UP(new_cdclk_state->actual.cdclk, 1000); 388 + DIV_ROUND_UP(intel_cdclk_actual(new_cdclk_state), 1000); 366 389 367 390 intel_pmdemand_update_max_ddiclk(display, state, new_pmdemand_state); 368 391
+4 -3
drivers/gpu/drm/i915/display/intel_pps.c
··· 5 5 6 6 #include <linux/debugfs.h> 7 7 8 + #include <drm/drm_print.h> 9 + 8 10 #include "g4x_dp.h" 9 - #include "i915_drv.h" 10 11 #include "i915_reg.h" 12 + #include "i915_utils.h" 11 13 #include "intel_de.h" 12 14 #include "intel_display_power_well.h" 13 15 #include "intel_display_regs.h" ··· 894 892 static void edp_panel_vdd_schedule_off(struct intel_dp *intel_dp) 895 893 { 896 894 struct intel_display *display = to_intel_display(intel_dp); 897 - struct drm_i915_private *i915 = to_i915(display->drm); 898 895 unsigned long delay; 899 896 900 897 /* ··· 909 908 * operations. 910 909 */ 911 910 delay = msecs_to_jiffies(intel_dp->pps.panel_power_cycle_delay * 5); 912 - queue_delayed_work(i915->unordered_wq, 911 + queue_delayed_work(display->wq.unordered, 913 912 &intel_dp->pps.panel_vdd_work, delay); 914 913 } 915 914
+24 -7
drivers/gpu/drm/i915/display/intel_psr.c
··· 28 28 #include <drm/drm_debugfs.h> 29 29 #include <drm/drm_vblank.h> 30 30 31 - #include "i915_drv.h" 32 31 #include "i915_reg.h" 33 32 #include "intel_alpm.h" 34 33 #include "intel_atomic.h" ··· 47 48 #include "intel_psr.h" 48 49 #include "intel_psr_regs.h" 49 50 #include "intel_snps_phy.h" 51 + #include "intel_step.h" 50 52 #include "intel_vblank.h" 51 53 #include "intel_vrr.h" 52 54 #include "skl_universal_plane.h" ··· 448 448 void intel_psr_irq_handler(struct intel_dp *intel_dp, u32 psr_iir) 449 449 { 450 450 struct intel_display *display = to_intel_display(intel_dp); 451 - struct drm_i915_private *dev_priv = to_i915(display->drm); 452 451 enum transcoder cpu_transcoder = intel_dp->psr.transcoder; 453 452 ktime_t time_ns = ktime_get(); 454 453 ··· 492 493 intel_de_rmw(display, psr_imr_reg(display, cpu_transcoder), 493 494 0, psr_irq_psr_error_bit_get(intel_dp)); 494 495 495 - queue_work(dev_priv->unordered_wq, &intel_dp->psr.work); 496 + queue_work(display->wq.unordered, &intel_dp->psr.work); 496 497 } 497 498 } 498 499 ··· 2888 2889 return 0; 2889 2890 } 2890 2891 2892 + void intel_psr2_panic_force_full_update(struct intel_display *display, 2893 + struct intel_crtc_state *crtc_state) 2894 + { 2895 + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 2896 + enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; 2897 + u32 val = man_trk_ctl_enable_bit_get(display); 2898 + 2899 + /* SF partial frame enable has to be set even on full update */ 2900 + val |= man_trk_ctl_partial_frame_bit_get(display); 2901 + val |= man_trk_ctl_continuos_full_frame(display); 2902 + 2903 + /* Directly write the register */ 2904 + intel_de_write_fw(display, PSR2_MAN_TRK_CTL(display, cpu_transcoder), val); 2905 + 2906 + if (!crtc_state->enable_psr2_su_region_et) 2907 + return; 2908 + 2909 + intel_de_write_fw(display, PIPE_SRCSZ_ERLY_TPT(crtc->pipe), 0); 2910 + } 2911 + 2891 2912 void intel_psr_pre_plane_update(struct intel_atomic_state *state, 2892 2913 struct intel_crtc *crtc) 2893 2914 { ··· 3339 3320 enum fb_op_origin origin) 3340 3321 { 3341 3322 struct intel_display *display = to_intel_display(intel_dp); 3342 - struct drm_i915_private *i915 = to_i915(display->drm); 3343 3323 3344 3324 if (!intel_dp->psr.dc3co_exitline || !intel_dp->psr.sel_update_enabled || 3345 3325 !intel_dp->psr.active) ··· 3353 3335 return; 3354 3336 3355 3337 tgl_psr2_enable_dc3co(intel_dp); 3356 - mod_delayed_work(i915->unordered_wq, &intel_dp->psr.dc3co_work, 3338 + mod_delayed_work(display->wq.unordered, &intel_dp->psr.dc3co_work, 3357 3339 intel_dp->psr.dc3co_exit_delay); 3358 3340 } 3359 3341 3360 3342 static void _psr_flush_handle(struct intel_dp *intel_dp) 3361 3343 { 3362 3344 struct intel_display *display = to_intel_display(intel_dp); 3363 - struct drm_i915_private *dev_priv = to_i915(display->drm); 3364 3345 3365 3346 if (intel_dp->psr.psr2_sel_fetch_enabled) { 3366 3347 if (intel_dp->psr.psr2_sel_fetch_cff_enabled) { ··· 3384 3367 3385 3368 if (!intel_dp->psr.psr2_sel_fetch_enabled && !intel_dp->psr.active && 3386 3369 !intel_dp->psr.busy_frontbuffer_bits) 3387 - queue_work(dev_priv->unordered_wq, &intel_dp->psr.work); 3370 + queue_work(display->wq.unordered, &intel_dp->psr.work); 3388 3371 } 3389 3372 3390 3373 /**
+2
drivers/gpu/drm/i915/display/intel_psr.h
··· 57 57 struct intel_crtc *crtc); 58 58 void intel_psr2_program_trans_man_trk_ctl(struct intel_dsb *dsb, 59 59 const struct intel_crtc_state *crtc_state); 60 + void intel_psr2_panic_force_full_update(struct intel_display *display, 61 + struct intel_crtc_state *crtc_state); 60 62 void intel_psr_pause(struct intel_dp *intel_dp); 61 63 void intel_psr_resume(struct intel_dp *intel_dp); 62 64 bool intel_psr_needs_vblank_notification(const struct intel_crtc_state *crtc_state);
+4 -4
drivers/gpu/drm/i915/display/intel_snps_hdmi_pll.c
··· 103 103 DIV_ROUND_DOWN_ULL(curve_1_interpolated, CURVE0_MULTIPLIER))); 104 104 105 105 ana_cp_int_temp = 106 - DIV_ROUND_CLOSEST_ULL(DIV_ROUND_DOWN_ULL(adjusted_vco_clk1, curve_2_scaled1), 107 - CURVE2_MULTIPLIER); 106 + DIV64_U64_ROUND_CLOSEST(DIV_ROUND_DOWN_ULL(adjusted_vco_clk1, curve_2_scaled1), 107 + CURVE2_MULTIPLIER); 108 108 109 - *ana_cp_int = max(1, min(ana_cp_int_temp, 127)); 109 + *ana_cp_int = clamp(ana_cp_int_temp, 1, 127); 110 110 111 111 curve_2_scaled_int = curve_2_scaled1 * (*ana_cp_int); 112 112 ··· 125 125 curve_1_interpolated); 126 126 127 127 *ana_cp_prop = DIV64_U64_ROUND_UP(adjusted_vco_clk2, curve_2_scaled2); 128 - *ana_cp_prop = max(1, min(*ana_cp_prop, 127)); 128 + *ana_cp_prop = clamp(*ana_cp_prop, 1, 127); 129 129 } 130 130 131 131 static void compute_hdmi_tmds_pll(u64 pixel_clock, u32 refclk,
+7 -7
drivers/gpu/drm/i915/display/intel_sprite.c
··· 41 41 42 42 #include "i915_utils.h" 43 43 #include "i9xx_plane.h" 44 - #include "intel_atomic_plane.h" 45 44 #include "intel_de.h" 46 45 #include "intel_display_types.h" 47 46 #include "intel_fb.h" 48 47 #include "intel_frontbuffer.h" 48 + #include "intel_plane.h" 49 49 #include "intel_sprite.h" 50 50 #include "intel_sprite_regs.h" 51 51 ··· 1366 1366 } 1367 1367 } 1368 1368 1369 - ret = intel_atomic_plane_check_clipping(plane_state, crtc_state, 1370 - min_scale, max_scale, true); 1369 + ret = intel_plane_check_clipping(plane_state, crtc_state, 1370 + min_scale, max_scale, true); 1371 1371 if (ret) 1372 1372 return ret; 1373 1373 ··· 1421 1421 if (ret) 1422 1422 return ret; 1423 1423 1424 - ret = intel_atomic_plane_check_clipping(plane_state, crtc_state, 1425 - DRM_PLANE_NO_SCALING, 1426 - DRM_PLANE_NO_SCALING, 1427 - true); 1424 + ret = intel_plane_check_clipping(plane_state, crtc_state, 1425 + DRM_PLANE_NO_SCALING, 1426 + DRM_PLANE_NO_SCALING, 1427 + true); 1428 1428 if (ret) 1429 1429 return ret; 1430 1430
+57 -64
drivers/gpu/drm/i915/display/intel_vrr_regs.h
··· 8 8 9 9 #include "intel_display_reg_defs.h" 10 10 11 - /* VRR registers */ 12 11 #define _TRANS_VRR_CTL_A 0x60420 13 12 #define _TRANS_VRR_CTL_B 0x61420 14 13 #define _TRANS_VRR_CTL_C 0x62420 15 14 #define _TRANS_VRR_CTL_D 0x63420 16 - #define TRANS_VRR_CTL(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_VRR_CTL_A) 17 - #define VRR_CTL_VRR_ENABLE REG_BIT(31) 18 - #define VRR_CTL_IGN_MAX_SHIFT REG_BIT(30) 19 - #define VRR_CTL_FLIP_LINE_EN REG_BIT(29) 20 - #define VRR_CTL_PIPELINE_FULL_MASK REG_GENMASK(10, 3) 21 - #define VRR_CTL_PIPELINE_FULL(x) REG_FIELD_PREP(VRR_CTL_PIPELINE_FULL_MASK, (x)) 22 - #define VRR_CTL_PIPELINE_FULL_OVERRIDE REG_BIT(0) 23 - #define XELPD_VRR_CTL_VRR_GUARDBAND_MASK REG_GENMASK(15, 0) 24 - #define XELPD_VRR_CTL_VRR_GUARDBAND(x) REG_FIELD_PREP(XELPD_VRR_CTL_VRR_GUARDBAND_MASK, (x)) 15 + #define TRANS_VRR_CTL(display, trans) _MMIO_TRANS2((display), (trans), _TRANS_VRR_CTL_A) 16 + #define VRR_CTL_VRR_ENABLE REG_BIT(31) 17 + #define VRR_CTL_IGN_MAX_SHIFT REG_BIT(30) 18 + #define VRR_CTL_FLIP_LINE_EN REG_BIT(29) 19 + #define VRR_CTL_CMRR_ENABLE REG_BIT(27) 20 + #define VRR_CTL_PIPELINE_FULL_MASK REG_GENMASK(10, 3) 21 + #define VRR_CTL_PIPELINE_FULL(x) REG_FIELD_PREP(VRR_CTL_PIPELINE_FULL_MASK, (x)) 22 + #define VRR_CTL_PIPELINE_FULL_OVERRIDE REG_BIT(0) 23 + #define XELPD_VRR_CTL_VRR_GUARDBAND_MASK REG_GENMASK(15, 0) 24 + #define XELPD_VRR_CTL_VRR_GUARDBAND(x) REG_FIELD_PREP(XELPD_VRR_CTL_VRR_GUARDBAND_MASK, (x)) 25 25 26 26 #define _TRANS_VRR_VMAX_A 0x60424 27 27 #define _TRANS_VRR_VMAX_B 0x61424 28 28 #define _TRANS_VRR_VMAX_C 0x62424 29 29 #define _TRANS_VRR_VMAX_D 0x63424 30 - #define TRANS_VRR_VMAX(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_VRR_VMAX_A) 31 - #define VRR_VMAX_MASK REG_GENMASK(19, 0) 30 + #define TRANS_VRR_VMAX(display, trans) _MMIO_TRANS2((display), (trans), _TRANS_VRR_VMAX_A) 31 + #define VRR_VMAX_MASK REG_GENMASK(19, 0) 32 32 33 33 #define _TRANS_VRR_VMIN_A 0x60434 34 34 #define _TRANS_VRR_VMIN_B 0x61434 35 35 #define _TRANS_VRR_VMIN_C 0x62434 36 36 #define _TRANS_VRR_VMIN_D 0x63434 37 - #define TRANS_VRR_VMIN(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_VRR_VMIN_A) 38 - #define VRR_VMIN_MASK REG_GENMASK(15, 0) 37 + #define TRANS_VRR_VMIN(display, trans) _MMIO_TRANS2((display), (trans), _TRANS_VRR_VMIN_A) 38 + #define VRR_VMIN_MASK REG_GENMASK(15, 0) 39 39 40 40 #define _TRANS_VRR_VMAXSHIFT_A 0x60428 41 41 #define _TRANS_VRR_VMAXSHIFT_B 0x61428 42 42 #define _TRANS_VRR_VMAXSHIFT_C 0x62428 43 43 #define _TRANS_VRR_VMAXSHIFT_D 0x63428 44 - #define TRANS_VRR_VMAXSHIFT(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, \ 45 - _TRANS_VRR_VMAXSHIFT_A) 46 - #define VRR_VMAXSHIFT_DEC_MASK REG_GENMASK(29, 16) 47 - #define VRR_VMAXSHIFT_DEC REG_BIT(16) 48 - #define VRR_VMAXSHIFT_INC_MASK REG_GENMASK(12, 0) 44 + #define TRANS_VRR_VMAXSHIFT(display, trans) _MMIO_TRANS2((display), (trans), _TRANS_VRR_VMAXSHIFT_A) 45 + #define VRR_VMAXSHIFT_DEC_MASK REG_GENMASK(29, 16) 46 + #define VRR_VMAXSHIFT_DEC REG_BIT(16) 47 + #define VRR_VMAXSHIFT_INC_MASK REG_GENMASK(12, 0) 49 48 50 49 #define _TRANS_VRR_STATUS_A 0x6042c 51 50 #define _TRANS_VRR_STATUS_B 0x6142c 52 51 #define _TRANS_VRR_STATUS_C 0x6242c 53 52 #define _TRANS_VRR_STATUS_D 0x6342c 54 - #define TRANS_VRR_STATUS(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_VRR_STATUS_A) 55 - #define VRR_STATUS_VMAX_REACHED REG_BIT(31) 56 - #define VRR_STATUS_NOFLIP_TILL_BNDR REG_BIT(30) 57 - #define VRR_STATUS_FLIP_BEF_BNDR REG_BIT(29) 58 - #define VRR_STATUS_NO_FLIP_FRAME REG_BIT(28) 59 - #define VRR_STATUS_VRR_EN_LIVE REG_BIT(27) 60 - #define VRR_STATUS_FLIPS_SERVICED REG_BIT(26) 61 - #define VRR_STATUS_VBLANK_MASK REG_GENMASK(22, 20) 62 - #define STATUS_FSM_IDLE REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 0) 63 - #define STATUS_FSM_WAIT_TILL_FDB REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 1) 64 - #define STATUS_FSM_WAIT_TILL_FS REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 2) 65 - #define STATUS_FSM_WAIT_TILL_FLIP REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 3) 66 - #define STATUS_FSM_PIPELINE_FILL REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 4) 67 - #define STATUS_FSM_ACTIVE REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 5) 68 - #define STATUS_FSM_LEGACY_VBLANK REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 6) 53 + #define TRANS_VRR_STATUS(display, trans) _MMIO_TRANS2((display), (trans), _TRANS_VRR_STATUS_A) 54 + #define VRR_STATUS_VMAX_REACHED REG_BIT(31) 55 + #define VRR_STATUS_NOFLIP_TILL_BNDR REG_BIT(30) 56 + #define VRR_STATUS_FLIP_BEF_BNDR REG_BIT(29) 57 + #define VRR_STATUS_NO_FLIP_FRAME REG_BIT(28) 58 + #define VRR_STATUS_VRR_EN_LIVE REG_BIT(27) 59 + #define VRR_STATUS_FLIPS_SERVICED REG_BIT(26) 60 + #define VRR_STATUS_VBLANK_MASK REG_GENMASK(22, 20) 61 + #define STATUS_FSM_IDLE REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 0) 62 + #define STATUS_FSM_WAIT_TILL_FDB REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 1) 63 + #define STATUS_FSM_WAIT_TILL_FS REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 2) 64 + #define STATUS_FSM_WAIT_TILL_FLIP REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 3) 65 + #define STATUS_FSM_PIPELINE_FILL REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 4) 66 + #define STATUS_FSM_ACTIVE REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 5) 67 + #define STATUS_FSM_LEGACY_VBLANK REG_FIELD_PREP(VRR_STATUS_VBLANK_MASK, 6) 69 68 70 69 #define _TRANS_VRR_VTOTAL_PREV_A 0x60480 71 70 #define _TRANS_VRR_VTOTAL_PREV_B 0x61480 72 71 #define _TRANS_VRR_VTOTAL_PREV_C 0x62480 73 72 #define _TRANS_VRR_VTOTAL_PREV_D 0x63480 74 - #define TRANS_VRR_VTOTAL_PREV(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, \ 75 - _TRANS_VRR_VTOTAL_PREV_A) 76 - #define VRR_VTOTAL_FLIP_BEFR_BNDR REG_BIT(31) 77 - #define VRR_VTOTAL_FLIP_AFTER_BNDR REG_BIT(30) 78 - #define VRR_VTOTAL_FLIP_AFTER_DBLBUF REG_BIT(29) 79 - #define VRR_VTOTAL_PREV_FRAME_MASK REG_GENMASK(19, 0) 73 + #define TRANS_VRR_VTOTAL_PREV(display, trans) _MMIO_TRANS2((display), (trans), _TRANS_VRR_VTOTAL_PREV_A) 74 + #define VRR_VTOTAL_FLIP_BEFR_BNDR REG_BIT(31) 75 + #define VRR_VTOTAL_FLIP_AFTER_BNDR REG_BIT(30) 76 + #define VRR_VTOTAL_FLIP_AFTER_DBLBUF REG_BIT(29) 77 + #define VRR_VTOTAL_PREV_FRAME_MASK REG_GENMASK(19, 0) 80 78 81 79 #define _TRANS_VRR_FLIPLINE_A 0x60438 82 80 #define _TRANS_VRR_FLIPLINE_B 0x61438 83 81 #define _TRANS_VRR_FLIPLINE_C 0x62438 84 82 #define _TRANS_VRR_FLIPLINE_D 0x63438 85 - #define TRANS_VRR_FLIPLINE(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, \ 86 - _TRANS_VRR_FLIPLINE_A) 87 - #define VRR_FLIPLINE_MASK REG_GENMASK(19, 0) 83 + #define TRANS_VRR_FLIPLINE(display, trans) _MMIO_TRANS2((display), (trans), _TRANS_VRR_FLIPLINE_A) 84 + #define VRR_FLIPLINE_MASK REG_GENMASK(19, 0) 88 85 89 86 #define _TRANS_VRR_STATUS2_A 0x6043c 90 87 #define _TRANS_VRR_STATUS2_B 0x6143c 91 88 #define _TRANS_VRR_STATUS2_C 0x6243c 92 89 #define _TRANS_VRR_STATUS2_D 0x6343c 93 - #define TRANS_VRR_STATUS2(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_VRR_STATUS2_A) 94 - #define VRR_STATUS2_VERT_LN_CNT_MASK REG_GENMASK(19, 0) 90 + #define TRANS_VRR_STATUS2(display, trans) _MMIO_TRANS2((display), (trans), _TRANS_VRR_STATUS2_A) 91 + #define VRR_STATUS2_VERT_LN_CNT_MASK REG_GENMASK(19, 0) 95 92 96 93 #define _TRANS_PUSH_A 0x60a70 97 94 #define _TRANS_PUSH_B 0x61a70 98 95 #define _TRANS_PUSH_C 0x62a70 99 96 #define _TRANS_PUSH_D 0x63a70 100 - #define TRANS_PUSH(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_PUSH_A) 101 - #define TRANS_PUSH_EN REG_BIT(31) 102 - #define TRANS_PUSH_SEND REG_BIT(30) 97 + #define TRANS_PUSH(display, trans) _MMIO_TRANS2((display), (trans), _TRANS_PUSH_A) 98 + #define TRANS_PUSH_EN REG_BIT(31) 99 + #define TRANS_PUSH_SEND REG_BIT(30) 103 100 104 101 #define _TRANS_VRR_VSYNC_A 0x60078 105 - #define TRANS_VRR_VSYNC(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_VRR_VSYNC_A) 106 - #define VRR_VSYNC_END_MASK REG_GENMASK(28, 16) 107 - #define VRR_VSYNC_END(vsync_end) REG_FIELD_PREP(VRR_VSYNC_END_MASK, (vsync_end)) 108 - #define VRR_VSYNC_START_MASK REG_GENMASK(12, 0) 109 - #define VRR_VSYNC_START(vsync_start) REG_FIELD_PREP(VRR_VSYNC_START_MASK, (vsync_start)) 102 + #define TRANS_VRR_VSYNC(display, trans) _MMIO_TRANS2((display), (trans), _TRANS_VRR_VSYNC_A) 103 + #define VRR_VSYNC_END_MASK REG_GENMASK(28, 16) 104 + #define VRR_VSYNC_END(vsync_end) REG_FIELD_PREP(VRR_VSYNC_END_MASK, (vsync_end)) 105 + #define VRR_VSYNC_START_MASK REG_GENMASK(12, 0) 106 + #define VRR_VSYNC_START(vsync_start) REG_FIELD_PREP(VRR_VSYNC_START_MASK, (vsync_start)) 110 107 111 108 /* Common register for HDMI EMP and DP AS SDP */ 112 109 #define _EMP_AS_SDP_TL_A 0x60204 113 - #define EMP_AS_SDP_DB_TL_MASK REG_GENMASK(12, 0) 114 - #define EMP_AS_SDP_TL(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _EMP_AS_SDP_TL_A) 115 - #define EMP_AS_SDP_DB_TL(db_transmit_line) REG_FIELD_PREP(EMP_AS_SDP_DB_TL_MASK, (db_transmit_line)) 116 - 117 - /*CMRR Registers*/ 110 + #define EMP_AS_SDP_TL(display, trans) _MMIO_TRANS2((display), (trans), _EMP_AS_SDP_TL_A) 111 + #define EMP_AS_SDP_DB_TL_MASK REG_GENMASK(12, 0) 112 + #define EMP_AS_SDP_DB_TL(db_transmit_line) REG_FIELD_PREP(EMP_AS_SDP_DB_TL_MASK, (db_transmit_line)) 118 113 119 114 #define _TRANS_CMRR_M_LO_A 0x604F0 120 - #define TRANS_CMRR_M_LO(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_CMRR_M_LO_A) 115 + #define TRANS_CMRR_M_LO(display, trans) _MMIO_TRANS2((display), (trans), _TRANS_CMRR_M_LO_A) 121 116 122 117 #define _TRANS_CMRR_M_HI_A 0x604F4 123 - #define TRANS_CMRR_M_HI(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_CMRR_M_HI_A) 118 + #define TRANS_CMRR_M_HI(display, trans) _MMIO_TRANS2((display), (trans), _TRANS_CMRR_M_HI_A) 124 119 125 120 #define _TRANS_CMRR_N_LO_A 0x604F8 126 - #define TRANS_CMRR_N_LO(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_CMRR_N_LO_A) 121 + #define TRANS_CMRR_N_LO(display, trans) _MMIO_TRANS2((display), (trans), _TRANS_CMRR_N_LO_A) 127 122 128 123 #define _TRANS_CMRR_N_HI_A 0x604FC 129 - #define TRANS_CMRR_N_HI(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _TRANS_CMRR_N_HI_A) 130 - 131 - #define VRR_CTL_CMRR_ENABLE REG_BIT(27) 124 + #define TRANS_CMRR_N_HI(display, trans) _MMIO_TRANS2((display), (trans), _TRANS_CMRR_N_HI_A) 132 125 133 126 #endif /* __INTEL_VRR_REGS__ */
+31 -5
drivers/gpu/drm/i915/display/skl_universal_plane.c
··· 9 9 #include <drm/drm_fourcc.h> 10 10 11 11 #include "pxp/intel_pxp.h" 12 - 13 12 #include "i915_drv.h" 14 - #include "intel_atomic_plane.h" 15 13 #include "intel_bo.h" 16 14 #include "intel_de.h" 17 15 #include "intel_display_irq.h" ··· 19 21 #include "intel_fb.h" 20 22 #include "intel_fbc.h" 21 23 #include "intel_frontbuffer.h" 24 + #include "intel_plane.h" 22 25 #include "intel_psr.h" 23 26 #include "intel_psr_regs.h" 24 27 #include "skl_scaler.h" ··· 2327 2328 max_scale = skl_plane_max_scale(display, fb); 2328 2329 } 2329 2330 2330 - ret = intel_atomic_plane_check_clipping(plane_state, crtc_state, 2331 - min_scale, max_scale, true); 2331 + ret = intel_plane_check_clipping(plane_state, crtc_state, 2332 + min_scale, max_scale, true); 2332 2333 if (ret) 2333 2334 return ret; 2334 2335 ··· 2791 2792 return caps; 2792 2793 } 2793 2794 2795 + static void skl_disable_tiling(struct intel_plane *plane) 2796 + { 2797 + struct intel_plane_state *state = to_intel_plane_state(plane->base.state); 2798 + struct intel_display *display = to_intel_display(plane); 2799 + const struct drm_framebuffer *fb = state->hw.fb; 2800 + u32 plane_ctl; 2801 + 2802 + plane_ctl = intel_de_read(display, PLANE_CTL(plane->pipe, plane->id)); 2803 + 2804 + if (intel_fb_uses_dpt(fb)) { 2805 + /* if DPT is enabled, keep tiling, but disable compression */ 2806 + plane_ctl &= ~PLANE_CTL_RENDER_DECOMPRESSION_ENABLE; 2807 + } else { 2808 + /* if DPT is not supported, disable tiling, and update stride */ 2809 + u32 stride = state->view.color_plane[0].scanout_stride / 64; 2810 + 2811 + plane_ctl &= ~PLANE_CTL_TILED_MASK; 2812 + intel_de_write_fw(display, PLANE_STRIDE(plane->pipe, plane->id), 2813 + PLANE_STRIDE_(stride)); 2814 + } 2815 + intel_de_write_fw(display, PLANE_CTL(plane->pipe, plane->id), plane_ctl); 2816 + 2817 + intel_de_write_fw(display, PLANE_SURF(plane->pipe, plane->id), 2818 + skl_plane_surf(state, 0)); 2819 + } 2820 + 2794 2821 struct intel_plane * 2795 2822 skl_universal_plane_create(struct intel_display *display, 2796 2823 enum pipe pipe, enum plane_id plane_id) ··· 2863 2838 plane->max_height = skl_plane_max_height; 2864 2839 plane->min_cdclk = skl_plane_min_cdclk; 2865 2840 } 2841 + plane->disable_tiling = skl_disable_tiling; 2866 2842 2867 2843 if (DISPLAY_VER(display) >= 13) 2868 2844 plane->max_stride = adl_plane_max_stride; ··· 3036 3010 return; 3037 3011 } 3038 3012 3039 - intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); 3013 + intel_fb = intel_bo_alloc_framebuffer(); 3040 3014 if (!intel_fb) { 3041 3015 drm_dbg_kms(display->drm, "failed to alloc fb\n"); 3042 3016 return;
+220 -232
drivers/gpu/drm/i915/display/skl_watermark.c
··· 6 6 #include <linux/debugfs.h> 7 7 8 8 #include <drm/drm_blend.h> 9 + #include <drm/drm_file.h> 10 + #include <drm/drm_print.h> 9 11 10 12 #include "soc/intel_dram.h" 11 - 12 - #include "i915_drv.h" 13 13 #include "i915_reg.h" 14 + #include "i915_utils.h" 14 15 #include "i9xx_wm.h" 15 16 #include "intel_atomic.h" 16 - #include "intel_atomic_plane.h" 17 17 #include "intel_bw.h" 18 18 #include "intel_cdclk.h" 19 19 #include "intel_crtc.h" ··· 26 26 #include "intel_display_types.h" 27 27 #include "intel_fb.h" 28 28 #include "intel_fixed.h" 29 + #include "intel_flipq.h" 29 30 #include "intel_pcode.h" 31 + #include "intel_plane.h" 30 32 #include "intel_wm.h" 31 33 #include "skl_universal_plane_regs.h" 32 34 #include "skl_watermark.h" 33 35 #include "skl_watermark_regs.h" 34 36 35 - /*It is expected that DSB can do posted writes to every register in 36 - * the pipe and planes within 100us. For flip queue use case, the 37 - * recommended DSB execution time is 100us + one SAGV block time. 38 - */ 39 - #define DSB_EXE_TIME 100 37 + struct intel_dbuf_state { 38 + struct intel_global_state base; 39 + 40 + struct skl_ddb_entry ddb[I915_MAX_PIPES]; 41 + unsigned int weight[I915_MAX_PIPES]; 42 + u8 slices[I915_MAX_PIPES]; 43 + u8 enabled_slices; 44 + u8 active_pipes; 45 + u8 mdclk_cdclk_ratio; 46 + bool joined_mbus; 47 + }; 48 + 49 + #define to_intel_dbuf_state(global_state) \ 50 + container_of_const((global_state), struct intel_dbuf_state, base) 51 + 52 + #define intel_atomic_get_old_dbuf_state(state) \ 53 + to_intel_dbuf_state(intel_atomic_get_old_global_obj_state(state, &to_intel_display(state)->dbuf.obj)) 54 + #define intel_atomic_get_new_dbuf_state(state) \ 55 + to_intel_dbuf_state(intel_atomic_get_new_global_obj_state(state, &to_intel_display(state)->dbuf.obj)) 40 56 41 57 static void skl_sagv_disable(struct intel_display *display); 42 58 ··· 103 87 static u32 104 88 intel_sagv_block_time(struct intel_display *display) 105 89 { 106 - struct drm_i915_private *i915 = to_i915(display->drm); 107 - 108 90 if (DISPLAY_VER(display) >= 14) { 109 91 u32 val; 110 92 ··· 113 99 u32 val = 0; 114 100 int ret; 115 101 116 - ret = snb_pcode_read(&i915->uncore, 117 - GEN12_PCODE_READ_SAGV_BLOCK_TIME_US, 118 - &val, NULL); 102 + ret = intel_pcode_read(display->drm, 103 + GEN12_PCODE_READ_SAGV_BLOCK_TIME_US, 104 + &val, NULL); 119 105 if (ret) { 120 106 drm_dbg_kms(display->drm, "Couldn't read SAGV block time!\n"); 121 107 return 0; ··· 173 159 */ 174 160 static void skl_sagv_enable(struct intel_display *display) 175 161 { 176 - struct drm_i915_private *i915 = to_i915(display->drm); 177 162 int ret; 178 163 179 164 if (!intel_has_sagv(display)) ··· 182 169 return; 183 170 184 171 drm_dbg_kms(display->drm, "Enabling SAGV\n"); 185 - ret = snb_pcode_write(&i915->uncore, GEN9_PCODE_SAGV_CONTROL, 186 - GEN9_SAGV_ENABLE); 172 + ret = intel_pcode_write(display->drm, GEN9_PCODE_SAGV_CONTROL, 173 + GEN9_SAGV_ENABLE); 187 174 188 175 /* We don't need to wait for SAGV when enabling */ 189 176 ··· 205 192 206 193 static void skl_sagv_disable(struct intel_display *display) 207 194 { 208 - struct drm_i915_private *i915 = to_i915(display->drm); 209 195 int ret; 210 196 211 197 if (!intel_has_sagv(display)) ··· 215 203 216 204 drm_dbg_kms(display->drm, "Disabling SAGV\n"); 217 205 /* bspec says to keep retrying for at least 1 ms */ 218 - ret = skl_pcode_request(&i915->uncore, GEN9_PCODE_SAGV_CONTROL, 219 - GEN9_SAGV_DISABLE, 220 - GEN9_SAGV_IS_DISABLED, GEN9_SAGV_IS_DISABLED, 221 - 1); 206 + ret = intel_pcode_request(display->drm, GEN9_PCODE_SAGV_CONTROL, 207 + GEN9_SAGV_DISABLE, 208 + GEN9_SAGV_IS_DISABLED, GEN9_SAGV_IS_DISABLED, 1); 222 209 /* 223 210 * Some skl systems, pre-release machines in particular, 224 211 * don't actually have SAGV. ··· 243 232 if (!new_bw_state) 244 233 return; 245 234 246 - if (!intel_can_enable_sagv(display, new_bw_state)) 235 + if (!intel_bw_can_enable_sagv(display, new_bw_state)) 247 236 skl_sagv_disable(display); 248 237 } 249 238 ··· 256 245 if (!new_bw_state) 257 246 return; 258 247 259 - if (intel_can_enable_sagv(display, new_bw_state)) 248 + if (intel_bw_can_enable_sagv(display, new_bw_state)) 260 249 skl_sagv_enable(display); 261 - } 262 - 263 - static void icl_sagv_pre_plane_update(struct intel_atomic_state *state) 264 - { 265 - struct intel_display *display = to_intel_display(state); 266 - const struct intel_bw_state *old_bw_state = 267 - intel_atomic_get_old_bw_state(state); 268 - const struct intel_bw_state *new_bw_state = 269 - intel_atomic_get_new_bw_state(state); 270 - u16 old_mask, new_mask; 271 - 272 - if (!new_bw_state) 273 - return; 274 - 275 - old_mask = old_bw_state->qgv_points_mask; 276 - new_mask = old_bw_state->qgv_points_mask | new_bw_state->qgv_points_mask; 277 - 278 - if (old_mask == new_mask) 279 - return; 280 - 281 - WARN_ON(!new_bw_state->base.changed); 282 - 283 - drm_dbg_kms(display->drm, "Restricting QGV points: 0x%x -> 0x%x\n", 284 - old_mask, new_mask); 285 - 286 - /* 287 - * Restrict required qgv points before updating the configuration. 288 - * According to BSpec we can't mask and unmask qgv points at the same 289 - * time. Also masking should be done before updating the configuration 290 - * and unmasking afterwards. 291 - */ 292 - icl_pcode_restrict_qgv_points(display, new_mask); 293 - } 294 - 295 - static void icl_sagv_post_plane_update(struct intel_atomic_state *state) 296 - { 297 - struct intel_display *display = to_intel_display(state); 298 - const struct intel_bw_state *old_bw_state = 299 - intel_atomic_get_old_bw_state(state); 300 - const struct intel_bw_state *new_bw_state = 301 - intel_atomic_get_new_bw_state(state); 302 - u16 old_mask, new_mask; 303 - 304 - if (!new_bw_state) 305 - return; 306 - 307 - old_mask = old_bw_state->qgv_points_mask | new_bw_state->qgv_points_mask; 308 - new_mask = new_bw_state->qgv_points_mask; 309 - 310 - if (old_mask == new_mask) 311 - return; 312 - 313 - WARN_ON(!new_bw_state->base.changed); 314 - 315 - drm_dbg_kms(display->drm, "Relaxing QGV points: 0x%x -> 0x%x\n", 316 - old_mask, new_mask); 317 - 318 - /* 319 - * Allow required qgv points after updating the configuration. 320 - * According to BSpec we can't mask and unmask qgv points at the same 321 - * time. Also masking should be done before updating the configuration 322 - * and unmasking afterwards. 323 - */ 324 - icl_pcode_restrict_qgv_points(display, new_mask); 325 250 } 326 251 327 252 void intel_sagv_pre_plane_update(struct intel_atomic_state *state) ··· 391 444 return tgl_crtc_can_enable_sagv(crtc_state); 392 445 else 393 446 return skl_crtc_can_enable_sagv(crtc_state); 394 - } 395 - 396 - bool intel_can_enable_sagv(struct intel_display *display, 397 - const struct intel_bw_state *bw_state) 398 - { 399 - if (DISPLAY_VER(display) < 11 && 400 - bw_state->active_pipes && !is_power_of_2(bw_state->active_pipes)) 401 - return false; 402 - 403 - return bw_state->pipe_sagv_reject == 0; 404 447 } 405 448 406 449 static u16 skl_ddb_entry_init(struct skl_ddb_entry *entry, ··· 2173 2236 } 2174 2237 2175 2238 return min(1, DIV_ROUND_UP(crtc_state->pixel_rate, 2176 - 2 * cdclk_state->logical.cdclk)); 2239 + 2 * intel_cdclk_logical(cdclk_state))); 2177 2240 } 2178 2241 2179 2242 static int ··· 2617 2680 return enable ? '*' : ' '; 2618 2681 } 2619 2682 2683 + static noinline_for_stack void 2684 + skl_print_plane_changes(struct intel_display *display, 2685 + struct intel_plane *plane, 2686 + const struct skl_plane_wm *old_wm, 2687 + const struct skl_plane_wm *new_wm) 2688 + { 2689 + drm_dbg_kms(display->drm, 2690 + "[PLANE:%d:%s] level %cwm0,%cwm1,%cwm2,%cwm3,%cwm4,%cwm5,%cwm6,%cwm7,%ctwm,%cswm,%cstwm" 2691 + " -> %cwm0,%cwm1,%cwm2,%cwm3,%cwm4,%cwm5,%cwm6,%cwm7,%ctwm,%cswm,%cstwm\n", 2692 + plane->base.base.id, plane->base.name, 2693 + enast(old_wm->wm[0].enable), enast(old_wm->wm[1].enable), 2694 + enast(old_wm->wm[2].enable), enast(old_wm->wm[3].enable), 2695 + enast(old_wm->wm[4].enable), enast(old_wm->wm[5].enable), 2696 + enast(old_wm->wm[6].enable), enast(old_wm->wm[7].enable), 2697 + enast(old_wm->trans_wm.enable), 2698 + enast(old_wm->sagv.wm0.enable), 2699 + enast(old_wm->sagv.trans_wm.enable), 2700 + enast(new_wm->wm[0].enable), enast(new_wm->wm[1].enable), 2701 + enast(new_wm->wm[2].enable), enast(new_wm->wm[3].enable), 2702 + enast(new_wm->wm[4].enable), enast(new_wm->wm[5].enable), 2703 + enast(new_wm->wm[6].enable), enast(new_wm->wm[7].enable), 2704 + enast(new_wm->trans_wm.enable), 2705 + enast(new_wm->sagv.wm0.enable), 2706 + enast(new_wm->sagv.trans_wm.enable)); 2707 + 2708 + drm_dbg_kms(display->drm, 2709 + "[PLANE:%d:%s] lines %c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%4d" 2710 + " -> %c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%4d\n", 2711 + plane->base.base.id, plane->base.name, 2712 + enast(old_wm->wm[0].ignore_lines), old_wm->wm[0].lines, 2713 + enast(old_wm->wm[1].ignore_lines), old_wm->wm[1].lines, 2714 + enast(old_wm->wm[2].ignore_lines), old_wm->wm[2].lines, 2715 + enast(old_wm->wm[3].ignore_lines), old_wm->wm[3].lines, 2716 + enast(old_wm->wm[4].ignore_lines), old_wm->wm[4].lines, 2717 + enast(old_wm->wm[5].ignore_lines), old_wm->wm[5].lines, 2718 + enast(old_wm->wm[6].ignore_lines), old_wm->wm[6].lines, 2719 + enast(old_wm->wm[7].ignore_lines), old_wm->wm[7].lines, 2720 + enast(old_wm->trans_wm.ignore_lines), old_wm->trans_wm.lines, 2721 + enast(old_wm->sagv.wm0.ignore_lines), old_wm->sagv.wm0.lines, 2722 + enast(old_wm->sagv.trans_wm.ignore_lines), old_wm->sagv.trans_wm.lines, 2723 + enast(new_wm->wm[0].ignore_lines), new_wm->wm[0].lines, 2724 + enast(new_wm->wm[1].ignore_lines), new_wm->wm[1].lines, 2725 + enast(new_wm->wm[2].ignore_lines), new_wm->wm[2].lines, 2726 + enast(new_wm->wm[3].ignore_lines), new_wm->wm[3].lines, 2727 + enast(new_wm->wm[4].ignore_lines), new_wm->wm[4].lines, 2728 + enast(new_wm->wm[5].ignore_lines), new_wm->wm[5].lines, 2729 + enast(new_wm->wm[6].ignore_lines), new_wm->wm[6].lines, 2730 + enast(new_wm->wm[7].ignore_lines), new_wm->wm[7].lines, 2731 + enast(new_wm->trans_wm.ignore_lines), new_wm->trans_wm.lines, 2732 + enast(new_wm->sagv.wm0.ignore_lines), new_wm->sagv.wm0.lines, 2733 + enast(new_wm->sagv.trans_wm.ignore_lines), new_wm->sagv.trans_wm.lines); 2734 + 2735 + drm_dbg_kms(display->drm, 2736 + "[PLANE:%d:%s] blocks %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%5d" 2737 + " -> %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%5d\n", 2738 + plane->base.base.id, plane->base.name, 2739 + old_wm->wm[0].blocks, old_wm->wm[1].blocks, 2740 + old_wm->wm[2].blocks, old_wm->wm[3].blocks, 2741 + old_wm->wm[4].blocks, old_wm->wm[5].blocks, 2742 + old_wm->wm[6].blocks, old_wm->wm[7].blocks, 2743 + old_wm->trans_wm.blocks, 2744 + old_wm->sagv.wm0.blocks, 2745 + old_wm->sagv.trans_wm.blocks, 2746 + new_wm->wm[0].blocks, new_wm->wm[1].blocks, 2747 + new_wm->wm[2].blocks, new_wm->wm[3].blocks, 2748 + new_wm->wm[4].blocks, new_wm->wm[5].blocks, 2749 + new_wm->wm[6].blocks, new_wm->wm[7].blocks, 2750 + new_wm->trans_wm.blocks, 2751 + new_wm->sagv.wm0.blocks, 2752 + new_wm->sagv.trans_wm.blocks); 2753 + 2754 + drm_dbg_kms(display->drm, 2755 + "[PLANE:%d:%s] min_ddb %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%5d" 2756 + " -> %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%5d\n", 2757 + plane->base.base.id, plane->base.name, 2758 + old_wm->wm[0].min_ddb_alloc, old_wm->wm[1].min_ddb_alloc, 2759 + old_wm->wm[2].min_ddb_alloc, old_wm->wm[3].min_ddb_alloc, 2760 + old_wm->wm[4].min_ddb_alloc, old_wm->wm[5].min_ddb_alloc, 2761 + old_wm->wm[6].min_ddb_alloc, old_wm->wm[7].min_ddb_alloc, 2762 + old_wm->trans_wm.min_ddb_alloc, 2763 + old_wm->sagv.wm0.min_ddb_alloc, 2764 + old_wm->sagv.trans_wm.min_ddb_alloc, 2765 + new_wm->wm[0].min_ddb_alloc, new_wm->wm[1].min_ddb_alloc, 2766 + new_wm->wm[2].min_ddb_alloc, new_wm->wm[3].min_ddb_alloc, 2767 + new_wm->wm[4].min_ddb_alloc, new_wm->wm[5].min_ddb_alloc, 2768 + new_wm->wm[6].min_ddb_alloc, new_wm->wm[7].min_ddb_alloc, 2769 + new_wm->trans_wm.min_ddb_alloc, 2770 + new_wm->sagv.wm0.min_ddb_alloc, 2771 + new_wm->sagv.trans_wm.min_ddb_alloc); 2772 + } 2773 + 2620 2774 static void 2621 2775 skl_print_wm_changes(struct intel_atomic_state *state) 2622 2776 { ··· 2737 2709 2738 2710 if (skl_ddb_entry_equal(old, new)) 2739 2711 continue; 2740 - 2741 2712 drm_dbg_kms(display->drm, 2742 2713 "[PLANE:%d:%s] ddb (%4d - %4d) -> (%4d - %4d), size %4d -> %4d\n", 2743 2714 plane->base.base.id, plane->base.name, ··· 2754 2727 if (skl_plane_wm_equals(display, old_wm, new_wm)) 2755 2728 continue; 2756 2729 2757 - drm_dbg_kms(display->drm, 2758 - "[PLANE:%d:%s] level %cwm0,%cwm1,%cwm2,%cwm3,%cwm4,%cwm5,%cwm6,%cwm7,%ctwm,%cswm,%cstwm" 2759 - " -> %cwm0,%cwm1,%cwm2,%cwm3,%cwm4,%cwm5,%cwm6,%cwm7,%ctwm,%cswm,%cstwm\n", 2760 - plane->base.base.id, plane->base.name, 2761 - enast(old_wm->wm[0].enable), enast(old_wm->wm[1].enable), 2762 - enast(old_wm->wm[2].enable), enast(old_wm->wm[3].enable), 2763 - enast(old_wm->wm[4].enable), enast(old_wm->wm[5].enable), 2764 - enast(old_wm->wm[6].enable), enast(old_wm->wm[7].enable), 2765 - enast(old_wm->trans_wm.enable), 2766 - enast(old_wm->sagv.wm0.enable), 2767 - enast(old_wm->sagv.trans_wm.enable), 2768 - enast(new_wm->wm[0].enable), enast(new_wm->wm[1].enable), 2769 - enast(new_wm->wm[2].enable), enast(new_wm->wm[3].enable), 2770 - enast(new_wm->wm[4].enable), enast(new_wm->wm[5].enable), 2771 - enast(new_wm->wm[6].enable), enast(new_wm->wm[7].enable), 2772 - enast(new_wm->trans_wm.enable), 2773 - enast(new_wm->sagv.wm0.enable), 2774 - enast(new_wm->sagv.trans_wm.enable)); 2775 - 2776 - drm_dbg_kms(display->drm, 2777 - "[PLANE:%d:%s] lines %c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%4d" 2778 - " -> %c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%4d\n", 2779 - plane->base.base.id, plane->base.name, 2780 - enast(old_wm->wm[0].ignore_lines), old_wm->wm[0].lines, 2781 - enast(old_wm->wm[1].ignore_lines), old_wm->wm[1].lines, 2782 - enast(old_wm->wm[2].ignore_lines), old_wm->wm[2].lines, 2783 - enast(old_wm->wm[3].ignore_lines), old_wm->wm[3].lines, 2784 - enast(old_wm->wm[4].ignore_lines), old_wm->wm[4].lines, 2785 - enast(old_wm->wm[5].ignore_lines), old_wm->wm[5].lines, 2786 - enast(old_wm->wm[6].ignore_lines), old_wm->wm[6].lines, 2787 - enast(old_wm->wm[7].ignore_lines), old_wm->wm[7].lines, 2788 - enast(old_wm->trans_wm.ignore_lines), old_wm->trans_wm.lines, 2789 - enast(old_wm->sagv.wm0.ignore_lines), old_wm->sagv.wm0.lines, 2790 - enast(old_wm->sagv.trans_wm.ignore_lines), old_wm->sagv.trans_wm.lines, 2791 - enast(new_wm->wm[0].ignore_lines), new_wm->wm[0].lines, 2792 - enast(new_wm->wm[1].ignore_lines), new_wm->wm[1].lines, 2793 - enast(new_wm->wm[2].ignore_lines), new_wm->wm[2].lines, 2794 - enast(new_wm->wm[3].ignore_lines), new_wm->wm[3].lines, 2795 - enast(new_wm->wm[4].ignore_lines), new_wm->wm[4].lines, 2796 - enast(new_wm->wm[5].ignore_lines), new_wm->wm[5].lines, 2797 - enast(new_wm->wm[6].ignore_lines), new_wm->wm[6].lines, 2798 - enast(new_wm->wm[7].ignore_lines), new_wm->wm[7].lines, 2799 - enast(new_wm->trans_wm.ignore_lines), new_wm->trans_wm.lines, 2800 - enast(new_wm->sagv.wm0.ignore_lines), new_wm->sagv.wm0.lines, 2801 - enast(new_wm->sagv.trans_wm.ignore_lines), new_wm->sagv.trans_wm.lines); 2802 - 2803 - drm_dbg_kms(display->drm, 2804 - "[PLANE:%d:%s] blocks %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%5d" 2805 - " -> %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%5d\n", 2806 - plane->base.base.id, plane->base.name, 2807 - old_wm->wm[0].blocks, old_wm->wm[1].blocks, 2808 - old_wm->wm[2].blocks, old_wm->wm[3].blocks, 2809 - old_wm->wm[4].blocks, old_wm->wm[5].blocks, 2810 - old_wm->wm[6].blocks, old_wm->wm[7].blocks, 2811 - old_wm->trans_wm.blocks, 2812 - old_wm->sagv.wm0.blocks, 2813 - old_wm->sagv.trans_wm.blocks, 2814 - new_wm->wm[0].blocks, new_wm->wm[1].blocks, 2815 - new_wm->wm[2].blocks, new_wm->wm[3].blocks, 2816 - new_wm->wm[4].blocks, new_wm->wm[5].blocks, 2817 - new_wm->wm[6].blocks, new_wm->wm[7].blocks, 2818 - new_wm->trans_wm.blocks, 2819 - new_wm->sagv.wm0.blocks, 2820 - new_wm->sagv.trans_wm.blocks); 2821 - 2822 - drm_dbg_kms(display->drm, 2823 - "[PLANE:%d:%s] min_ddb %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%5d" 2824 - " -> %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%5d\n", 2825 - plane->base.base.id, plane->base.name, 2826 - old_wm->wm[0].min_ddb_alloc, old_wm->wm[1].min_ddb_alloc, 2827 - old_wm->wm[2].min_ddb_alloc, old_wm->wm[3].min_ddb_alloc, 2828 - old_wm->wm[4].min_ddb_alloc, old_wm->wm[5].min_ddb_alloc, 2829 - old_wm->wm[6].min_ddb_alloc, old_wm->wm[7].min_ddb_alloc, 2830 - old_wm->trans_wm.min_ddb_alloc, 2831 - old_wm->sagv.wm0.min_ddb_alloc, 2832 - old_wm->sagv.trans_wm.min_ddb_alloc, 2833 - new_wm->wm[0].min_ddb_alloc, new_wm->wm[1].min_ddb_alloc, 2834 - new_wm->wm[2].min_ddb_alloc, new_wm->wm[3].min_ddb_alloc, 2835 - new_wm->wm[4].min_ddb_alloc, new_wm->wm[5].min_ddb_alloc, 2836 - new_wm->wm[6].min_ddb_alloc, new_wm->wm[7].min_ddb_alloc, 2837 - new_wm->trans_wm.min_ddb_alloc, 2838 - new_wm->sagv.wm0.min_ddb_alloc, 2839 - new_wm->sagv.trans_wm.min_ddb_alloc); 2730 + skl_print_plane_changes(display, plane, old_wm, new_wm); 2840 2731 } 2841 2732 } 2842 2733 } ··· 2858 2913 return 0; 2859 2914 } 2860 2915 2861 - /* 2862 - * If Fixed Refresh Rate or For VRR case Vmin = Vmax = Flipline: 2863 - * Program DEEP PKG_C_LATENCY Pkg C with highest valid latency from 2864 - * watermark level1 and up and above. If watermark level 1 is 2865 - * invalid program it with all 1's. 2866 - * Program PKG_C_LATENCY Added Wake Time = DSB execution time 2867 - * If Variable Refresh Rate where Vmin != Vmax != Flipline: 2868 - * Program DEEP PKG_C_LATENCY Pkg C with all 1's. 2869 - * Program PKG_C_LATENCY Added Wake Time = 0 2870 - */ 2916 + static int pkgc_max_linetime(struct intel_atomic_state *state) 2917 + { 2918 + struct intel_display *display = to_intel_display(state); 2919 + const struct intel_crtc_state *crtc_state; 2920 + struct intel_crtc *crtc; 2921 + int i, max_linetime; 2922 + 2923 + /* 2924 + * Apparenty the hardware uses WM_LINETIME internally for 2925 + * this stuff, compute everything based on that. 2926 + */ 2927 + for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) { 2928 + display->pkgc.disable[crtc->pipe] = crtc_state->vrr.enable; 2929 + display->pkgc.linetime[crtc->pipe] = DIV_ROUND_UP(crtc_state->linetime, 8); 2930 + } 2931 + 2932 + max_linetime = 0; 2933 + for_each_intel_crtc(display->drm, crtc) { 2934 + if (display->pkgc.disable[crtc->pipe]) 2935 + return 0; 2936 + 2937 + max_linetime = max(display->pkgc.linetime[crtc->pipe], max_linetime); 2938 + } 2939 + 2940 + return max_linetime; 2941 + } 2942 + 2871 2943 void 2872 2944 intel_program_dpkgc_latency(struct intel_atomic_state *state) 2873 2945 { 2874 2946 struct intel_display *display = to_intel_display(state); 2875 - struct intel_crtc *crtc; 2876 - struct intel_crtc_state *new_crtc_state; 2877 - u32 latency = LNL_PKG_C_LATENCY_MASK; 2878 - u32 added_wake_time = 0; 2879 - u32 max_linetime = 0; 2880 - u32 clear, val; 2881 - bool fixed_refresh_rate = false; 2882 - int i; 2947 + int max_linetime, latency, added_wake_time = 0; 2883 2948 2884 2949 if (DISPLAY_VER(display) < 20) 2885 2950 return; 2886 2951 2887 - for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) { 2888 - if (!new_crtc_state->vrr.enable || 2889 - (new_crtc_state->vrr.vmin == new_crtc_state->vrr.vmax && 2890 - new_crtc_state->vrr.vmin == new_crtc_state->vrr.flipline)) 2891 - fixed_refresh_rate = true; 2952 + mutex_lock(&display->wm.wm_mutex); 2892 2953 2893 - max_linetime = max(new_crtc_state->linetime, max_linetime); 2954 + latency = skl_watermark_max_latency(display, 1); 2955 + 2956 + /* FIXME runtime changes to enable_flipq are racy */ 2957 + if (display->params.enable_flipq) 2958 + added_wake_time = intel_flipq_exec_time_us(display); 2959 + 2960 + /* 2961 + * Wa_22020432604 2962 + * "PKG_C_LATENCY Added Wake Time field is not working" 2963 + */ 2964 + if (latency && IS_DISPLAY_VER(display, 20, 30)) { 2965 + latency += added_wake_time; 2966 + added_wake_time = 0; 2894 2967 } 2895 2968 2896 - if (fixed_refresh_rate) { 2897 - added_wake_time = DSB_EXE_TIME + 2898 - display->sagv.block_time_us; 2969 + max_linetime = pkgc_max_linetime(state); 2899 2970 2900 - latency = skl_watermark_max_latency(display, 1); 2901 - 2902 - /* Wa_22020432604 */ 2903 - if ((DISPLAY_VER(display) == 20 || DISPLAY_VER(display) == 30) && !latency) { 2904 - latency += added_wake_time; 2905 - added_wake_time = 0; 2906 - } 2907 - 2908 - /* Wa_22020299601 */ 2909 - if ((latency && max_linetime) && 2910 - (DISPLAY_VER(display) == 20 || DISPLAY_VER(display) == 30)) { 2911 - latency = max_linetime * DIV_ROUND_UP(latency, max_linetime); 2912 - } else if (!latency) { 2913 - latency = LNL_PKG_C_LATENCY_MASK; 2914 - } 2971 + if (max_linetime == 0 || latency == 0) { 2972 + latency = REG_FIELD_GET(LNL_PKG_C_LATENCY_MASK, 2973 + LNL_PKG_C_LATENCY_MASK); 2974 + added_wake_time = 0; 2975 + } else { 2976 + /* 2977 + * Wa_22020299601 2978 + * "Increase the latency programmed in PKG_C_LATENCY Pkg C Latency to be a 2979 + * multiple of the pipeline time from WM_LINETIME" 2980 + */ 2981 + latency = roundup(latency, max_linetime); 2915 2982 } 2916 2983 2917 - clear = LNL_ADDED_WAKE_TIME_MASK | LNL_PKG_C_LATENCY_MASK; 2918 - val = REG_FIELD_PREP(LNL_PKG_C_LATENCY_MASK, latency) | 2919 - REG_FIELD_PREP(LNL_ADDED_WAKE_TIME_MASK, added_wake_time); 2984 + intel_de_write(display, LNL_PKG_C_LATENCY, 2985 + REG_FIELD_PREP(LNL_ADDED_WAKE_TIME_MASK, added_wake_time) | 2986 + REG_FIELD_PREP(LNL_PKG_C_LATENCY_MASK, latency)); 2920 2987 2921 - intel_de_rmw(display, LNL_PKG_C_LATENCY, clear, val); 2988 + mutex_unlock(&display->wm.wm_mutex); 2922 2989 } 2923 2990 2924 2991 static int ··· 2968 3011 * drm_atomic_check_only() gets upset if we pull more crtcs 2969 3012 * into the state, so we have to calculate this based on the 2970 3013 * individual intel_crtc_can_enable_sagv() rather than 2971 - * the overall intel_can_enable_sagv(). Otherwise the 3014 + * the overall intel_bw_can_enable_sagv(). Otherwise the 2972 3015 * crtcs not included in the commit would not switch to the 2973 3016 * SAGV watermarks when we are about to enable SAGV, and that 2974 3017 * would lead to underruns. This does mean extra power draw ··· 3236 3279 3237 3280 static void skl_read_wm_latency(struct intel_display *display, u16 wm[]) 3238 3281 { 3239 - struct drm_i915_private *i915 = to_i915(display->drm); 3240 3282 int num_levels = display->wm.num_levels; 3241 3283 int read_latency = DISPLAY_VER(display) >= 12 ? 3 : 2; 3242 3284 int mult = display->platform.dg2 ? 2 : 1; ··· 3244 3288 3245 3289 /* read the first set of memory latencies[0:3] */ 3246 3290 val = 0; /* data0 to be programmed to 0 for first set */ 3247 - ret = snb_pcode_read(&i915->uncore, GEN9_PCODE_READ_MEM_LATENCY, &val, NULL); 3291 + ret = intel_pcode_read(display->drm, GEN9_PCODE_READ_MEM_LATENCY, &val, NULL); 3248 3292 if (ret) { 3249 3293 drm_err(display->drm, "SKL Mailbox read error = %d\n", ret); 3250 3294 return; ··· 3257 3301 3258 3302 /* read the second set of memory latencies[4:7] */ 3259 3303 val = 1; /* data0 to be programmed to 1 for second set */ 3260 - ret = snb_pcode_read(&i915->uncore, GEN9_PCODE_READ_MEM_LATENCY, &val, NULL); 3304 + ret = intel_pcode_read(display->drm, GEN9_PCODE_READ_MEM_LATENCY, &val, NULL); 3261 3305 if (ret) { 3262 3306 drm_err(display->drm, "SKL Mailbox read error = %d\n", ret); 3263 3307 return; ··· 3647 3691 WARN_ON(!new_dbuf_state->base.changed); 3648 3692 3649 3693 gen9_dbuf_slices_update(display, new_slices); 3694 + } 3695 + 3696 + int intel_dbuf_num_enabled_slices(const struct intel_dbuf_state *dbuf_state) 3697 + { 3698 + return hweight8(dbuf_state->enabled_slices); 3699 + } 3700 + 3701 + int intel_dbuf_num_active_pipes(const struct intel_dbuf_state *dbuf_state) 3702 + { 3703 + return hweight8(dbuf_state->active_pipes); 3704 + } 3705 + 3706 + bool intel_dbuf_pmdemand_needs_update(struct intel_atomic_state *state) 3707 + { 3708 + struct intel_display *display = to_intel_display(state); 3709 + const struct intel_dbuf_state *new_dbuf_state, *old_dbuf_state; 3710 + 3711 + new_dbuf_state = intel_atomic_get_new_dbuf_state(state); 3712 + old_dbuf_state = intel_atomic_get_old_dbuf_state(state); 3713 + 3714 + if (new_dbuf_state && 3715 + new_dbuf_state->active_pipes != old_dbuf_state->active_pipes) 3716 + return true; 3717 + 3718 + if (DISPLAY_VER(display) < 30) { 3719 + if (new_dbuf_state && 3720 + new_dbuf_state->enabled_slices != 3721 + old_dbuf_state->enabled_slices) 3722 + return true; 3723 + } 3724 + 3725 + return false; 3650 3726 } 3651 3727 3652 3728 static void skl_mbus_sanitize(struct intel_display *display)
+7 -26
drivers/gpu/drm/i915/display/skl_watermark.h
··· 8 8 9 9 #include <linux/types.h> 10 10 11 - #include "intel_display_limits.h" 12 - #include "intel_global_state.h" 13 - #include "intel_wm_types.h" 14 - 11 + enum plane_id; 15 12 struct intel_atomic_state; 16 - struct intel_bw_state; 17 13 struct intel_crtc; 18 14 struct intel_crtc_state; 15 + struct intel_dbuf_state; 19 16 struct intel_display; 20 17 struct intel_plane; 21 18 struct intel_plane_state; 19 + struct skl_ddb_entry; 22 20 struct skl_pipe_wm; 23 21 struct skl_wm_level; 24 22 ··· 25 27 void intel_sagv_pre_plane_update(struct intel_atomic_state *state); 26 28 void intel_sagv_post_plane_update(struct intel_atomic_state *state); 27 29 bool intel_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state); 28 - bool intel_can_enable_sagv(struct intel_display *display, 29 - const struct intel_bw_state *bw_state); 30 30 bool intel_has_sagv(struct intel_display *display); 31 31 32 32 u32 skl_ddb_dbuf_slice_mask(struct intel_display *display, ··· 59 63 struct intel_plane *plane, int width, 60 64 int height, int cpp); 61 65 62 - struct intel_dbuf_state { 63 - struct intel_global_state base; 64 - 65 - struct skl_ddb_entry ddb[I915_MAX_PIPES]; 66 - unsigned int weight[I915_MAX_PIPES]; 67 - u8 slices[I915_MAX_PIPES]; 68 - u8 enabled_slices; 69 - u8 active_pipes; 70 - u8 mdclk_cdclk_ratio; 71 - bool joined_mbus; 72 - }; 73 - 74 66 struct intel_dbuf_state * 75 67 intel_atomic_get_dbuf_state(struct intel_atomic_state *state); 76 68 77 - #define to_intel_dbuf_state(global_state) \ 78 - container_of_const((global_state), struct intel_dbuf_state, base) 79 - 80 - #define intel_atomic_get_old_dbuf_state(state) \ 81 - to_intel_dbuf_state(intel_atomic_get_old_global_obj_state(state, &to_intel_display(state)->dbuf.obj)) 82 - #define intel_atomic_get_new_dbuf_state(state) \ 83 - to_intel_dbuf_state(intel_atomic_get_new_global_obj_state(state, &to_intel_display(state)->dbuf.obj)) 69 + int intel_dbuf_num_enabled_slices(const struct intel_dbuf_state *dbuf_state); 70 + int intel_dbuf_num_active_pipes(const struct intel_dbuf_state *dbuf_state); 84 71 85 72 int intel_dbuf_init(struct intel_display *display); 86 73 int intel_dbuf_state_set_mdclk_cdclk_ratio(struct intel_atomic_state *state, ··· 76 97 void intel_dbuf_mbus_pre_ddb_update(struct intel_atomic_state *state); 77 98 void intel_dbuf_mbus_post_ddb_update(struct intel_atomic_state *state); 78 99 void intel_program_dpkgc_latency(struct intel_atomic_state *state); 100 + 101 + bool intel_dbuf_pmdemand_needs_update(struct intel_atomic_state *state); 79 102 80 103 #endif /* __SKL_WATERMARK_H__ */ 81 104
+1 -1
drivers/gpu/drm/i915/display/vlv_dsi.c
··· 1591 1591 1592 1592 static void vlv_dphy_param_init(struct intel_dsi *intel_dsi) 1593 1593 { 1594 + struct intel_display *display = to_intel_display(&intel_dsi->base); 1594 1595 struct intel_connector *connector = intel_dsi->attached_connector; 1595 - struct intel_display *display = to_intel_display(connector); 1596 1596 struct mipi_config *mipi_config = connector->panel.vbt.dsi.config; 1597 1597 u32 tlpx_ns, extra_byte_count, tlpx_ui; 1598 1598 u32 ui_num, ui_den;
+6
drivers/gpu/drm/i915/gem/i915_gem_object.h
··· 16 16 #include "i915_gem_ww.h" 17 17 #include "i915_vma_types.h" 18 18 19 + struct drm_scanout_buffer; 19 20 enum intel_region_id; 21 + struct intel_framebuffer; 20 22 21 23 #define obj_to_i915(obj__) to_i915((obj__)->base.dev) 22 24 ··· 692 690 693 691 int __i915_gem_object_put_pages(struct drm_i915_gem_object *obj); 694 692 int i915_gem_object_truncate(struct drm_i915_gem_object *obj); 693 + 694 + struct intel_framebuffer *i915_gem_object_alloc_framebuffer(void); 695 + int i915_gem_object_panic_setup(struct drm_scanout_buffer *sb); 696 + void i915_gem_object_panic_finish(struct intel_framebuffer *fb); 695 697 696 698 /** 697 699 * i915_gem_object_pin_map - return a contiguous mapping of the entire object
+142
drivers/gpu/drm/i915/gem/i915_gem_pages.c
··· 4 4 */ 5 5 6 6 #include <drm/drm_cache.h> 7 + #include <drm/drm_panic.h> 7 8 #include <linux/vmalloc.h> 8 9 10 + #include "display/intel_fb.h" 11 + #include "display/intel_display_types.h" 9 12 #include "gt/intel_gt.h" 10 13 #include "gt/intel_tlb.h" 11 14 ··· 355 352 kvfree(pfns); 356 353 357 354 return vaddr ?: ERR_PTR(-ENOMEM); 355 + } 356 + 357 + struct i915_panic_data { 358 + struct page **pages; 359 + int page; 360 + void *vaddr; 361 + }; 362 + 363 + struct i915_framebuffer { 364 + struct intel_framebuffer base; 365 + struct i915_panic_data panic; 366 + }; 367 + 368 + static inline struct i915_panic_data *to_i915_panic_data(struct intel_framebuffer *fb) 369 + { 370 + return &container_of_const(fb, struct i915_framebuffer, base)->panic; 371 + } 372 + 373 + static void i915_panic_kunmap(struct i915_panic_data *panic) 374 + { 375 + if (panic->vaddr) { 376 + drm_clflush_virt_range(panic->vaddr, PAGE_SIZE); 377 + kunmap_local(panic->vaddr); 378 + panic->vaddr = NULL; 379 + } 380 + } 381 + 382 + static struct page **i915_gem_object_panic_pages(struct drm_i915_gem_object *obj) 383 + { 384 + unsigned long n_pages = obj->base.size >> PAGE_SHIFT, i; 385 + struct page *page; 386 + struct page **pages; 387 + struct sgt_iter iter; 388 + 389 + /* For a 3840x2160 32 bits Framebuffer, this should require ~64K */ 390 + pages = kmalloc_array(n_pages, sizeof(*pages), GFP_ATOMIC); 391 + if (!pages) 392 + return NULL; 393 + 394 + i = 0; 395 + for_each_sgt_page(page, iter, obj->mm.pages) 396 + pages[i++] = page; 397 + return pages; 398 + } 399 + 400 + static void i915_gem_object_panic_map_set_pixel(struct drm_scanout_buffer *sb, unsigned int x, 401 + unsigned int y, u32 color) 402 + { 403 + struct intel_framebuffer *fb = (struct intel_framebuffer *)sb->private; 404 + unsigned int offset = fb->panic_tiling(sb->width, x, y); 405 + 406 + iosys_map_wr(&sb->map[0], offset, u32, color); 407 + } 408 + 409 + /* 410 + * The scanout buffer pages are not mapped, so for each pixel, 411 + * use kmap_local_page_try_from_panic() to map the page, and write the pixel. 412 + * Try to keep the map from the previous pixel, to avoid too much map/unmap. 413 + */ 414 + static void i915_gem_object_panic_page_set_pixel(struct drm_scanout_buffer *sb, unsigned int x, 415 + unsigned int y, u32 color) 416 + { 417 + unsigned int new_page; 418 + unsigned int offset; 419 + struct intel_framebuffer *fb = (struct intel_framebuffer *)sb->private; 420 + struct i915_panic_data *panic = to_i915_panic_data(fb); 421 + 422 + if (fb->panic_tiling) 423 + offset = fb->panic_tiling(sb->width, x, y); 424 + else 425 + offset = y * sb->pitch[0] + x * sb->format->cpp[0]; 426 + 427 + new_page = offset >> PAGE_SHIFT; 428 + offset = offset % PAGE_SIZE; 429 + if (new_page != panic->page) { 430 + i915_panic_kunmap(panic); 431 + panic->page = new_page; 432 + panic->vaddr = 433 + kmap_local_page_try_from_panic(panic->pages[panic->page]); 434 + } 435 + if (panic->vaddr) { 436 + u32 *pix = panic->vaddr + offset; 437 + *pix = color; 438 + } 439 + } 440 + 441 + struct intel_framebuffer *i915_gem_object_alloc_framebuffer(void) 442 + { 443 + struct i915_framebuffer *i915_fb; 444 + 445 + i915_fb = kzalloc(sizeof(*i915_fb), GFP_KERNEL); 446 + if (i915_fb) 447 + return &i915_fb->base; 448 + return NULL; 449 + } 450 + 451 + /* 452 + * Setup the gem framebuffer for drm_panic access. 453 + * Use current vaddr if it exists, or setup a list of pages. 454 + * pfn is not supported yet. 455 + */ 456 + int i915_gem_object_panic_setup(struct drm_scanout_buffer *sb) 457 + { 458 + enum i915_map_type has_type; 459 + struct intel_framebuffer *fb = (struct intel_framebuffer *)sb->private; 460 + struct i915_panic_data *panic = to_i915_panic_data(fb); 461 + struct drm_i915_gem_object *obj = to_intel_bo(intel_fb_bo(&fb->base)); 462 + void *ptr; 463 + 464 + ptr = page_unpack_bits(obj->mm.mapping, &has_type); 465 + if (ptr) { 466 + if (i915_gem_object_has_iomem(obj)) 467 + iosys_map_set_vaddr_iomem(&sb->map[0], (void __iomem *)ptr); 468 + else 469 + iosys_map_set_vaddr(&sb->map[0], ptr); 470 + 471 + if (fb->panic_tiling) 472 + sb->set_pixel = i915_gem_object_panic_map_set_pixel; 473 + return 0; 474 + } 475 + if (i915_gem_object_has_struct_page(obj)) { 476 + panic->pages = i915_gem_object_panic_pages(obj); 477 + if (!panic->pages) 478 + return -ENOMEM; 479 + panic->page = -1; 480 + sb->set_pixel = i915_gem_object_panic_page_set_pixel; 481 + return 0; 482 + } 483 + return -EOPNOTSUPP; 484 + } 485 + 486 + void i915_gem_object_panic_finish(struct intel_framebuffer *fb) 487 + { 488 + struct i915_panic_data *panic = to_i915_panic_data(fb); 489 + 490 + i915_panic_kunmap(panic); 491 + panic->page = -1; 492 + kfree(panic->pages); 493 + panic->pages = NULL; 358 494 } 359 495 360 496 /* get, pin, and map the pages of the object into kernel space */
+1 -13
drivers/gpu/drm/i915/i915_reg.h
··· 385 385 #define VLV_PCBR _MMIO(VLV_DISPLAY_BASE + 0x2120) 386 386 #define VLV_PCBR_ADDR_SHIFT 12 387 387 388 - #define DISPLAY_PLANE_FLIP_PENDING(plane) (1 << (11 - (plane))) /* A and B only */ 389 388 #define EIR _MMIO(0x20b0) 390 389 #define EMR _MMIO(0x20b4) 391 390 #define ESR _MMIO(0x20b8) ··· 762 763 */ 763 764 #define GEN9_CLKGATE_DIS_0 _MMIO(0x46530) 764 765 #define DARBF_GATING_DIS REG_BIT(27) 765 - #define MTL_PIPEDMC_GATING_DIS_A REG_BIT(15) 766 - #define MTL_PIPEDMC_GATING_DIS_B REG_BIT(14) 766 + #define MTL_PIPEDMC_GATING_DIS(pipe) REG_BIT(15 - (pipe)) 767 767 #define PWM2_GATING_DIS REG_BIT(14) 768 768 #define PWM1_GATING_DIS REG_BIT(13) 769 769 ··· 1202 1204 * 3DSTATE_SO_BUFFERs that the next streamed vertex output goes to. 1203 1205 */ 1204 1206 #define GEN7_SO_WRITE_OFFSET(n) _MMIO(0x5280 + (n) * 4) 1205 - 1206 - /* SKL Fuse Status */ 1207 - enum skl_power_gate { 1208 - SKL_PG0, 1209 - SKL_PG1, 1210 - SKL_PG2, 1211 - ICL_PG3, 1212 - ICL_PG4, 1213 - }; 1214 - 1215 1207 1216 1208 #define GEN9_TIMESTAMP_OVERRIDE _MMIO(0x44074) 1217 1209 #define GEN9_TIMESTAMP_OVERRIDE_US_COUNTER_DIVIDER_SHIFT 0
+5
drivers/gpu/drm/i915/i915_vma.h
··· 335 335 return drm_mm_node_allocated(node) && node->color != color; 336 336 } 337 337 338 + static inline void __iomem *i915_vma_get_iomap(struct i915_vma *vma) 339 + { 340 + return READ_ONCE(vma->iomap); 341 + } 342 + 338 343 /** 339 344 * i915_vma_pin_iomap - calls ioremap_wc to map the GGTT VMA via the aperture 340 345 * @vma: VMA to iomap
+26 -3
drivers/gpu/drm/i915/intel_pcode.c
··· 110 110 } 111 111 112 112 int snb_pcode_write_timeout(struct intel_uncore *uncore, u32 mbox, u32 val, 113 - int fast_timeout_us, int slow_timeout_ms) 113 + int timeout_ms) 114 114 { 115 115 int err; 116 116 117 117 mutex_lock(&uncore->i915->sb_lock); 118 - err = __snb_pcode_rw(uncore, mbox, &val, NULL, 119 - fast_timeout_us, slow_timeout_ms, false); 118 + err = __snb_pcode_rw(uncore, mbox, &val, NULL, 250, timeout_ms, false); 120 119 mutex_unlock(&uncore->i915->sb_lock); 121 120 122 121 if (err) { ··· 271 272 err = snb_pcode_write(uncore, mbox, val); 272 273 273 274 return err; 275 + } 276 + 277 + /* Helpers with drm device */ 278 + int intel_pcode_read(struct drm_device *drm, u32 mbox, u32 *val, u32 *val1) 279 + { 280 + struct drm_i915_private *i915 = to_i915(drm); 281 + 282 + return snb_pcode_read(&i915->uncore, mbox, val, val1); 283 + } 284 + 285 + int intel_pcode_write_timeout(struct drm_device *drm, u32 mbox, u32 val, int timeout_ms) 286 + { 287 + struct drm_i915_private *i915 = to_i915(drm); 288 + 289 + return snb_pcode_write_timeout(&i915->uncore, mbox, val, timeout_ms); 290 + } 291 + 292 + int intel_pcode_request(struct drm_device *drm, u32 mbox, u32 request, 293 + u32 reply_mask, u32 reply, int timeout_base_ms) 294 + { 295 + struct drm_i915_private *i915 = to_i915(drm); 296 + 297 + return skl_pcode_request(&i915->uncore, mbox, request, reply_mask, reply, 298 + timeout_base_ms); 274 299 }
+12 -3
drivers/gpu/drm/i915/intel_pcode.h
··· 8 8 9 9 #include <linux/types.h> 10 10 11 + struct drm_device; 11 12 struct intel_uncore; 12 13 13 14 int snb_pcode_read(struct intel_uncore *uncore, u32 mbox, u32 *val, u32 *val1); 14 - int snb_pcode_write_timeout(struct intel_uncore *uncore, u32 mbox, u32 val, 15 - int fast_timeout_us, int slow_timeout_ms); 15 + int snb_pcode_write_timeout(struct intel_uncore *uncore, u32 mbox, u32 val, int timeout_ms); 16 16 #define snb_pcode_write(uncore, mbox, val) \ 17 - snb_pcode_write_timeout(uncore, mbox, val, 500, 0) 17 + snb_pcode_write_timeout((uncore), (mbox), (val), 1) 18 18 19 19 int skl_pcode_request(struct intel_uncore *uncore, u32 mbox, u32 request, 20 20 u32 reply_mask, u32 reply, int timeout_base_ms); ··· 26 26 */ 27 27 int snb_pcode_read_p(struct intel_uncore *uncore, u32 mbcmd, u32 p1, u32 p2, u32 *val); 28 28 int snb_pcode_write_p(struct intel_uncore *uncore, u32 mbcmd, u32 p1, u32 p2, u32 val); 29 + 30 + /* Helpers with drm device */ 31 + int intel_pcode_read(struct drm_device *drm, u32 mbox, u32 *val, u32 *val1); 32 + int intel_pcode_write_timeout(struct drm_device *drm, u32 mbox, u32 val, int timeout_ms); 33 + #define intel_pcode_write(drm, mbox, val) \ 34 + intel_pcode_write_timeout((drm), (mbox), (val), 1) 35 + 36 + int intel_pcode_request(struct drm_device *drm, u32 mbox, u32 request, 37 + u32 reply_mask, u32 reply, int timeout_base_ms); 29 38 30 39 #endif /* _INTEL_PCODE_H */
+10 -10
drivers/gpu/drm/i915/selftests/i915_request.c
··· 73 73 /* Basic preliminary test to create a request and let it loose! */ 74 74 75 75 request = mock_request(rcs0(i915)->kernel_context, HZ / 10); 76 - if (!request) 77 - return -ENOMEM; 76 + if (IS_ERR(request)) 77 + return PTR_ERR(request); 78 78 79 79 i915_request_add(request); 80 80 ··· 91 91 /* Submit a request, then wait upon it */ 92 92 93 93 request = mock_request(rcs0(i915)->kernel_context, T); 94 - if (!request) 95 - return -ENOMEM; 94 + if (IS_ERR(request)) 95 + return PTR_ERR(request); 96 96 97 97 i915_request_get(request); 98 98 ··· 160 160 /* Submit a request, treat it as a fence and wait upon it */ 161 161 162 162 request = mock_request(rcs0(i915)->kernel_context, T); 163 - if (!request) 164 - return -ENOMEM; 163 + if (IS_ERR(request)) 164 + return PTR_ERR(request); 165 165 166 166 if (dma_fence_wait_timeout(&request->fence, false, T) != -ETIME) { 167 167 pr_err("fence wait success before submit (expected timeout)!\n"); ··· 219 219 GEM_BUG_ON(IS_ERR(ce)); 220 220 request = mock_request(ce, 2 * HZ); 221 221 intel_context_put(ce); 222 - if (!request) { 223 - err = -ENOMEM; 222 + if (IS_ERR(request)) { 223 + err = PTR_ERR(request); 224 224 goto err_context_0; 225 225 } 226 226 ··· 237 237 GEM_BUG_ON(IS_ERR(ce)); 238 238 vip = mock_request(ce, 0); 239 239 intel_context_put(ce); 240 - if (!vip) { 241 - err = -ENOMEM; 240 + if (IS_ERR(vip)) { 241 + err = PTR_ERR(vip); 242 242 goto err_context_1; 243 243 } 244 244
+1 -1
drivers/gpu/drm/i915/selftests/mock_request.c
··· 35 35 /* NB the i915->requests slab cache is enlarged to fit mock_request */ 36 36 request = intel_context_create_request(ce); 37 37 if (IS_ERR(request)) 38 - return NULL; 38 + return request; 39 39 40 40 request->mock.delay = delay; 41 41 return request;
+3 -2
drivers/gpu/drm/i915/soc/intel_dram.c
··· 14 14 #include "intel_dram.h" 15 15 #include "intel_mchbar_regs.h" 16 16 #include "intel_pcode.h" 17 + #include "intel_uncore.h" 17 18 #include "vlv_iosf_sb.h" 18 19 19 20 struct dram_dimm_info { ··· 591 590 u32 val = 0; 592 591 int ret; 593 592 594 - ret = snb_pcode_read(&dev_priv->uncore, ICL_PCODE_MEM_SUBSYSYSTEM_INFO | 595 - ICL_PCODE_MEM_SS_READ_GLOBAL_INFO, &val, NULL); 593 + ret = intel_pcode_read(&dev_priv->drm, ICL_PCODE_MEM_SUBSYSYSTEM_INFO | 594 + ICL_PCODE_MEM_SS_READ_GLOBAL_INFO, &val, NULL); 596 595 if (ret) 597 596 return ret; 598 597
+26
drivers/gpu/drm/ttm/ttm_bo_util.c
··· 382 382 } 383 383 384 384 /** 385 + * ttm_bo_kmap_try_from_panic 386 + * 387 + * @bo: The buffer object 388 + * @page: The page to map 389 + * 390 + * Sets up a kernel virtual mapping using kmap_local_page_try_from_panic(). 391 + * This should only be called from the panic handler, if you make sure the bo 392 + * is the one being displayed, so is properly allocated, and protected. 393 + * 394 + * Returns the vaddr, that you can use to write to the bo, and that you should 395 + * pass to kunmap_local() when you're done with this page, or NULL if the bo 396 + * is in iomem. 397 + */ 398 + void *ttm_bo_kmap_try_from_panic(struct ttm_buffer_object *bo, unsigned long page) 399 + { 400 + if (page + 1 > PFN_UP(bo->resource->size)) 401 + return NULL; 402 + 403 + if (!bo->resource->bus.is_iomem && bo->ttm->pages && bo->ttm->pages[page]) 404 + return kmap_local_page_try_from_panic(bo->ttm->pages[page]); 405 + 406 + return NULL; 407 + } 408 + EXPORT_SYMBOL(ttm_bo_kmap_try_from_panic); 409 + 410 + /** 385 411 * ttm_bo_kmap 386 412 * 387 413 * @bo: The buffer object.
+2 -1
drivers/gpu/drm/xe/Makefile
··· 205 205 i915-display/icl_dsi.o \ 206 206 i915-display/intel_alpm.o \ 207 207 i915-display/intel_atomic.o \ 208 - i915-display/intel_atomic_plane.o \ 209 208 i915-display/intel_audio.o \ 210 209 i915-display/intel_backlight.o \ 211 210 i915-display/intel_bios.o \ ··· 254 255 i915-display/intel_fbc.o \ 255 256 i915-display/intel_fdi.o \ 256 257 i915-display/intel_fifo_underrun.o \ 258 + i915-display/intel_flipq.o \ 257 259 i915-display/intel_frontbuffer.o \ 258 260 i915-display/intel_global_state.o \ 259 261 i915-display/intel_gmbus.o \ ··· 271 271 i915-display/intel_modeset_verify.o \ 272 272 i915-display/intel_panel.o \ 273 273 i915-display/intel_pfit.o \ 274 + i915-display/intel_plane.o \ 274 275 i915-display/intel_pmdemand.o \ 275 276 i915-display/intel_pch.o \ 276 277 i915-display/intel_pps.o \
-31
drivers/gpu/drm/xe/compat-i915-headers/intel_pcode.h
··· 6 6 #ifndef __INTEL_PCODE_H__ 7 7 #define __INTEL_PCODE_H__ 8 8 9 - #include "intel_uncore.h" 10 9 #include "xe_pcode.h" 11 - 12 - static inline int 13 - snb_pcode_write_timeout(struct intel_uncore *uncore, u32 mbox, u32 val, 14 - int fast_timeout_us, int slow_timeout_ms) 15 - { 16 - return xe_pcode_write_timeout(__compat_uncore_to_tile(uncore), mbox, val, 17 - slow_timeout_ms ?: 1); 18 - } 19 - 20 - static inline int 21 - snb_pcode_write(struct intel_uncore *uncore, u32 mbox, u32 val) 22 - { 23 - 24 - return xe_pcode_write(__compat_uncore_to_tile(uncore), mbox, val); 25 - } 26 - 27 - static inline int 28 - snb_pcode_read(struct intel_uncore *uncore, u32 mbox, u32 *val, u32 *val1) 29 - { 30 - return xe_pcode_read(__compat_uncore_to_tile(uncore), mbox, val, val1); 31 - } 32 - 33 - static inline int 34 - skl_pcode_request(struct intel_uncore *uncore, u32 mbox, 35 - u32 request, u32 reply_mask, u32 reply, 36 - int timeout_base_ms) 37 - { 38 - return xe_pcode_request(__compat_uncore_to_tile(uncore), mbox, request, reply_mask, reply, 39 - timeout_base_ms); 40 - } 41 10 42 11 #endif /* __INTEL_PCODE_H__ */
-7
drivers/gpu/drm/xe/compat-i915-headers/intel_uncore.h
··· 24 24 return xe_root_tile_mmio(xe); 25 25 } 26 26 27 - static inline struct xe_tile *__compat_uncore_to_tile(struct intel_uncore *uncore) 28 - { 29 - struct xe_device *xe = container_of(uncore, struct xe_device, uncore); 30 - 31 - return xe_device_get_root_tile(xe); 32 - } 33 - 34 27 static inline u32 intel_uncore_read(struct intel_uncore *uncore, 35 28 i915_reg_t i915_reg) 36 29 {
+91
drivers/gpu/drm/xe/display/intel_bo.c
··· 1 1 // SPDX-License-Identifier: MIT 2 2 /* Copyright © 2024 Intel Corporation */ 3 3 4 + #include <drm/drm_cache.h> 4 5 #include <drm/drm_gem.h> 6 + #include <drm/drm_panic.h> 7 + 8 + #include "intel_fb.h" 9 + #include "intel_display_types.h" 5 10 6 11 #include "xe_bo.h" 7 12 #include "intel_bo.h" ··· 63 58 void intel_bo_describe(struct seq_file *m, struct drm_gem_object *obj) 64 59 { 65 60 /* FIXME */ 61 + } 62 + 63 + struct xe_panic_data { 64 + struct page **pages; 65 + int page; 66 + void *vaddr; 67 + }; 68 + 69 + struct xe_framebuffer { 70 + struct intel_framebuffer base; 71 + struct xe_panic_data panic; 72 + }; 73 + 74 + static inline struct xe_panic_data *to_xe_panic_data(struct intel_framebuffer *fb) 75 + { 76 + return &container_of_const(fb, struct xe_framebuffer, base)->panic; 77 + } 78 + 79 + static void xe_panic_kunmap(struct xe_panic_data *panic) 80 + { 81 + if (panic->vaddr) { 82 + drm_clflush_virt_range(panic->vaddr, PAGE_SIZE); 83 + kunmap_local(panic->vaddr); 84 + panic->vaddr = NULL; 85 + } 86 + } 87 + 88 + /* 89 + * The scanout buffer pages are not mapped, so for each pixel, 90 + * use kmap_local_page_try_from_panic() to map the page, and write the pixel. 91 + * Try to keep the map from the previous pixel, to avoid too much map/unmap. 92 + */ 93 + static void xe_panic_page_set_pixel(struct drm_scanout_buffer *sb, unsigned int x, 94 + unsigned int y, u32 color) 95 + { 96 + struct intel_framebuffer *fb = (struct intel_framebuffer *)sb->private; 97 + struct xe_panic_data *panic = to_xe_panic_data(fb); 98 + struct xe_bo *bo = gem_to_xe_bo(intel_fb_bo(&fb->base)); 99 + unsigned int new_page; 100 + unsigned int offset; 101 + 102 + if (fb->panic_tiling) 103 + offset = fb->panic_tiling(sb->width, x, y); 104 + else 105 + offset = y * sb->pitch[0] + x * sb->format->cpp[0]; 106 + 107 + new_page = offset >> PAGE_SHIFT; 108 + offset = offset % PAGE_SIZE; 109 + if (new_page != panic->page) { 110 + xe_panic_kunmap(panic); 111 + panic->page = new_page; 112 + panic->vaddr = ttm_bo_kmap_try_from_panic(&bo->ttm, 113 + panic->page); 114 + } 115 + if (panic->vaddr) { 116 + u32 *pix = panic->vaddr + offset; 117 + *pix = color; 118 + } 119 + } 120 + 121 + struct intel_framebuffer *intel_bo_alloc_framebuffer(void) 122 + { 123 + struct xe_framebuffer *xe_fb; 124 + 125 + xe_fb = kzalloc(sizeof(*xe_fb), GFP_KERNEL); 126 + if (xe_fb) 127 + return &xe_fb->base; 128 + return NULL; 129 + } 130 + 131 + int intel_bo_panic_setup(struct drm_scanout_buffer *sb) 132 + { 133 + struct intel_framebuffer *fb = (struct intel_framebuffer *)sb->private; 134 + struct xe_panic_data *panic = to_xe_panic_data(fb); 135 + 136 + panic->page = -1; 137 + sb->set_pixel = xe_panic_page_set_pixel; 138 + return 0; 139 + } 140 + 141 + void intel_bo_panic_finish(struct intel_framebuffer *fb) 142 + { 143 + struct xe_panic_data *panic = to_xe_panic_data(fb); 144 + 145 + xe_panic_kunmap(panic); 146 + panic->page = -1; 66 147 }
+5
drivers/gpu/drm/xe/display/xe_fb_pin.c
··· 457 457 { 458 458 return 0; 459 459 } 460 + 461 + void intel_fb_get_map(struct i915_vma *vma, struct iosys_map *map) 462 + { 463 + *map = vma->bo->vmap; 464 + }
+1 -1
drivers/gpu/drm/xe/display/xe_plane_initial.c
··· 10 10 #include "xe_ggtt.h" 11 11 #include "xe_mmio.h" 12 12 13 - #include "intel_atomic_plane.h" 14 13 #include "intel_crtc.h" 15 14 #include "intel_display.h" 16 15 #include "intel_display_core.h" ··· 18 19 #include "intel_fb.h" 19 20 #include "intel_fb_pin.h" 20 21 #include "intel_frontbuffer.h" 22 + #include "intel_plane.h" 21 23 #include "intel_plane_initial.h" 22 24 #include "xe_bo.h" 23 25 #include "xe_wa.h"
+30
drivers/gpu/drm/xe/xe_pcode.c
··· 336 336 return xe_pcode_ready(xe, false); 337 337 } 338 338 ALLOW_ERROR_INJECTION(xe_pcode_probe_early, ERRNO); /* See xe_pci_probe */ 339 + 340 + /* Helpers with drm device. These should only be called by the display side */ 341 + #if IS_ENABLED(CONFIG_DRM_XE_DISPLAY) 342 + 343 + int intel_pcode_read(struct drm_device *drm, u32 mbox, u32 *val, u32 *val1) 344 + { 345 + struct xe_device *xe = to_xe_device(drm); 346 + struct xe_tile *tile = xe_device_get_root_tile(xe); 347 + 348 + return xe_pcode_read(tile, mbox, val, val1); 349 + } 350 + 351 + int intel_pcode_write_timeout(struct drm_device *drm, u32 mbox, u32 val, int timeout_ms) 352 + { 353 + struct xe_device *xe = to_xe_device(drm); 354 + struct xe_tile *tile = xe_device_get_root_tile(xe); 355 + 356 + return xe_pcode_write_timeout(tile, mbox, val, timeout_ms); 357 + } 358 + 359 + int intel_pcode_request(struct drm_device *drm, u32 mbox, u32 request, 360 + u32 reply_mask, u32 reply, int timeout_base_ms) 361 + { 362 + struct xe_device *xe = to_xe_device(drm); 363 + struct xe_tile *tile = xe_device_get_root_tile(xe); 364 + 365 + return xe_pcode_request(tile, mbox, request, reply_mask, reply, timeout_base_ms); 366 + } 367 + 368 + #endif
+11 -1
drivers/gpu/drm/xe/xe_pcode.h
··· 7 7 #define _XE_PCODE_H_ 8 8 9 9 #include <linux/types.h> 10 - struct xe_tile; 10 + 11 + struct drm_device; 11 12 struct xe_device; 13 + struct xe_tile; 12 14 13 15 void xe_pcode_init(struct xe_tile *tile); 14 16 int xe_pcode_probe_early(struct xe_device *xe); ··· 33 31 (FIELD_PREP(PCODE_MB_COMMAND, mbcmd)\ 34 32 | FIELD_PREP(PCODE_MB_PARAM1, param1)\ 35 33 | FIELD_PREP(PCODE_MB_PARAM2, param2)) 34 + 35 + /* Helpers with drm device */ 36 + int intel_pcode_read(struct drm_device *drm, u32 mbox, u32 *val, u32 *val1); 37 + int intel_pcode_write_timeout(struct drm_device *drm, u32 mbox, u32 val, int timeout_ms); 38 + #define intel_pcode_write(drm, mbox, val) \ 39 + intel_pcode_write_timeout((drm), (mbox), (val), 1) 40 + int intel_pcode_request(struct drm_device *drm, u32 mbox, u32 request, 41 + u32 reply_mask, u32 reply, int timeout_base_ms); 36 42 37 43 #endif
+6
include/drm/drm_panic.h
··· 72 72 void (*set_pixel)(struct drm_scanout_buffer *sb, unsigned int x, 73 73 unsigned int y, u32 color); 74 74 75 + /** 76 + * @private: private pointer that you can use in the callbacks 77 + * set_pixel() 78 + */ 79 + void *private; 80 + 75 81 }; 76 82 77 83 #ifdef CONFIG_DRM_PANIC
+1
include/drm/ttm/ttm_bo.h
··· 409 409 int ttm_bo_kmap(struct ttm_buffer_object *bo, unsigned long start_page, 410 410 unsigned long num_pages, struct ttm_bo_kmap_obj *map); 411 411 void ttm_bo_kunmap(struct ttm_bo_kmap_obj *map); 412 + void *ttm_bo_kmap_try_from_panic(struct ttm_buffer_object *bo, unsigned long page); 412 413 int ttm_bo_vmap(struct ttm_buffer_object *bo, struct iosys_map *map); 413 414 void ttm_bo_vunmap(struct ttm_buffer_object *bo, struct iosys_map *map); 414 415 int ttm_bo_mmap_obj(struct vm_area_struct *vma, struct ttm_buffer_object *bo);