1d38ceaf9SAlex Deucher /* 2d38ceaf9SAlex Deucher * Copyright 2014 Advanced Micro Devices, Inc. 3d38ceaf9SAlex Deucher * 4d38ceaf9SAlex Deucher * Permission is hereby granted, free of charge, to any person obtaining a 5d38ceaf9SAlex Deucher * copy of this software and associated documentation files (the "Software"), 6d38ceaf9SAlex Deucher * to deal in the Software without restriction, including without limitation 7d38ceaf9SAlex Deucher * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8d38ceaf9SAlex Deucher * and/or sell copies of the Software, and to permit persons to whom the 9d38ceaf9SAlex Deucher * Software is furnished to do so, subject to the following conditions: 10d38ceaf9SAlex Deucher * 11d38ceaf9SAlex Deucher * The above copyright notice and this permission notice shall be included in 12d38ceaf9SAlex Deucher * all copies or substantial portions of the Software. 13d38ceaf9SAlex Deucher * 14d38ceaf9SAlex Deucher * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15d38ceaf9SAlex Deucher * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16d38ceaf9SAlex Deucher * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17d38ceaf9SAlex Deucher * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18d38ceaf9SAlex Deucher * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19d38ceaf9SAlex Deucher * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20d38ceaf9SAlex Deucher * OTHER DEALINGS IN THE SOFTWARE. 21d38ceaf9SAlex Deucher * 22d38ceaf9SAlex Deucher */ 23d38ceaf9SAlex Deucher 24d38ceaf9SAlex Deucher #ifndef __AMDGPU_IH_H__ 25d38ceaf9SAlex Deucher #define __AMDGPU_IH_H__ 26d38ceaf9SAlex Deucher 278c65fe5fSChristian König /* Maximum number of IVs processed at once */ 288c65fe5fSChristian König #define AMDGPU_IH_MAX_NUM_IVS 32 298c65fe5fSChristian König 30bf80d34bSPhilip Yang #define IH_RING_SIZE (256 * 1024) 31*bcfb9ceeSPhilip Yang #define IH_SW_RING_SIZE (16 * 1024) /* enough for 512 CAM entries */ 32bf80d34bSPhilip Yang 33d38ceaf9SAlex Deucher struct amdgpu_device; 341ffdeca6SChristian König struct amdgpu_iv_entry; 35d766e6a3SAlex Deucher 363c06aaffSHawking Zhang struct amdgpu_ih_regs { 373c06aaffSHawking Zhang uint32_t ih_rb_base; 383c06aaffSHawking Zhang uint32_t ih_rb_base_hi; 393c06aaffSHawking Zhang uint32_t ih_rb_cntl; 403c06aaffSHawking Zhang uint32_t ih_rb_wptr; 413c06aaffSHawking Zhang uint32_t ih_rb_rptr; 423c06aaffSHawking Zhang uint32_t ih_doorbell_rptr; 433c06aaffSHawking Zhang uint32_t ih_rb_wptr_addr_lo; 443c06aaffSHawking Zhang uint32_t ih_rb_wptr_addr_hi; 453c06aaffSHawking Zhang uint32_t psp_reg_id; 463c06aaffSHawking Zhang }; 473c06aaffSHawking Zhang 48d38ceaf9SAlex Deucher /* 49d38ceaf9SAlex Deucher * R6xx+ IH ring 50d38ceaf9SAlex Deucher */ 51d38ceaf9SAlex Deucher struct amdgpu_ih_ring { 52d38ceaf9SAlex Deucher unsigned ring_size; 53d38ceaf9SAlex Deucher uint32_t ptr_mask; 54d38ceaf9SAlex Deucher u32 doorbell_index; 55d38ceaf9SAlex Deucher bool use_doorbell; 56d38ceaf9SAlex Deucher bool use_bus_addr; 57d81f78b4SChristian König 58d81f78b4SChristian König struct amdgpu_bo *ring_obj; 59d81f78b4SChristian König volatile uint32_t *ring; 60d81f78b4SChristian König uint64_t gpu_addr; 61d81f78b4SChristian König 62d81f78b4SChristian König uint64_t wptr_addr; 63d81f78b4SChristian König volatile uint32_t *wptr_cpu; 64d81f78b4SChristian König 65d81f78b4SChristian König uint64_t rptr_addr; 66d81f78b4SChristian König volatile uint32_t *rptr_cpu; 67d81f78b4SChristian König 68d81f78b4SChristian König bool enabled; 69d81f78b4SChristian König unsigned rptr; 703c06aaffSHawking Zhang struct amdgpu_ih_regs ih_regs; 713f1d1eb2SJonathan Kim 723f1d1eb2SJonathan Kim /* For waiting on IH processing at checkpoint. */ 733f1d1eb2SJonathan Kim wait_queue_head_t wait_process; 743c2d6ea2SPhilip Yang uint64_t processed_timestamp; 75d38ceaf9SAlex Deucher }; 76d38ceaf9SAlex Deucher 773c2d6ea2SPhilip Yang /* return true if time stamp t2 is after t1 with 48bit wrap around */ 783c2d6ea2SPhilip Yang #define amdgpu_ih_ts_after(t1, t2) \ 793c2d6ea2SPhilip Yang (((int64_t)((t2) << 16) - (int64_t)((t1) << 16)) > 0LL) 803c2d6ea2SPhilip Yang 81aa47d117SHuang Rui /* provided by the ih block */ 82aa47d117SHuang Rui struct amdgpu_ih_funcs { 83aa47d117SHuang Rui /* ring read/write ptr handling, called from interrupt context */ 848bb9eb48SChristian König u32 (*get_wptr)(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih); 858bb9eb48SChristian König void (*decode_iv)(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, 86aa47d117SHuang Rui struct amdgpu_iv_entry *entry); 873c2d6ea2SPhilip Yang uint64_t (*decode_iv_ts)(struct amdgpu_ih_ring *ih, u32 rptr, 883c2d6ea2SPhilip Yang signed int offset); 898bb9eb48SChristian König void (*set_rptr)(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih); 90aa47d117SHuang Rui }; 91aa47d117SHuang Rui 928bb9eb48SChristian König #define amdgpu_ih_get_wptr(adev, ih) (adev)->irq.ih_funcs->get_wptr((adev), (ih)) 938bb9eb48SChristian König #define amdgpu_ih_decode_iv(adev, iv) \ 948bb9eb48SChristian König (adev)->irq.ih_funcs->decode_iv((adev), (ih), (iv)) 953c2d6ea2SPhilip Yang #define amdgpu_ih_decode_iv_ts(adev, ih, rptr, offset) \ 963c2d6ea2SPhilip Yang (WARN_ON_ONCE(!(adev)->irq.ih_funcs->decode_iv_ts) ? 0 : \ 973c2d6ea2SPhilip Yang (adev)->irq.ih_funcs->decode_iv_ts((ih), (rptr), (offset))) 988bb9eb48SChristian König #define amdgpu_ih_set_rptr(adev, ih) (adev)->irq.ih_funcs->set_rptr((adev), (ih)) 99aa47d117SHuang Rui 100425c3143SChristian König int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, 101425c3143SChristian König unsigned ring_size, bool use_bus_addr); 102425c3143SChristian König void amdgpu_ih_ring_fini(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih); 103bf80d34bSPhilip Yang void amdgpu_ih_ring_write(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, 104bf80d34bSPhilip Yang const uint32_t *iv, unsigned int num_dw); 1053c2d6ea2SPhilip Yang int amdgpu_ih_wait_on_checkpoint_process_ts(struct amdgpu_device *adev, 1063f1d1eb2SJonathan Kim struct amdgpu_ih_ring *ih); 107e2fb6e0aSChristian König int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih); 10878bd101cSHawking Zhang void amdgpu_ih_decode_iv_helper(struct amdgpu_device *adev, 10978bd101cSHawking Zhang struct amdgpu_ih_ring *ih, 11078bd101cSHawking Zhang struct amdgpu_iv_entry *entry); 1113c2d6ea2SPhilip Yang uint64_t amdgpu_ih_decode_iv_ts_helper(struct amdgpu_ih_ring *ih, u32 rptr, 1123c2d6ea2SPhilip Yang signed int offset); 113d38ceaf9SAlex Deucher #endif 114