xref: /linux/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h (revision cca69fe8ff98b6321765752e0e46d7470e870630)
178023016SChristian König /*
278023016SChristian König  * Copyright 2016 Advanced Micro Devices, Inc.
378023016SChristian König  *
478023016SChristian König  * Permission is hereby granted, free of charge, to any person obtaining a
578023016SChristian König  * copy of this software and associated documentation files (the "Software"),
678023016SChristian König  * to deal in the Software without restriction, including without limitation
778023016SChristian König  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
878023016SChristian König  * and/or sell copies of the Software, and to permit persons to whom the
978023016SChristian König  * Software is furnished to do so, subject to the following conditions:
1078023016SChristian König  *
1178023016SChristian König  * The above copyright notice and this permission notice shall be included in
1278023016SChristian König  * all copies or substantial portions of the Software.
1378023016SChristian König  *
1478023016SChristian König  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1578023016SChristian König  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1678023016SChristian König  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1778023016SChristian König  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
1878023016SChristian König  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
1978023016SChristian König  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2078023016SChristian König  * OTHER DEALINGS IN THE SOFTWARE.
2178023016SChristian König  *
2278023016SChristian König  * Authors: Christian König
2378023016SChristian König  */
2478023016SChristian König #ifndef __AMDGPU_RING_H__
2578023016SChristian König #define __AMDGPU_RING_H__
2678023016SChristian König 
2778023016SChristian König #include "gpu_scheduler.h"
2878023016SChristian König 
2978023016SChristian König /* max number of rings */
30f7243053SLeo Liu #define AMDGPU_MAX_RINGS		18
3178023016SChristian König #define AMDGPU_MAX_GFX_RINGS		1
3278023016SChristian König #define AMDGPU_MAX_COMPUTE_RINGS	8
3378023016SChristian König #define AMDGPU_MAX_VCE_RINGS		3
34f7243053SLeo Liu #define AMDGPU_MAX_UVD_ENC_RINGS	2
3578023016SChristian König 
3678023016SChristian König /* some special values for the owner field */
3778023016SChristian König #define AMDGPU_FENCE_OWNER_UNDEFINED	((void*)0ul)
3878023016SChristian König #define AMDGPU_FENCE_OWNER_VM		((void*)1ul)
3978023016SChristian König 
4078023016SChristian König #define AMDGPU_FENCE_FLAG_64BIT         (1 << 0)
4178023016SChristian König #define AMDGPU_FENCE_FLAG_INT           (1 << 1)
4278023016SChristian König 
4378023016SChristian König enum amdgpu_ring_type {
4478023016SChristian König 	AMDGPU_RING_TYPE_GFX,
4578023016SChristian König 	AMDGPU_RING_TYPE_COMPUTE,
4678023016SChristian König 	AMDGPU_RING_TYPE_SDMA,
4778023016SChristian König 	AMDGPU_RING_TYPE_UVD,
482068751dSTrigger Huang 	AMDGPU_RING_TYPE_VCE,
4950c3e232SLeo Liu 	AMDGPU_RING_TYPE_KIQ,
50*cca69fe8SLeo Liu 	AMDGPU_RING_TYPE_UVD_ENC,
51*cca69fe8SLeo Liu 	AMDGPU_RING_TYPE_VCN_DEC
5278023016SChristian König };
5378023016SChristian König 
5478023016SChristian König struct amdgpu_device;
5578023016SChristian König struct amdgpu_ring;
5678023016SChristian König struct amdgpu_ib;
5778023016SChristian König struct amdgpu_cs_parser;
5878023016SChristian König 
5978023016SChristian König /*
6078023016SChristian König  * Fences.
6178023016SChristian König  */
6278023016SChristian König struct amdgpu_fence_driver {
6378023016SChristian König 	uint64_t			gpu_addr;
6478023016SChristian König 	volatile uint32_t		*cpu_addr;
6578023016SChristian König 	/* sync_seq is protected by ring emission lock */
6678023016SChristian König 	uint32_t			sync_seq;
6778023016SChristian König 	atomic_t			last_seq;
6878023016SChristian König 	bool				initialized;
6978023016SChristian König 	struct amdgpu_irq_src		*irq_src;
7078023016SChristian König 	unsigned			irq_type;
7178023016SChristian König 	struct timer_list		fallback_timer;
7278023016SChristian König 	unsigned			num_fences_mask;
7378023016SChristian König 	spinlock_t			lock;
74220196b3SDave Airlie 	struct dma_fence		**fences;
7578023016SChristian König };
7678023016SChristian König 
7778023016SChristian König int amdgpu_fence_driver_init(struct amdgpu_device *adev);
7878023016SChristian König void amdgpu_fence_driver_fini(struct amdgpu_device *adev);
7978023016SChristian König void amdgpu_fence_driver_force_completion(struct amdgpu_device *adev);
8065781c78SMonk Liu void amdgpu_fence_driver_force_completion_ring(struct amdgpu_ring *ring);
8178023016SChristian König 
8278023016SChristian König int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring,
8378023016SChristian König 				  unsigned num_hw_submission);
8478023016SChristian König int amdgpu_fence_driver_start_ring(struct amdgpu_ring *ring,
8578023016SChristian König 				   struct amdgpu_irq_src *irq_src,
8678023016SChristian König 				   unsigned irq_type);
8778023016SChristian König void amdgpu_fence_driver_suspend(struct amdgpu_device *adev);
8878023016SChristian König void amdgpu_fence_driver_resume(struct amdgpu_device *adev);
89220196b3SDave Airlie int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **fence);
9078023016SChristian König void amdgpu_fence_process(struct amdgpu_ring *ring);
9178023016SChristian König int amdgpu_fence_wait_empty(struct amdgpu_ring *ring);
9278023016SChristian König unsigned amdgpu_fence_count_emitted(struct amdgpu_ring *ring);
9378023016SChristian König 
9478023016SChristian König /*
9578023016SChristian König  * Rings.
9678023016SChristian König  */
9778023016SChristian König 
9878023016SChristian König /* provided by hw blocks that expose a ring buffer for commands */
9978023016SChristian König struct amdgpu_ring_funcs {
10021cd942eSChristian König 	enum amdgpu_ring_type	type;
10179887142SChristian König 	uint32_t		align_mask;
10279887142SChristian König 	u32			nop;
103536fbf94SKen Wang 	bool			support_64bit_ptrs;
1040eeb68b3SChristian König 	unsigned		vmhub;
10521cd942eSChristian König 
10678023016SChristian König 	/* ring read/write ptr handling */
107536fbf94SKen Wang 	u64 (*get_rptr)(struct amdgpu_ring *ring);
108536fbf94SKen Wang 	u64 (*get_wptr)(struct amdgpu_ring *ring);
10978023016SChristian König 	void (*set_wptr)(struct amdgpu_ring *ring);
11078023016SChristian König 	/* validating and patching of IBs */
11178023016SChristian König 	int (*parse_cs)(struct amdgpu_cs_parser *p, uint32_t ib_idx);
112e12f3d7aSChristian König 	/* constants to calculate how many DW are needed for an emit */
113e12f3d7aSChristian König 	unsigned emit_frame_size;
114e12f3d7aSChristian König 	unsigned emit_ib_size;
11578023016SChristian König 	/* command emit functions */
11678023016SChristian König 	void (*emit_ib)(struct amdgpu_ring *ring,
11778023016SChristian König 			struct amdgpu_ib *ib,
11878023016SChristian König 			unsigned vm_id, bool ctx_switch);
11978023016SChristian König 	void (*emit_fence)(struct amdgpu_ring *ring, uint64_t addr,
12078023016SChristian König 			   uint64_t seq, unsigned flags);
12178023016SChristian König 	void (*emit_pipeline_sync)(struct amdgpu_ring *ring);
12278023016SChristian König 	void (*emit_vm_flush)(struct amdgpu_ring *ring, unsigned vm_id,
12378023016SChristian König 			      uint64_t pd_addr);
12478023016SChristian König 	void (*emit_hdp_flush)(struct amdgpu_ring *ring);
12578023016SChristian König 	void (*emit_hdp_invalidate)(struct amdgpu_ring *ring);
12678023016SChristian König 	void (*emit_gds_switch)(struct amdgpu_ring *ring, uint32_t vmid,
12778023016SChristian König 				uint32_t gds_base, uint32_t gds_size,
12878023016SChristian König 				uint32_t gws_base, uint32_t gws_size,
12978023016SChristian König 				uint32_t oa_base, uint32_t oa_size);
13078023016SChristian König 	/* testing functions */
13178023016SChristian König 	int (*test_ring)(struct amdgpu_ring *ring);
13278023016SChristian König 	int (*test_ib)(struct amdgpu_ring *ring, long timeout);
13378023016SChristian König 	/* insert NOP packets */
13478023016SChristian König 	void (*insert_nop)(struct amdgpu_ring *ring, uint32_t count);
135135d4735SLeo Liu 	void (*insert_end)(struct amdgpu_ring *ring);
13678023016SChristian König 	/* pad the indirect buffer to the necessary number of dw */
13778023016SChristian König 	void (*pad_ib)(struct amdgpu_ring *ring, struct amdgpu_ib *ib);
13878023016SChristian König 	unsigned (*init_cond_exec)(struct amdgpu_ring *ring);
13978023016SChristian König 	void (*patch_cond_exec)(struct amdgpu_ring *ring, unsigned offset);
14078023016SChristian König 	/* note usage for clock and power gating */
14178023016SChristian König 	void (*begin_use)(struct amdgpu_ring *ring);
14278023016SChristian König 	void (*end_use)(struct amdgpu_ring *ring);
14378023016SChristian König 	void (*emit_switch_buffer) (struct amdgpu_ring *ring);
14478023016SChristian König 	void (*emit_cntxcntl) (struct amdgpu_ring *ring, uint32_t flags);
145b6091c12SXiangliang Yu 	void (*emit_rreg)(struct amdgpu_ring *ring, uint32_t reg);
146b6091c12SXiangliang Yu 	void (*emit_wreg)(struct amdgpu_ring *ring, uint32_t reg, uint32_t val);
1473b4d68e9SMonk Liu 	void (*emit_tmz)(struct amdgpu_ring *ring, bool start);
14878023016SChristian König };
14978023016SChristian König 
15078023016SChristian König struct amdgpu_ring {
15178023016SChristian König 	struct amdgpu_device		*adev;
15278023016SChristian König 	const struct amdgpu_ring_funcs	*funcs;
15378023016SChristian König 	struct amdgpu_fence_driver	fence_drv;
15478023016SChristian König 	struct amd_gpu_scheduler	sched;
15578023016SChristian König 
15678023016SChristian König 	struct amdgpu_bo	*ring_obj;
15778023016SChristian König 	volatile uint32_t	*ring;
15878023016SChristian König 	unsigned		rptr_offs;
159536fbf94SKen Wang 	u64			wptr;
160536fbf94SKen Wang 	u64			wptr_old;
16178023016SChristian König 	unsigned		ring_size;
16278023016SChristian König 	unsigned		max_dw;
16378023016SChristian König 	int			count_dw;
16478023016SChristian König 	uint64_t		gpu_addr;
165536fbf94SKen Wang 	uint64_t		ptr_mask;
166536fbf94SKen Wang 	uint32_t		buf_mask;
16778023016SChristian König 	bool			ready;
16878023016SChristian König 	u32			idx;
16978023016SChristian König 	u32			me;
17078023016SChristian König 	u32			pipe;
17178023016SChristian König 	u32			queue;
17278023016SChristian König 	struct amdgpu_bo	*mqd_obj;
173f3972b53SMonk Liu 	uint64_t                mqd_gpu_addr;
17459a82d7dSXiangliang Yu 	void                    *mqd_ptr;
17534534610SAlex Deucher 	uint64_t                eop_gpu_addr;
17678023016SChristian König 	u32			doorbell_index;
17778023016SChristian König 	bool			use_doorbell;
17878023016SChristian König 	unsigned		wptr_offs;
17978023016SChristian König 	unsigned		fence_offs;
18078023016SChristian König 	uint64_t		current_ctx;
18178023016SChristian König 	char			name[16];
18278023016SChristian König 	unsigned		cond_exe_offs;
18378023016SChristian König 	u64			cond_exe_gpu_addr;
18478023016SChristian König 	volatile u32		*cond_exe_cpu_addr;
1854789c463SChristian König 	unsigned		vm_inv_eng;
18678023016SChristian König #if defined(CONFIG_DEBUG_FS)
18778023016SChristian König 	struct dentry *ent;
18878023016SChristian König #endif
18978023016SChristian König };
19078023016SChristian König 
19178023016SChristian König int amdgpu_ring_alloc(struct amdgpu_ring *ring, unsigned ndw);
19278023016SChristian König void amdgpu_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count);
19378023016SChristian König void amdgpu_ring_generic_pad_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib);
19478023016SChristian König void amdgpu_ring_commit(struct amdgpu_ring *ring);
19578023016SChristian König void amdgpu_ring_undo(struct amdgpu_ring *ring);
19678023016SChristian König int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,
19779887142SChristian König 		     unsigned ring_size, struct amdgpu_irq_src *irq_src,
19879887142SChristian König 		     unsigned irq_type);
19978023016SChristian König void amdgpu_ring_fini(struct amdgpu_ring *ring);
200c79ecfbfSMonk Liu static inline void amdgpu_ring_clear_ring(struct amdgpu_ring *ring)
201c79ecfbfSMonk Liu {
202c79ecfbfSMonk Liu 	int i = 0;
203e09706f4SMonk Liu 	while (i <= ring->buf_mask)
204c79ecfbfSMonk Liu 		ring->ring[i++] = ring->funcs->nop;
205c79ecfbfSMonk Liu 
206c79ecfbfSMonk Liu }
20778023016SChristian König 
20878023016SChristian König #endif
209