if (!adev->mman.sdma_access_ptr)
return -EACCES;
- if (!drm_dev_enter(adev_to_drm(adev), &idx))
+ if (!adev->mman.buffer_funcs_enabled || !drm_dev_enter(adev_to_drm(adev), &idx))
return -ENODEV;
if (write)
if (enable) {
struct drm_gpu_scheduler *sched;
- if (!adev->mman.num_buffer_funcs_scheds ||
- !adev->mman.buffer_funcs_scheds[0]->ready) {
+ if (!adev->mman.num_buffer_funcs_scheds) {
dev_warn(adev->dev, "Not enabling DMA transfers for in kernel use");
return;
}
{
struct drm_gpu_scheduler *sched;
struct amdgpu_vmhub *hub;
- int i;
+ int i, n;
adev->mman.buffer_funcs = buffer_funcs;
- for (i = 0; i < adev->sdma.num_instances; i++) {
+ for (i = 0, n = 0; i < adev->sdma.num_instances; i++) {
if (adev->sdma.has_page_queue)
sched = &adev->sdma.instance[i].page.sched;
else
sched = &adev->sdma.instance[i].ring.sched;
- adev->mman.buffer_funcs_scheds[i] = sched;
+
+ if (!sched->ready)
+ continue;
+
+ adev->mman.buffer_funcs_scheds[n++] = sched;
+ }
+
+ if (n == 0) {
+ adev->mman.num_buffer_funcs_scheds = 0;
+ drm_warn(&adev->ddev, "No working sdma ring available\n");
+ return;
}
/* Navi1x's workaround requires us to limit to a single SDMA sched
*/
hub = &adev->vmhub[AMDGPU_GFXHUB(0)];
adev->mman.num_buffer_funcs_scheds = hub->sdma_invalidation_workaround ?
- 1 : adev->sdma.num_instances;
+ 1 : n;
}
#if defined(CONFIG_DEBUG_FS)
cik_sdma_set_ring_funcs(adev);
cik_sdma_set_irq_funcs(adev);
- cik_sdma_set_buffer_funcs(adev);
amdgpu_sdma_set_vm_pte_scheds(adev, &cik_sdma_vm_pte_funcs);
return 0;
static int cik_sdma_hw_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = ip_block->adev;
+ int r;
+
+ r = cik_sdma_start(adev);
+ if (r)
+ return r;
+
+ cik_sdma_set_buffer_funcs(adev);
- return cik_sdma_start(adev);
+ return 0;
}
static int cik_sdma_hw_fini(struct amdgpu_ip_block *ip_block)
return r;
sdma_v2_4_set_ring_funcs(adev);
- sdma_v2_4_set_buffer_funcs(adev);
amdgpu_sdma_set_vm_pte_scheds(adev, &sdma_v2_4_vm_pte_funcs);
sdma_v2_4_set_irq_funcs(adev);
if (r)
return r;
- return r;
+ sdma_v2_4_set_buffer_funcs(adev);
+
+ return 0;
}
static int sdma_v2_4_hw_fini(struct amdgpu_ip_block *ip_block)
return r;
sdma_v3_0_set_ring_funcs(adev);
- sdma_v3_0_set_buffer_funcs(adev);
amdgpu_sdma_set_vm_pte_scheds(adev, &sdma_v3_0_vm_pte_funcs);
sdma_v3_0_set_irq_funcs(adev);
if (r)
return r;
- return r;
+ sdma_v3_0_set_buffer_funcs(adev);
+
+ return 0;
}
static int sdma_v3_0_hw_fini(struct amdgpu_ip_block *ip_block)
adev->sdma.has_page_queue = true;
sdma_v4_0_set_ring_funcs(adev);
- sdma_v4_0_set_buffer_funcs(adev);
amdgpu_sdma_set_vm_pte_scheds(adev, &sdma_v4_0_vm_pte_funcs);
sdma_v4_0_set_irq_funcs(adev);
sdma_v4_0_set_ras_funcs(adev);
static int sdma_v4_0_hw_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = ip_block->adev;
+ int r;
if (adev->flags & AMD_IS_APU)
amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_SDMA, false, 0);
if (!amdgpu_sriov_vf(adev))
sdma_v4_0_init_golden_registers(adev);
- return sdma_v4_0_start(adev);
+ r = sdma_v4_0_start(adev);
+ if (r)
+ return r;
+ sdma_v4_0_set_buffer_funcs(adev);
+
+ return 0;
}
static int sdma_v4_0_hw_fini(struct amdgpu_ip_block *ip_block)
adev->sdma.has_page_queue = true;
sdma_v4_4_2_set_ring_funcs(adev);
- sdma_v4_4_2_set_buffer_funcs(adev);
amdgpu_sdma_set_vm_pte_scheds(adev, &sdma_v4_4_2_vm_pte_funcs);
sdma_v4_4_2_set_irq_funcs(adev);
sdma_v4_4_2_set_ras_funcs(adev);
sdma_v4_4_2_inst_init_golden_registers(adev, inst_mask);
r = sdma_v4_4_2_inst_start(adev, inst_mask, false);
+ if (r)
+ return r;
+ sdma_v4_4_2_set_buffer_funcs(adev);
- return r;
+ return 0;
}
static int sdma_v4_4_2_hw_fini(struct amdgpu_ip_block *ip_block)
return r;
sdma_v5_0_set_ring_funcs(adev);
- sdma_v5_0_set_buffer_funcs(adev);
amdgpu_sdma_set_vm_pte_scheds(adev, &sdma_v5_0_vm_pte_funcs);
sdma_v5_0_set_irq_funcs(adev);
sdma_v5_0_set_mqd_funcs(adev);
sdma_v5_0_init_golden_registers(adev);
r = sdma_v5_0_start(adev);
+ if (r)
+ return r;
+ sdma_v5_0_set_buffer_funcs(adev);
- return r;
+ return 0;
}
static int sdma_v5_0_hw_fini(struct amdgpu_ip_block *ip_block)
return r;
sdma_v5_2_set_ring_funcs(adev);
- sdma_v5_2_set_buffer_funcs(adev);
amdgpu_sdma_set_vm_pte_scheds(adev, &sdma_v5_2_vm_pte_funcs);
sdma_v5_2_set_irq_funcs(adev);
sdma_v5_2_set_mqd_funcs(adev);
static int sdma_v5_2_hw_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = ip_block->adev;
+ int r;
- return sdma_v5_2_start(adev);
+ r = sdma_v5_2_start(adev);
+ if (r)
+ return r;
+ sdma_v5_2_set_buffer_funcs(adev);
+
+ return 0;
}
static int sdma_v5_2_hw_fini(struct amdgpu_ip_block *ip_block)
return r;
sdma_v6_0_set_ring_funcs(adev);
- sdma_v6_0_set_buffer_funcs(adev);
amdgpu_sdma_set_vm_pte_scheds(adev, &sdma_v6_0_vm_pte_funcs);
sdma_v6_0_set_irq_funcs(adev);
sdma_v6_0_set_mqd_funcs(adev);
r = sdma_v6_0_start(adev);
if (r)
return r;
+ sdma_v6_0_set_buffer_funcs(adev);
return sdma_v6_0_set_userq_trap_interrupts(adev, true);
}
}
sdma_v7_0_set_ring_funcs(adev);
- sdma_v7_0_set_buffer_funcs(adev);
amdgpu_sdma_set_vm_pte_scheds(adev, &sdma_v7_0_vm_pte_funcs);
sdma_v7_0_set_irq_funcs(adev);
sdma_v7_0_set_mqd_funcs(adev);
r = sdma_v7_0_start(adev);
if (r)
return r;
+ sdma_v7_0_set_buffer_funcs(adev);
return sdma_v7_0_set_userq_trap_interrupts(adev, true);
}
}
sdma_v7_1_set_ring_funcs(adev);
- sdma_v7_1_set_buffer_funcs(adev);
amdgpu_sdma_set_vm_pte_scheds(adev, &sdma_v7_1_vm_pte_funcs);
sdma_v7_1_set_irq_funcs(adev);
sdma_v7_1_set_mqd_funcs(adev);
{
struct amdgpu_device *adev = ip_block->adev;
uint32_t inst_mask;
+ int r;
inst_mask = GENMASK(adev->sdma.num_instances - 1, 0);
- return sdma_v7_1_inst_start(adev, inst_mask);
+ r = sdma_v7_1_inst_start(adev, inst_mask);
+ if (r)
+ return r;
+ sdma_v7_1_set_buffer_funcs(adev);
+
+ return 0;
}
static int sdma_v7_1_hw_fini(struct amdgpu_ip_block *ip_block)
adev->sdma.num_instances = SDMA_MAX_INSTANCE;
si_dma_set_ring_funcs(adev);
- si_dma_set_buffer_funcs(adev);
amdgpu_sdma_set_vm_pte_scheds(adev, &si_dma_vm_pte_funcs);
si_dma_set_irq_funcs(adev);
static int si_dma_hw_init(struct amdgpu_ip_block *ip_block)
{
struct amdgpu_device *adev = ip_block->adev;
+ int r;
- return si_dma_start(adev);
+ r = si_dma_start(adev);
+ if (r)
+ return r;
+ si_dma_set_buffer_funcs(adev);
+
+ return 0;
}
static int si_dma_hw_fini(struct amdgpu_ip_block *ip_block)