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-fixes-2020-05-15' of git://anongit.freedesktop.org/drm/drm

Pull drm fixes from Dave Airlie:
"As mentioned last week an i915 PR came in late, but I left it, so the
i915 bits of this cover 2 weeks, which is why it's likely a bit larger
than usual.

Otherwise it's mostly amdgpu fixes, one tegra fix, one meson fix.

i915:
- Handle idling during i915_gem_evict_something busy loops (Chris)
- Mark current submissions with a weak-dependency (Chris)
- Propagate error from completed fences (Chris)
- Fixes on execlist to avoid GPU hang situation (Chris)
- Fixes couple deadlocks (Chris)
- Timeslice preemption fixes (Chris)
- Fix Display Port interrupt handling on Tiger Lake (Imre)
- Reduce debug noise around Frame Buffer Compression (Peter)
- Fix logic around IPC W/a for Coffee Lake and Kaby Lake (Sultan)
- Avoid dereferencing a dead context (Chris)

tegra:
- tegra120/4 smmu fixes

amdgpu:
- Clockgating fixes
- Fix fbdev with scatter/gather display
- S4 fix for navi
- Soft recovery for gfx10
- Freesync fixes
- Atomic check cursor fix
- Add a gfxoff quirk
- MST fix

amdkfd:
- Fix GEM reference counting

meson:
- error code propogation fix"

* tag 'drm-fixes-2020-05-15' of git://anongit.freedesktop.org/drm/drm: (29 commits)
drm/i915: Handle idling during i915_gem_evict_something busy loops
drm/meson: pm resume add return errno branch
drm/amd/amdgpu: Update update_config() logic
drm/amd/amdgpu: add raven1 part to the gfxoff quirk list
drm/i915: Mark concurrent submissions with a weak-dependency
drm/i915: Propagate error from completed fences
drm/i915/gvt: Fix kernel oops for 3-level ppgtt guest
drm/i915/gvt: Init DPLL/DDI vreg for virtual display instead of inheritance.
drm/amd/display: add basic atomic check for cursor plane
drm/amd/display: Fix vblank and pageflip event handling for FreeSync
drm/amdgpu: implement soft_recovery for gfx10
drm/amdgpu: enable hibernate support on Navi1X
drm/amdgpu: Use GEM obj reference for KFD BOs
drm/amdgpu: force fbdev into vram
drm/amd/powerplay: perform PG ungate prior to CG ungate
drm/amdgpu: drop unnecessary cancel_delayed_work_sync on PG ungate
drm/amdgpu: disable MGCG/MGLS also on gfx CG ungate
drm/i915/execlists: Track inflight CCID
drm/i915/execlists: Avoid reusing the same logical CCID
drm/i915/gem: Remove object_is_locked assertion from unpin_from_display_plane
...

+439 -274
+1
drivers/gpu/drm/amd/amdgpu/amdgpu.h
··· 945 945 946 946 /* s3/s4 mask */ 947 947 bool in_suspend; 948 + bool in_hibernate; 948 949 949 950 /* record last mm index being written through WREG32*/ 950 951 unsigned long last_mm_index;
+3 -2
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
··· 1343 1343 } 1344 1344 1345 1345 /* Free the BO*/ 1346 - amdgpu_bo_unref(&mem->bo); 1346 + drm_gem_object_put_unlocked(&mem->bo->tbo.base); 1347 1347 mutex_destroy(&mem->lock); 1348 1348 kfree(mem); 1349 1349 ··· 1688 1688 | KFD_IOC_ALLOC_MEM_FLAGS_WRITABLE 1689 1689 | KFD_IOC_ALLOC_MEM_FLAGS_EXECUTABLE; 1690 1690 1691 - (*mem)->bo = amdgpu_bo_ref(bo); 1691 + drm_gem_object_get(&bo->tbo.base); 1692 + (*mem)->bo = bo; 1692 1693 (*mem)->va = va; 1693 1694 (*mem)->domain = (bo->preferred_domains & AMDGPU_GEM_DOMAIN_VRAM) ? 1694 1695 AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT;
+2
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
··· 1181 1181 struct amdgpu_device *adev = drm_dev->dev_private; 1182 1182 int r; 1183 1183 1184 + adev->in_hibernate = true; 1184 1185 r = amdgpu_device_suspend(drm_dev, true); 1186 + adev->in_hibernate = false; 1185 1187 if (r) 1186 1188 return r; 1187 1189 return amdgpu_asic_reset(adev);
+1 -2
drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
··· 133 133 u32 cpp; 134 134 u64 flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | 135 135 AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS | 136 - AMDGPU_GEM_CREATE_VRAM_CLEARED | 137 - AMDGPU_GEM_CREATE_CPU_GTT_USWC; 136 + AMDGPU_GEM_CREATE_VRAM_CLEARED; 138 137 139 138 info = drm_get_format_info(adev->ddev, mode_cmd); 140 139 cpp = info->cpp[0];
+16 -6
drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
··· 4273 4273 /* === CGCG /CGLS for GFX 3D Only === */ 4274 4274 gfx_v10_0_update_3d_clock_gating(adev, enable); 4275 4275 /* === MGCG + MGLS === */ 4276 - /* gfx_v10_0_update_medium_grain_clock_gating(adev, enable); */ 4276 + gfx_v10_0_update_medium_grain_clock_gating(adev, enable); 4277 4277 } 4278 4278 4279 4279 if (adev->cg_flags & ··· 4353 4353 switch (adev->asic_type) { 4354 4354 case CHIP_NAVI10: 4355 4355 case CHIP_NAVI14: 4356 - if (!enable) { 4357 - amdgpu_gfx_off_ctrl(adev, false); 4358 - cancel_delayed_work_sync(&adev->gfx.gfx_off_delay_work); 4359 - } else 4360 - amdgpu_gfx_off_ctrl(adev, true); 4356 + amdgpu_gfx_off_ctrl(adev, enable); 4361 4357 break; 4362 4358 default: 4363 4359 break; ··· 4914 4918 ref, mask); 4915 4919 } 4916 4920 4921 + static void gfx_v10_0_ring_soft_recovery(struct amdgpu_ring *ring, 4922 + unsigned vmid) 4923 + { 4924 + struct amdgpu_device *adev = ring->adev; 4925 + uint32_t value = 0; 4926 + 4927 + value = REG_SET_FIELD(value, SQ_CMD, CMD, 0x03); 4928 + value = REG_SET_FIELD(value, SQ_CMD, MODE, 0x01); 4929 + value = REG_SET_FIELD(value, SQ_CMD, CHECK_VMID, 1); 4930 + value = REG_SET_FIELD(value, SQ_CMD, VM_ID, vmid); 4931 + WREG32_SOC15(GC, 0, mmSQ_CMD, value); 4932 + } 4933 + 4917 4934 static void 4918 4935 gfx_v10_0_set_gfx_eop_interrupt_state(struct amdgpu_device *adev, 4919 4936 uint32_t me, uint32_t pipe, ··· 5318 5309 .emit_wreg = gfx_v10_0_ring_emit_wreg, 5319 5310 .emit_reg_wait = gfx_v10_0_ring_emit_reg_wait, 5320 5311 .emit_reg_write_reg_wait = gfx_v10_0_ring_emit_reg_write_reg_wait, 5312 + .soft_recovery = gfx_v10_0_ring_soft_recovery, 5321 5313 }; 5322 5314 5323 5315 static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_compute = {
+5 -9
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
··· 1236 1236 { 0x1002, 0x15dd, 0x1002, 0x15dd, 0xc8 }, 1237 1237 /* https://bugzilla.kernel.org/show_bug.cgi?id=207171 */ 1238 1238 { 0x1002, 0x15dd, 0x103c, 0x83e7, 0xd3 }, 1239 + /* GFXOFF is unstable on C6 parts with a VBIOS 113-RAVEN-114 */ 1240 + { 0x1002, 0x15dd, 0x1002, 0x15dd, 0xc6 }, 1239 1241 { 0, 0, 0, 0, 0 }, 1240 1242 }; 1241 1243 ··· 5027 5025 switch (adev->asic_type) { 5028 5026 case CHIP_RAVEN: 5029 5027 case CHIP_RENOIR: 5030 - if (!enable) { 5028 + if (!enable) 5031 5029 amdgpu_gfx_off_ctrl(adev, false); 5032 - cancel_delayed_work_sync(&adev->gfx.gfx_off_delay_work); 5033 - } 5030 + 5034 5031 if (adev->pg_flags & AMD_PG_SUPPORT_RLC_SMU_HS) { 5035 5032 gfx_v9_0_enable_sck_slow_down_on_power_up(adev, true); 5036 5033 gfx_v9_0_enable_sck_slow_down_on_power_down(adev, true); ··· 5053 5052 amdgpu_gfx_off_ctrl(adev, true); 5054 5053 break; 5055 5054 case CHIP_VEGA12: 5056 - if (!enable) { 5057 - amdgpu_gfx_off_ctrl(adev, false); 5058 - cancel_delayed_work_sync(&adev->gfx.gfx_off_delay_work); 5059 - } else { 5060 - amdgpu_gfx_off_ctrl(adev, true); 5061 - } 5055 + amdgpu_gfx_off_ctrl(adev, enable); 5062 5056 break; 5063 5057 default: 5064 5058 break;
+79 -84
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
··· 441 441 442 442 /** 443 443 * dm_crtc_high_irq() - Handles CRTC interrupt 444 - * @interrupt_params: ignored 444 + * @interrupt_params: used for determining the CRTC instance 445 445 * 446 446 * Handles the CRTC/VSYNC interrupt by notfying DRM's VBLANK 447 447 * event handler. ··· 455 455 unsigned long flags; 456 456 457 457 acrtc = get_crtc_by_otg_inst(adev, irq_params->irq_src - IRQ_TYPE_VBLANK); 458 - 459 - if (acrtc) { 460 - acrtc_state = to_dm_crtc_state(acrtc->base.state); 461 - 462 - DRM_DEBUG_VBL("crtc:%d, vupdate-vrr:%d\n", 463 - acrtc->crtc_id, 464 - amdgpu_dm_vrr_active(acrtc_state)); 465 - 466 - /* Core vblank handling at start of front-porch is only possible 467 - * in non-vrr mode, as only there vblank timestamping will give 468 - * valid results while done in front-porch. Otherwise defer it 469 - * to dm_vupdate_high_irq after end of front-porch. 470 - */ 471 - if (!amdgpu_dm_vrr_active(acrtc_state)) 472 - drm_crtc_handle_vblank(&acrtc->base); 473 - 474 - /* Following stuff must happen at start of vblank, for crc 475 - * computation and below-the-range btr support in vrr mode. 476 - */ 477 - amdgpu_dm_crtc_handle_crc_irq(&acrtc->base); 478 - 479 - if (acrtc_state->stream && adev->family >= AMDGPU_FAMILY_AI && 480 - acrtc_state->vrr_params.supported && 481 - acrtc_state->freesync_config.state == VRR_STATE_ACTIVE_VARIABLE) { 482 - spin_lock_irqsave(&adev->ddev->event_lock, flags); 483 - mod_freesync_handle_v_update( 484 - adev->dm.freesync_module, 485 - acrtc_state->stream, 486 - &acrtc_state->vrr_params); 487 - 488 - dc_stream_adjust_vmin_vmax( 489 - adev->dm.dc, 490 - acrtc_state->stream, 491 - &acrtc_state->vrr_params.adjust); 492 - spin_unlock_irqrestore(&adev->ddev->event_lock, flags); 493 - } 494 - } 495 - } 496 - 497 - #if defined(CONFIG_DRM_AMD_DC_DCN) 498 - /** 499 - * dm_dcn_crtc_high_irq() - Handles VStartup interrupt for DCN generation ASICs 500 - * @interrupt params - interrupt parameters 501 - * 502 - * Notify DRM's vblank event handler at VSTARTUP 503 - * 504 - * Unlike DCE hardware, we trigger the handler at VSTARTUP. at which: 505 - * * We are close enough to VUPDATE - the point of no return for hw 506 - * * We are in the fixed portion of variable front porch when vrr is enabled 507 - * * We are before VUPDATE, where double-buffered vrr registers are swapped 508 - * 509 - * It is therefore the correct place to signal vblank, send user flip events, 510 - * and update VRR. 511 - */ 512 - static void dm_dcn_crtc_high_irq(void *interrupt_params) 513 - { 514 - struct common_irq_params *irq_params = interrupt_params; 515 - struct amdgpu_device *adev = irq_params->adev; 516 - struct amdgpu_crtc *acrtc; 517 - struct dm_crtc_state *acrtc_state; 518 - unsigned long flags; 519 - 520 - acrtc = get_crtc_by_otg_inst(adev, irq_params->irq_src - IRQ_TYPE_VBLANK); 521 - 522 458 if (!acrtc) 523 459 return; 524 460 ··· 464 528 amdgpu_dm_vrr_active(acrtc_state), 465 529 acrtc_state->active_planes); 466 530 531 + /** 532 + * Core vblank handling at start of front-porch is only possible 533 + * in non-vrr mode, as only there vblank timestamping will give 534 + * valid results while done in front-porch. Otherwise defer it 535 + * to dm_vupdate_high_irq after end of front-porch. 536 + */ 537 + if (!amdgpu_dm_vrr_active(acrtc_state)) 538 + drm_crtc_handle_vblank(&acrtc->base); 539 + 540 + /** 541 + * Following stuff must happen at start of vblank, for crc 542 + * computation and below-the-range btr support in vrr mode. 543 + */ 467 544 amdgpu_dm_crtc_handle_crc_irq(&acrtc->base); 468 - drm_crtc_handle_vblank(&acrtc->base); 545 + 546 + /* BTR updates need to happen before VUPDATE on Vega and above. */ 547 + if (adev->family < AMDGPU_FAMILY_AI) 548 + return; 469 549 470 550 spin_lock_irqsave(&adev->ddev->event_lock, flags); 471 551 472 - if (acrtc_state->vrr_params.supported && 552 + if (acrtc_state->stream && acrtc_state->vrr_params.supported && 473 553 acrtc_state->freesync_config.state == VRR_STATE_ACTIVE_VARIABLE) { 474 - mod_freesync_handle_v_update( 475 - adev->dm.freesync_module, 476 - acrtc_state->stream, 477 - &acrtc_state->vrr_params); 554 + mod_freesync_handle_v_update(adev->dm.freesync_module, 555 + acrtc_state->stream, 556 + &acrtc_state->vrr_params); 478 557 479 - dc_stream_adjust_vmin_vmax( 480 - adev->dm.dc, 481 - acrtc_state->stream, 482 - &acrtc_state->vrr_params.adjust); 558 + dc_stream_adjust_vmin_vmax(adev->dm.dc, acrtc_state->stream, 559 + &acrtc_state->vrr_params.adjust); 483 560 } 484 561 485 562 /* ··· 505 556 * avoid race conditions between flip programming and completion, 506 557 * which could cause too early flip completion events. 507 558 */ 508 - if (acrtc->pflip_status == AMDGPU_FLIP_SUBMITTED && 559 + if (adev->family >= AMDGPU_FAMILY_RV && 560 + acrtc->pflip_status == AMDGPU_FLIP_SUBMITTED && 509 561 acrtc_state->active_planes == 0) { 510 562 if (acrtc->event) { 511 563 drm_crtc_send_vblank_event(&acrtc->base, acrtc->event); ··· 518 568 519 569 spin_unlock_irqrestore(&adev->ddev->event_lock, flags); 520 570 } 521 - #endif 522 571 523 572 static int dm_set_clockgating_state(void *handle, 524 573 enum amd_clockgating_state state) ··· 2394 2445 c_irq_params->adev = adev; 2395 2446 c_irq_params->irq_src = int_params.irq_source; 2396 2447 2448 + amdgpu_dm_irq_register_interrupt( 2449 + adev, &int_params, dm_crtc_high_irq, c_irq_params); 2450 + } 2451 + 2452 + /* Use VUPDATE_NO_LOCK interrupt on DCN, which seems to correspond to 2453 + * the regular VUPDATE interrupt on DCE. We want DC_IRQ_SOURCE_VUPDATEx 2454 + * to trigger at end of each vblank, regardless of state of the lock, 2455 + * matching DCE behaviour. 2456 + */ 2457 + for (i = DCN_1_0__SRCID__OTG0_IHC_V_UPDATE_NO_LOCK_INTERRUPT; 2458 + i <= DCN_1_0__SRCID__OTG0_IHC_V_UPDATE_NO_LOCK_INTERRUPT + adev->mode_info.num_crtc - 1; 2459 + i++) { 2460 + r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_DCE, i, &adev->vupdate_irq); 2461 + 2462 + if (r) { 2463 + DRM_ERROR("Failed to add vupdate irq id!\n"); 2464 + return r; 2465 + } 2466 + 2467 + int_params.int_context = INTERRUPT_HIGH_IRQ_CONTEXT; 2468 + int_params.irq_source = 2469 + dc_interrupt_to_irq_source(dc, i, 0); 2470 + 2471 + c_irq_params = &adev->dm.vupdate_params[int_params.irq_source - DC_IRQ_SOURCE_VUPDATE1]; 2472 + 2473 + c_irq_params->adev = adev; 2474 + c_irq_params->irq_src = int_params.irq_source; 2475 + 2397 2476 amdgpu_dm_irq_register_interrupt(adev, &int_params, 2398 - dm_dcn_crtc_high_irq, c_irq_params); 2477 + dm_vupdate_high_irq, c_irq_params); 2399 2478 } 2400 2479 2401 2480 /* Use GRPH_PFLIP interrupt */ ··· 4429 4452 struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); 4430 4453 struct amdgpu_device *adev = crtc->dev->dev_private; 4431 4454 int rc; 4432 - 4433 - /* Do not set vupdate for DCN hardware */ 4434 - if (adev->family > AMDGPU_FAMILY_AI) 4435 - return 0; 4436 4455 4437 4456 irq_source = IRQ_TYPE_VUPDATE + acrtc->otg_inst; 4438 4457 ··· 7855 7882 struct drm_crtc_state *old_crtc_state, *new_crtc_state; 7856 7883 struct dm_crtc_state *dm_new_crtc_state, *dm_old_crtc_state; 7857 7884 struct dm_plane_state *dm_new_plane_state, *dm_old_plane_state; 7885 + struct amdgpu_crtc *new_acrtc; 7858 7886 bool needs_reset; 7859 7887 int ret = 0; 7860 7888 ··· 7865 7891 dm_new_plane_state = to_dm_plane_state(new_plane_state); 7866 7892 dm_old_plane_state = to_dm_plane_state(old_plane_state); 7867 7893 7868 - /*TODO Implement atomic check for cursor plane */ 7869 - if (plane->type == DRM_PLANE_TYPE_CURSOR) 7894 + /*TODO Implement better atomic check for cursor plane */ 7895 + if (plane->type == DRM_PLANE_TYPE_CURSOR) { 7896 + if (!enable || !new_plane_crtc || 7897 + drm_atomic_plane_disabling(plane->state, new_plane_state)) 7898 + return 0; 7899 + 7900 + new_acrtc = to_amdgpu_crtc(new_plane_crtc); 7901 + 7902 + if ((new_plane_state->crtc_w > new_acrtc->max_cursor_width) || 7903 + (new_plane_state->crtc_h > new_acrtc->max_cursor_height)) { 7904 + DRM_DEBUG_ATOMIC("Bad cursor size %d x %d\n", 7905 + new_plane_state->crtc_w, new_plane_state->crtc_h); 7906 + return -EINVAL; 7907 + } 7908 + 7909 + if (new_plane_state->crtc_x <= -new_acrtc->max_cursor_width || 7910 + new_plane_state->crtc_y <= -new_acrtc->max_cursor_height) { 7911 + DRM_DEBUG_ATOMIC("Bad cursor position %d, %d\n", 7912 + new_plane_state->crtc_x, new_plane_state->crtc_y); 7913 + return -EINVAL; 7914 + } 7915 + 7870 7916 return 0; 7917 + } 7871 7918 7872 7919 needs_reset = should_reset_plane(state, plane, old_plane_state, 7873 7920 new_plane_state);
+5 -5
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
··· 398 398 struct mod_hdcp_display *display = &hdcp_work[link_index].display; 399 399 struct mod_hdcp_link *link = &hdcp_work[link_index].link; 400 400 401 - memset(display, 0, sizeof(*display)); 402 - memset(link, 0, sizeof(*link)); 403 - 404 - display->index = aconnector->base.index; 405 - 406 401 if (config->dpms_off) { 407 402 hdcp_remove_display(hdcp_work, link_index, aconnector); 408 403 return; 409 404 } 405 + 406 + memset(display, 0, sizeof(*display)); 407 + memset(link, 0, sizeof(*link)); 408 + 409 + display->index = aconnector->base.index; 410 410 display->state = MOD_HDCP_DISPLAY_ACTIVE; 411 411 412 412 if (aconnector->dc_sink != NULL)
+3 -3
drivers/gpu/drm/amd/powerplay/amd_powerplay.c
··· 319 319 if (*level & profile_mode_mask) { 320 320 hwmgr->saved_dpm_level = hwmgr->dpm_level; 321 321 hwmgr->en_umd_pstate = true; 322 - amdgpu_device_ip_set_clockgating_state(hwmgr->adev, 323 - AMD_IP_BLOCK_TYPE_GFX, 324 - AMD_CG_STATE_UNGATE); 325 322 amdgpu_device_ip_set_powergating_state(hwmgr->adev, 326 323 AMD_IP_BLOCK_TYPE_GFX, 327 324 AMD_PG_STATE_UNGATE); 325 + amdgpu_device_ip_set_clockgating_state(hwmgr->adev, 326 + AMD_IP_BLOCK_TYPE_GFX, 327 + AMD_CG_STATE_UNGATE); 328 328 } 329 329 } else { 330 330 /* exit umd pstate, restore level, enable gfx cg*/
+4 -4
drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
··· 1476 1476 bool use_baco = !smu->is_apu && 1477 1477 ((adev->in_gpu_reset && 1478 1478 (amdgpu_asic_reset_method(adev) == AMD_RESET_METHOD_BACO)) || 1479 - (adev->in_runpm && amdgpu_asic_supports_baco(adev))); 1479 + ((adev->in_runpm || adev->in_hibernate) && amdgpu_asic_supports_baco(adev))); 1480 1480 1481 1481 ret = smu_get_smc_version(smu, NULL, &smu_version); 1482 1482 if (ret) { ··· 1744 1744 if (*level & profile_mode_mask) { 1745 1745 smu_dpm_ctx->saved_dpm_level = smu_dpm_ctx->dpm_level; 1746 1746 smu_dpm_ctx->enable_umd_pstate = true; 1747 - amdgpu_device_ip_set_clockgating_state(smu->adev, 1748 - AMD_IP_BLOCK_TYPE_GFX, 1749 - AMD_CG_STATE_UNGATE); 1750 1747 amdgpu_device_ip_set_powergating_state(smu->adev, 1751 1748 AMD_IP_BLOCK_TYPE_GFX, 1752 1749 AMD_PG_STATE_UNGATE); 1750 + amdgpu_device_ip_set_clockgating_state(smu->adev, 1751 + AMD_IP_BLOCK_TYPE_GFX, 1752 + AMD_CG_STATE_UNGATE); 1753 1753 } 1754 1754 } else { 1755 1755 /* exit umd pstate, restore level, enable gfx cg*/
+1 -2
drivers/gpu/drm/i915/display/intel_fbc.c
··· 485 485 if (!ret) 486 486 goto err_llb; 487 487 else if (ret > 1) { 488 - DRM_INFO("Reducing the compressed framebuffer size. This may lead to less power savings than a non-reduced-size. Try to increase stolen memory size if available in BIOS.\n"); 489 - 488 + DRM_INFO_ONCE("Reducing the compressed framebuffer size. This may lead to less power savings than a non-reduced-size. Try to increase stolen memory size if available in BIOS.\n"); 490 489 } 491 490 492 491 fbc->threshold = ret;
+1 -6
drivers/gpu/drm/i915/gem/i915_gem_domain.c
··· 368 368 struct drm_i915_private *i915 = to_i915(obj->base.dev); 369 369 struct i915_vma *vma; 370 370 371 - GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj)); 372 371 if (!atomic_read(&obj->bind_count)) 373 372 return; 374 373 ··· 399 400 void 400 401 i915_gem_object_unpin_from_display_plane(struct i915_vma *vma) 401 402 { 402 - struct drm_i915_gem_object *obj = vma->obj; 403 - 404 - assert_object_held(obj); 405 - 406 403 /* Bump the LRU to try and avoid premature eviction whilst flipping */ 407 - i915_gem_object_bump_inactive_ggtt(obj); 404 + i915_gem_object_bump_inactive_ggtt(vma->obj); 408 405 409 406 i915_vma_unpin(vma); 410 407 }
+7 -1
drivers/gpu/drm/i915/gt/intel_context_types.h
··· 69 69 #define CONTEXT_NOPREEMPT 7 70 70 71 71 u32 *lrc_reg_state; 72 - u64 lrc_desc; 72 + union { 73 + struct { 74 + u32 lrca; 75 + u32 ccid; 76 + }; 77 + u64 desc; 78 + } lrc; 73 79 u32 tag; /* cookie passed to HW to track this context on submission */ 74 80 75 81 /* Time on GPU as tracked by the hw. */
-9
drivers/gpu/drm/i915/gt/intel_engine.h
··· 333 333 return intel_engine_has_preemption(engine); 334 334 } 335 335 336 - static inline bool 337 - intel_engine_has_timeslices(const struct intel_engine_cs *engine) 338 - { 339 - if (!IS_ACTIVE(CONFIG_DRM_I915_TIMESLICE_DURATION)) 340 - return false; 341 - 342 - return intel_engine_has_semaphores(engine); 343 - } 344 - 345 336 #endif /* _INTEL_RINGBUFFER_H_ */
+6
drivers/gpu/drm/i915/gt/intel_engine_cs.c
··· 1295 1295 1296 1296 if (engine->id == RENDER_CLASS && IS_GEN_RANGE(dev_priv, 4, 7)) 1297 1297 drm_printf(m, "\tCCID: 0x%08x\n", ENGINE_READ(engine, CCID)); 1298 + if (HAS_EXECLISTS(dev_priv)) { 1299 + drm_printf(m, "\tEL_STAT_HI: 0x%08x\n", 1300 + ENGINE_READ(engine, RING_EXECLIST_STATUS_HI)); 1301 + drm_printf(m, "\tEL_STAT_LO: 0x%08x\n", 1302 + ENGINE_READ(engine, RING_EXECLIST_STATUS_LO)); 1303 + } 1298 1304 drm_printf(m, "\tRING_START: 0x%08x\n", 1299 1305 ENGINE_READ(engine, RING_START)); 1300 1306 drm_printf(m, "\tRING_HEAD: 0x%08x\n",
+29 -6
drivers/gpu/drm/i915/gt/intel_engine_types.h
··· 157 157 struct i915_priolist default_priolist; 158 158 159 159 /** 160 + * @ccid: identifier for contexts submitted to this engine 161 + */ 162 + u32 ccid; 163 + 164 + /** 165 + * @yield: CCID at the time of the last semaphore-wait interrupt. 166 + * 167 + * Instead of leaving a semaphore busy-spinning on an engine, we would 168 + * like to switch to another ready context, i.e. yielding the semaphore 169 + * timeslice. 170 + */ 171 + u32 yield; 172 + 173 + /** 160 174 * @error_interrupt: CS Master EIR 161 175 * 162 176 * The CS generates an interrupt when it detects an error. We capture ··· 309 295 u32 context_size; 310 296 u32 mmio_base; 311 297 312 - unsigned int context_tag; 313 - #define NUM_CONTEXT_TAG roundup_pow_of_two(2 * EXECLIST_MAX_PORTS) 298 + unsigned long context_tag; 314 299 315 300 struct rb_node uabi_node; 316 301 ··· 496 483 #define I915_ENGINE_SUPPORTS_STATS BIT(1) 497 484 #define I915_ENGINE_HAS_PREEMPTION BIT(2) 498 485 #define I915_ENGINE_HAS_SEMAPHORES BIT(3) 499 - #define I915_ENGINE_NEEDS_BREADCRUMB_TASKLET BIT(4) 500 - #define I915_ENGINE_IS_VIRTUAL BIT(5) 501 - #define I915_ENGINE_HAS_RELATIVE_MMIO BIT(6) 502 - #define I915_ENGINE_REQUIRES_CMD_PARSER BIT(7) 486 + #define I915_ENGINE_HAS_TIMESLICES BIT(4) 487 + #define I915_ENGINE_NEEDS_BREADCRUMB_TASKLET BIT(5) 488 + #define I915_ENGINE_IS_VIRTUAL BIT(6) 489 + #define I915_ENGINE_HAS_RELATIVE_MMIO BIT(7) 490 + #define I915_ENGINE_REQUIRES_CMD_PARSER BIT(8) 503 491 unsigned int flags; 504 492 505 493 /* ··· 596 582 intel_engine_has_semaphores(const struct intel_engine_cs *engine) 597 583 { 598 584 return engine->flags & I915_ENGINE_HAS_SEMAPHORES; 585 + } 586 + 587 + static inline bool 588 + intel_engine_has_timeslices(const struct intel_engine_cs *engine) 589 + { 590 + if (!IS_ACTIVE(CONFIG_DRM_I915_TIMESLICE_DURATION)) 591 + return false; 592 + 593 + return engine->flags & I915_ENGINE_HAS_TIMESLICES; 599 594 } 600 595 601 596 static inline bool
+13 -2
drivers/gpu/drm/i915/gt/intel_gt_irq.c
··· 39 39 } 40 40 } 41 41 42 + if (iir & GT_WAIT_SEMAPHORE_INTERRUPT) { 43 + WRITE_ONCE(engine->execlists.yield, 44 + ENGINE_READ_FW(engine, RING_EXECLIST_STATUS_HI)); 45 + ENGINE_TRACE(engine, "semaphore yield: %08x\n", 46 + engine->execlists.yield); 47 + if (del_timer(&engine->execlists.timer)) 48 + tasklet = true; 49 + } 50 + 42 51 if (iir & GT_CONTEXT_SWITCH_INTERRUPT) 43 52 tasklet = true; 44 53 ··· 237 228 const u32 irqs = 238 229 GT_CS_MASTER_ERROR_INTERRUPT | 239 230 GT_RENDER_USER_INTERRUPT | 240 - GT_CONTEXT_SWITCH_INTERRUPT; 231 + GT_CONTEXT_SWITCH_INTERRUPT | 232 + GT_WAIT_SEMAPHORE_INTERRUPT; 241 233 struct intel_uncore *uncore = gt->uncore; 242 234 const u32 dmask = irqs << 16 | irqs; 243 235 const u32 smask = irqs << 16; ··· 376 366 const u32 irqs = 377 367 GT_CS_MASTER_ERROR_INTERRUPT | 378 368 GT_RENDER_USER_INTERRUPT | 379 - GT_CONTEXT_SWITCH_INTERRUPT; 369 + GT_CONTEXT_SWITCH_INTERRUPT | 370 + GT_WAIT_SEMAPHORE_INTERRUPT; 380 371 const u32 gt_interrupts[] = { 381 372 irqs << GEN8_RCS_IRQ_SHIFT | irqs << GEN8_BCS_IRQ_SHIFT, 382 373 irqs << GEN8_VCS0_IRQ_SHIFT | irqs << GEN8_VCS1_IRQ_SHIFT,
+81 -39
drivers/gpu/drm/i915/gt/intel_lrc.c
··· 456 456 * engine info, SW context ID and SW counter need to form a unique number 457 457 * (Context ID) per lrc. 458 458 */ 459 - static u64 459 + static u32 460 460 lrc_descriptor(struct intel_context *ce, struct intel_engine_cs *engine) 461 461 { 462 - u64 desc; 462 + u32 desc; 463 463 464 464 desc = INTEL_LEGACY_32B_CONTEXT; 465 465 if (i915_vm_is_4lvl(ce->vm)) ··· 470 470 if (IS_GEN(engine->i915, 8)) 471 471 desc |= GEN8_CTX_L3LLC_COHERENT; 472 472 473 - desc |= i915_ggtt_offset(ce->state); /* bits 12-31 */ 474 - /* 475 - * The following 32bits are copied into the OA reports (dword 2). 476 - * Consider updating oa_get_render_ctx_id in i915_perf.c when changing 477 - * anything below. 478 - */ 479 - if (INTEL_GEN(engine->i915) >= 11) { 480 - desc |= (u64)engine->instance << GEN11_ENGINE_INSTANCE_SHIFT; 481 - /* bits 48-53 */ 482 - 483 - desc |= (u64)engine->class << GEN11_ENGINE_CLASS_SHIFT; 484 - /* bits 61-63 */ 485 - } 486 - 487 - return desc; 473 + return i915_ggtt_offset(ce->state) | desc; 488 474 } 489 475 490 476 static inline unsigned int dword_in_page(void *addr) ··· 1178 1192 __execlists_update_reg_state(ce, engine, head); 1179 1193 1180 1194 /* We've switched away, so this should be a no-op, but intent matters */ 1181 - ce->lrc_desc |= CTX_DESC_FORCE_RESTORE; 1195 + ce->lrc.desc |= CTX_DESC_FORCE_RESTORE; 1182 1196 } 1183 1197 1184 1198 static u32 intel_context_get_runtime(const struct intel_context *ce) ··· 1237 1251 if (IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)) 1238 1252 execlists_check_context(ce, engine); 1239 1253 1240 - ce->lrc_desc &= ~GENMASK_ULL(47, 37); 1241 1254 if (ce->tag) { 1242 1255 /* Use a fixed tag for OA and friends */ 1243 - ce->lrc_desc |= (u64)ce->tag << 32; 1256 + GEM_BUG_ON(ce->tag <= BITS_PER_LONG); 1257 + ce->lrc.ccid = ce->tag; 1244 1258 } else { 1245 1259 /* We don't need a strict matching tag, just different values */ 1246 - ce->lrc_desc |= 1247 - (u64)(++engine->context_tag % NUM_CONTEXT_TAG) << 1248 - GEN11_SW_CTX_ID_SHIFT; 1249 - BUILD_BUG_ON(NUM_CONTEXT_TAG > GEN12_MAX_CONTEXT_HW_ID); 1260 + unsigned int tag = ffs(engine->context_tag); 1261 + 1262 + GEM_BUG_ON(tag == 0 || tag >= BITS_PER_LONG); 1263 + clear_bit(tag - 1, &engine->context_tag); 1264 + ce->lrc.ccid = tag << (GEN11_SW_CTX_ID_SHIFT - 32); 1265 + 1266 + BUILD_BUG_ON(BITS_PER_LONG > GEN12_MAX_CONTEXT_HW_ID); 1250 1267 } 1268 + 1269 + ce->lrc.ccid |= engine->execlists.ccid; 1251 1270 1252 1271 __intel_gt_pm_get(engine->gt); 1253 1272 execlists_context_status_change(rq, INTEL_CONTEXT_SCHEDULE_IN); ··· 1293 1302 1294 1303 static inline void 1295 1304 __execlists_schedule_out(struct i915_request *rq, 1296 - struct intel_engine_cs * const engine) 1305 + struct intel_engine_cs * const engine, 1306 + unsigned int ccid) 1297 1307 { 1298 1308 struct intel_context * const ce = rq->context; 1299 1309 ··· 1311 1319 if (list_is_last_rcu(&rq->link, &ce->timeline->requests) && 1312 1320 i915_request_completed(rq)) 1313 1321 intel_engine_add_retire(engine, ce->timeline); 1322 + 1323 + ccid >>= GEN11_SW_CTX_ID_SHIFT - 32; 1324 + ccid &= GEN12_MAX_CONTEXT_HW_ID; 1325 + if (ccid < BITS_PER_LONG) { 1326 + GEM_BUG_ON(ccid == 0); 1327 + GEM_BUG_ON(test_bit(ccid - 1, &engine->context_tag)); 1328 + set_bit(ccid - 1, &engine->context_tag); 1329 + } 1314 1330 1315 1331 intel_context_update_runtime(ce); 1316 1332 intel_engine_context_out(engine); ··· 1345 1345 { 1346 1346 struct intel_context * const ce = rq->context; 1347 1347 struct intel_engine_cs *cur, *old; 1348 + u32 ccid; 1348 1349 1349 1350 trace_i915_request_out(rq); 1350 1351 1352 + ccid = rq->context->lrc.ccid; 1351 1353 old = READ_ONCE(ce->inflight); 1352 1354 do 1353 1355 cur = ptr_unmask_bits(old, 2) ? ptr_dec(old) : NULL; 1354 1356 while (!try_cmpxchg(&ce->inflight, &old, cur)); 1355 1357 if (!cur) 1356 - __execlists_schedule_out(rq, old); 1358 + __execlists_schedule_out(rq, old, ccid); 1357 1359 1358 1360 i915_request_put(rq); 1359 1361 } ··· 1363 1361 static u64 execlists_update_context(struct i915_request *rq) 1364 1362 { 1365 1363 struct intel_context *ce = rq->context; 1366 - u64 desc = ce->lrc_desc; 1364 + u64 desc = ce->lrc.desc; 1367 1365 u32 tail, prev; 1368 1366 1369 1367 /* ··· 1402 1400 */ 1403 1401 wmb(); 1404 1402 1405 - ce->lrc_desc &= ~CTX_DESC_FORCE_RESTORE; 1403 + ce->lrc.desc &= ~CTX_DESC_FORCE_RESTORE; 1406 1404 return desc; 1407 1405 } 1408 1406 ··· 1721 1719 struct i915_request *w = 1722 1720 container_of(p->waiter, typeof(*w), sched); 1723 1721 1722 + if (p->flags & I915_DEPENDENCY_WEAK) 1723 + continue; 1724 + 1724 1725 /* Leave semaphores spinning on the other engines */ 1725 1726 if (w->engine != rq->engine) 1726 1727 continue; ··· 1759 1754 } 1760 1755 1761 1756 static bool 1762 - need_timeslice(struct intel_engine_cs *engine, const struct i915_request *rq) 1757 + need_timeslice(const struct intel_engine_cs *engine, 1758 + const struct i915_request *rq) 1763 1759 { 1764 1760 int hint; 1765 1761 ··· 1772 1766 hint = max(hint, rq_prio(list_next_entry(rq, sched.link))); 1773 1767 1774 1768 return hint >= effective_prio(rq); 1769 + } 1770 + 1771 + static bool 1772 + timeslice_yield(const struct intel_engine_execlists *el, 1773 + const struct i915_request *rq) 1774 + { 1775 + /* 1776 + * Once bitten, forever smitten! 1777 + * 1778 + * If the active context ever busy-waited on a semaphore, 1779 + * it will be treated as a hog until the end of its timeslice (i.e. 1780 + * until it is scheduled out and replaced by a new submission, 1781 + * possibly even its own lite-restore). The HW only sends an interrupt 1782 + * on the first miss, and we do know if that semaphore has been 1783 + * signaled, or even if it is now stuck on another semaphore. Play 1784 + * safe, yield if it might be stuck -- it will be given a fresh 1785 + * timeslice in the near future. 1786 + */ 1787 + return rq->context->lrc.ccid == READ_ONCE(el->yield); 1788 + } 1789 + 1790 + static bool 1791 + timeslice_expired(const struct intel_engine_execlists *el, 1792 + const struct i915_request *rq) 1793 + { 1794 + return timer_expired(&el->timer) || timeslice_yield(el, rq); 1775 1795 } 1776 1796 1777 1797 static int ··· 1815 1783 return READ_ONCE(engine->props.timeslice_duration_ms); 1816 1784 } 1817 1785 1818 - static unsigned long 1819 - active_timeslice(const struct intel_engine_cs *engine) 1786 + static unsigned long active_timeslice(const struct intel_engine_cs *engine) 1820 1787 { 1821 1788 const struct intel_engine_execlists *execlists = &engine->execlists; 1822 1789 const struct i915_request *rq = *execlists->active; ··· 1977 1946 1978 1947 last = NULL; 1979 1948 } else if (need_timeslice(engine, last) && 1980 - timer_expired(&engine->execlists.timer)) { 1949 + timeslice_expired(execlists, last)) { 1981 1950 ENGINE_TRACE(engine, 1982 - "expired last=%llx:%lld, prio=%d, hint=%d\n", 1951 + "expired last=%llx:%lld, prio=%d, hint=%d, yield?=%s\n", 1983 1952 last->fence.context, 1984 1953 last->fence.seqno, 1985 1954 last->sched.attr.priority, 1986 - execlists->queue_priority_hint); 1955 + execlists->queue_priority_hint, 1956 + yesno(timeslice_yield(execlists, last))); 1987 1957 1988 1958 ring_set_paused(engine, 1); 1989 1959 defer_active(engine); ··· 2245 2213 } 2246 2214 clear_ports(port + 1, last_port - port); 2247 2215 2216 + WRITE_ONCE(execlists->yield, -1); 2248 2217 execlists_submit_ports(engine); 2249 2218 set_preempt_timeout(engine, *active); 2250 2219 } else { ··· 3076 3043 if (IS_ERR(vaddr)) 3077 3044 return PTR_ERR(vaddr); 3078 3045 3079 - ce->lrc_desc = lrc_descriptor(ce, engine) | CTX_DESC_FORCE_RESTORE; 3046 + ce->lrc.lrca = lrc_descriptor(ce, engine) | CTX_DESC_FORCE_RESTORE; 3080 3047 ce->lrc_reg_state = vaddr + LRC_STATE_PN * PAGE_SIZE; 3081 3048 __execlists_update_reg_state(ce, engine, ce->ring->tail); 3082 3049 ··· 3105 3072 ce, ce->engine, ce->ring, true); 3106 3073 __execlists_update_reg_state(ce, ce->engine, ce->ring->tail); 3107 3074 3108 - ce->lrc_desc |= CTX_DESC_FORCE_RESTORE; 3075 + ce->lrc.desc |= CTX_DESC_FORCE_RESTORE; 3109 3076 } 3110 3077 3111 3078 static const struct intel_context_ops execlists_context_ops = { ··· 3574 3541 3575 3542 enable_error_interrupt(engine); 3576 3543 3577 - engine->context_tag = 0; 3544 + engine->context_tag = GENMASK(BITS_PER_LONG - 2, 0); 3578 3545 } 3579 3546 3580 3547 static bool unexpected_starting_state(struct intel_engine_cs *engine) ··· 3786 3753 head, ce->ring->tail); 3787 3754 __execlists_reset_reg_state(ce, engine); 3788 3755 __execlists_update_reg_state(ce, engine, head); 3789 - ce->lrc_desc |= CTX_DESC_FORCE_RESTORE; /* paranoid: GPU was reset! */ 3756 + ce->lrc.desc |= CTX_DESC_FORCE_RESTORE; /* paranoid: GPU was reset! */ 3790 3757 3791 3758 unwind: 3792 3759 /* Push back any incomplete requests for replay after the reset. */ ··· 4402 4369 engine->flags |= I915_ENGINE_SUPPORTS_STATS; 4403 4370 if (!intel_vgpu_active(engine->i915)) { 4404 4371 engine->flags |= I915_ENGINE_HAS_SEMAPHORES; 4405 - if (HAS_LOGICAL_RING_PREEMPTION(engine->i915)) 4372 + if (HAS_LOGICAL_RING_PREEMPTION(engine->i915)) { 4406 4373 engine->flags |= I915_ENGINE_HAS_PREEMPTION; 4374 + if (IS_ACTIVE(CONFIG_DRM_I915_TIMESLICE_DURATION)) 4375 + engine->flags |= I915_ENGINE_HAS_TIMESLICES; 4376 + } 4407 4377 } 4408 4378 4409 4379 if (INTEL_GEN(engine->i915) >= 12) ··· 4485 4449 engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT << shift; 4486 4450 engine->irq_keep_mask = GT_CONTEXT_SWITCH_INTERRUPT << shift; 4487 4451 engine->irq_keep_mask |= GT_CS_MASTER_ERROR_INTERRUPT << shift; 4452 + engine->irq_keep_mask |= GT_WAIT_SEMAPHORE_INTERRUPT << shift; 4488 4453 } 4489 4454 4490 4455 static void rcs_submission_override(struct intel_engine_cs *engine) ··· 4552 4515 execlists->csb_size = GEN8_CSB_ENTRIES; 4553 4516 else 4554 4517 execlists->csb_size = GEN11_CSB_ENTRIES; 4518 + 4519 + if (INTEL_GEN(engine->i915) >= 11) { 4520 + execlists->ccid |= engine->instance << (GEN11_ENGINE_INSTANCE_SHIFT - 32); 4521 + execlists->ccid |= engine->class << (GEN11_ENGINE_CLASS_SHIFT - 32); 4522 + } 4555 4523 4556 4524 reset_csb_pointers(engine); 4557 4525
+18 -16
drivers/gpu/drm/i915/gt/selftest_lrc.c
··· 929 929 goto err; 930 930 } 931 931 932 - cs = intel_ring_begin(rq, 10); 932 + cs = intel_ring_begin(rq, 14); 933 933 if (IS_ERR(cs)) { 934 934 err = PTR_ERR(cs); 935 935 goto err; ··· 941 941 *cs++ = MI_SEMAPHORE_WAIT | 942 942 MI_SEMAPHORE_GLOBAL_GTT | 943 943 MI_SEMAPHORE_POLL | 944 - MI_SEMAPHORE_SAD_NEQ_SDD; 945 - *cs++ = 0; 944 + MI_SEMAPHORE_SAD_GTE_SDD; 945 + *cs++ = idx; 946 946 *cs++ = offset; 947 947 *cs++ = 0; 948 948 ··· 950 950 *cs++ = i915_mmio_reg_offset(RING_TIMESTAMP(rq->engine->mmio_base)); 951 951 *cs++ = offset + idx * sizeof(u32); 952 952 *cs++ = 0; 953 + 954 + *cs++ = MI_STORE_DWORD_IMM_GEN4 | MI_USE_GGTT; 955 + *cs++ = offset; 956 + *cs++ = 0; 957 + *cs++ = idx + 1; 953 958 954 959 intel_ring_advance(rq, cs); 955 960 ··· 989 984 990 985 for_each_engine(engine, gt, id) { 991 986 enum { A1, A2, B1 }; 992 - enum { X = 1, Y, Z }; 987 + enum { X = 1, Z, Y }; 993 988 struct i915_request *rq[3] = {}; 994 989 struct intel_context *ce; 995 990 unsigned long heartbeat; ··· 1022 1017 goto err; 1023 1018 } 1024 1019 1025 - rq[0] = create_rewinder(ce, NULL, slot, 1); 1020 + rq[0] = create_rewinder(ce, NULL, slot, X); 1026 1021 if (IS_ERR(rq[0])) { 1027 1022 intel_context_put(ce); 1028 1023 goto err; 1029 1024 } 1030 1025 1031 - rq[1] = create_rewinder(ce, NULL, slot, 2); 1026 + rq[1] = create_rewinder(ce, NULL, slot, Y); 1032 1027 intel_context_put(ce); 1033 1028 if (IS_ERR(rq[1])) 1034 1029 goto err; ··· 1046 1041 goto err; 1047 1042 } 1048 1043 1049 - rq[2] = create_rewinder(ce, rq[0], slot, 3); 1044 + rq[2] = create_rewinder(ce, rq[0], slot, Z); 1050 1045 intel_context_put(ce); 1051 1046 if (IS_ERR(rq[2])) 1052 1047 goto err; ··· 1060 1055 GEM_BUG_ON(!timer_pending(&engine->execlists.timer)); 1061 1056 1062 1057 /* ELSP[] = { { A:rq1, A:rq2 }, { B:rq1 } } */ 1063 - GEM_BUG_ON(!i915_request_is_active(rq[A1])); 1064 - GEM_BUG_ON(!i915_request_is_active(rq[A2])); 1065 - GEM_BUG_ON(!i915_request_is_active(rq[B1])); 1066 - 1067 - /* Wait for the timeslice to kick in */ 1068 - del_timer(&engine->execlists.timer); 1069 - tasklet_hi_schedule(&engine->execlists.tasklet); 1070 - intel_engine_flush_submission(engine); 1071 - 1058 + if (i915_request_is_active(rq[A2])) { /* semaphore yielded! */ 1059 + /* Wait for the timeslice to kick in */ 1060 + del_timer(&engine->execlists.timer); 1061 + tasklet_hi_schedule(&engine->execlists.tasklet); 1062 + intel_engine_flush_submission(engine); 1063 + } 1072 1064 /* -> ELSP[] = { { A:rq1 }, { B:rq1 } } */ 1073 1065 GEM_BUG_ON(!i915_request_is_active(rq[A1])); 1074 1066 GEM_BUG_ON(!i915_request_is_active(rq[B1]));
+1 -1
drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
··· 217 217 static void guc_add_request(struct intel_guc *guc, struct i915_request *rq) 218 218 { 219 219 struct intel_engine_cs *engine = rq->engine; 220 - u32 ctx_desc = lower_32_bits(rq->context->lrc_desc); 220 + u32 ctx_desc = rq->context->lrc.ccid; 221 221 u32 ring_tail = intel_ring_set_tail(rq->ring, rq->tail) / sizeof(u64); 222 222 223 223 guc_wq_item_append(guc, engine->guc_id, ctx_desc,
+44 -5
drivers/gpu/drm/i915/gvt/display.c
··· 208 208 SKL_FUSE_PG_DIST_STATUS(SKL_PG0) | 209 209 SKL_FUSE_PG_DIST_STATUS(SKL_PG1) | 210 210 SKL_FUSE_PG_DIST_STATUS(SKL_PG2); 211 - vgpu_vreg_t(vgpu, LCPLL1_CTL) |= 212 - LCPLL_PLL_ENABLE | 213 - LCPLL_PLL_LOCK; 214 - vgpu_vreg_t(vgpu, LCPLL2_CTL) |= LCPLL_PLL_ENABLE; 215 - 211 + /* 212 + * Only 1 PIPE enabled in current vGPU display and PIPE_A is 213 + * tied to TRANSCODER_A in HW, so it's safe to assume PIPE_A, 214 + * TRANSCODER_A can be enabled. PORT_x depends on the input of 215 + * setup_virtual_dp_monitor, we can bind DPLL0 to any PORT_x 216 + * so we fixed to DPLL0 here. 217 + * Setup DPLL0: DP link clk 1620 MHz, non SSC, DP Mode 218 + */ 219 + vgpu_vreg_t(vgpu, DPLL_CTRL1) = 220 + DPLL_CTRL1_OVERRIDE(DPLL_ID_SKL_DPLL0); 221 + vgpu_vreg_t(vgpu, DPLL_CTRL1) |= 222 + DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1620, DPLL_ID_SKL_DPLL0); 223 + vgpu_vreg_t(vgpu, LCPLL1_CTL) = 224 + LCPLL_PLL_ENABLE | LCPLL_PLL_LOCK; 225 + vgpu_vreg_t(vgpu, DPLL_STATUS) = DPLL_LOCK(DPLL_ID_SKL_DPLL0); 226 + /* 227 + * Golden M/N are calculated based on: 228 + * 24 bpp, 4 lanes, 154000 pixel clk (from virtual EDID), 229 + * DP link clk 1620 MHz and non-constant_n. 230 + * TODO: calculate DP link symbol clk and stream clk m/n. 231 + */ 232 + vgpu_vreg_t(vgpu, PIPE_DATA_M1(TRANSCODER_A)) = 63 << TU_SIZE_SHIFT; 233 + vgpu_vreg_t(vgpu, PIPE_DATA_M1(TRANSCODER_A)) |= 0x5b425e; 234 + vgpu_vreg_t(vgpu, PIPE_DATA_N1(TRANSCODER_A)) = 0x800000; 235 + vgpu_vreg_t(vgpu, PIPE_LINK_M1(TRANSCODER_A)) = 0x3cd6e; 236 + vgpu_vreg_t(vgpu, PIPE_LINK_N1(TRANSCODER_A)) = 0x80000; 216 237 } 217 238 218 239 if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) { 240 + vgpu_vreg_t(vgpu, DPLL_CTRL2) &= 241 + ~DPLL_CTRL2_DDI_CLK_OFF(PORT_B); 242 + vgpu_vreg_t(vgpu, DPLL_CTRL2) |= 243 + DPLL_CTRL2_DDI_CLK_SEL(DPLL_ID_SKL_DPLL0, PORT_B); 244 + vgpu_vreg_t(vgpu, DPLL_CTRL2) |= 245 + DPLL_CTRL2_DDI_SEL_OVERRIDE(PORT_B); 219 246 vgpu_vreg_t(vgpu, SFUSE_STRAP) |= SFUSE_STRAP_DDIB_DETECTED; 220 247 vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) &= 221 248 ~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK | ··· 263 236 } 264 237 265 238 if (intel_vgpu_has_monitor_on_port(vgpu, PORT_C)) { 239 + vgpu_vreg_t(vgpu, DPLL_CTRL2) &= 240 + ~DPLL_CTRL2_DDI_CLK_OFF(PORT_C); 241 + vgpu_vreg_t(vgpu, DPLL_CTRL2) |= 242 + DPLL_CTRL2_DDI_CLK_SEL(DPLL_ID_SKL_DPLL0, PORT_C); 243 + vgpu_vreg_t(vgpu, DPLL_CTRL2) |= 244 + DPLL_CTRL2_DDI_SEL_OVERRIDE(PORT_C); 266 245 vgpu_vreg_t(vgpu, SDEISR) |= SDE_PORTC_HOTPLUG_CPT; 267 246 vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) &= 268 247 ~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK | ··· 289 256 } 290 257 291 258 if (intel_vgpu_has_monitor_on_port(vgpu, PORT_D)) { 259 + vgpu_vreg_t(vgpu, DPLL_CTRL2) &= 260 + ~DPLL_CTRL2_DDI_CLK_OFF(PORT_D); 261 + vgpu_vreg_t(vgpu, DPLL_CTRL2) |= 262 + DPLL_CTRL2_DDI_CLK_SEL(DPLL_ID_SKL_DPLL0, PORT_D); 263 + vgpu_vreg_t(vgpu, DPLL_CTRL2) |= 264 + DPLL_CTRL2_DDI_SEL_OVERRIDE(PORT_D); 292 265 vgpu_vreg_t(vgpu, SDEISR) |= SDE_PORTD_HOTPLUG_CPT; 293 266 vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) &= 294 267 ~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK |
+7 -3
drivers/gpu/drm/i915/gvt/scheduler.c
··· 290 290 shadow_context_descriptor_update(struct intel_context *ce, 291 291 struct intel_vgpu_workload *workload) 292 292 { 293 - u64 desc = ce->lrc_desc; 293 + u64 desc = ce->lrc.desc; 294 294 295 295 /* 296 296 * Update bits 0-11 of the context descriptor which includes flags ··· 300 300 desc |= (u64)workload->ctx_desc.addressing_mode << 301 301 GEN8_CTX_ADDRESSING_MODE_SHIFT; 302 302 303 - ce->lrc_desc = desc; 303 + ce->lrc.desc = desc; 304 304 } 305 305 306 306 static int copy_workload_to_ring_buffer(struct intel_vgpu_workload *workload) ··· 379 379 for (i = 0; i < GVT_RING_CTX_NR_PDPS; i++) { 380 380 struct i915_page_directory * const pd = 381 381 i915_pd_entry(ppgtt->pd, i); 382 - 382 + /* skip now as current i915 ppgtt alloc won't allocate 383 + top level pdp for non 4-level table, won't impact 384 + shadow ppgtt. */ 385 + if (!pd) 386 + break; 383 387 px_dma(pd) = mm->ppgtt_mm.shadow_pdps[i]; 384 388 } 385 389 }
+12 -14
drivers/gpu/drm/i915/i915_gem_evict.c
··· 128 128 active = NULL; 129 129 INIT_LIST_HEAD(&eviction_list); 130 130 list_for_each_entry_safe(vma, next, &vm->bound_list, vm_link) { 131 + if (vma == active) { /* now seen this vma twice */ 132 + if (flags & PIN_NONBLOCK) 133 + break; 134 + 135 + active = ERR_PTR(-EAGAIN); 136 + } 137 + 131 138 /* 132 139 * We keep this list in a rough least-recently scanned order 133 140 * of active elements (inactive elements are cheap to reap). ··· 150 143 * To notice when we complete one full cycle, we record the 151 144 * first active element seen, before moving it to the tail. 152 145 */ 153 - if (i915_vma_is_active(vma)) { 154 - if (vma == active) { 155 - if (flags & PIN_NONBLOCK) 156 - break; 146 + if (active != ERR_PTR(-EAGAIN) && i915_vma_is_active(vma)) { 147 + if (!active) 148 + active = vma; 157 149 158 - active = ERR_PTR(-EAGAIN); 159 - } 160 - 161 - if (active != ERR_PTR(-EAGAIN)) { 162 - if (!active) 163 - active = vma; 164 - 165 - list_move_tail(&vma->vm_link, &vm->bound_list); 166 - continue; 167 - } 150 + list_move_tail(&vma->vm_link, &vm->bound_list); 151 + continue; 168 152 } 169 153 170 154 if (mark_free(&scan, vma, flags, &eviction_list))
+7 -5
drivers/gpu/drm/i915/i915_gpu_error.c
··· 1207 1207 static void record_request(const struct i915_request *request, 1208 1208 struct i915_request_coredump *erq) 1209 1209 { 1210 - const struct i915_gem_context *ctx; 1211 - 1212 1210 erq->flags = request->fence.flags; 1213 1211 erq->context = request->fence.context; 1214 1212 erq->seqno = request->fence.seqno; ··· 1217 1219 1218 1220 erq->pid = 0; 1219 1221 rcu_read_lock(); 1220 - ctx = rcu_dereference(request->context->gem_context); 1221 - if (ctx) 1222 - erq->pid = pid_nr(ctx->pid); 1222 + if (!intel_context_is_closed(request->context)) { 1223 + const struct i915_gem_context *ctx; 1224 + 1225 + ctx = rcu_dereference(request->context->gem_context); 1226 + if (ctx) 1227 + erq->pid = pid_nr(ctx->pid); 1228 + } 1223 1229 rcu_read_unlock(); 1224 1230 } 1225 1231
+3 -13
drivers/gpu/drm/i915/i915_irq.c
··· 3361 3361 u32 de_pipe_masked = gen8_de_pipe_fault_mask(dev_priv) | 3362 3362 GEN8_PIPE_CDCLK_CRC_DONE; 3363 3363 u32 de_pipe_enables; 3364 - u32 de_port_masked = GEN8_AUX_CHANNEL_A; 3364 + u32 de_port_masked = gen8_de_port_aux_mask(dev_priv); 3365 3365 u32 de_port_enables; 3366 3366 u32 de_misc_masked = GEN8_DE_EDP_PSR; 3367 3367 enum pipe pipe; ··· 3369 3369 if (INTEL_GEN(dev_priv) <= 10) 3370 3370 de_misc_masked |= GEN8_DE_MISC_GSE; 3371 3371 3372 - if (INTEL_GEN(dev_priv) >= 9) { 3373 - de_port_masked |= GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C | 3374 - GEN9_AUX_CHANNEL_D; 3375 - if (IS_GEN9_LP(dev_priv)) 3376 - de_port_masked |= BXT_DE_PORT_GMBUS; 3377 - } 3378 - 3379 - if (INTEL_GEN(dev_priv) >= 11) 3380 - de_port_masked |= ICL_AUX_CHANNEL_E; 3381 - 3382 - if (IS_CNL_WITH_PORT_F(dev_priv) || INTEL_GEN(dev_priv) >= 11) 3383 - de_port_masked |= CNL_AUX_CHANNEL_F; 3372 + if (IS_GEN9_LP(dev_priv)) 3373 + de_port_masked |= BXT_DE_PORT_GMBUS; 3384 3374 3385 3375 de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK | 3386 3376 GEN8_PIPE_FIFO_UNDERRUN;
+2 -4
drivers/gpu/drm/i915/i915_perf.c
··· 1310 1310 * dropped by GuC. They won't be part of the context 1311 1311 * ID in the OA reports, so squash those lower bits. 1312 1312 */ 1313 - stream->specific_ctx_id = 1314 - lower_32_bits(ce->lrc_desc) >> 12; 1313 + stream->specific_ctx_id = ce->lrc.lrca >> 12; 1315 1314 1316 1315 /* 1317 1316 * GuC uses the top bit to signal proxy submission, so ··· 1327 1328 ((1U << GEN11_SW_CTX_ID_WIDTH) - 1) << (GEN11_SW_CTX_ID_SHIFT - 32); 1328 1329 /* 1329 1330 * Pick an unused context id 1330 - * 0 - (NUM_CONTEXT_TAG - 1) are used by other contexts 1331 + * 0 - BITS_PER_LONG are used by other contexts 1331 1332 * GEN12_MAX_CONTEXT_HW_ID (0x7ff) is used by idle context 1332 1333 */ 1333 1334 stream->specific_ctx_id = (GEN12_MAX_CONTEXT_HW_ID - 1) << (GEN11_SW_CTX_ID_SHIFT - 32); 1334 - BUILD_BUG_ON((GEN12_MAX_CONTEXT_HW_ID - 1) < NUM_CONTEXT_TAG); 1335 1335 break; 1336 1336 } 1337 1337
+1
drivers/gpu/drm/i915/i915_reg.h
··· 3094 3094 #define GT_BSD_CS_ERROR_INTERRUPT (1 << 15) 3095 3095 #define GT_BSD_USER_INTERRUPT (1 << 12) 3096 3096 #define GT_RENDER_L3_PARITY_ERROR_INTERRUPT_S1 (1 << 11) /* hsw+; rsvd on snb, ivb, vlv */ 3097 + #define GT_WAIT_SEMAPHORE_INTERRUPT REG_BIT(11) /* bdw+ */ 3097 3098 #define GT_CONTEXT_SWITCH_INTERRUPT (1 << 8) 3098 3099 #define GT_RENDER_L3_PARITY_ERROR_INTERRUPT (1 << 5) /* !snb */ 3099 3100 #define GT_RENDER_PIPECTL_NOTIFY_INTERRUPT (1 << 4)
+9 -3
drivers/gpu/drm/i915/i915_request.c
··· 1017 1017 GEM_BUG_ON(to == from); 1018 1018 GEM_BUG_ON(to->timeline == from->timeline); 1019 1019 1020 - if (i915_request_completed(from)) 1020 + if (i915_request_completed(from)) { 1021 + i915_sw_fence_set_error_once(&to->submit, from->fence.error); 1021 1022 return 0; 1023 + } 1022 1024 1023 1025 if (to->engine->schedule) { 1024 - ret = i915_sched_node_add_dependency(&to->sched, &from->sched); 1026 + ret = i915_sched_node_add_dependency(&to->sched, 1027 + &from->sched, 1028 + I915_DEPENDENCY_EXTERNAL); 1025 1029 if (ret < 0) 1026 1030 return ret; 1027 1031 } ··· 1187 1183 1188 1184 /* Couple the dependency tree for PI on this exposed to->fence */ 1189 1185 if (to->engine->schedule) { 1190 - err = i915_sched_node_add_dependency(&to->sched, &from->sched); 1186 + err = i915_sched_node_add_dependency(&to->sched, 1187 + &from->sched, 1188 + I915_DEPENDENCY_WEAK); 1191 1189 if (err < 0) 1192 1190 return err; 1193 1191 }
+3 -3
drivers/gpu/drm/i915/i915_scheduler.c
··· 456 456 } 457 457 458 458 int i915_sched_node_add_dependency(struct i915_sched_node *node, 459 - struct i915_sched_node *signal) 459 + struct i915_sched_node *signal, 460 + unsigned long flags) 460 461 { 461 462 struct i915_dependency *dep; 462 463 ··· 466 465 return -ENOMEM; 467 466 468 467 if (!__i915_sched_node_add_dependency(node, signal, dep, 469 - I915_DEPENDENCY_EXTERNAL | 470 - I915_DEPENDENCY_ALLOC)) 468 + flags | I915_DEPENDENCY_ALLOC)) 471 469 i915_dependency_free(dep); 472 470 473 471 return 0;
+2 -1
drivers/gpu/drm/i915/i915_scheduler.h
··· 34 34 unsigned long flags); 35 35 36 36 int i915_sched_node_add_dependency(struct i915_sched_node *node, 37 - struct i915_sched_node *signal); 37 + struct i915_sched_node *signal, 38 + unsigned long flags); 38 39 39 40 void i915_sched_node_fini(struct i915_sched_node *node); 40 41
+1
drivers/gpu/drm/i915/i915_scheduler_types.h
··· 78 78 unsigned long flags; 79 79 #define I915_DEPENDENCY_ALLOC BIT(0) 80 80 #define I915_DEPENDENCY_EXTERNAL BIT(1) 81 + #define I915_DEPENDENCY_WEAK BIT(2) 81 82 }; 82 83 83 84 #endif /* _I915_SCHEDULER_TYPES_H_ */
+9 -16
drivers/gpu/drm/i915/i915_vma.c
··· 1228 1228 1229 1229 lockdep_assert_held(&vma->vm->mutex); 1230 1230 1231 - /* 1232 - * First wait upon any activity as retiring the request may 1233 - * have side-effects such as unpinning or even unbinding this vma. 1234 - * 1235 - * XXX Actually waiting under the vm->mutex is a hinderance and 1236 - * should be pipelined wherever possible. In cases where that is 1237 - * unavoidable, we should lift the wait to before the mutex. 1238 - */ 1239 - ret = i915_vma_sync(vma); 1240 - if (ret) 1241 - return ret; 1242 - 1243 1231 if (i915_vma_is_pinned(vma)) { 1244 1232 vma_print_allocator(vma, "is pinned"); 1245 1233 return -EAGAIN; ··· 1301 1313 if (!drm_mm_node_allocated(&vma->node)) 1302 1314 return 0; 1303 1315 1304 - if (i915_vma_is_bound(vma, I915_VMA_GLOBAL_BIND)) 1305 - /* XXX not always required: nop_clear_range */ 1306 - wakeref = intel_runtime_pm_get(&vm->i915->runtime_pm); 1307 - 1308 1316 /* Optimistic wait before taking the mutex */ 1309 1317 err = i915_vma_sync(vma); 1310 1318 if (err) 1311 1319 goto out_rpm; 1320 + 1321 + if (i915_vma_is_pinned(vma)) { 1322 + vma_print_allocator(vma, "is pinned"); 1323 + return -EAGAIN; 1324 + } 1325 + 1326 + if (i915_vma_is_bound(vma, I915_VMA_GLOBAL_BIND)) 1327 + /* XXX not always required: nop_clear_range */ 1328 + wakeref = intel_runtime_pm_get(&vm->i915->runtime_pm); 1312 1329 1313 1330 err = mutex_lock_interruptible(&vm->mutex); 1314 1331 if (err)
+1 -1
drivers/gpu/drm/i915/intel_pm.c
··· 4992 4992 * WaIncreaseLatencyIPCEnabled: kbl,cfl 4993 4993 * Display WA #1141: kbl,cfl 4994 4994 */ 4995 - if ((IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) || 4995 + if ((IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) && 4996 4996 dev_priv->ipc_enabled) 4997 4997 latency += 4; 4998 4998
+1 -1
drivers/gpu/drm/i915/selftests/i915_vma.c
··· 173 173 } 174 174 175 175 nc = 0; 176 - for_each_prime_number(num_ctx, 2 * NUM_CONTEXT_TAG) { 176 + for_each_prime_number(num_ctx, 2 * BITS_PER_LONG) { 177 177 for (; nc < num_ctx; nc++) { 178 178 ctx = mock_context(i915, "mock"); 179 179 if (!ctx)
+1 -3
drivers/gpu/drm/meson/meson_drv.c
··· 412 412 if (priv->afbcd.ops) 413 413 priv->afbcd.ops->init(priv); 414 414 415 - drm_mode_config_helper_resume(priv->drm); 416 - 417 - return 0; 415 + return drm_mode_config_helper_resume(priv->drm); 418 416 } 419 417 420 418 static int compare_of(struct device *dev, void *data)
+2 -1
drivers/gpu/drm/tegra/drm.c
··· 1039 1039 1040 1040 static bool host1x_drm_wants_iommu(struct host1x_device *dev) 1041 1041 { 1042 + struct host1x *host1x = dev_get_drvdata(dev->dev.parent); 1042 1043 struct iommu_domain *domain; 1043 1044 1044 1045 /* ··· 1077 1076 * sufficient and whether or not the host1x is attached to an IOMMU 1078 1077 * doesn't matter. 1079 1078 */ 1080 - if (!domain && dma_get_mask(dev->dev.parent) <= DMA_BIT_MASK(32)) 1079 + if (!domain && host1x_get_dma_mask(host1x) <= DMA_BIT_MASK(32)) 1081 1080 return true; 1082 1081 1083 1082 return domain != NULL;
+55 -4
drivers/gpu/host1x/dev.c
··· 192 192 } 193 193 } 194 194 195 + static bool host1x_wants_iommu(struct host1x *host1x) 196 + { 197 + /* 198 + * If we support addressing a maximum of 32 bits of physical memory 199 + * and if the host1x firewall is enabled, there's no need to enable 200 + * IOMMU support. This can happen for example on Tegra20, Tegra30 201 + * and Tegra114. 202 + * 203 + * Tegra124 and later can address up to 34 bits of physical memory and 204 + * many platforms come equipped with more than 2 GiB of system memory, 205 + * which requires crossing the 4 GiB boundary. But there's a catch: on 206 + * SoCs before Tegra186 (i.e. Tegra124 and Tegra210), the host1x can 207 + * only address up to 32 bits of memory in GATHER opcodes, which means 208 + * that command buffers need to either be in the first 2 GiB of system 209 + * memory (which could quickly lead to memory exhaustion), or command 210 + * buffers need to be treated differently from other buffers (which is 211 + * not possible with the current ABI). 212 + * 213 + * A third option is to use the IOMMU in these cases to make sure all 214 + * buffers will be mapped into a 32-bit IOVA space that host1x can 215 + * address. This allows all of the system memory to be used and works 216 + * within the limitations of the host1x on these SoCs. 217 + * 218 + * In summary, default to enable IOMMU on Tegra124 and later. For any 219 + * of the earlier SoCs, only use the IOMMU for additional safety when 220 + * the host1x firewall is disabled. 221 + */ 222 + if (host1x->info->dma_mask <= DMA_BIT_MASK(32)) { 223 + if (IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL)) 224 + return false; 225 + } 226 + 227 + return true; 228 + } 229 + 195 230 static struct iommu_domain *host1x_iommu_attach(struct host1x *host) 196 231 { 197 232 struct iommu_domain *domain = iommu_get_domain_for_dev(host->dev); 198 233 int err; 199 234 200 235 /* 201 - * If the host1x firewall is enabled, there's no need to enable IOMMU 202 - * support. Similarly, if host1x is already attached to an IOMMU (via 203 - * the DMA API), don't try to attach again. 236 + * We may not always want to enable IOMMU support (for example if the 237 + * host1x firewall is already enabled and we don't support addressing 238 + * more than 32 bits of physical memory), so check for that first. 239 + * 240 + * Similarly, if host1x is already attached to an IOMMU (via the DMA 241 + * API), don't try to attach again. 204 242 */ 205 - if (IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL) || domain) 243 + if (!host1x_wants_iommu(host) || domain) 206 244 return domain; 207 245 208 246 host->group = iommu_group_get(host->dev); ··· 539 501 bus_unregister(&host1x_bus_type); 540 502 } 541 503 module_exit(tegra_host1x_exit); 504 + 505 + /** 506 + * host1x_get_dma_mask() - query the supported DMA mask for host1x 507 + * @host1x: host1x instance 508 + * 509 + * Note that this returns the supported DMA mask for host1x, which can be 510 + * different from the applicable DMA mask under certain circumstances. 511 + */ 512 + u64 host1x_get_dma_mask(struct host1x *host1x) 513 + { 514 + return host1x->info->dma_mask; 515 + } 516 + EXPORT_SYMBOL(host1x_get_dma_mask); 542 517 543 518 MODULE_AUTHOR("Thierry Reding <thierry.reding@avionic-design.de>"); 544 519 MODULE_AUTHOR("Terje Bergstrom <tbergstrom@nvidia.com>");
+3
include/linux/host1x.h
··· 17 17 HOST1X_CLASS_GR3D = 0x60, 18 18 }; 19 19 20 + struct host1x; 20 21 struct host1x_client; 21 22 struct iommu_group; 23 + 24 + u64 host1x_get_dma_mask(struct host1x *host1x); 22 25 23 26 /** 24 27 * struct host1x_client_ops - host1x client operations