mirror of https://github.com/torvalds/linux.git
drm fixes for 6.18-rc5
sched: - Fix deadlock amdgpu: - Reset fixes - Misc fixes - Panel scaling fixes - HDMI fix - S0ix fixes - Hibernation fix - Secure display fix - Suspend fix - MST fix amdkfd: - Process cleanup fix xe: - Fix missing synchronization on unbind - Fix device shutdown when doing FLR - Fix user fence signaling order i915: - Avoid lock inversion when pinning to GGTT on CHV/BXT+VTD - Fix conversion between clock ticks and nanoseconds mediatek: - Disable AFBC support on Mediatek DRM driver - Add pm_runtime support for GCE power control imagination: - kconfig: Fix dependencies nouveau: - Set DMA mask earlier - Advertize correct modifiers for GB20x pixpaper: - kconfig: Fix dependencies -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEEKbZHaGwW9KfbeusDHTzWXnEhr4FAmkOahUACgkQDHTzWXnE hr4tfQ//YrAFWBzlB6u08gOKj4KuH02pT9WKT/rtG99SX2zB1PtH8Z5QpKVcrlgb 3dx2IuMm2sFGX3q17BKkNwPKTBSEVY2ISPasidpPp7Q9wLylbuzhrdIDKpGWBw+p Zq36avNUyev1WCz91t01jR/K51vG2b83rq9ZUoG+wIJswfUDmIOlfvI/TXOp7in2 801W5oMAWi+NMr8VZTTPLY0Yya5k2oMD484IO28y/UcZ37t8t8ehQp9EX8wQLL7E KPee9bngEHUcrs8thJgkUchLzXJbjnpfnOqYodkgs4s890YcvLBbJPjVPxqTymiZ BT+6NKU4YnAkufA8JPlSNM+JhSn2VzGrdkZRRnQXtVxSVlh9fUTXNJaWVSvSucod O1UgJnc+Y/qsSjQsfuxKzNdLiFEOp6u2MLe8cZR419YU+KmrjTmqu+07BQjPONN7 +JYprDuZNbYWcWNUL12Mu1EumwfSJlIqtSoZSn9zZ59ZL/IQPjjx4dA5nmasTnmz lA8J5hHWeG+TOEthVYe4/an6QUvBt+Hpq+3nG4iYMYfLQg/U2aTzic2KlZP0v/A5 s9g0hMawsXxAAnm4JGsFkBIQ92nIPpNksQDj6ynqVG3IkO9Uf/8zsVSuoxfjDycG 5PYQ4ILGlqbPYt/bW6PsWIZIMfEHcOfegwNLB8yoPDZwmpm+4y4= =COpG -----END PGP SIGNATURE----- Merge tag 'drm-fixes-2025-11-08' of https://gitlab.freedesktop.org/drm/kernel Pull drm fixes from Dave Airlie: "Back from travel, thanks to Simona for handling things. regular fixes, seems about the right size, but spread out a bit. amdgpu has the usual range of fixes, xe has a few fixes, and nouveau has a couple of fixes, one for blackwell modifiers on 8/16 bit surfaces. Otherwise a few small fixes for mediatek, sched, imagination and pixpaper. sched: - Fix deadlock amdgpu: - Reset fixes - Misc fixes - Panel scaling fixes - HDMI fix - S0ix fixes - Hibernation fix - Secure display fix - Suspend fix - MST fix amdkfd: - Process cleanup fix xe: - Fix missing synchronization on unbind - Fix device shutdown when doing FLR - Fix user fence signaling order i915: - Avoid lock inversion when pinning to GGTT on CHV/BXT+VTD - Fix conversion between clock ticks and nanoseconds mediatek: - Disable AFBC support on Mediatek DRM driver - Add pm_runtime support for GCE power control imagination: - kconfig: Fix dependencies nouveau: - Set DMA mask earlier - Advertize correct modifiers for GB20x pixpaper: - kconfig: Fix dependencies" * tag 'drm-fixes-2025-11-08' of https://gitlab.freedesktop.org/drm/kernel: (26 commits) drm/xe: Enforce correct user fence signaling order using drm/xe: Do clean shutdown also when using flr drm/xe: Move declarations under conditional branch drm/xe/guc: Synchronize Dead CT worker with unbind drm/amd/display: Enable mst when it's detected but yet to be initialized drm/amdgpu: Fix wait after reset sequence in S3 drm/amd: Fix suspend failure with secure display TA drm/amdgpu: fix gpu page fault after hibernation on PF passthrough drm/tiny: pixpaper: add explicit dependency on MMU drm/nouveau: Advertise correct modifiers on GB20x drm: define NVIDIA DRM format modifiers for GB20x drm/nouveau: set DMA mask before creating the flush page drm/sched: Fix deadlock in drm_sched_entity_kill_jobs_cb drm/amd/display: Fix NULL deref in debugfs odm_combine_segments drm/amdkfd: Don't clear PT after process killed drm/amdgpu/smu: Handle S0ix for vangogh drm/amdgpu: Drop PMFW RLC notifier from amdgpu_device_suspend() drm/amd/display: Fix black screen with HDMI outputs drm/amd/display: Don't stretch non-native images by default in eDP drm/amd/pm: fix missing device_attr cleanup in amdgpu_pm_sysfs_init() ...
This commit is contained in:
commit
e811c33b1f
|
|
@ -1267,6 +1267,10 @@ static int unmap_bo_from_gpuvm(struct kgd_mem *mem,
|
|||
|
||||
(void)amdgpu_vm_bo_unmap(adev, bo_va, entry->va);
|
||||
|
||||
/* VM entity stopped if process killed, don't clear freed pt bo */
|
||||
if (!amdgpu_vm_ready(vm))
|
||||
return 0;
|
||||
|
||||
(void)amdgpu_vm_clear_freed(adev, vm, &bo_va->last_pt_update);
|
||||
|
||||
(void)amdgpu_sync_fence(sync, bo_va->last_pt_update, GFP_KERNEL);
|
||||
|
|
|
|||
|
|
@ -5243,10 +5243,6 @@ int amdgpu_device_suspend(struct drm_device *dev, bool notify_clients)
|
|||
if (amdgpu_sriov_vf(adev))
|
||||
amdgpu_virt_release_full_gpu(adev, false);
|
||||
|
||||
r = amdgpu_dpm_notify_rlc_state(adev, false);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2632,9 +2632,14 @@ static int amdgpu_pmops_suspend_noirq(struct device *dev)
|
|||
{
|
||||
struct drm_device *drm_dev = dev_get_drvdata(dev);
|
||||
struct amdgpu_device *adev = drm_to_adev(drm_dev);
|
||||
int r;
|
||||
|
||||
if (amdgpu_acpi_should_gpu_reset(adev))
|
||||
return amdgpu_asic_reset(adev);
|
||||
if (amdgpu_acpi_should_gpu_reset(adev)) {
|
||||
amdgpu_device_lock_reset_domain(adev->reset_domain);
|
||||
r = amdgpu_asic_reset(adev);
|
||||
amdgpu_device_unlock_reset_domain(adev->reset_domain);
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2355,8 +2355,11 @@ static int psp_securedisplay_initialize(struct psp_context *psp)
|
|||
if (!ret && !psp->securedisplay_context.context.resp_status) {
|
||||
psp->securedisplay_context.context.initialized = true;
|
||||
mutex_init(&psp->securedisplay_context.mutex);
|
||||
} else
|
||||
} else {
|
||||
/* don't try again */
|
||||
psp->securedisplay_context.context.bin_desc.size_bytes = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
mutex_lock(&psp->securedisplay_context.mutex);
|
||||
|
||||
|
|
|
|||
|
|
@ -407,7 +407,8 @@ static int aqua_vanjaram_switch_partition_mode(struct amdgpu_xcp_mgr *xcp_mgr,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (adev->kfd.init_complete && !amdgpu_in_reset(adev))
|
||||
if (adev->kfd.init_complete && !amdgpu_in_reset(adev) &&
|
||||
!adev->in_suspend)
|
||||
flags |= AMDGPU_XCP_OPS_KFD;
|
||||
|
||||
if (flags & AMDGPU_XCP_OPS_KFD) {
|
||||
|
|
|
|||
|
|
@ -3102,6 +3102,11 @@ static int gfx_v6_0_sw_init(struct amdgpu_ip_block *ip_block)
|
|||
return r;
|
||||
}
|
||||
|
||||
adev->gfx.gfx_supported_reset =
|
||||
amdgpu_get_soft_full_reset_mask(&adev->gfx.gfx_ring[0]);
|
||||
adev->gfx.compute_supported_reset =
|
||||
amdgpu_get_soft_full_reset_mask(&adev->gfx.compute_ring[0]);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4399,6 +4399,11 @@ static int gfx_v7_0_sw_init(struct amdgpu_ip_block *ip_block)
|
|||
|
||||
gfx_v7_0_gpu_early_init(adev);
|
||||
|
||||
adev->gfx.gfx_supported_reset =
|
||||
amdgpu_get_soft_full_reset_mask(&adev->gfx.gfx_ring[0]);
|
||||
adev->gfx.compute_supported_reset =
|
||||
amdgpu_get_soft_full_reset_mask(&adev->gfx.compute_ring[0]);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2023,6 +2023,11 @@ static int gfx_v8_0_sw_init(struct amdgpu_ip_block *ip_block)
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
adev->gfx.gfx_supported_reset =
|
||||
amdgpu_get_soft_full_reset_mask(&adev->gfx.gfx_ring[0]);
|
||||
adev->gfx.compute_supported_reset =
|
||||
amdgpu_get_soft_full_reset_mask(&adev->gfx.compute_ring[0]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2292,7 +2292,9 @@ static int gfx_v9_4_3_cp_resume(struct amdgpu_device *adev)
|
|||
r = amdgpu_xcp_init(adev->xcp_mgr, num_xcp, mode);
|
||||
|
||||
} else {
|
||||
if (amdgpu_xcp_query_partition_mode(adev->xcp_mgr,
|
||||
if (adev->in_suspend)
|
||||
amdgpu_xcp_restore_partition_mode(adev->xcp_mgr);
|
||||
else if (amdgpu_xcp_query_partition_mode(adev->xcp_mgr,
|
||||
AMDGPU_XCP_FL_NONE) ==
|
||||
AMDGPU_UNKNOWN_COMPUTE_PARTITION_MODE)
|
||||
r = amdgpu_xcp_switch_partition_mode(
|
||||
|
|
|
|||
|
|
@ -142,13 +142,37 @@ static int psp_v11_0_init_microcode(struct psp_context *psp)
|
|||
return err;
|
||||
}
|
||||
|
||||
static int psp_v11_wait_for_tos_unload(struct psp_context *psp)
|
||||
{
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
uint32_t sol_reg1, sol_reg2;
|
||||
int retry_loop;
|
||||
|
||||
/* Wait for the TOS to be unloaded */
|
||||
for (retry_loop = 0; retry_loop < 20; retry_loop++) {
|
||||
sol_reg1 = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81);
|
||||
usleep_range(1000, 2000);
|
||||
sol_reg2 = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81);
|
||||
if (sol_reg1 == sol_reg2)
|
||||
return 0;
|
||||
}
|
||||
dev_err(adev->dev, "TOS unload failed, C2PMSG_33: %x C2PMSG_81: %x",
|
||||
RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_33),
|
||||
RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81));
|
||||
|
||||
return -ETIME;
|
||||
}
|
||||
|
||||
static int psp_v11_0_wait_for_bootloader(struct psp_context *psp)
|
||||
{
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
|
||||
int ret;
|
||||
int retry_loop;
|
||||
|
||||
/* For a reset done at the end of S3, only wait for TOS to be unloaded */
|
||||
if (adev->in_s3 && !(adev->flags & AMD_IS_APU) && amdgpu_in_reset(adev))
|
||||
return psp_v11_wait_for_tos_unload(psp);
|
||||
|
||||
for (retry_loop = 0; retry_loop < 20; retry_loop++) {
|
||||
/* Wait for bootloader to signify that is
|
||||
ready having bit 31 of C2PMSG_35 set to 1 */
|
||||
|
|
|
|||
|
|
@ -3563,6 +3563,7 @@ static int dm_resume(struct amdgpu_ip_block *ip_block)
|
|||
/* Do mst topology probing after resuming cached state*/
|
||||
drm_connector_list_iter_begin(ddev, &iter);
|
||||
drm_for_each_connector_iter(connector, &iter) {
|
||||
bool init = false;
|
||||
|
||||
if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
|
||||
continue;
|
||||
|
|
@ -3572,7 +3573,14 @@ static int dm_resume(struct amdgpu_ip_block *ip_block)
|
|||
aconnector->mst_root)
|
||||
continue;
|
||||
|
||||
drm_dp_mst_topology_queue_probe(&aconnector->mst_mgr);
|
||||
scoped_guard(mutex, &aconnector->mst_mgr.lock) {
|
||||
init = !aconnector->mst_mgr.mst_primary;
|
||||
}
|
||||
if (init)
|
||||
dm_helpers_dp_mst_start_top_mgr(aconnector->dc_link->ctx,
|
||||
aconnector->dc_link, false);
|
||||
else
|
||||
drm_dp_mst_topology_queue_probe(&aconnector->mst_mgr);
|
||||
}
|
||||
drm_connector_list_iter_end(&iter);
|
||||
|
||||
|
|
@ -8030,7 +8038,7 @@ static int dm_encoder_helper_atomic_check(struct drm_encoder *encoder,
|
|||
"mode %dx%d@%dHz is not native, enabling scaling\n",
|
||||
adjusted_mode->hdisplay, adjusted_mode->vdisplay,
|
||||
drm_mode_vrefresh(adjusted_mode));
|
||||
dm_new_connector_state->scaling = RMX_FULL;
|
||||
dm_new_connector_state->scaling = RMX_ASPECT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1302,7 +1302,8 @@ static int odm_combine_segments_show(struct seq_file *m, void *unused)
|
|||
if (connector->status != connector_status_connected)
|
||||
return -ENODEV;
|
||||
|
||||
if (pipe_ctx != NULL && pipe_ctx->stream_res.tg->funcs->get_odm_combine_segments)
|
||||
if (pipe_ctx && pipe_ctx->stream_res.tg &&
|
||||
pipe_ctx->stream_res.tg->funcs->get_odm_combine_segments)
|
||||
pipe_ctx->stream_res.tg->funcs->get_odm_combine_segments(pipe_ctx->stream_res.tg, &segments);
|
||||
|
||||
seq_printf(m, "%d\n", segments);
|
||||
|
|
|
|||
|
|
@ -1141,6 +1141,7 @@ static bool detect_link_and_local_sink(struct dc_link *link,
|
|||
!sink->edid_caps.edid_hdmi)
|
||||
sink->sink_signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
|
||||
else if (dc_is_dvi_signal(sink->sink_signal) &&
|
||||
dc_is_dvi_signal(link->connector_signal) &&
|
||||
aud_support->hdmi_audio_native &&
|
||||
sink->edid_caps.edid_hdmi)
|
||||
sink->sink_signal = SIGNAL_TYPE_HDMI_TYPE_A;
|
||||
|
|
|
|||
|
|
@ -195,24 +195,6 @@ int amdgpu_dpm_set_mp1_state(struct amdgpu_device *adev,
|
|||
return ret;
|
||||
}
|
||||
|
||||
int amdgpu_dpm_notify_rlc_state(struct amdgpu_device *adev, bool en)
|
||||
{
|
||||
int ret = 0;
|
||||
const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
|
||||
|
||||
if (pp_funcs && pp_funcs->notify_rlc_state) {
|
||||
mutex_lock(&adev->pm.mutex);
|
||||
|
||||
ret = pp_funcs->notify_rlc_state(
|
||||
adev->powerplay.pp_handle,
|
||||
en);
|
||||
|
||||
mutex_unlock(&adev->pm.mutex);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int amdgpu_dpm_is_baco_supported(struct amdgpu_device *adev)
|
||||
{
|
||||
const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
|
||||
|
|
|
|||
|
|
@ -4724,14 +4724,14 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)
|
|||
ret = devm_device_add_group(adev->dev,
|
||||
&amdgpu_pm_policy_attr_group);
|
||||
if (ret)
|
||||
goto err_out0;
|
||||
goto err_out1;
|
||||
}
|
||||
|
||||
if (amdgpu_dpm_is_temp_metrics_supported(adev, SMU_TEMP_METRIC_GPUBOARD)) {
|
||||
ret = devm_device_add_group(adev->dev,
|
||||
&amdgpu_board_attr_group);
|
||||
if (ret)
|
||||
goto err_out0;
|
||||
goto err_out1;
|
||||
if (amdgpu_pm_get_sensor_generic(adev, AMDGPU_PP_SENSOR_MAXNODEPOWERLIMIT,
|
||||
(void *)&tmp) != -EOPNOTSUPP) {
|
||||
sysfs_add_file_to_group(&adev->dev->kobj,
|
||||
|
|
|
|||
|
|
@ -424,8 +424,6 @@ int amdgpu_dpm_mode1_reset(struct amdgpu_device *adev);
|
|||
int amdgpu_dpm_set_mp1_state(struct amdgpu_device *adev,
|
||||
enum pp_mp1_state mp1_state);
|
||||
|
||||
int amdgpu_dpm_notify_rlc_state(struct amdgpu_device *adev, bool en);
|
||||
|
||||
int amdgpu_dpm_set_gfx_power_up_by_imu(struct amdgpu_device *adev);
|
||||
|
||||
int amdgpu_dpm_baco_exit(struct amdgpu_device *adev);
|
||||
|
|
|
|||
|
|
@ -2040,6 +2040,12 @@ static int smu_disable_dpms(struct smu_context *smu)
|
|||
smu->is_apu && (amdgpu_in_reset(adev) || adev->in_s0ix))
|
||||
return 0;
|
||||
|
||||
/* vangogh s0ix */
|
||||
if ((amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(11, 5, 0) ||
|
||||
amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(11, 5, 2)) &&
|
||||
adev->in_s0ix)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* For gpu reset, runpm and hibernation through BACO,
|
||||
* BACO feature has to be kept enabled.
|
||||
|
|
|
|||
|
|
@ -2217,6 +2217,9 @@ static int vangogh_post_smu_init(struct smu_context *smu)
|
|||
uint32_t total_cu = adev->gfx.config.max_cu_per_sh *
|
||||
adev->gfx.config.max_sh_per_se * adev->gfx.config.max_shader_engines;
|
||||
|
||||
if (adev->in_s0ix)
|
||||
return 0;
|
||||
|
||||
/* allow message will be sent after enable message on Vangogh*/
|
||||
if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_GFXCLK_BIT) &&
|
||||
(adev->pg_flags & AMD_PG_SUPPORT_GFX_PG)) {
|
||||
|
|
|
|||
|
|
@ -205,7 +205,7 @@ static u64 div_u64_roundup(u64 nom, u32 den)
|
|||
|
||||
u64 intel_gt_clock_interval_to_ns(const struct intel_gt *gt, u64 count)
|
||||
{
|
||||
return div_u64_roundup(count * NSEC_PER_SEC, gt->clock_frequency);
|
||||
return mul_u64_u32_div(count, NSEC_PER_SEC, gt->clock_frequency);
|
||||
}
|
||||
|
||||
u64 intel_gt_pm_interval_to_ns(const struct intel_gt *gt, u64 count)
|
||||
|
|
@ -215,7 +215,7 @@ u64 intel_gt_pm_interval_to_ns(const struct intel_gt *gt, u64 count)
|
|||
|
||||
u64 intel_gt_ns_to_clock_interval(const struct intel_gt *gt, u64 ns)
|
||||
{
|
||||
return div_u64_roundup(gt->clock_frequency * ns, NSEC_PER_SEC);
|
||||
return mul_u64_u32_div(ns, gt->clock_frequency, NSEC_PER_SEC);
|
||||
}
|
||||
|
||||
u64 intel_gt_ns_to_pm_interval(const struct intel_gt *gt, u64 ns)
|
||||
|
|
|
|||
|
|
@ -1595,8 +1595,20 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
|
|||
err_vma_res:
|
||||
i915_vma_resource_free(vma_res);
|
||||
err_fence:
|
||||
if (work)
|
||||
dma_fence_work_commit_imm(&work->base);
|
||||
if (work) {
|
||||
/*
|
||||
* When pinning VMA to GGTT on CHV or BXT with VTD enabled,
|
||||
* commit VMA binding asynchronously to avoid risk of lock
|
||||
* inversion among reservation_ww locks held here and
|
||||
* cpu_hotplug_lock acquired from stop_machine(), which we
|
||||
* wrap around GGTT updates when running in those environments.
|
||||
*/
|
||||
if (i915_vma_is_ggtt(vma) &&
|
||||
intel_vm_no_concurrent_access_wa(vma->vm->i915))
|
||||
dma_fence_work_commit(&work->base);
|
||||
else
|
||||
dma_fence_work_commit_imm(&work->base);
|
||||
}
|
||||
err_rpm:
|
||||
intel_runtime_pm_put(&vma->vm->i915->runtime_pm, wakeref);
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ config DRM_POWERVR
|
|||
depends on DRM
|
||||
depends on MMU
|
||||
depends on PM
|
||||
depends on POWER_SEQUENCING || !POWER_SEQUENCING
|
||||
select DRM_EXEC
|
||||
select DRM_GEM_SHMEM_HELPER
|
||||
select DRM_SCHED
|
||||
|
|
|
|||
|
|
@ -283,6 +283,10 @@ static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
|
|||
unsigned int i;
|
||||
unsigned long flags;
|
||||
|
||||
/* release GCE HW usage and start autosuspend */
|
||||
pm_runtime_mark_last_busy(cmdq_cl->chan->mbox->dev);
|
||||
pm_runtime_put_autosuspend(cmdq_cl->chan->mbox->dev);
|
||||
|
||||
if (data->sta < 0)
|
||||
return;
|
||||
|
||||
|
|
@ -618,6 +622,9 @@ static void mtk_crtc_update_config(struct mtk_crtc *mtk_crtc, bool needs_vblank)
|
|||
mtk_crtc->config_updating = false;
|
||||
spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
|
||||
|
||||
if (pm_runtime_resume_and_get(mtk_crtc->cmdq_client.chan->mbox->dev) < 0)
|
||||
goto update_config_out;
|
||||
|
||||
mbox_send_message(mtk_crtc->cmdq_client.chan, cmdq_handle);
|
||||
mbox_client_txdone(mtk_crtc->cmdq_client.chan, 0);
|
||||
goto update_config_out;
|
||||
|
|
|
|||
|
|
@ -21,9 +21,6 @@
|
|||
|
||||
static const u64 modifiers[] = {
|
||||
DRM_FORMAT_MOD_LINEAR,
|
||||
DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
|
||||
AFBC_FORMAT_MOD_SPLIT |
|
||||
AFBC_FORMAT_MOD_SPARSE),
|
||||
DRM_FORMAT_MOD_INVALID,
|
||||
};
|
||||
|
||||
|
|
@ -71,26 +68,7 @@ static bool mtk_plane_format_mod_supported(struct drm_plane *plane,
|
|||
uint32_t format,
|
||||
uint64_t modifier)
|
||||
{
|
||||
if (modifier == DRM_FORMAT_MOD_LINEAR)
|
||||
return true;
|
||||
|
||||
if (modifier != DRM_FORMAT_MOD_ARM_AFBC(
|
||||
AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
|
||||
AFBC_FORMAT_MOD_SPLIT |
|
||||
AFBC_FORMAT_MOD_SPARSE))
|
||||
return false;
|
||||
|
||||
if (format != DRM_FORMAT_XRGB8888 &&
|
||||
format != DRM_FORMAT_ARGB8888 &&
|
||||
format != DRM_FORMAT_BGRX8888 &&
|
||||
format != DRM_FORMAT_BGRA8888 &&
|
||||
format != DRM_FORMAT_ABGR8888 &&
|
||||
format != DRM_FORMAT_XBGR8888 &&
|
||||
format != DRM_FORMAT_RGB888 &&
|
||||
format != DRM_FORMAT_BGR888)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return modifier == DRM_FORMAT_MOD_LINEAR;
|
||||
}
|
||||
|
||||
static void mtk_plane_destroy_state(struct drm_plane *plane,
|
||||
|
|
|
|||
|
|
@ -2867,7 +2867,9 @@ nv50_display_create(struct drm_device *dev)
|
|||
}
|
||||
|
||||
/* Assign the correct format modifiers */
|
||||
if (disp->disp->object.oclass >= TU102_DISP)
|
||||
if (disp->disp->object.oclass >= GB202_DISP)
|
||||
nouveau_display(dev)->format_modifiers = wndwca7e_modifiers;
|
||||
else if (disp->disp->object.oclass >= TU102_DISP)
|
||||
nouveau_display(dev)->format_modifiers = wndwc57e_modifiers;
|
||||
else
|
||||
if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_FERMI)
|
||||
|
|
|
|||
|
|
@ -104,4 +104,5 @@ struct nouveau_encoder *nv50_real_outp(struct drm_encoder *encoder);
|
|||
extern const u64 disp50xx_modifiers[];
|
||||
extern const u64 disp90xx_modifiers[];
|
||||
extern const u64 wndwc57e_modifiers[];
|
||||
extern const u64 wndwca7e_modifiers[];
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -786,13 +786,14 @@ nv50_wndw_destroy(struct drm_plane *plane)
|
|||
}
|
||||
|
||||
/* This function assumes the format has already been validated against the plane
|
||||
* and the modifier was validated against the device-wides modifier list at FB
|
||||
* and the modifier was validated against the device-wide modifier list at FB
|
||||
* creation time.
|
||||
*/
|
||||
static bool nv50_plane_format_mod_supported(struct drm_plane *plane,
|
||||
u32 format, u64 modifier)
|
||||
{
|
||||
struct nouveau_drm *drm = nouveau_drm(plane->dev);
|
||||
const struct drm_format_info *info = drm_format_info(format);
|
||||
uint8_t i;
|
||||
|
||||
/* All chipsets can display all formats in linear layout */
|
||||
|
|
@ -800,13 +801,32 @@ static bool nv50_plane_format_mod_supported(struct drm_plane *plane,
|
|||
return true;
|
||||
|
||||
if (drm->client.device.info.chipset < 0xc0) {
|
||||
const struct drm_format_info *info = drm_format_info(format);
|
||||
const uint8_t kind = (modifier >> 12) & 0xff;
|
||||
|
||||
if (!format) return false;
|
||||
|
||||
for (i = 0; i < info->num_planes; i++)
|
||||
if ((info->cpp[i] != 4) && kind != 0x70) return false;
|
||||
} else if (drm->client.device.info.chipset >= 0x1b2) {
|
||||
const uint8_t slayout = ((modifier >> 22) & 0x1) |
|
||||
((modifier >> 25) & 0x6);
|
||||
|
||||
if (!format)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Note in practice this implies only formats where cpp is equal
|
||||
* for each plane, or >= 4 for all planes, are supported.
|
||||
*/
|
||||
for (i = 0; i < info->num_planes; i++) {
|
||||
if (((info->cpp[i] == 2) && slayout != 3) ||
|
||||
((info->cpp[i] == 1) && slayout != 2) ||
|
||||
((info->cpp[i] >= 4) && slayout != 1))
|
||||
return false;
|
||||
|
||||
/* 24-bit not supported. It has yet another layout */
|
||||
WARN_ON(info->cpp[i] == 3);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -179,6 +179,39 @@ wndwca7e_ntfy_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
* Log2(block height) ----------------------------+ *
|
||||
* Page Kind ----------------------------------+ | *
|
||||
* Gob Height/Page Kind Generation ------+ | | *
|
||||
* Sector layout -------+ | | | *
|
||||
* Compression ------+ | | | | */
|
||||
const u64 wndwca7e_modifiers[] = { /* | | | | | */
|
||||
/* 4cpp+ modifiers */
|
||||
DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 0),
|
||||
DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 1),
|
||||
DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 2),
|
||||
DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 3),
|
||||
DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 4),
|
||||
DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 1, 2, 0x06, 5),
|
||||
/* 1cpp/8bpp modifiers */
|
||||
DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 2, 2, 0x06, 0),
|
||||
DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 2, 2, 0x06, 1),
|
||||
DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 2, 2, 0x06, 2),
|
||||
DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 2, 2, 0x06, 3),
|
||||
DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 2, 2, 0x06, 4),
|
||||
DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 2, 2, 0x06, 5),
|
||||
/* 2cpp/16bpp modifiers */
|
||||
DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 3, 2, 0x06, 0),
|
||||
DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 3, 2, 0x06, 1),
|
||||
DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 3, 2, 0x06, 2),
|
||||
DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 3, 2, 0x06, 3),
|
||||
DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 3, 2, 0x06, 4),
|
||||
DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 3, 2, 0x06, 5),
|
||||
/* All formats support linear */
|
||||
DRM_FORMAT_MOD_LINEAR,
|
||||
DRM_FORMAT_MOD_INVALID
|
||||
};
|
||||
|
||||
static const struct nv50_wndw_func
|
||||
wndwca7e = {
|
||||
.acquire = wndwc37e_acquire,
|
||||
|
|
|
|||
|
|
@ -1695,6 +1695,18 @@ nvkm_device_pci_new(struct pci_dev *pci_dev, const char *cfg, const char *dbg,
|
|||
*pdevice = &pdev->device;
|
||||
pdev->pdev = pci_dev;
|
||||
|
||||
/* Set DMA mask based on capabilities reported by the MMU subdev. */
|
||||
if (pdev->device.mmu && !pdev->device.pci->agp.bridge)
|
||||
bits = pdev->device.mmu->dma_bits;
|
||||
else
|
||||
bits = 32;
|
||||
|
||||
ret = dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(bits));
|
||||
if (ret && bits != 32) {
|
||||
dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(32));
|
||||
pdev->device.mmu->dma_bits = 32;
|
||||
}
|
||||
|
||||
ret = nvkm_device_ctor(&nvkm_device_pci_func, quirk, &pci_dev->dev,
|
||||
pci_is_pcie(pci_dev) ? NVKM_DEVICE_PCIE :
|
||||
pci_find_capability(pci_dev, PCI_CAP_ID_AGP) ?
|
||||
|
|
@ -1708,17 +1720,5 @@ nvkm_device_pci_new(struct pci_dev *pci_dev, const char *cfg, const char *dbg,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Set DMA mask based on capabilities reported by the MMU subdev. */
|
||||
if (pdev->device.mmu && !pdev->device.pci->agp.bridge)
|
||||
bits = pdev->device.mmu->dma_bits;
|
||||
else
|
||||
bits = 32;
|
||||
|
||||
ret = dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(bits));
|
||||
if (ret && bits != 32) {
|
||||
dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(32));
|
||||
pdev->device.mmu->dma_bits = 32;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -173,26 +173,15 @@ int drm_sched_entity_error(struct drm_sched_entity *entity)
|
|||
}
|
||||
EXPORT_SYMBOL(drm_sched_entity_error);
|
||||
|
||||
static void drm_sched_entity_kill_jobs_cb(struct dma_fence *f,
|
||||
struct dma_fence_cb *cb);
|
||||
|
||||
static void drm_sched_entity_kill_jobs_work(struct work_struct *wrk)
|
||||
{
|
||||
struct drm_sched_job *job = container_of(wrk, typeof(*job), work);
|
||||
|
||||
drm_sched_fence_scheduled(job->s_fence, NULL);
|
||||
drm_sched_fence_finished(job->s_fence, -ESRCH);
|
||||
WARN_ON(job->s_fence->parent);
|
||||
job->sched->ops->free_job(job);
|
||||
}
|
||||
|
||||
/* Signal the scheduler finished fence when the entity in question is killed. */
|
||||
static void drm_sched_entity_kill_jobs_cb(struct dma_fence *f,
|
||||
struct dma_fence_cb *cb)
|
||||
{
|
||||
struct drm_sched_job *job = container_of(cb, struct drm_sched_job,
|
||||
finish_cb);
|
||||
struct dma_fence *f;
|
||||
unsigned long index;
|
||||
|
||||
dma_fence_put(f);
|
||||
|
||||
/* Wait for all dependencies to avoid data corruptions */
|
||||
xa_for_each(&job->dependencies, index, f) {
|
||||
struct drm_sched_fence *s_fence = to_drm_sched_fence(f);
|
||||
|
|
@ -220,6 +209,21 @@ static void drm_sched_entity_kill_jobs_cb(struct dma_fence *f,
|
|||
dma_fence_put(f);
|
||||
}
|
||||
|
||||
drm_sched_fence_scheduled(job->s_fence, NULL);
|
||||
drm_sched_fence_finished(job->s_fence, -ESRCH);
|
||||
WARN_ON(job->s_fence->parent);
|
||||
job->sched->ops->free_job(job);
|
||||
}
|
||||
|
||||
/* Signal the scheduler finished fence when the entity in question is killed. */
|
||||
static void drm_sched_entity_kill_jobs_cb(struct dma_fence *f,
|
||||
struct dma_fence_cb *cb)
|
||||
{
|
||||
struct drm_sched_job *job = container_of(cb, struct drm_sched_job,
|
||||
finish_cb);
|
||||
|
||||
dma_fence_put(f);
|
||||
|
||||
INIT_WORK(&job->work, drm_sched_entity_kill_jobs_work);
|
||||
schedule_work(&job->work);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ config DRM_PANEL_MIPI_DBI
|
|||
config DRM_PIXPAPER
|
||||
tristate "DRM support for PIXPAPER display panels"
|
||||
depends on DRM && SPI
|
||||
depends on MMU
|
||||
select DRM_CLIENT_SELECTION
|
||||
select DRM_GEM_SHMEM_HELPER
|
||||
select DRM_KMS_HELPER
|
||||
|
|
|
|||
|
|
@ -988,16 +988,16 @@ void xe_device_shutdown(struct xe_device *xe)
|
|||
|
||||
drm_dbg(&xe->drm, "Shutting down device\n");
|
||||
|
||||
if (xe_driver_flr_disabled(xe)) {
|
||||
xe_display_pm_shutdown(xe);
|
||||
xe_display_pm_shutdown(xe);
|
||||
|
||||
xe_irq_suspend(xe);
|
||||
xe_irq_suspend(xe);
|
||||
|
||||
for_each_gt(gt, xe, id)
|
||||
xe_gt_shutdown(gt);
|
||||
for_each_gt(gt, xe, id)
|
||||
xe_gt_shutdown(gt);
|
||||
|
||||
xe_display_pm_shutdown_late(xe);
|
||||
} else {
|
||||
xe_display_pm_shutdown_late(xe);
|
||||
|
||||
if (!xe_driver_flr_disabled(xe)) {
|
||||
/* BOOM! */
|
||||
__xe_driver_flr(xe);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -165,7 +165,8 @@ int xe_exec_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
|
|||
|
||||
for (num_syncs = 0; num_syncs < args->num_syncs; num_syncs++) {
|
||||
err = xe_sync_entry_parse(xe, xef, &syncs[num_syncs],
|
||||
&syncs_user[num_syncs], SYNC_PARSE_FLAG_EXEC |
|
||||
&syncs_user[num_syncs], NULL, 0,
|
||||
SYNC_PARSE_FLAG_EXEC |
|
||||
(xe_vm_in_lr_mode(vm) ?
|
||||
SYNC_PARSE_FLAG_LR_MODE : 0));
|
||||
if (err)
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include <drm/drm_device.h>
|
||||
#include <drm/drm_drv.h>
|
||||
#include <drm/drm_file.h>
|
||||
#include <drm/drm_syncobj.h>
|
||||
#include <uapi/drm/xe_drm.h>
|
||||
|
||||
#include "xe_dep_scheduler.h"
|
||||
|
|
@ -324,6 +325,16 @@ struct xe_exec_queue *xe_exec_queue_create_bind(struct xe_device *xe,
|
|||
}
|
||||
xe_vm_put(migrate_vm);
|
||||
|
||||
if (!IS_ERR(q)) {
|
||||
int err = drm_syncobj_create(&q->ufence_syncobj,
|
||||
DRM_SYNCOBJ_CREATE_SIGNALED,
|
||||
NULL);
|
||||
if (err) {
|
||||
xe_exec_queue_put(q);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
}
|
||||
|
||||
return q;
|
||||
}
|
||||
ALLOW_ERROR_INJECTION(xe_exec_queue_create_bind, ERRNO);
|
||||
|
|
@ -333,6 +344,9 @@ void xe_exec_queue_destroy(struct kref *ref)
|
|||
struct xe_exec_queue *q = container_of(ref, struct xe_exec_queue, refcount);
|
||||
struct xe_exec_queue *eq, *next;
|
||||
|
||||
if (q->ufence_syncobj)
|
||||
drm_syncobj_put(q->ufence_syncobj);
|
||||
|
||||
if (xe_exec_queue_uses_pxp(q))
|
||||
xe_pxp_exec_queue_remove(gt_to_xe(q->gt)->pxp, q);
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#include "xe_hw_fence_types.h"
|
||||
#include "xe_lrc_types.h"
|
||||
|
||||
struct drm_syncobj;
|
||||
struct xe_execlist_exec_queue;
|
||||
struct xe_gt;
|
||||
struct xe_guc_exec_queue;
|
||||
|
|
@ -155,6 +156,12 @@ struct xe_exec_queue {
|
|||
struct list_head link;
|
||||
} pxp;
|
||||
|
||||
/** @ufence_syncobj: User fence syncobj */
|
||||
struct drm_syncobj *ufence_syncobj;
|
||||
|
||||
/** @ufence_timeline_value: User fence timeline value */
|
||||
u64 ufence_timeline_value;
|
||||
|
||||
/** @ops: submission backend exec queue operations */
|
||||
const struct xe_exec_queue_ops *ops;
|
||||
|
||||
|
|
|
|||
|
|
@ -200,6 +200,9 @@ static void guc_ct_fini(struct drm_device *drm, void *arg)
|
|||
{
|
||||
struct xe_guc_ct *ct = arg;
|
||||
|
||||
#if IS_ENABLED(CONFIG_DRM_XE_DEBUG)
|
||||
cancel_work_sync(&ct->dead.worker);
|
||||
#endif
|
||||
ct_exit_safe_mode(ct);
|
||||
destroy_workqueue(ct->g2h_wq);
|
||||
xa_destroy(&ct->fence_lookup);
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include <drm/drm_drv.h>
|
||||
#include <drm/drm_managed.h>
|
||||
#include <drm/drm_syncobj.h>
|
||||
#include <uapi/drm/xe_drm.h>
|
||||
|
||||
#include <generated/xe_wa_oob.h>
|
||||
|
|
@ -1389,7 +1390,9 @@ static int xe_oa_user_extensions(struct xe_oa *oa, enum xe_oa_user_extn_from fro
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int xe_oa_parse_syncs(struct xe_oa *oa, struct xe_oa_open_param *param)
|
||||
static int xe_oa_parse_syncs(struct xe_oa *oa,
|
||||
struct xe_oa_stream *stream,
|
||||
struct xe_oa_open_param *param)
|
||||
{
|
||||
int ret, num_syncs, num_ufence = 0;
|
||||
|
||||
|
|
@ -1409,7 +1412,9 @@ static int xe_oa_parse_syncs(struct xe_oa *oa, struct xe_oa_open_param *param)
|
|||
|
||||
for (num_syncs = 0; num_syncs < param->num_syncs; num_syncs++) {
|
||||
ret = xe_sync_entry_parse(oa->xe, param->xef, ¶m->syncs[num_syncs],
|
||||
¶m->syncs_user[num_syncs], 0);
|
||||
¶m->syncs_user[num_syncs],
|
||||
stream->ufence_syncobj,
|
||||
++stream->ufence_timeline_value, 0);
|
||||
if (ret)
|
||||
goto err_syncs;
|
||||
|
||||
|
|
@ -1539,7 +1544,7 @@ static long xe_oa_config_locked(struct xe_oa_stream *stream, u64 arg)
|
|||
return -ENODEV;
|
||||
|
||||
param.xef = stream->xef;
|
||||
err = xe_oa_parse_syncs(stream->oa, ¶m);
|
||||
err = xe_oa_parse_syncs(stream->oa, stream, ¶m);
|
||||
if (err)
|
||||
goto err_config_put;
|
||||
|
||||
|
|
@ -1635,6 +1640,7 @@ static void xe_oa_destroy_locked(struct xe_oa_stream *stream)
|
|||
if (stream->exec_q)
|
||||
xe_exec_queue_put(stream->exec_q);
|
||||
|
||||
drm_syncobj_put(stream->ufence_syncobj);
|
||||
kfree(stream);
|
||||
}
|
||||
|
||||
|
|
@ -1826,6 +1832,7 @@ static int xe_oa_stream_open_ioctl_locked(struct xe_oa *oa,
|
|||
struct xe_oa_open_param *param)
|
||||
{
|
||||
struct xe_oa_stream *stream;
|
||||
struct drm_syncobj *ufence_syncobj;
|
||||
int stream_fd;
|
||||
int ret;
|
||||
|
||||
|
|
@ -1836,17 +1843,31 @@ static int xe_oa_stream_open_ioctl_locked(struct xe_oa *oa,
|
|||
goto exit;
|
||||
}
|
||||
|
||||
ret = drm_syncobj_create(&ufence_syncobj, DRM_SYNCOBJ_CREATE_SIGNALED,
|
||||
NULL);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
stream = kzalloc(sizeof(*stream), GFP_KERNEL);
|
||||
if (!stream) {
|
||||
ret = -ENOMEM;
|
||||
goto exit;
|
||||
goto err_syncobj;
|
||||
}
|
||||
|
||||
stream->ufence_syncobj = ufence_syncobj;
|
||||
stream->oa = oa;
|
||||
ret = xe_oa_stream_init(stream, param);
|
||||
|
||||
ret = xe_oa_parse_syncs(oa, stream, param);
|
||||
if (ret)
|
||||
goto err_free;
|
||||
|
||||
ret = xe_oa_stream_init(stream, param);
|
||||
if (ret) {
|
||||
while (param->num_syncs--)
|
||||
xe_sync_entry_cleanup(¶m->syncs[param->num_syncs]);
|
||||
kfree(param->syncs);
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
if (!param->disabled) {
|
||||
ret = xe_oa_enable_locked(stream);
|
||||
if (ret)
|
||||
|
|
@ -1870,6 +1891,8 @@ static int xe_oa_stream_open_ioctl_locked(struct xe_oa *oa,
|
|||
xe_oa_stream_destroy(stream);
|
||||
err_free:
|
||||
kfree(stream);
|
||||
err_syncobj:
|
||||
drm_syncobj_put(ufence_syncobj);
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -2083,22 +2106,14 @@ int xe_oa_stream_open_ioctl(struct drm_device *dev, u64 data, struct drm_file *f
|
|||
goto err_exec_q;
|
||||
}
|
||||
|
||||
ret = xe_oa_parse_syncs(oa, ¶m);
|
||||
if (ret)
|
||||
goto err_exec_q;
|
||||
|
||||
mutex_lock(¶m.hwe->gt->oa.gt_lock);
|
||||
ret = xe_oa_stream_open_ioctl_locked(oa, ¶m);
|
||||
mutex_unlock(¶m.hwe->gt->oa.gt_lock);
|
||||
if (ret < 0)
|
||||
goto err_sync_cleanup;
|
||||
goto err_exec_q;
|
||||
|
||||
return ret;
|
||||
|
||||
err_sync_cleanup:
|
||||
while (param.num_syncs--)
|
||||
xe_sync_entry_cleanup(¶m.syncs[param.num_syncs]);
|
||||
kfree(param.syncs);
|
||||
err_exec_q:
|
||||
if (param.exec_q)
|
||||
xe_exec_queue_put(param.exec_q);
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@
|
|||
#include "regs/xe_reg_defs.h"
|
||||
#include "xe_hw_engine_types.h"
|
||||
|
||||
struct drm_syncobj;
|
||||
|
||||
#define DEFAULT_XE_OA_BUFFER_SIZE SZ_16M
|
||||
|
||||
enum xe_oa_report_header {
|
||||
|
|
@ -248,6 +250,12 @@ struct xe_oa_stream {
|
|||
/** @xef: xe_file with which the stream was opened */
|
||||
struct xe_file *xef;
|
||||
|
||||
/** @ufence_syncobj: User fence syncobj */
|
||||
struct drm_syncobj *ufence_syncobj;
|
||||
|
||||
/** @ufence_timeline_value: User fence timeline value */
|
||||
u64 ufence_timeline_value;
|
||||
|
||||
/** @last_fence: fence to use in stream destroy when needed */
|
||||
struct dma_fence *last_fence;
|
||||
|
||||
|
|
|
|||
|
|
@ -113,6 +113,8 @@ static void user_fence_cb(struct dma_fence *fence, struct dma_fence_cb *cb)
|
|||
int xe_sync_entry_parse(struct xe_device *xe, struct xe_file *xef,
|
||||
struct xe_sync_entry *sync,
|
||||
struct drm_xe_sync __user *sync_user,
|
||||
struct drm_syncobj *ufence_syncobj,
|
||||
u64 ufence_timeline_value,
|
||||
unsigned int flags)
|
||||
{
|
||||
struct drm_xe_sync sync_in;
|
||||
|
|
@ -192,10 +194,15 @@ int xe_sync_entry_parse(struct xe_device *xe, struct xe_file *xef,
|
|||
if (exec) {
|
||||
sync->addr = sync_in.addr;
|
||||
} else {
|
||||
sync->ufence_timeline_value = ufence_timeline_value;
|
||||
sync->ufence = user_fence_create(xe, sync_in.addr,
|
||||
sync_in.timeline_value);
|
||||
if (XE_IOCTL_DBG(xe, IS_ERR(sync->ufence)))
|
||||
return PTR_ERR(sync->ufence);
|
||||
sync->ufence_chain_fence = dma_fence_chain_alloc();
|
||||
if (!sync->ufence_chain_fence)
|
||||
return -ENOMEM;
|
||||
sync->ufence_syncobj = ufence_syncobj;
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
@ -239,7 +246,12 @@ void xe_sync_entry_signal(struct xe_sync_entry *sync, struct dma_fence *fence)
|
|||
} else if (sync->ufence) {
|
||||
int err;
|
||||
|
||||
dma_fence_get(fence);
|
||||
drm_syncobj_add_point(sync->ufence_syncobj,
|
||||
sync->ufence_chain_fence,
|
||||
fence, sync->ufence_timeline_value);
|
||||
sync->ufence_chain_fence = NULL;
|
||||
|
||||
fence = drm_syncobj_fence_get(sync->ufence_syncobj);
|
||||
user_fence_get(sync->ufence);
|
||||
err = dma_fence_add_callback(fence, &sync->ufence->cb,
|
||||
user_fence_cb);
|
||||
|
|
@ -259,7 +271,8 @@ void xe_sync_entry_cleanup(struct xe_sync_entry *sync)
|
|||
drm_syncobj_put(sync->syncobj);
|
||||
dma_fence_put(sync->fence);
|
||||
dma_fence_chain_free(sync->chain_fence);
|
||||
if (sync->ufence)
|
||||
dma_fence_chain_free(sync->ufence_chain_fence);
|
||||
if (!IS_ERR_OR_NULL(sync->ufence))
|
||||
user_fence_put(sync->ufence);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "xe_sync_types.h"
|
||||
|
||||
struct drm_syncobj;
|
||||
struct xe_device;
|
||||
struct xe_exec_queue;
|
||||
struct xe_file;
|
||||
|
|
@ -21,6 +22,8 @@ struct xe_vm;
|
|||
int xe_sync_entry_parse(struct xe_device *xe, struct xe_file *xef,
|
||||
struct xe_sync_entry *sync,
|
||||
struct drm_xe_sync __user *sync_user,
|
||||
struct drm_syncobj *ufence_syncobj,
|
||||
u64 ufence_timeline_value,
|
||||
unsigned int flags);
|
||||
int xe_sync_entry_add_deps(struct xe_sync_entry *sync,
|
||||
struct xe_sched_job *job);
|
||||
|
|
|
|||
|
|
@ -18,9 +18,12 @@ struct xe_sync_entry {
|
|||
struct drm_syncobj *syncobj;
|
||||
struct dma_fence *fence;
|
||||
struct dma_fence_chain *chain_fence;
|
||||
struct dma_fence_chain *ufence_chain_fence;
|
||||
struct drm_syncobj *ufence_syncobj;
|
||||
struct xe_user_fence *ufence;
|
||||
u64 addr;
|
||||
u64 timeline_value;
|
||||
u64 ufence_timeline_value;
|
||||
u32 type;
|
||||
u32 flags;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3606,8 +3606,12 @@ int xe_vm_bind_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
|
|||
|
||||
syncs_user = u64_to_user_ptr(args->syncs);
|
||||
for (num_syncs = 0; num_syncs < args->num_syncs; num_syncs++) {
|
||||
struct xe_exec_queue *__q = q ?: vm->q[0];
|
||||
|
||||
err = xe_sync_entry_parse(xe, xef, &syncs[num_syncs],
|
||||
&syncs_user[num_syncs],
|
||||
__q->ufence_syncobj,
|
||||
++__q->ufence_timeline_value,
|
||||
(xe_vm_in_lr_mode(vm) ?
|
||||
SYNC_PARSE_FLAG_LR_MODE : 0) |
|
||||
(!args->num_binds ?
|
||||
|
|
|
|||
|
|
@ -979,14 +979,20 @@ extern "C" {
|
|||
* 2 = Gob Height 8, Turing+ Page Kind mapping
|
||||
* 3 = Reserved for future use.
|
||||
*
|
||||
* 22:22 s Sector layout. On Tegra GPUs prior to Xavier, there is a further
|
||||
* bit remapping step that occurs at an even lower level than the
|
||||
* page kind and block linear swizzles. This causes the layout of
|
||||
* surfaces mapped in those SOC's GPUs to be incompatible with the
|
||||
* equivalent mapping on other GPUs in the same system.
|
||||
* 22:22 s Sector layout. There is a further bit remapping step that occurs
|
||||
* 26:27 at an even lower level than the page kind and block linear
|
||||
* swizzles. This causes the bit arrangement of surfaces in memory
|
||||
* to differ subtly, and prevents direct sharing of surfaces between
|
||||
* GPUs with different layouts.
|
||||
*
|
||||
* 0 = Tegra K1 - Tegra Parker/TX2 Layout.
|
||||
* 1 = Desktop GPU and Tegra Xavier+ Layout
|
||||
* 0 = Tegra K1 - Tegra Parker/TX2 Layout
|
||||
* 1 = Pre-GB20x, GB20x 32+ bpp, GB10, Tegra Xavier-Orin Layout
|
||||
* 2 = GB20x(Blackwell 2)+ 8 bpp surface layout
|
||||
* 3 = GB20x(Blackwell 2)+ 16 bpp surface layout
|
||||
* 4 = Reserved for future use.
|
||||
* 5 = Reserved for future use.
|
||||
* 6 = Reserved for future use.
|
||||
* 7 = Reserved for future use.
|
||||
*
|
||||
* 25:23 c Lossless Framebuffer Compression type.
|
||||
*
|
||||
|
|
@ -1001,7 +1007,7 @@ extern "C" {
|
|||
* 6 = Reserved for future use
|
||||
* 7 = Reserved for future use
|
||||
*
|
||||
* 55:25 - Reserved for future use. Must be zero.
|
||||
* 55:28 - Reserved for future use. Must be zero.
|
||||
*/
|
||||
#define DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(c, s, g, k, h) \
|
||||
fourcc_mod_code(NVIDIA, (0x10 | \
|
||||
|
|
@ -1009,6 +1015,7 @@ extern "C" {
|
|||
(((k) & 0xff) << 12) | \
|
||||
(((g) & 0x3) << 20) | \
|
||||
(((s) & 0x1) << 22) | \
|
||||
(((s) & 0x6) << 25) | \
|
||||
(((c) & 0x7) << 23)))
|
||||
|
||||
/* To grandfather in prior block linear format modifiers to the above layout,
|
||||
|
|
|
|||
Loading…
Reference in New Issue