| 1 | |
| 2 | * Copyright 2014 Advanced Micro Devices, Inc.
|
| 3 | *
|
| 4 | * Permission is hereby granted, free of charge, to any person obtaining a
|
| 5 | * copy of this software and associated documentation files (the "Software"),
|
| 6 | * to deal in the Software without restriction, including without limitation
|
| 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
| 8 | * and/or sell copies of the Software, and to permit persons to whom the
|
| 9 | * Software is furnished to do so, subject to the following conditions:
|
| 10 | *
|
| 11 | * The above copyright notice and this permission notice shall be included in
|
| 12 | * all copies or substantial portions of the Software.
|
| 13 | *
|
| 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
| 17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
| 18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
| 19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 20 | * OTHER DEALINGS IN THE SOFTWARE.
|
| 21 | *
|
| 22 |
|
| 23 |
|
| 24 | #ifndef __AMDGPU_IH_H__
|
| 25 | #define __AMDGPU_IH_H__
|
| 26 |
|
| 27 |
|
| 28 | #define AMDGPU_IH_MAX_NUM_IVS 32
|
| 29 |
|
| 30 | #define IH_RING_SIZE (256 * 1024)
|
| 31 | #define IH_SW_RING_SIZE (16 * 1024)
|
| 32 |
|
| 33 | struct amdgpu_device;
|
| 34 | struct amdgpu_iv_entry;
|
| 35 |
|
| 36 | struct amdgpu_ih_regs {
|
| 37 | uint32_t ih_rb_base;
|
| 38 | uint32_t ih_rb_base_hi;
|
| 39 | uint32_t ih_rb_cntl;
|
| 40 | uint32_t ih_rb_wptr;
|
| 41 | uint32_t ih_rb_rptr;
|
| 42 | uint32_t ih_doorbell_rptr;
|
| 43 | uint32_t ih_rb_wptr_addr_lo;
|
| 44 | uint32_t ih_rb_wptr_addr_hi;
|
| 45 | uint32_t psp_reg_id;
|
| 46 | };
|
| 47 |
|
| 48 | |
| 49 | * R6xx+ IH ring
|
| 50 |
|
| 51 | struct amdgpu_ih_ring {
|
| 52 | unsigned ring_size;
|
| 53 | uint32_t ptr_mask;
|
| 54 | u32 doorbell_index;
|
| 55 | bool use_doorbell;
|
| 56 | bool use_bus_addr;
|
| 57 |
|
| 58 | struct amdgpu_bo *ring_obj;
|
| 59 | uint32_t *ring;
|
| 60 | uint64_t gpu_addr;
|
| 61 |
|
| 62 | uint64_t wptr_addr;
|
| 63 | uint32_t *wptr_cpu;
|
| 64 |
|
| 65 | uint64_t rptr_addr;
|
| 66 | uint32_t *rptr_cpu;
|
| 67 |
|
| 68 | bool enabled;
|
| 69 | unsigned rptr;
|
| 70 | struct amdgpu_ih_regs ih_regs;
|
| 71 |
|
| 72 |
|
| 73 | wait_queue_head_t wait_process;
|
| 74 | uint64_t processed_timestamp;
|
| 75 | bool overflow;
|
| 76 | };
|
| 77 |
|
| 78 |
|
| 79 | #define amdgpu_ih_ts_after(t1, t2) \
|
| 80 | (((int64_t)((t2) << 16) - (int64_t)((t1) << 16)) > 0LL)
|
| 81 |
|
| 82 | #define amdgpu_ih_ts_after_or_equal(t1, t2) \
|
| 83 | (((int64_t)((t2) << 16) - (int64_t)((t1) << 16)) >= 0LL)
|
| 84 |
|
| 85 |
|
| 86 | struct amdgpu_ih_funcs {
|
| 87 |
|
| 88 | u32 (*get_wptr)(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih);
|
| 89 | void (*decode_iv)(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
|
| 90 | struct amdgpu_iv_entry *entry);
|
| 91 | uint64_t (*decode_iv_ts)(struct amdgpu_ih_ring *ih, u32 rptr,
|
| 92 | signed int offset);
|
| 93 | void (*set_rptr)(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih);
|
| 94 | |
| 95 | * Returns buf, or NULL if this IH version does not support node_id decoding.
|
| 96 |
|
| 97 | const char *(*node_id_to_die_name)(struct amdgpu_device *adev,
|
| 98 | unsigned int node_id,
|
| 99 | char *buf, size_t size);
|
| 100 | };
|
| 101 |
|
| 102 | #define amdgpu_ih_get_wptr(adev, ih) (adev)->irq.ih_funcs->get_wptr((adev), (ih))
|
| 103 | #define amdgpu_ih_decode_iv(adev, iv) \
|
| 104 | (adev)->irq.ih_funcs->decode_iv((adev), (ih), (iv))
|
| 105 | #define amdgpu_ih_decode_iv_ts(adev, ih, rptr, offset) \
|
| 106 | (WARN_ON_ONCE(!(adev)->irq.ih_funcs->decode_iv_ts) ? 0 : \
|
| 107 | (adev)->irq.ih_funcs->decode_iv_ts((ih), (rptr), (offset)))
|
| 108 | #define amdgpu_ih_set_rptr(adev, ih) (adev)->irq.ih_funcs->set_rptr((adev), (ih))
|
| 109 |
|
| 110 | int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
|
| 111 | unsigned ring_size, bool use_bus_addr);
|
| 112 | void amdgpu_ih_ring_fini(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih);
|
| 113 | void amdgpu_ih_ring_write(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
|
| 114 | const uint32_t *iv, unsigned int num_dw);
|
| 115 | int amdgpu_ih_wait_on_checkpoint_process_ts(struct amdgpu_device *adev,
|
| 116 | struct amdgpu_ih_ring *ih);
|
| 117 | int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih);
|
| 118 | void amdgpu_ih_decode_iv_helper(struct amdgpu_device *adev,
|
| 119 | struct amdgpu_ih_ring *ih,
|
| 120 | struct amdgpu_iv_entry *entry);
|
| 121 | uint64_t amdgpu_ih_decode_iv_ts_helper(struct amdgpu_ih_ring *ih, u32 rptr,
|
| 122 | signed int offset);
|
| 123 | const char *amdgpu_ih_ring_name(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih);
|
| 124 | #endif
|