Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2018 Advanced Micro Devices, Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  *
0022  */
0023 
0024 #include "amdgpu.h"
0025 #include "amdgpu_sdma.h"
0026 #include "amdgpu_ras.h"
0027 
0028 #define AMDGPU_CSA_SDMA_SIZE 64
0029 /* SDMA CSA reside in the 3rd page of CSA */
0030 #define AMDGPU_CSA_SDMA_OFFSET (4096 * 2)
0031 
0032 /*
0033  * GPU SDMA IP block helpers function.
0034  */
0035 
0036 struct amdgpu_sdma_instance *amdgpu_sdma_get_instance_from_ring(struct amdgpu_ring *ring)
0037 {
0038     struct amdgpu_device *adev = ring->adev;
0039     int i;
0040 
0041     for (i = 0; i < adev->sdma.num_instances; i++)
0042         if (ring == &adev->sdma.instance[i].ring ||
0043             ring == &adev->sdma.instance[i].page)
0044             return &adev->sdma.instance[i];
0045 
0046     return NULL;
0047 }
0048 
0049 int amdgpu_sdma_get_index_from_ring(struct amdgpu_ring *ring, uint32_t *index)
0050 {
0051     struct amdgpu_device *adev = ring->adev;
0052     int i;
0053 
0054     for (i = 0; i < adev->sdma.num_instances; i++) {
0055         if (ring == &adev->sdma.instance[i].ring ||
0056             ring == &adev->sdma.instance[i].page) {
0057             *index = i;
0058             return 0;
0059         }
0060     }
0061 
0062     return -EINVAL;
0063 }
0064 
0065 uint64_t amdgpu_sdma_get_csa_mc_addr(struct amdgpu_ring *ring,
0066                      unsigned vmid)
0067 {
0068     struct amdgpu_device *adev = ring->adev;
0069     uint64_t csa_mc_addr;
0070     uint32_t index = 0;
0071     int r;
0072 
0073     /* don't enable OS preemption on SDMA under SRIOV */
0074     if (amdgpu_sriov_vf(adev) || vmid == 0 || !amdgpu_mcbp)
0075         return 0;
0076 
0077     if (ring->is_mes_queue) {
0078         uint32_t offset = 0;
0079 
0080         offset = offsetof(struct amdgpu_mes_ctx_meta_data,
0081                   sdma[ring->idx].sdma_meta_data);
0082         csa_mc_addr = amdgpu_mes_ctx_get_offs_gpu_addr(ring, offset);
0083     } else {
0084         r = amdgpu_sdma_get_index_from_ring(ring, &index);
0085 
0086         if (r || index > 31)
0087             csa_mc_addr = 0;
0088         else
0089             csa_mc_addr = amdgpu_csa_vaddr(adev) +
0090                 AMDGPU_CSA_SDMA_OFFSET +
0091                 index * AMDGPU_CSA_SDMA_SIZE;
0092     }
0093 
0094     return csa_mc_addr;
0095 }
0096 
0097 int amdgpu_sdma_ras_late_init(struct amdgpu_device *adev,
0098                   struct ras_common_if *ras_block)
0099 {
0100     int r, i;
0101 
0102     r = amdgpu_ras_block_late_init(adev, ras_block);
0103     if (r)
0104         return r;
0105 
0106     if (amdgpu_ras_is_supported(adev, ras_block->block)) {
0107         for (i = 0; i < adev->sdma.num_instances; i++) {
0108             r = amdgpu_irq_get(adev, &adev->sdma.ecc_irq,
0109                 AMDGPU_SDMA_IRQ_INSTANCE0 + i);
0110             if (r)
0111                 goto late_fini;
0112         }
0113     }
0114 
0115     return 0;
0116 
0117 late_fini:
0118     amdgpu_ras_block_late_fini(adev, ras_block);
0119     return r;
0120 }
0121 
0122 int amdgpu_sdma_process_ras_data_cb(struct amdgpu_device *adev,
0123         void *err_data,
0124         struct amdgpu_iv_entry *entry)
0125 {
0126     kgd2kfd_set_sram_ecc_flag(adev->kfd.dev);
0127 
0128     if (amdgpu_sriov_vf(adev))
0129         return AMDGPU_RAS_SUCCESS;
0130 
0131     amdgpu_ras_reset_gpu(adev);
0132 
0133     return AMDGPU_RAS_SUCCESS;
0134 }
0135 
0136 int amdgpu_sdma_process_ecc_irq(struct amdgpu_device *adev,
0137                       struct amdgpu_irq_src *source,
0138                       struct amdgpu_iv_entry *entry)
0139 {
0140     struct ras_common_if *ras_if = adev->sdma.ras_if;
0141     struct ras_dispatch_if ih_data = {
0142         .entry = entry,
0143     };
0144 
0145     if (!ras_if)
0146         return 0;
0147 
0148     ih_data.head = *ras_if;
0149 
0150     amdgpu_ras_interrupt_dispatch(adev, &ih_data);
0151     return 0;
0152 }