Merge tag 'drm-misc-next-fixes-2021-09-09' of git://anongit.freedesktop.org/drm/drm...
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / amdgpu / amdgpu_sdma.c
1 /*
2  * Copyright 2018 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 #include "amdgpu.h"
25 #include "amdgpu_sdma.h"
26 #include "amdgpu_ras.h"
27
28 #define AMDGPU_CSA_SDMA_SIZE 64
29 /* SDMA CSA reside in the 3rd page of CSA */
30 #define AMDGPU_CSA_SDMA_OFFSET (4096 * 2)
31
32 /*
33  * GPU SDMA IP block helpers function.
34  */
35
36 struct amdgpu_sdma_instance *amdgpu_sdma_get_instance_from_ring(struct amdgpu_ring *ring)
37 {
38         struct amdgpu_device *adev = ring->adev;
39         int i;
40
41         for (i = 0; i < adev->sdma.num_instances; i++)
42                 if (ring == &adev->sdma.instance[i].ring ||
43                     ring == &adev->sdma.instance[i].page)
44                         return &adev->sdma.instance[i];
45
46         return NULL;
47 }
48
49 int amdgpu_sdma_get_index_from_ring(struct amdgpu_ring *ring, uint32_t *index)
50 {
51         struct amdgpu_device *adev = ring->adev;
52         int i;
53
54         for (i = 0; i < adev->sdma.num_instances; i++) {
55                 if (ring == &adev->sdma.instance[i].ring ||
56                         ring == &adev->sdma.instance[i].page) {
57                         *index = i;
58                         return 0;
59                 }
60         }
61
62         return -EINVAL;
63 }
64
65 uint64_t amdgpu_sdma_get_csa_mc_addr(struct amdgpu_ring *ring,
66                                      unsigned vmid)
67 {
68         struct amdgpu_device *adev = ring->adev;
69         uint64_t csa_mc_addr;
70         uint32_t index = 0;
71         int r;
72
73         /* don't enable OS preemption on SDMA under SRIOV */
74         if (amdgpu_sriov_vf(adev) || vmid == 0 || !amdgpu_mcbp)
75                 return 0;
76
77         r = amdgpu_sdma_get_index_from_ring(ring, &index);
78
79         if (r || index > 31)
80                 csa_mc_addr = 0;
81         else
82                 csa_mc_addr = amdgpu_csa_vaddr(adev) +
83                         AMDGPU_CSA_SDMA_OFFSET +
84                         index * AMDGPU_CSA_SDMA_SIZE;
85
86         return csa_mc_addr;
87 }
88
89 int amdgpu_sdma_ras_late_init(struct amdgpu_device *adev,
90                               void *ras_ih_info)
91 {
92         int r, i;
93         struct ras_ih_if *ih_info = (struct ras_ih_if *)ras_ih_info;
94         struct ras_fs_if fs_info = {
95                 .sysfs_name = "sdma_err_count",
96         };
97
98         if (!ih_info)
99                 return -EINVAL;
100
101         if (!adev->sdma.ras_if) {
102                 adev->sdma.ras_if = kmalloc(sizeof(struct ras_common_if), GFP_KERNEL);
103                 if (!adev->sdma.ras_if)
104                         return -ENOMEM;
105                 adev->sdma.ras_if->block = AMDGPU_RAS_BLOCK__SDMA;
106                 adev->sdma.ras_if->type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE;
107                 adev->sdma.ras_if->sub_block_index = 0;
108         }
109         fs_info.head = ih_info->head = *adev->sdma.ras_if;
110
111         r = amdgpu_ras_late_init(adev, adev->sdma.ras_if,
112                                  &fs_info, ih_info);
113         if (r)
114                 goto free;
115
116         if (amdgpu_ras_is_supported(adev, adev->sdma.ras_if->block)) {
117                 for (i = 0; i < adev->sdma.num_instances; i++) {
118                         r = amdgpu_irq_get(adev, &adev->sdma.ecc_irq,
119                                 AMDGPU_SDMA_IRQ_INSTANCE0 + i);
120                         if (r)
121                                 goto late_fini;
122                 }
123         } else {
124                 r = 0;
125                 goto free;
126         }
127
128         return 0;
129
130 late_fini:
131         amdgpu_ras_late_fini(adev, adev->sdma.ras_if, ih_info);
132 free:
133         kfree(adev->sdma.ras_if);
134         adev->sdma.ras_if = NULL;
135         return r;
136 }
137
138 void amdgpu_sdma_ras_fini(struct amdgpu_device *adev)
139 {
140         if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__SDMA) &&
141                         adev->sdma.ras_if) {
142                 struct ras_common_if *ras_if = adev->sdma.ras_if;
143                 struct ras_ih_if ih_info = {
144                         .head = *ras_if,
145                         /* the cb member will not be used by
146                          * amdgpu_ras_interrupt_remove_handler, init it only
147                          * to cheat the check in ras_late_fini
148                          */
149                         .cb = amdgpu_sdma_process_ras_data_cb,
150                 };
151
152                 amdgpu_ras_late_fini(adev, ras_if, &ih_info);
153                 kfree(ras_if);
154         }
155 }
156
157 int amdgpu_sdma_process_ras_data_cb(struct amdgpu_device *adev,
158                 void *err_data,
159                 struct amdgpu_iv_entry *entry)
160 {
161         kgd2kfd_set_sram_ecc_flag(adev->kfd.dev);
162         amdgpu_ras_reset_gpu(adev);
163
164         return AMDGPU_RAS_SUCCESS;
165 }
166
167 int amdgpu_sdma_process_ecc_irq(struct amdgpu_device *adev,
168                                       struct amdgpu_irq_src *source,
169                                       struct amdgpu_iv_entry *entry)
170 {
171         struct ras_common_if *ras_if = adev->sdma.ras_if;
172         struct ras_dispatch_if ih_data = {
173                 .entry = entry,
174         };
175
176         if (!ras_if)
177                 return 0;
178
179         ih_data.head = *ras_if;
180
181         amdgpu_ras_interrupt_dispatch(adev, &ih_data);
182         return 0;
183 }