18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Copyright 2016 Advanced Micro Devices, Inc. 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 58c2ecf20Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 68c2ecf20Sopenharmony_ci * to deal in the Software without restriction, including without limitation 78c2ecf20Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 88c2ecf20Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 98c2ecf20Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 108c2ecf20Sopenharmony_ci * 118c2ecf20Sopenharmony_ci * The above copyright notice and this permission notice shall be included in 128c2ecf20Sopenharmony_ci * all copies or substantial portions of the Software. 138c2ecf20Sopenharmony_ci * 148c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 158c2ecf20Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 168c2ecf20Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 178c2ecf20Sopenharmony_ci * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 188c2ecf20Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 198c2ecf20Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 208c2ecf20Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE. 218c2ecf20Sopenharmony_ci * 228c2ecf20Sopenharmony_ci * Authors: Christian König 238c2ecf20Sopenharmony_ci */ 248c2ecf20Sopenharmony_ci#ifndef __AMDGPU_RING_H__ 258c2ecf20Sopenharmony_ci#define __AMDGPU_RING_H__ 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci#include <drm/amdgpu_drm.h> 288c2ecf20Sopenharmony_ci#include <drm/gpu_scheduler.h> 298c2ecf20Sopenharmony_ci#include <drm/drm_print.h> 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci/* max number of rings */ 328c2ecf20Sopenharmony_ci#define AMDGPU_MAX_RINGS 28 338c2ecf20Sopenharmony_ci#define AMDGPU_MAX_HWIP_RINGS 8 348c2ecf20Sopenharmony_ci#define AMDGPU_MAX_GFX_RINGS 2 358c2ecf20Sopenharmony_ci#define AMDGPU_MAX_COMPUTE_RINGS 8 368c2ecf20Sopenharmony_ci#define AMDGPU_MAX_VCE_RINGS 3 378c2ecf20Sopenharmony_ci#define AMDGPU_MAX_UVD_ENC_RINGS 2 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci#define AMDGPU_RING_PRIO_DEFAULT 1 408c2ecf20Sopenharmony_ci#define AMDGPU_RING_PRIO_MAX AMDGPU_GFX_PIPE_PRIO_MAX 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci/* some special values for the owner field */ 438c2ecf20Sopenharmony_ci#define AMDGPU_FENCE_OWNER_UNDEFINED ((void *)0ul) 448c2ecf20Sopenharmony_ci#define AMDGPU_FENCE_OWNER_VM ((void *)1ul) 458c2ecf20Sopenharmony_ci#define AMDGPU_FENCE_OWNER_KFD ((void *)2ul) 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci#define AMDGPU_FENCE_FLAG_64BIT (1 << 0) 488c2ecf20Sopenharmony_ci#define AMDGPU_FENCE_FLAG_INT (1 << 1) 498c2ecf20Sopenharmony_ci#define AMDGPU_FENCE_FLAG_TC_WB_ONLY (1 << 2) 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci#define to_amdgpu_ring(s) container_of((s), struct amdgpu_ring, sched) 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci#define AMDGPU_IB_POOL_SIZE (1024 * 1024) 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_cienum amdgpu_ring_type { 568c2ecf20Sopenharmony_ci AMDGPU_RING_TYPE_GFX = AMDGPU_HW_IP_GFX, 578c2ecf20Sopenharmony_ci AMDGPU_RING_TYPE_COMPUTE = AMDGPU_HW_IP_COMPUTE, 588c2ecf20Sopenharmony_ci AMDGPU_RING_TYPE_SDMA = AMDGPU_HW_IP_DMA, 598c2ecf20Sopenharmony_ci AMDGPU_RING_TYPE_UVD = AMDGPU_HW_IP_UVD, 608c2ecf20Sopenharmony_ci AMDGPU_RING_TYPE_VCE = AMDGPU_HW_IP_VCE, 618c2ecf20Sopenharmony_ci AMDGPU_RING_TYPE_UVD_ENC = AMDGPU_HW_IP_UVD_ENC, 628c2ecf20Sopenharmony_ci AMDGPU_RING_TYPE_VCN_DEC = AMDGPU_HW_IP_VCN_DEC, 638c2ecf20Sopenharmony_ci AMDGPU_RING_TYPE_VCN_ENC = AMDGPU_HW_IP_VCN_ENC, 648c2ecf20Sopenharmony_ci AMDGPU_RING_TYPE_VCN_JPEG = AMDGPU_HW_IP_VCN_JPEG, 658c2ecf20Sopenharmony_ci AMDGPU_RING_TYPE_KIQ, 668c2ecf20Sopenharmony_ci AMDGPU_RING_TYPE_MES 678c2ecf20Sopenharmony_ci}; 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_cienum amdgpu_ib_pool_type { 708c2ecf20Sopenharmony_ci /* Normal submissions to the top of the pipeline. */ 718c2ecf20Sopenharmony_ci AMDGPU_IB_POOL_DELAYED, 728c2ecf20Sopenharmony_ci /* Immediate submissions to the bottom of the pipeline. */ 738c2ecf20Sopenharmony_ci AMDGPU_IB_POOL_IMMEDIATE, 748c2ecf20Sopenharmony_ci /* Direct submission to the ring buffer during init and reset. */ 758c2ecf20Sopenharmony_ci AMDGPU_IB_POOL_DIRECT, 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci AMDGPU_IB_POOL_MAX 788c2ecf20Sopenharmony_ci}; 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_cistruct amdgpu_device; 818c2ecf20Sopenharmony_cistruct amdgpu_ring; 828c2ecf20Sopenharmony_cistruct amdgpu_ib; 838c2ecf20Sopenharmony_cistruct amdgpu_cs_parser; 848c2ecf20Sopenharmony_cistruct amdgpu_job; 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_cistruct amdgpu_sched { 878c2ecf20Sopenharmony_ci u32 num_scheds; 888c2ecf20Sopenharmony_ci struct drm_gpu_scheduler *sched[AMDGPU_MAX_HWIP_RINGS]; 898c2ecf20Sopenharmony_ci}; 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci/* 928c2ecf20Sopenharmony_ci * Fences. 938c2ecf20Sopenharmony_ci */ 948c2ecf20Sopenharmony_cistruct amdgpu_fence_driver { 958c2ecf20Sopenharmony_ci uint64_t gpu_addr; 968c2ecf20Sopenharmony_ci volatile uint32_t *cpu_addr; 978c2ecf20Sopenharmony_ci /* sync_seq is protected by ring emission lock */ 988c2ecf20Sopenharmony_ci uint32_t sync_seq; 998c2ecf20Sopenharmony_ci atomic_t last_seq; 1008c2ecf20Sopenharmony_ci bool initialized; 1018c2ecf20Sopenharmony_ci struct amdgpu_irq_src *irq_src; 1028c2ecf20Sopenharmony_ci unsigned irq_type; 1038c2ecf20Sopenharmony_ci struct timer_list fallback_timer; 1048c2ecf20Sopenharmony_ci unsigned num_fences_mask; 1058c2ecf20Sopenharmony_ci spinlock_t lock; 1068c2ecf20Sopenharmony_ci struct dma_fence **fences; 1078c2ecf20Sopenharmony_ci}; 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ciint amdgpu_fence_driver_init(struct amdgpu_device *adev); 1108c2ecf20Sopenharmony_civoid amdgpu_fence_driver_fini(struct amdgpu_device *adev); 1118c2ecf20Sopenharmony_civoid amdgpu_fence_driver_force_completion(struct amdgpu_ring *ring); 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ciint amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring, 1148c2ecf20Sopenharmony_ci unsigned num_hw_submission); 1158c2ecf20Sopenharmony_ciint amdgpu_fence_driver_start_ring(struct amdgpu_ring *ring, 1168c2ecf20Sopenharmony_ci struct amdgpu_irq_src *irq_src, 1178c2ecf20Sopenharmony_ci unsigned irq_type); 1188c2ecf20Sopenharmony_civoid amdgpu_fence_driver_suspend(struct amdgpu_device *adev); 1198c2ecf20Sopenharmony_civoid amdgpu_fence_driver_resume(struct amdgpu_device *adev); 1208c2ecf20Sopenharmony_ciint amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **fence, 1218c2ecf20Sopenharmony_ci unsigned flags); 1228c2ecf20Sopenharmony_ciint amdgpu_fence_emit_polling(struct amdgpu_ring *ring, uint32_t *s, 1238c2ecf20Sopenharmony_ci uint32_t timeout); 1248c2ecf20Sopenharmony_cibool amdgpu_fence_process(struct amdgpu_ring *ring); 1258c2ecf20Sopenharmony_ciint amdgpu_fence_wait_empty(struct amdgpu_ring *ring); 1268c2ecf20Sopenharmony_cisigned long amdgpu_fence_wait_polling(struct amdgpu_ring *ring, 1278c2ecf20Sopenharmony_ci uint32_t wait_seq, 1288c2ecf20Sopenharmony_ci signed long timeout); 1298c2ecf20Sopenharmony_ciunsigned amdgpu_fence_count_emitted(struct amdgpu_ring *ring); 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci/* 1328c2ecf20Sopenharmony_ci * Rings. 1338c2ecf20Sopenharmony_ci */ 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci/* provided by hw blocks that expose a ring buffer for commands */ 1368c2ecf20Sopenharmony_cistruct amdgpu_ring_funcs { 1378c2ecf20Sopenharmony_ci enum amdgpu_ring_type type; 1388c2ecf20Sopenharmony_ci uint32_t align_mask; 1398c2ecf20Sopenharmony_ci u32 nop; 1408c2ecf20Sopenharmony_ci bool support_64bit_ptrs; 1418c2ecf20Sopenharmony_ci bool no_user_fence; 1428c2ecf20Sopenharmony_ci unsigned vmhub; 1438c2ecf20Sopenharmony_ci unsigned extra_dw; 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_ci /* ring read/write ptr handling */ 1468c2ecf20Sopenharmony_ci u64 (*get_rptr)(struct amdgpu_ring *ring); 1478c2ecf20Sopenharmony_ci u64 (*get_wptr)(struct amdgpu_ring *ring); 1488c2ecf20Sopenharmony_ci void (*set_wptr)(struct amdgpu_ring *ring); 1498c2ecf20Sopenharmony_ci /* validating and patching of IBs */ 1508c2ecf20Sopenharmony_ci int (*parse_cs)(struct amdgpu_cs_parser *p, uint32_t ib_idx); 1518c2ecf20Sopenharmony_ci int (*patch_cs_in_place)(struct amdgpu_cs_parser *p, uint32_t ib_idx); 1528c2ecf20Sopenharmony_ci /* constants to calculate how many DW are needed for an emit */ 1538c2ecf20Sopenharmony_ci unsigned emit_frame_size; 1548c2ecf20Sopenharmony_ci unsigned emit_ib_size; 1558c2ecf20Sopenharmony_ci /* command emit functions */ 1568c2ecf20Sopenharmony_ci void (*emit_ib)(struct amdgpu_ring *ring, 1578c2ecf20Sopenharmony_ci struct amdgpu_job *job, 1588c2ecf20Sopenharmony_ci struct amdgpu_ib *ib, 1598c2ecf20Sopenharmony_ci uint32_t flags); 1608c2ecf20Sopenharmony_ci void (*emit_fence)(struct amdgpu_ring *ring, uint64_t addr, 1618c2ecf20Sopenharmony_ci uint64_t seq, unsigned flags); 1628c2ecf20Sopenharmony_ci void (*emit_pipeline_sync)(struct amdgpu_ring *ring); 1638c2ecf20Sopenharmony_ci void (*emit_vm_flush)(struct amdgpu_ring *ring, unsigned vmid, 1648c2ecf20Sopenharmony_ci uint64_t pd_addr); 1658c2ecf20Sopenharmony_ci void (*emit_hdp_flush)(struct amdgpu_ring *ring); 1668c2ecf20Sopenharmony_ci void (*emit_gds_switch)(struct amdgpu_ring *ring, uint32_t vmid, 1678c2ecf20Sopenharmony_ci uint32_t gds_base, uint32_t gds_size, 1688c2ecf20Sopenharmony_ci uint32_t gws_base, uint32_t gws_size, 1698c2ecf20Sopenharmony_ci uint32_t oa_base, uint32_t oa_size); 1708c2ecf20Sopenharmony_ci /* testing functions */ 1718c2ecf20Sopenharmony_ci int (*test_ring)(struct amdgpu_ring *ring); 1728c2ecf20Sopenharmony_ci int (*test_ib)(struct amdgpu_ring *ring, long timeout); 1738c2ecf20Sopenharmony_ci /* insert NOP packets */ 1748c2ecf20Sopenharmony_ci void (*insert_nop)(struct amdgpu_ring *ring, uint32_t count); 1758c2ecf20Sopenharmony_ci void (*insert_start)(struct amdgpu_ring *ring); 1768c2ecf20Sopenharmony_ci void (*insert_end)(struct amdgpu_ring *ring); 1778c2ecf20Sopenharmony_ci /* pad the indirect buffer to the necessary number of dw */ 1788c2ecf20Sopenharmony_ci void (*pad_ib)(struct amdgpu_ring *ring, struct amdgpu_ib *ib); 1798c2ecf20Sopenharmony_ci unsigned (*init_cond_exec)(struct amdgpu_ring *ring); 1808c2ecf20Sopenharmony_ci void (*patch_cond_exec)(struct amdgpu_ring *ring, unsigned offset); 1818c2ecf20Sopenharmony_ci /* note usage for clock and power gating */ 1828c2ecf20Sopenharmony_ci void (*begin_use)(struct amdgpu_ring *ring); 1838c2ecf20Sopenharmony_ci void (*end_use)(struct amdgpu_ring *ring); 1848c2ecf20Sopenharmony_ci void (*emit_switch_buffer) (struct amdgpu_ring *ring); 1858c2ecf20Sopenharmony_ci void (*emit_cntxcntl) (struct amdgpu_ring *ring, uint32_t flags); 1868c2ecf20Sopenharmony_ci void (*emit_rreg)(struct amdgpu_ring *ring, uint32_t reg, 1878c2ecf20Sopenharmony_ci uint32_t reg_val_offs); 1888c2ecf20Sopenharmony_ci void (*emit_wreg)(struct amdgpu_ring *ring, uint32_t reg, uint32_t val); 1898c2ecf20Sopenharmony_ci void (*emit_reg_wait)(struct amdgpu_ring *ring, uint32_t reg, 1908c2ecf20Sopenharmony_ci uint32_t val, uint32_t mask); 1918c2ecf20Sopenharmony_ci void (*emit_reg_write_reg_wait)(struct amdgpu_ring *ring, 1928c2ecf20Sopenharmony_ci uint32_t reg0, uint32_t reg1, 1938c2ecf20Sopenharmony_ci uint32_t ref, uint32_t mask); 1948c2ecf20Sopenharmony_ci void (*emit_frame_cntl)(struct amdgpu_ring *ring, bool start, 1958c2ecf20Sopenharmony_ci bool secure); 1968c2ecf20Sopenharmony_ci /* Try to soft recover the ring to make the fence signal */ 1978c2ecf20Sopenharmony_ci void (*soft_recovery)(struct amdgpu_ring *ring, unsigned vmid); 1988c2ecf20Sopenharmony_ci int (*preempt_ib)(struct amdgpu_ring *ring); 1998c2ecf20Sopenharmony_ci void (*emit_mem_sync)(struct amdgpu_ring *ring); 2008c2ecf20Sopenharmony_ci}; 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_cistruct amdgpu_ring { 2038c2ecf20Sopenharmony_ci struct amdgpu_device *adev; 2048c2ecf20Sopenharmony_ci const struct amdgpu_ring_funcs *funcs; 2058c2ecf20Sopenharmony_ci struct amdgpu_fence_driver fence_drv; 2068c2ecf20Sopenharmony_ci struct drm_gpu_scheduler sched; 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_ci struct amdgpu_bo *ring_obj; 2098c2ecf20Sopenharmony_ci volatile uint32_t *ring; 2108c2ecf20Sopenharmony_ci unsigned rptr_offs; 2118c2ecf20Sopenharmony_ci u64 wptr; 2128c2ecf20Sopenharmony_ci u64 wptr_old; 2138c2ecf20Sopenharmony_ci unsigned ring_size; 2148c2ecf20Sopenharmony_ci unsigned max_dw; 2158c2ecf20Sopenharmony_ci int count_dw; 2168c2ecf20Sopenharmony_ci uint64_t gpu_addr; 2178c2ecf20Sopenharmony_ci uint64_t ptr_mask; 2188c2ecf20Sopenharmony_ci uint32_t buf_mask; 2198c2ecf20Sopenharmony_ci u32 idx; 2208c2ecf20Sopenharmony_ci u32 me; 2218c2ecf20Sopenharmony_ci u32 pipe; 2228c2ecf20Sopenharmony_ci u32 queue; 2238c2ecf20Sopenharmony_ci struct amdgpu_bo *mqd_obj; 2248c2ecf20Sopenharmony_ci uint64_t mqd_gpu_addr; 2258c2ecf20Sopenharmony_ci void *mqd_ptr; 2268c2ecf20Sopenharmony_ci uint64_t eop_gpu_addr; 2278c2ecf20Sopenharmony_ci u32 doorbell_index; 2288c2ecf20Sopenharmony_ci bool use_doorbell; 2298c2ecf20Sopenharmony_ci bool use_pollmem; 2308c2ecf20Sopenharmony_ci unsigned wptr_offs; 2318c2ecf20Sopenharmony_ci unsigned fence_offs; 2328c2ecf20Sopenharmony_ci uint64_t current_ctx; 2338c2ecf20Sopenharmony_ci char name[16]; 2348c2ecf20Sopenharmony_ci u32 trail_seq; 2358c2ecf20Sopenharmony_ci unsigned trail_fence_offs; 2368c2ecf20Sopenharmony_ci u64 trail_fence_gpu_addr; 2378c2ecf20Sopenharmony_ci volatile u32 *trail_fence_cpu_addr; 2388c2ecf20Sopenharmony_ci unsigned cond_exe_offs; 2398c2ecf20Sopenharmony_ci u64 cond_exe_gpu_addr; 2408c2ecf20Sopenharmony_ci volatile u32 *cond_exe_cpu_addr; 2418c2ecf20Sopenharmony_ci unsigned vm_inv_eng; 2428c2ecf20Sopenharmony_ci struct dma_fence *vmid_wait; 2438c2ecf20Sopenharmony_ci bool has_compute_vm_bug; 2448c2ecf20Sopenharmony_ci bool no_scheduler; 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_ci atomic_t num_jobs[DRM_SCHED_PRIORITY_COUNT]; 2478c2ecf20Sopenharmony_ci struct mutex priority_mutex; 2488c2ecf20Sopenharmony_ci /* protected by priority_mutex */ 2498c2ecf20Sopenharmony_ci int priority; 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_ci#if defined(CONFIG_DEBUG_FS) 2528c2ecf20Sopenharmony_ci struct dentry *ent; 2538c2ecf20Sopenharmony_ci#endif 2548c2ecf20Sopenharmony_ci}; 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_ci#define amdgpu_ring_parse_cs(r, p, ib) ((r)->funcs->parse_cs((p), (ib))) 2578c2ecf20Sopenharmony_ci#define amdgpu_ring_patch_cs_in_place(r, p, ib) ((r)->funcs->patch_cs_in_place((p), (ib))) 2588c2ecf20Sopenharmony_ci#define amdgpu_ring_test_ring(r) (r)->funcs->test_ring((r)) 2598c2ecf20Sopenharmony_ci#define amdgpu_ring_test_ib(r, t) (r)->funcs->test_ib((r), (t)) 2608c2ecf20Sopenharmony_ci#define amdgpu_ring_get_rptr(r) (r)->funcs->get_rptr((r)) 2618c2ecf20Sopenharmony_ci#define amdgpu_ring_get_wptr(r) (r)->funcs->get_wptr((r)) 2628c2ecf20Sopenharmony_ci#define amdgpu_ring_set_wptr(r) (r)->funcs->set_wptr((r)) 2638c2ecf20Sopenharmony_ci#define amdgpu_ring_emit_ib(r, job, ib, flags) ((r)->funcs->emit_ib((r), (job), (ib), (flags))) 2648c2ecf20Sopenharmony_ci#define amdgpu_ring_emit_pipeline_sync(r) (r)->funcs->emit_pipeline_sync((r)) 2658c2ecf20Sopenharmony_ci#define amdgpu_ring_emit_vm_flush(r, vmid, addr) (r)->funcs->emit_vm_flush((r), (vmid), (addr)) 2668c2ecf20Sopenharmony_ci#define amdgpu_ring_emit_fence(r, addr, seq, flags) (r)->funcs->emit_fence((r), (addr), (seq), (flags)) 2678c2ecf20Sopenharmony_ci#define amdgpu_ring_emit_gds_switch(r, v, db, ds, wb, ws, ab, as) (r)->funcs->emit_gds_switch((r), (v), (db), (ds), (wb), (ws), (ab), (as)) 2688c2ecf20Sopenharmony_ci#define amdgpu_ring_emit_hdp_flush(r) (r)->funcs->emit_hdp_flush((r)) 2698c2ecf20Sopenharmony_ci#define amdgpu_ring_emit_switch_buffer(r) (r)->funcs->emit_switch_buffer((r)) 2708c2ecf20Sopenharmony_ci#define amdgpu_ring_emit_cntxcntl(r, d) (r)->funcs->emit_cntxcntl((r), (d)) 2718c2ecf20Sopenharmony_ci#define amdgpu_ring_emit_rreg(r, d, o) (r)->funcs->emit_rreg((r), (d), (o)) 2728c2ecf20Sopenharmony_ci#define amdgpu_ring_emit_wreg(r, d, v) (r)->funcs->emit_wreg((r), (d), (v)) 2738c2ecf20Sopenharmony_ci#define amdgpu_ring_emit_reg_wait(r, d, v, m) (r)->funcs->emit_reg_wait((r), (d), (v), (m)) 2748c2ecf20Sopenharmony_ci#define amdgpu_ring_emit_reg_write_reg_wait(r, d0, d1, v, m) (r)->funcs->emit_reg_write_reg_wait((r), (d0), (d1), (v), (m)) 2758c2ecf20Sopenharmony_ci#define amdgpu_ring_emit_frame_cntl(r, b, s) (r)->funcs->emit_frame_cntl((r), (b), (s)) 2768c2ecf20Sopenharmony_ci#define amdgpu_ring_pad_ib(r, ib) ((r)->funcs->pad_ib((r), (ib))) 2778c2ecf20Sopenharmony_ci#define amdgpu_ring_init_cond_exec(r) (r)->funcs->init_cond_exec((r)) 2788c2ecf20Sopenharmony_ci#define amdgpu_ring_patch_cond_exec(r,o) (r)->funcs->patch_cond_exec((r),(o)) 2798c2ecf20Sopenharmony_ci#define amdgpu_ring_preempt_ib(r) (r)->funcs->preempt_ib(r) 2808c2ecf20Sopenharmony_ci 2818c2ecf20Sopenharmony_ciint amdgpu_ring_alloc(struct amdgpu_ring *ring, unsigned ndw); 2828c2ecf20Sopenharmony_civoid amdgpu_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count); 2838c2ecf20Sopenharmony_civoid amdgpu_ring_generic_pad_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib); 2848c2ecf20Sopenharmony_civoid amdgpu_ring_commit(struct amdgpu_ring *ring); 2858c2ecf20Sopenharmony_civoid amdgpu_ring_undo(struct amdgpu_ring *ring); 2868c2ecf20Sopenharmony_ciint amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring, 2878c2ecf20Sopenharmony_ci unsigned int ring_size, struct amdgpu_irq_src *irq_src, 2888c2ecf20Sopenharmony_ci unsigned int irq_type, unsigned int prio); 2898c2ecf20Sopenharmony_civoid amdgpu_ring_fini(struct amdgpu_ring *ring); 2908c2ecf20Sopenharmony_civoid amdgpu_ring_emit_reg_write_reg_wait_helper(struct amdgpu_ring *ring, 2918c2ecf20Sopenharmony_ci uint32_t reg0, uint32_t val0, 2928c2ecf20Sopenharmony_ci uint32_t reg1, uint32_t val1); 2938c2ecf20Sopenharmony_cibool amdgpu_ring_soft_recovery(struct amdgpu_ring *ring, unsigned int vmid, 2948c2ecf20Sopenharmony_ci struct dma_fence *fence); 2958c2ecf20Sopenharmony_ci 2968c2ecf20Sopenharmony_cistatic inline void amdgpu_ring_set_preempt_cond_exec(struct amdgpu_ring *ring, 2978c2ecf20Sopenharmony_ci bool cond_exec) 2988c2ecf20Sopenharmony_ci{ 2998c2ecf20Sopenharmony_ci *ring->cond_exe_cpu_addr = cond_exec; 3008c2ecf20Sopenharmony_ci} 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_cistatic inline void amdgpu_ring_clear_ring(struct amdgpu_ring *ring) 3038c2ecf20Sopenharmony_ci{ 3048c2ecf20Sopenharmony_ci int i = 0; 3058c2ecf20Sopenharmony_ci while (i <= ring->buf_mask) 3068c2ecf20Sopenharmony_ci ring->ring[i++] = ring->funcs->nop; 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_ci} 3098c2ecf20Sopenharmony_ci 3108c2ecf20Sopenharmony_cistatic inline void amdgpu_ring_write(struct amdgpu_ring *ring, uint32_t v) 3118c2ecf20Sopenharmony_ci{ 3128c2ecf20Sopenharmony_ci if (ring->count_dw <= 0) 3138c2ecf20Sopenharmony_ci DRM_ERROR("amdgpu: writing more dwords to the ring than expected!\n"); 3148c2ecf20Sopenharmony_ci ring->ring[ring->wptr++ & ring->buf_mask] = v; 3158c2ecf20Sopenharmony_ci ring->wptr &= ring->ptr_mask; 3168c2ecf20Sopenharmony_ci ring->count_dw--; 3178c2ecf20Sopenharmony_ci} 3188c2ecf20Sopenharmony_ci 3198c2ecf20Sopenharmony_cistatic inline void amdgpu_ring_write_multiple(struct amdgpu_ring *ring, 3208c2ecf20Sopenharmony_ci void *src, int count_dw) 3218c2ecf20Sopenharmony_ci{ 3228c2ecf20Sopenharmony_ci unsigned occupied, chunk1, chunk2; 3238c2ecf20Sopenharmony_ci void *dst; 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_ci if (unlikely(ring->count_dw < count_dw)) 3268c2ecf20Sopenharmony_ci DRM_ERROR("amdgpu: writing more dwords to the ring than expected!\n"); 3278c2ecf20Sopenharmony_ci 3288c2ecf20Sopenharmony_ci occupied = ring->wptr & ring->buf_mask; 3298c2ecf20Sopenharmony_ci dst = (void *)&ring->ring[occupied]; 3308c2ecf20Sopenharmony_ci chunk1 = ring->buf_mask + 1 - occupied; 3318c2ecf20Sopenharmony_ci chunk1 = (chunk1 >= count_dw) ? count_dw: chunk1; 3328c2ecf20Sopenharmony_ci chunk2 = count_dw - chunk1; 3338c2ecf20Sopenharmony_ci chunk1 <<= 2; 3348c2ecf20Sopenharmony_ci chunk2 <<= 2; 3358c2ecf20Sopenharmony_ci 3368c2ecf20Sopenharmony_ci if (chunk1) 3378c2ecf20Sopenharmony_ci memcpy(dst, src, chunk1); 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_ci if (chunk2) { 3408c2ecf20Sopenharmony_ci src += chunk1; 3418c2ecf20Sopenharmony_ci dst = (void *)ring->ring; 3428c2ecf20Sopenharmony_ci memcpy(dst, src, chunk2); 3438c2ecf20Sopenharmony_ci } 3448c2ecf20Sopenharmony_ci 3458c2ecf20Sopenharmony_ci ring->wptr += count_dw; 3468c2ecf20Sopenharmony_ci ring->wptr &= ring->ptr_mask; 3478c2ecf20Sopenharmony_ci ring->count_dw -= count_dw; 3488c2ecf20Sopenharmony_ci} 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_ciint amdgpu_ring_test_helper(struct amdgpu_ring *ring); 3518c2ecf20Sopenharmony_ci 3528c2ecf20Sopenharmony_ciint amdgpu_debugfs_ring_init(struct amdgpu_device *adev, 3538c2ecf20Sopenharmony_ci struct amdgpu_ring *ring); 3548c2ecf20Sopenharmony_civoid amdgpu_debugfs_ring_fini(struct amdgpu_ring *ring); 3558c2ecf20Sopenharmony_ci 3568c2ecf20Sopenharmony_ci#endif 357