summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_device.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_device.c93
1 files changed, 54 insertions, 39 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index feab90e3efd1..942f0251c748 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -717,7 +717,12 @@ void amdgpu_device_mm_access(struct amdgpu_device *adev, loff_t pos,
if (!drm_dev_enter(adev_to_drm(adev), &idx))
return;
- BUG_ON(!IS_ALIGNED(pos, 4) || !IS_ALIGNED(size, 4));
+ if (!IS_ALIGNED(pos, 4) || !IS_ALIGNED(size, 4)) {
+ dev_err(adev->dev, "unaligned pos/size (pos=0x%llx, size=0x%zx)\n",
+ pos, size);
+ drm_dev_exit(idx);
+ return;
+ }
spin_lock_irqsave(&adev->mmio_idx_lock, flags);
for (last = pos + size; pos < last; pos += 4) {
@@ -1913,6 +1918,20 @@ static void amdgpu_uid_fini(struct amdgpu_device *adev)
adev->uid_info = NULL;
}
+static struct pci_dev *amdgpu_device_find_parent(struct amdgpu_device *adev)
+{
+ struct pci_dev *parent = adev->pdev;
+
+ /* skip upstream/downstream switches internal to dGPU */
+ while ((parent = pci_upstream_bridge(parent))) {
+ if (parent->vendor == PCI_VENDOR_ID_ATI)
+ continue;
+ break;
+ }
+
+ return parent;
+}
+
/**
* amdgpu_device_ip_early_init - run early init for hardware IPs
*
@@ -2014,7 +2033,7 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
adev->flags |= AMD_IS_PX;
if (!(adev->flags & AMD_IS_APU)) {
- parent = pcie_find_root_port(adev->pdev);
+ parent = amdgpu_device_find_parent(adev);
adev->has_pr3 = parent ? pci_pr3_present(parent) : false;
}
@@ -2221,7 +2240,6 @@ static int amdgpu_device_init_schedulers(struct amdgpu_device *adev)
{
struct drm_sched_init_args args = {
.ops = &amdgpu_sched_ops,
- .num_rqs = DRM_SCHED_PRIORITY_COUNT,
.timeout_wq = adev->reset_domain->wq,
.dev = adev->dev,
};
@@ -2460,7 +2478,7 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
if (r)
goto init_failed;
- amdgpu_ttm_set_buffer_funcs_status(adev, true);
+ amdgpu_ttm_enable_buffer_funcs(adev);
/* Don't init kfd if whole hive need to be reset during init */
if (adev->init_lvl->level != AMDGPU_INIT_LEVEL_MINIMAL_XGMI) {
@@ -3148,7 +3166,7 @@ static int amdgpu_device_ip_suspend(struct amdgpu_device *adev)
amdgpu_virt_request_full_gpu(adev, false);
}
- amdgpu_ttm_set_buffer_funcs_status(adev, false);
+ amdgpu_ttm_disable_buffer_funcs(adev);
r = amdgpu_device_ip_suspend_phase1(adev);
if (r)
@@ -3363,7 +3381,7 @@ static int amdgpu_device_ip_resume(struct amdgpu_device *adev)
r = amdgpu_device_ip_resume_phase2(adev);
- amdgpu_ttm_set_buffer_funcs_status(adev, true);
+ amdgpu_ttm_enable_buffer_funcs(adev);
if (r)
return r;
@@ -3648,6 +3666,7 @@ static int amdgpu_device_sys_interface_init(struct amdgpu_device *adev)
amdgpu_reg_state_sysfs_init(adev);
amdgpu_xcp_sysfs_init(adev);
amdgpu_uma_sysfs_init(adev);
+ amdgpu_ptl_sysfs_init(adev);
return r;
}
@@ -3664,6 +3683,7 @@ static void amdgpu_device_sys_interface_fini(struct amdgpu_device *adev)
amdgpu_reg_state_sysfs_fini(adev);
amdgpu_xcp_sysfs_fini(adev);
amdgpu_uma_sysfs_fini(adev);
+ amdgpu_ptl_sysfs_fini(adev);
}
/**
@@ -3701,7 +3721,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
adev->num_rings = 0;
RCU_INIT_POINTER(adev->gang_submit, dma_fence_get_stub());
adev->mman.buffer_funcs = NULL;
- adev->mman.buffer_funcs_ring = NULL;
+ adev->mman.num_buffer_funcs_scheds = 0;
adev->vm_manager.vm_pte_funcs = NULL;
adev->vm_manager.vm_pte_num_scheds = 0;
adev->gmc.gmc_funcs = NULL;
@@ -3732,10 +3752,14 @@ int amdgpu_device_init(struct amdgpu_device *adev,
mutex_init(&adev->virt.vf_errors.lock);
hash_init(adev->mn_hash);
mutex_init(&adev->psp.mutex);
+ mutex_init(&adev->psp.ptl.mutex);
mutex_init(&adev->notifier_lock);
mutex_init(&adev->pm.stable_pstate_ctx_lock);
mutex_init(&adev->benchmark_mutex);
mutex_init(&adev->gfx.reset_sem_mutex);
+
+ /* Associate locks with lockdep classes for ordering validation */
+ amdgpu_lockdep_set_class(adev);
/* Initialize the mutex for cleaner shader isolation between GFX and compute processes */
mutex_init(&adev->enforce_isolation_mutex);
for (i = 0; i < MAX_XCP; ++i) {
@@ -3857,6 +3881,9 @@ int amdgpu_device_init(struct amdgpu_device *adev,
* completed before the need for a different level is detected.
*/
amdgpu_set_init_level(adev, AMDGPU_INIT_LEVEL_DEFAULT);
+
+ amdgpu_device_check_iommu_direct_map(adev);
+
/* early init functions */
r = amdgpu_device_ip_early_init(adev);
if (r)
@@ -4114,8 +4141,6 @@ fence_driver_init:
if (px)
vga_switcheroo_init_domain_pm_ops(adev->dev, &adev->vga_pm_domain);
- amdgpu_device_check_iommu_direct_map(adev);
-
adev->pm_nb.notifier_call = amdgpu_device_pm_notifier;
r = register_pm_notifier(&adev->pm_nb);
if (r)
@@ -4213,7 +4238,7 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev)
/* disable ras feature must before hw fini */
amdgpu_ras_pre_fini(adev);
- amdgpu_ttm_set_buffer_funcs_status(adev, false);
+ amdgpu_ttm_disable_buffer_funcs(adev);
/*
* device went through surprise hotplug; we need to destroy topology
@@ -4480,7 +4505,7 @@ int amdgpu_device_suspend(struct drm_device *dev, bool notify_clients)
if (r)
goto unwind_userq;
- amdgpu_ttm_set_buffer_funcs_status(adev, false);
+ amdgpu_ttm_disable_buffer_funcs(adev);
amdgpu_fence_driver_hw_fini(adev);
@@ -4494,7 +4519,7 @@ int amdgpu_device_suspend(struct drm_device *dev, bool notify_clients)
return 0;
unwind_evict:
- amdgpu_ttm_set_buffer_funcs_status(adev, true);
+ amdgpu_ttm_enable_buffer_funcs(adev);
amdgpu_fence_driver_hw_init(adev);
unwind_userq:
@@ -5087,11 +5112,12 @@ link_reset_failed:
int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev,
struct amdgpu_reset_context *reset_context)
{
- int i, r = 0;
struct amdgpu_job *job = NULL;
+ struct dma_fence *fence = NULL;
struct amdgpu_device *tmp_adev = reset_context->reset_req_dev;
bool need_full_reset =
test_bit(AMDGPU_NEED_FULL_RESET, &reset_context->flags);
+ int i, r;
if (reset_context->reset_req_dev == adev)
job = reset_context->job;
@@ -5101,6 +5127,9 @@ int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev,
amdgpu_fence_driver_isr_toggle(adev, true);
+ if (job)
+ fence = &job->hw_fence->base;
+
/* block all schedulers and reset given job's ring */
for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
struct amdgpu_ring *ring = adev->rings[i];
@@ -5109,14 +5138,11 @@ int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev,
continue;
/* after all hw jobs are reset, hw fence is meaningless, so force_completion */
- amdgpu_fence_driver_force_completion(ring);
+ amdgpu_fence_driver_force_completion(ring, fence);
}
amdgpu_fence_driver_isr_toggle(adev, false);
- if (job && job->vm)
- drm_sched_increase_karma(&job->base);
-
r = amdgpu_reset_prepare_hwcontext(adev, reset_context);
/* If reset handler not implemented, continue; otherwise return */
if (r == -EOPNOTSUPP)
@@ -5228,7 +5254,7 @@ int amdgpu_device_reinit_after_reset(struct amdgpu_reset_context *reset_context)
if (r)
goto out;
- amdgpu_ttm_set_buffer_funcs_status(tmp_adev, true);
+ amdgpu_ttm_enable_buffer_funcs(tmp_adev);
r = amdgpu_device_ip_resume_phase3(tmp_adev);
if (r)
@@ -5914,8 +5940,6 @@ static void amdgpu_device_partner_bandwidth(struct amdgpu_device *adev,
enum pci_bus_speed *speed,
enum pcie_link_width *width)
{
- struct pci_dev *parent = adev->pdev;
-
if (!speed || !width)
return;
@@ -5923,13 +5947,11 @@ static void amdgpu_device_partner_bandwidth(struct amdgpu_device *adev,
*width = PCIE_LNK_WIDTH_UNKNOWN;
if (amdgpu_device_pcie_dynamic_switching_supported(adev)) {
- while ((parent = pci_upstream_bridge(parent))) {
- /* skip upstream/downstream switches internal to dGPU*/
- if (parent->vendor == PCI_VENDOR_ID_ATI)
- continue;
+ struct pci_dev *parent = amdgpu_device_find_parent(adev);
+
+ if (parent) {
*speed = pcie_get_speed_cap(parent);
*width = pcie_get_width_cap(parent);
- break;
}
} else {
/* use the current speeds rather than max if switching is not supported */
@@ -5956,22 +5978,15 @@ static void amdgpu_device_gpu_bandwidth(struct amdgpu_device *adev,
if (!speed || !width)
return;
- parent = pci_upstream_bridge(parent);
- if (parent && parent->vendor == PCI_VENDOR_ID_ATI) {
- /* use the upstream/downstream switches internal to dGPU */
+ /* use the device itself */
+ *speed = pcie_get_speed_cap(adev->pdev);
+ *width = pcie_get_width_cap(adev->pdev);
+
+ /* use the link outside the device */
+ parent = amdgpu_device_find_parent(adev);
+ if (parent) {
*speed = pcie_get_speed_cap(parent);
*width = pcie_get_width_cap(parent);
- while ((parent = pci_upstream_bridge(parent))) {
- if (parent->vendor == PCI_VENDOR_ID_ATI) {
- /* use the upstream/downstream switches internal to dGPU */
- *speed = pcie_get_speed_cap(parent);
- *width = pcie_get_width_cap(parent);
- }
- }
- } else {
- /* use the device itself */
- *speed = pcie_get_speed_cap(adev->pdev);
- *width = pcie_get_width_cap(adev->pdev);
}
}