| .. | .. |
|---|
| 24 | 24 | #ifndef __AMDGPU_IH_H__ |
|---|
| 25 | 25 | #define __AMDGPU_IH_H__ |
|---|
| 26 | 26 | |
|---|
| 27 | | -#include <linux/chash.h> |
|---|
| 28 | | -#include "soc15_ih_clientid.h" |
|---|
| 27 | +/* Maximum number of IVs processed at once */ |
|---|
| 28 | +#define AMDGPU_IH_MAX_NUM_IVS 32 |
|---|
| 29 | 29 | |
|---|
| 30 | 30 | struct amdgpu_device; |
|---|
| 31 | | - |
|---|
| 32 | | -#define AMDGPU_IH_CLIENTID_LEGACY 0 |
|---|
| 33 | | -#define AMDGPU_IH_CLIENTID_MAX SOC15_IH_CLIENTID_MAX |
|---|
| 34 | | - |
|---|
| 35 | | -#define AMDGPU_PAGEFAULT_HASH_BITS 8 |
|---|
| 36 | | -struct amdgpu_retryfault_hashtable { |
|---|
| 37 | | - DECLARE_CHASH_TABLE(hash, AMDGPU_PAGEFAULT_HASH_BITS, 8, 0); |
|---|
| 38 | | - spinlock_t lock; |
|---|
| 39 | | - int count; |
|---|
| 40 | | -}; |
|---|
| 31 | +struct amdgpu_iv_entry; |
|---|
| 41 | 32 | |
|---|
| 42 | 33 | /* |
|---|
| 43 | 34 | * R6xx+ IH ring |
|---|
| 44 | 35 | */ |
|---|
| 45 | 36 | struct amdgpu_ih_ring { |
|---|
| 46 | | - struct amdgpu_bo *ring_obj; |
|---|
| 47 | | - volatile uint32_t *ring; |
|---|
| 48 | | - unsigned rptr; |
|---|
| 49 | 37 | unsigned ring_size; |
|---|
| 50 | | - uint64_t gpu_addr; |
|---|
| 51 | 38 | uint32_t ptr_mask; |
|---|
| 52 | | - atomic_t lock; |
|---|
| 53 | | - bool enabled; |
|---|
| 54 | | - unsigned wptr_offs; |
|---|
| 55 | | - unsigned rptr_offs; |
|---|
| 56 | 39 | u32 doorbell_index; |
|---|
| 57 | 40 | bool use_doorbell; |
|---|
| 58 | 41 | bool use_bus_addr; |
|---|
| 59 | | - dma_addr_t rb_dma_addr; /* only used when use_bus_addr = true */ |
|---|
| 60 | | - struct amdgpu_retryfault_hashtable *faults; |
|---|
| 42 | + |
|---|
| 43 | + struct amdgpu_bo *ring_obj; |
|---|
| 44 | + volatile uint32_t *ring; |
|---|
| 45 | + uint64_t gpu_addr; |
|---|
| 46 | + |
|---|
| 47 | + uint64_t wptr_addr; |
|---|
| 48 | + volatile uint32_t *wptr_cpu; |
|---|
| 49 | + |
|---|
| 50 | + uint64_t rptr_addr; |
|---|
| 51 | + volatile uint32_t *rptr_cpu; |
|---|
| 52 | + |
|---|
| 53 | + bool enabled; |
|---|
| 54 | + unsigned rptr; |
|---|
| 55 | + atomic_t lock; |
|---|
| 61 | 56 | }; |
|---|
| 62 | 57 | |
|---|
| 63 | | -#define AMDGPU_IH_SRC_DATA_MAX_SIZE_DW 4 |
|---|
| 64 | | - |
|---|
| 65 | | -struct amdgpu_iv_entry { |
|---|
| 66 | | - unsigned client_id; |
|---|
| 67 | | - unsigned src_id; |
|---|
| 68 | | - unsigned ring_id; |
|---|
| 69 | | - unsigned vmid; |
|---|
| 70 | | - unsigned vmid_src; |
|---|
| 71 | | - uint64_t timestamp; |
|---|
| 72 | | - unsigned timestamp_src; |
|---|
| 73 | | - unsigned pasid; |
|---|
| 74 | | - unsigned pasid_src; |
|---|
| 75 | | - unsigned src_data[AMDGPU_IH_SRC_DATA_MAX_SIZE_DW]; |
|---|
| 76 | | - const uint32_t *iv_entry; |
|---|
| 58 | +/* provided by the ih block */ |
|---|
| 59 | +struct amdgpu_ih_funcs { |
|---|
| 60 | + /* ring read/write ptr handling, called from interrupt context */ |
|---|
| 61 | + u32 (*get_wptr)(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih); |
|---|
| 62 | + void (*decode_iv)(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, |
|---|
| 63 | + struct amdgpu_iv_entry *entry); |
|---|
| 64 | + void (*set_rptr)(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih); |
|---|
| 77 | 65 | }; |
|---|
| 78 | 66 | |
|---|
| 79 | | -int amdgpu_ih_ring_init(struct amdgpu_device *adev, unsigned ring_size, |
|---|
| 80 | | - bool use_bus_addr); |
|---|
| 81 | | -void amdgpu_ih_ring_fini(struct amdgpu_device *adev); |
|---|
| 82 | | -int amdgpu_ih_process(struct amdgpu_device *adev); |
|---|
| 83 | | -int amdgpu_ih_add_fault(struct amdgpu_device *adev, u64 key); |
|---|
| 84 | | -void amdgpu_ih_clear_fault(struct amdgpu_device *adev, u64 key); |
|---|
| 67 | +#define amdgpu_ih_get_wptr(adev, ih) (adev)->irq.ih_funcs->get_wptr((adev), (ih)) |
|---|
| 68 | +#define amdgpu_ih_decode_iv(adev, iv) \ |
|---|
| 69 | + (adev)->irq.ih_funcs->decode_iv((adev), (ih), (iv)) |
|---|
| 70 | +#define amdgpu_ih_set_rptr(adev, ih) (adev)->irq.ih_funcs->set_rptr((adev), (ih)) |
|---|
| 71 | + |
|---|
| 72 | +int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, |
|---|
| 73 | + unsigned ring_size, bool use_bus_addr); |
|---|
| 74 | +void amdgpu_ih_ring_fini(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih); |
|---|
| 75 | +int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih); |
|---|
| 85 | 76 | |
|---|
| 86 | 77 | #endif |
|---|