2351 lines · 70.4 KB · C
RawDownload
/* * Copyright 2008 Advanced Micro Devices, Inc. * Copyright 2008 Red Hat Inc. * Copyright 2009 Jerome Glisse. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * Authors: Dave Airlie *          Alex Deucher *          Jerome Glisse */#ifndef __AMDGPU_H__#define __AMDGPU_H__ #include <linux/atomic.h>#include <linux/wait.h>#include <linux/list.h>#include <linux/kref.h>#include <linux/interval_tree.h>#include <linux/hashtable.h>#include <linux/fence.h> #include <ttm/ttm_bo_api.h>#include <ttm/ttm_bo_driver.h>#include <ttm/ttm_placement.h>#include <ttm/ttm_module.h>#include <ttm/ttm_execbuf_util.h> #include <drm/drm_gem.h>#include <drm/amdgpu_drm.h> #include "amd_shared.h"#include "amdgpu_family.h"#include "amdgpu_mode.h"#include "amdgpu_ih.h"#include "amdgpu_irq.h"#include "amdgpu_ucode.h"#include "amdgpu_gds.h" /* * Modules parameters. */extern int amdgpu_modeset;extern int amdgpu_vram_limit;extern int amdgpu_gart_size;extern int amdgpu_benchmarking;extern int amdgpu_testing;extern int amdgpu_audio;extern int amdgpu_disp_priority;extern int amdgpu_hw_i2c;extern int amdgpu_pcie_gen2;extern int amdgpu_msi;extern int amdgpu_lockup_timeout;extern int amdgpu_dpm;extern int amdgpu_smc_load_fw;extern int amdgpu_aspm;extern int amdgpu_runtime_pm;extern int amdgpu_hard_reset;extern unsigned amdgpu_ip_block_mask;extern int amdgpu_bapm;extern int amdgpu_deep_color;extern int amdgpu_vm_size;extern int amdgpu_vm_block_size; #define AMDGPU_MAX_USEC_TIMEOUT			100000	/* 100 ms */#define AMDGPU_FENCE_JIFFIES_TIMEOUT		(HZ / 2)/* AMDGPU_IB_POOL_SIZE must be a power of 2 */#define AMDGPU_IB_POOL_SIZE			16#define AMDGPU_DEBUGFS_MAX_COMPONENTS		32#define AMDGPUFB_CONN_LIMIT			4#define AMDGPU_BIOS_NUM_SCRATCH			8 /* max number of rings */#define AMDGPU_MAX_RINGS			16#define AMDGPU_MAX_GFX_RINGS			1#define AMDGPU_MAX_COMPUTE_RINGS		8#define AMDGPU_MAX_VCE_RINGS			2 /* number of hw syncs before falling back on blocking */#define AMDGPU_NUM_SYNCS			4 /* hardcode that limit for now */#define AMDGPU_VA_RESERVED_SIZE			(8 << 20) /* hard reset data */#define AMDGPU_ASIC_RESET_DATA                  0x39d5e86b /* reset flags */#define AMDGPU_RESET_GFX			(1 << 0)#define AMDGPU_RESET_COMPUTE			(1 << 1)#define AMDGPU_RESET_DMA			(1 << 2)#define AMDGPU_RESET_CP				(1 << 3)#define AMDGPU_RESET_GRBM			(1 << 4)#define AMDGPU_RESET_DMA1			(1 << 5)#define AMDGPU_RESET_RLC			(1 << 6)#define AMDGPU_RESET_SEM			(1 << 7)#define AMDGPU_RESET_IH				(1 << 8)#define AMDGPU_RESET_VMC			(1 << 9)#define AMDGPU_RESET_MC				(1 << 10)#define AMDGPU_RESET_DISPLAY			(1 << 11)#define AMDGPU_RESET_UVD			(1 << 12)#define AMDGPU_RESET_VCE			(1 << 13)#define AMDGPU_RESET_VCE1			(1 << 14) /* CG block flags */#define AMDGPU_CG_BLOCK_GFX			(1 << 0)#define AMDGPU_CG_BLOCK_MC			(1 << 1)#define AMDGPU_CG_BLOCK_SDMA			(1 << 2)#define AMDGPU_CG_BLOCK_UVD			(1 << 3)#define AMDGPU_CG_BLOCK_VCE			(1 << 4)#define AMDGPU_CG_BLOCK_HDP			(1 << 5)#define AMDGPU_CG_BLOCK_BIF			(1 << 6) /* CG flags */#define AMDGPU_CG_SUPPORT_GFX_MGCG		(1 << 0)#define AMDGPU_CG_SUPPORT_GFX_MGLS		(1 << 1)#define AMDGPU_CG_SUPPORT_GFX_CGCG		(1 << 2)#define AMDGPU_CG_SUPPORT_GFX_CGLS		(1 << 3)#define AMDGPU_CG_SUPPORT_GFX_CGTS		(1 << 4)#define AMDGPU_CG_SUPPORT_GFX_CGTS_LS		(1 << 5)#define AMDGPU_CG_SUPPORT_GFX_CP_LS		(1 << 6)#define AMDGPU_CG_SUPPORT_GFX_RLC_LS		(1 << 7)#define AMDGPU_CG_SUPPORT_MC_LS			(1 << 8)#define AMDGPU_CG_SUPPORT_MC_MGCG		(1 << 9)#define AMDGPU_CG_SUPPORT_SDMA_LS		(1 << 10)#define AMDGPU_CG_SUPPORT_SDMA_MGCG		(1 << 11)#define AMDGPU_CG_SUPPORT_BIF_LS		(1 << 12)#define AMDGPU_CG_SUPPORT_UVD_MGCG		(1 << 13)#define AMDGPU_CG_SUPPORT_VCE_MGCG		(1 << 14)#define AMDGPU_CG_SUPPORT_HDP_LS		(1 << 15)#define AMDGPU_CG_SUPPORT_HDP_MGCG		(1 << 16) /* PG flags */#define AMDGPU_PG_SUPPORT_GFX_PG		(1 << 0)#define AMDGPU_PG_SUPPORT_GFX_SMG		(1 << 1)#define AMDGPU_PG_SUPPORT_GFX_DMG		(1 << 2)#define AMDGPU_PG_SUPPORT_UVD			(1 << 3)#define AMDGPU_PG_SUPPORT_VCE			(1 << 4)#define AMDGPU_PG_SUPPORT_CP			(1 << 5)#define AMDGPU_PG_SUPPORT_GDS			(1 << 6)#define AMDGPU_PG_SUPPORT_RLC_SMU_HS		(1 << 7)#define AMDGPU_PG_SUPPORT_SDMA			(1 << 8)#define AMDGPU_PG_SUPPORT_ACP			(1 << 9)#define AMDGPU_PG_SUPPORT_SAMU			(1 << 10) /* GFX current status */#define AMDGPU_GFX_NORMAL_MODE			0x00000000L#define AMDGPU_GFX_SAFE_MODE			0x00000001L#define AMDGPU_GFX_PG_DISABLED_MODE		0x00000002L#define AMDGPU_GFX_CG_DISABLED_MODE		0x00000004L#define AMDGPU_GFX_LBPW_DISABLED_MODE		0x00000008L /* max cursor sizes (in pixels) */#define CIK_CURSOR_WIDTH 128#define CIK_CURSOR_HEIGHT 128 struct amdgpu_device;struct amdgpu_fence;struct amdgpu_ib;struct amdgpu_vm;struct amdgpu_ring;struct amdgpu_semaphore;struct amdgpu_cs_parser;struct amdgpu_irq_src; enum amdgpu_cp_irq {	AMDGPU_CP_IRQ_GFX_EOP = 0,	AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP,	AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE1_EOP,	AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE2_EOP,	AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE3_EOP,	AMDGPU_CP_IRQ_COMPUTE_MEC2_PIPE0_EOP,	AMDGPU_CP_IRQ_COMPUTE_MEC2_PIPE1_EOP,	AMDGPU_CP_IRQ_COMPUTE_MEC2_PIPE2_EOP,	AMDGPU_CP_IRQ_COMPUTE_MEC2_PIPE3_EOP, 	AMDGPU_CP_IRQ_LAST}; enum amdgpu_sdma_irq {	AMDGPU_SDMA_IRQ_TRAP0 = 0,	AMDGPU_SDMA_IRQ_TRAP1, 	AMDGPU_SDMA_IRQ_LAST}; enum amdgpu_thermal_irq {	AMDGPU_THERMAL_IRQ_LOW_TO_HIGH = 0,	AMDGPU_THERMAL_IRQ_HIGH_TO_LOW, 	AMDGPU_THERMAL_IRQ_LAST}; int amdgpu_set_clockgating_state(struct amdgpu_device *adev,				  enum amd_ip_block_type block_type,				  enum amd_clockgating_state state);int amdgpu_set_powergating_state(struct amdgpu_device *adev,				  enum amd_ip_block_type block_type,				  enum amd_powergating_state state); struct amdgpu_ip_block_version {	enum amd_ip_block_type type;	u32 major;	u32 minor;	u32 rev;	const struct amd_ip_funcs *funcs;}; int amdgpu_ip_block_version_cmp(struct amdgpu_device *adev,				enum amd_ip_block_type type,				u32 major, u32 minor); const struct amdgpu_ip_block_version * amdgpu_get_ip_block(					struct amdgpu_device *adev,					enum amd_ip_block_type type); /* provided by hw blocks that can move/clear data.  e.g., gfx or sdma */struct amdgpu_buffer_funcs {	/* maximum bytes in a single operation */	uint32_t	copy_max_bytes; 	/* number of dw to reserve per operation */	unsigned	copy_num_dw; 	/* used for buffer migration */	void (*emit_copy_buffer)(struct amdgpu_ring *ring,				 /* src addr in bytes */				 uint64_t src_offset,				 /* dst addr in bytes */				 uint64_t dst_offset,				 /* number of byte to transfer */				 uint32_t byte_count); 	/* maximum bytes in a single operation */	uint32_t	fill_max_bytes; 	/* number of dw to reserve per operation */	unsigned	fill_num_dw; 	/* used for buffer clearing */	void (*emit_fill_buffer)(struct amdgpu_ring *ring,				 /* value to write to memory */				 uint32_t src_data,				 /* dst addr in bytes */				 uint64_t dst_offset,				 /* number of byte to fill */				 uint32_t byte_count);}; /* provided by hw blocks that can write ptes, e.g., sdma */struct amdgpu_vm_pte_funcs {	/* copy pte entries from GART */	void (*copy_pte)(struct amdgpu_ib *ib,			 uint64_t pe, uint64_t src,			 unsigned count);	/* write pte one entry at a time with addr mapping */	void (*write_pte)(struct amdgpu_ib *ib,			  uint64_t pe,			  uint64_t addr, unsigned count,			  uint32_t incr, uint32_t flags);	/* for linear pte/pde updates without addr mapping */	void (*set_pte_pde)(struct amdgpu_ib *ib,			    uint64_t pe,			    uint64_t addr, unsigned count,			    uint32_t incr, uint32_t flags);	/* pad the indirect buffer to the necessary number of dw */	void (*pad_ib)(struct amdgpu_ib *ib);}; /* provided by the gmc block */struct amdgpu_gart_funcs {	/* flush the vm tlb via mmio */	void (*flush_gpu_tlb)(struct amdgpu_device *adev,			      uint32_t vmid);	/* write pte/pde updates using the cpu */	int (*set_pte_pde)(struct amdgpu_device *adev,			   void *cpu_pt_addr, /* cpu addr of page table */			   uint32_t gpu_page_idx, /* pte/pde to update */			   uint64_t addr, /* addr to write into pte/pde */			   uint32_t flags); /* access flags */}; /* provided by the ih block */struct amdgpu_ih_funcs {	/* ring read/write ptr handling, called from interrupt context */	u32 (*get_wptr)(struct amdgpu_device *adev);	void (*decode_iv)(struct amdgpu_device *adev,			  struct amdgpu_iv_entry *entry);	void (*set_rptr)(struct amdgpu_device *adev);}; /* provided by hw blocks that expose a ring buffer for commands */struct amdgpu_ring_funcs {	/* ring read/write ptr handling */	u32 (*get_rptr)(struct amdgpu_ring *ring);	u32 (*get_wptr)(struct amdgpu_ring *ring);	void (*set_wptr)(struct amdgpu_ring *ring);	/* validating and patching of IBs */	int (*parse_cs)(struct amdgpu_cs_parser *p, uint32_t ib_idx);	/* command emit functions */	void (*emit_ib)(struct amdgpu_ring *ring,			struct amdgpu_ib *ib);	void (*emit_fence)(struct amdgpu_ring *ring, uint64_t addr,			   uint64_t seq, unsigned flags);	bool (*emit_semaphore)(struct amdgpu_ring *ring,			       struct amdgpu_semaphore *semaphore,			       bool emit_wait);	void (*emit_vm_flush)(struct amdgpu_ring *ring, unsigned vm_id,			      uint64_t pd_addr);	void (*emit_hdp_flush)(struct amdgpu_ring *ring);	void (*emit_gds_switch)(struct amdgpu_ring *ring, uint32_t vmid,				uint32_t gds_base, uint32_t gds_size,				uint32_t gws_base, uint32_t gws_size,				uint32_t oa_base, uint32_t oa_size);	/* testing functions */	int (*test_ring)(struct amdgpu_ring *ring);	int (*test_ib)(struct amdgpu_ring *ring);	bool (*is_lockup)(struct amdgpu_ring *ring);}; /* * BIOS. */bool amdgpu_get_bios(struct amdgpu_device *adev);bool amdgpu_read_bios(struct amdgpu_device *adev); /* * Dummy page */struct amdgpu_dummy_page {	struct page	*page;	dma_addr_t	addr;};int amdgpu_dummy_page_init(struct amdgpu_device *adev);void amdgpu_dummy_page_fini(struct amdgpu_device *adev);  /* * Clocks */ #define AMDGPU_MAX_PPLL 3 struct amdgpu_clock {	struct amdgpu_pll ppll[AMDGPU_MAX_PPLL];	struct amdgpu_pll spll;	struct amdgpu_pll mpll;	/* 10 Khz units */	uint32_t default_mclk;	uint32_t default_sclk;	uint32_t default_dispclk;	uint32_t current_dispclk;	uint32_t dp_extclk;	uint32_t max_pixel_clock;}; /* * Fences. */struct amdgpu_fence_driver {	struct amdgpu_ring		*ring;	uint64_t			gpu_addr;	volatile uint32_t		*cpu_addr;	/* sync_seq is protected by ring emission lock */	uint64_t			sync_seq[AMDGPU_MAX_RINGS];	atomic64_t			last_seq;	bool				initialized;	bool				delayed_irq;	struct amdgpu_irq_src		*irq_src;	unsigned			irq_type;	struct delayed_work             lockup_work;}; /* some special values for the owner field */#define AMDGPU_FENCE_OWNER_UNDEFINED	((void*)0ul)#define AMDGPU_FENCE_OWNER_VM		((void*)1ul)#define AMDGPU_FENCE_OWNER_MOVE		((void*)2ul) #define AMDGPU_FENCE_FLAG_64BIT         (1 << 0)#define AMDGPU_FENCE_FLAG_INT           (1 << 1) struct amdgpu_fence {	struct fence base; 	/* RB, DMA, etc. */	struct amdgpu_ring		*ring;	uint64_t			seq; 	/* filp or special value for fence creator */	void				*owner; 	wait_queue_t			fence_wake;}; struct amdgpu_user_fence {	/* write-back bo */	struct amdgpu_bo 	*bo;	/* write-back address offset to bo start */	uint32_t                offset;}; int amdgpu_fence_driver_init(struct amdgpu_device *adev);void amdgpu_fence_driver_fini(struct amdgpu_device *adev);void amdgpu_fence_driver_force_completion(struct amdgpu_device *adev); void amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring);int amdgpu_fence_driver_start_ring(struct amdgpu_ring *ring,				   struct amdgpu_irq_src *irq_src,				   unsigned irq_type);int amdgpu_fence_emit(struct amdgpu_ring *ring, void *owner,		      struct amdgpu_fence **fence);int amdgpu_fence_recreate(struct amdgpu_ring *ring, void *owner,			  uint64_t seq, struct amdgpu_fence **fence);void amdgpu_fence_process(struct amdgpu_ring *ring);int amdgpu_fence_wait_next(struct amdgpu_ring *ring);int amdgpu_fence_wait_empty(struct amdgpu_ring *ring);unsigned amdgpu_fence_count_emitted(struct amdgpu_ring *ring); bool amdgpu_fence_signaled(struct amdgpu_fence *fence);int amdgpu_fence_wait(struct amdgpu_fence *fence, bool interruptible);int amdgpu_fence_wait_any(struct amdgpu_device *adev,			  struct amdgpu_fence **fences,			  bool intr);struct amdgpu_fence *amdgpu_fence_ref(struct amdgpu_fence *fence);void amdgpu_fence_unref(struct amdgpu_fence **fence); bool amdgpu_fence_need_sync(struct amdgpu_fence *fence,			    struct amdgpu_ring *ring);void amdgpu_fence_note_sync(struct amdgpu_fence *fence,			    struct amdgpu_ring *ring); static inline struct amdgpu_fence *amdgpu_fence_later(struct amdgpu_fence *a,						      struct amdgpu_fence *b){	if (!a) {		return b;	} 	if (!b) {		return a;	} 	BUG_ON(a->ring != b->ring); 	if (a->seq > b->seq) {		return a;	} else {		return b;	}} static inline bool amdgpu_fence_is_earlier(struct amdgpu_fence *a,					   struct amdgpu_fence *b){	if (!a) {		return false;	} 	if (!b) {		return true;	} 	BUG_ON(a->ring != b->ring); 	return a->seq < b->seq;} int amdgpu_user_fence_emit(struct amdgpu_ring *ring, struct amdgpu_user_fence *user, 			   void *owner, struct amdgpu_fence **fence); /* * TTM. */struct amdgpu_mman {	struct ttm_bo_global_ref        bo_global_ref;	struct drm_global_reference	mem_global_ref;	struct ttm_bo_device		bdev;	bool				mem_global_referenced;	bool				initialized; #if defined(CONFIG_DEBUG_FS)	struct dentry			*vram;	struct dentry			*gtt;#endif

Lines 1–500 of 2351.