]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/gpu/drm/amd/amdgpu/umc_v6_1.c
Merge branch 'sched-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[linux.git] / drivers / gpu / drm / amd / amdgpu / umc_v6_1.c
1 /*
2  * Copyright 2019 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 #include "umc_v6_1.h"
24 #include "amdgpu_ras.h"
25 #include "amdgpu.h"
26
27 #include "rsmu/rsmu_0_0_2_offset.h"
28 #include "rsmu/rsmu_0_0_2_sh_mask.h"
29 #include "umc/umc_6_1_1_offset.h"
30 #include "umc/umc_6_1_1_sh_mask.h"
31 #include "umc/umc_6_1_2_offset.h"
32
33 #define UMC_6_INST_DIST                 0x40000
34
35 /*
36  * (addr / 256) * 8192, the higher 26 bits in ErrorAddr
37  * is the index of 8KB block
38  */
39 #define ADDR_OF_8KB_BLOCK(addr)                 (((addr) & ~0xffULL) << 5)
40 /* channel index is the index of 256B block */
41 #define ADDR_OF_256B_BLOCK(channel_index)       ((channel_index) << 8)
42 /* offset in 256B block */
43 #define OFFSET_IN_256B_BLOCK(addr)              ((addr) & 0xffULL)
44
45 #define LOOP_UMC_INST(umc_inst) for ((umc_inst) = 0; (umc_inst) < adev->umc.umc_inst_num; (umc_inst)++)
46 #define LOOP_UMC_CH_INST(ch_inst) for ((ch_inst) = 0; (ch_inst) < adev->umc.channel_inst_num; (ch_inst)++)
47 #define LOOP_UMC_INST_AND_CH(umc_inst, ch_inst) LOOP_UMC_INST((umc_inst)) LOOP_UMC_CH_INST((ch_inst))
48
49 const uint32_t
50         umc_v6_1_channel_idx_tbl[UMC_V6_1_UMC_INSTANCE_NUM][UMC_V6_1_CHANNEL_INSTANCE_NUM] = {
51                 {2, 18, 11, 27},        {4, 20, 13, 29},
52                 {1, 17, 8, 24},         {7, 23, 14, 30},
53                 {10, 26, 3, 19},        {12, 28, 5, 21},
54                 {9, 25, 0, 16},         {15, 31, 6, 22}
55 };
56
57 static void umc_v6_1_enable_umc_index_mode(struct amdgpu_device *adev)
58 {
59         WREG32_FIELD15(RSMU, 0, RSMU_UMC_INDEX_REGISTER_NBIF_VG20_GPU,
60                         RSMU_UMC_INDEX_MODE_EN, 1);
61 }
62
63 static void umc_v6_1_disable_umc_index_mode(struct amdgpu_device *adev)
64 {
65         WREG32_FIELD15(RSMU, 0, RSMU_UMC_INDEX_REGISTER_NBIF_VG20_GPU,
66                         RSMU_UMC_INDEX_MODE_EN, 0);
67 }
68
69 static uint32_t umc_v6_1_get_umc_index_mode_state(struct amdgpu_device *adev)
70 {
71         uint32_t rsmu_umc_index;
72
73         rsmu_umc_index = RREG32_SOC15(RSMU, 0,
74                         mmRSMU_UMC_INDEX_REGISTER_NBIF_VG20_GPU);
75
76         return REG_GET_FIELD(rsmu_umc_index,
77                         RSMU_UMC_INDEX_REGISTER_NBIF_VG20_GPU,
78                         RSMU_UMC_INDEX_MODE_EN);
79 }
80
81 static inline uint32_t get_umc_6_reg_offset(struct amdgpu_device *adev,
82                                             uint32_t umc_inst,
83                                             uint32_t ch_inst)
84 {
85         return adev->umc.channel_offs*ch_inst + UMC_6_INST_DIST*umc_inst;
86 }
87
88 static void umc_v6_1_query_correctable_error_count(struct amdgpu_device *adev,
89                                                    uint32_t umc_reg_offset,
90                                                    unsigned long *error_count)
91 {
92         uint32_t ecc_err_cnt_sel, ecc_err_cnt_sel_addr;
93         uint32_t ecc_err_cnt, ecc_err_cnt_addr;
94         uint64_t mc_umc_status;
95         uint32_t mc_umc_status_addr;
96
97         if (adev->asic_type == CHIP_ARCTURUS) {
98                 /* UMC 6_1_2 registers */
99                 ecc_err_cnt_sel_addr =
100                         SOC15_REG_OFFSET(UMC, 0, mmUMCCH0_0_EccErrCntSel_ARCT);
101                 ecc_err_cnt_addr =
102                         SOC15_REG_OFFSET(UMC, 0, mmUMCCH0_0_EccErrCnt_ARCT);
103                 mc_umc_status_addr =
104                         SOC15_REG_OFFSET(UMC, 0, mmMCA_UMC_UMC0_MCUMC_STATUST0_ARCT);
105         } else {
106                 /* UMC 6_1_1 registers */
107                 ecc_err_cnt_sel_addr =
108                         SOC15_REG_OFFSET(UMC, 0, mmUMCCH0_0_EccErrCntSel);
109                 ecc_err_cnt_addr =
110                         SOC15_REG_OFFSET(UMC, 0, mmUMCCH0_0_EccErrCnt);
111                 mc_umc_status_addr =
112                         SOC15_REG_OFFSET(UMC, 0, mmMCA_UMC_UMC0_MCUMC_STATUST0);
113         }
114
115         /* select the lower chip and check the error count */
116         ecc_err_cnt_sel = RREG32_PCIE((ecc_err_cnt_sel_addr + umc_reg_offset) * 4);
117         ecc_err_cnt_sel = REG_SET_FIELD(ecc_err_cnt_sel, UMCCH0_0_EccErrCntSel,
118                                         EccErrCntCsSel, 0);
119         WREG32_PCIE((ecc_err_cnt_sel_addr + umc_reg_offset) * 4, ecc_err_cnt_sel);
120         ecc_err_cnt = RREG32_PCIE((ecc_err_cnt_addr + umc_reg_offset) * 4);
121         *error_count +=
122                 (REG_GET_FIELD(ecc_err_cnt, UMCCH0_0_EccErrCnt, EccErrCnt) -
123                  UMC_V6_1_CE_CNT_INIT);
124         /* clear the lower chip err count */
125         WREG32_PCIE((ecc_err_cnt_addr + umc_reg_offset) * 4, UMC_V6_1_CE_CNT_INIT);
126
127         /* select the higher chip and check the err counter */
128         ecc_err_cnt_sel = REG_SET_FIELD(ecc_err_cnt_sel, UMCCH0_0_EccErrCntSel,
129                                         EccErrCntCsSel, 1);
130         WREG32_PCIE((ecc_err_cnt_sel_addr + umc_reg_offset) * 4, ecc_err_cnt_sel);
131         ecc_err_cnt = RREG32_PCIE((ecc_err_cnt_addr + umc_reg_offset) * 4);
132         *error_count +=
133                 (REG_GET_FIELD(ecc_err_cnt, UMCCH0_0_EccErrCnt, EccErrCnt) -
134                  UMC_V6_1_CE_CNT_INIT);
135         /* clear the higher chip err count */
136         WREG32_PCIE((ecc_err_cnt_addr + umc_reg_offset) * 4, UMC_V6_1_CE_CNT_INIT);
137
138         /* check for SRAM correctable error
139           MCUMC_STATUS is a 64 bit register */
140         mc_umc_status = RREG64_PCIE((mc_umc_status_addr + umc_reg_offset) * 4);
141         if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, ErrorCodeExt) == 6 &&
142             REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1 &&
143             REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, CECC) == 1)
144                 *error_count += 1;
145 }
146
147 static void umc_v6_1_querry_uncorrectable_error_count(struct amdgpu_device *adev,
148                                                       uint32_t umc_reg_offset,
149                                                       unsigned long *error_count)
150 {
151         uint64_t mc_umc_status;
152         uint32_t mc_umc_status_addr;
153
154         if (adev->asic_type == CHIP_ARCTURUS) {
155                 /* UMC 6_1_2 registers */
156                 mc_umc_status_addr =
157                         SOC15_REG_OFFSET(UMC, 0, mmMCA_UMC_UMC0_MCUMC_STATUST0_ARCT);
158         } else {
159                 /* UMC 6_1_1 registers */
160                 mc_umc_status_addr =
161                         SOC15_REG_OFFSET(UMC, 0, mmMCA_UMC_UMC0_MCUMC_STATUST0);
162         }
163
164         /* check the MCUMC_STATUS */
165         mc_umc_status = RREG64_PCIE((mc_umc_status_addr + umc_reg_offset) * 4);
166         if ((REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1) &&
167             (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Deferred) == 1 ||
168             REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC) == 1 ||
169             REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, PCC) == 1 ||
170             REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UC) == 1 ||
171             REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, TCC) == 1))
172                 *error_count += 1;
173 }
174
175 static void umc_v6_1_query_ras_error_count(struct amdgpu_device *adev,
176                                            void *ras_error_status)
177 {
178         struct ras_err_data* err_data = (struct ras_err_data*)ras_error_status;
179
180         uint32_t umc_inst        = 0;
181         uint32_t ch_inst         = 0;
182         uint32_t umc_reg_offset  = 0;
183
184         uint32_t rsmu_umc_index_state = umc_v6_1_get_umc_index_mode_state(adev);
185
186         if (rsmu_umc_index_state)
187                 umc_v6_1_disable_umc_index_mode(adev);
188
189         LOOP_UMC_INST_AND_CH(umc_inst, ch_inst) {
190                 umc_reg_offset = get_umc_6_reg_offset(adev,
191                                                       umc_inst,
192                                                       ch_inst);
193
194                 umc_v6_1_query_correctable_error_count(adev,
195                                                        umc_reg_offset,
196                                                        &(err_data->ce_count));
197                 umc_v6_1_querry_uncorrectable_error_count(adev,
198                                                           umc_reg_offset,
199                                                           &(err_data->ue_count));
200         }
201
202         if (rsmu_umc_index_state)
203                 umc_v6_1_enable_umc_index_mode(adev);
204 }
205
206 static void umc_v6_1_query_error_address(struct amdgpu_device *adev,
207                                          struct ras_err_data *err_data,
208                                          uint32_t umc_reg_offset,
209                                          uint32_t ch_inst,
210                                          uint32_t umc_inst)
211 {
212         uint32_t lsb, mc_umc_status_addr;
213         uint64_t mc_umc_status, err_addr, retired_page, mc_umc_addrt0;
214         struct eeprom_table_record *err_rec;
215         uint32_t channel_index = adev->umc.channel_idx_tbl[umc_inst * adev->umc.channel_inst_num + ch_inst];
216
217         if (adev->asic_type == CHIP_ARCTURUS) {
218                 /* UMC 6_1_2 registers */
219                 mc_umc_status_addr =
220                         SOC15_REG_OFFSET(UMC, 0, mmMCA_UMC_UMC0_MCUMC_STATUST0_ARCT);
221                 mc_umc_addrt0 =
222                         SOC15_REG_OFFSET(UMC, 0, mmMCA_UMC_UMC0_MCUMC_ADDRT0_ARCT);
223         } else {
224                 /* UMC 6_1_1 registers */
225                 mc_umc_status_addr =
226                         SOC15_REG_OFFSET(UMC, 0, mmMCA_UMC_UMC0_MCUMC_STATUST0);
227                 mc_umc_addrt0 =
228                         SOC15_REG_OFFSET(UMC, 0, mmMCA_UMC_UMC0_MCUMC_ADDRT0);
229         }
230
231         /* skip error address process if -ENOMEM */
232         if (!err_data->err_addr) {
233                 /* clear umc status */
234                 WREG64_PCIE((mc_umc_status_addr + umc_reg_offset) * 4, 0x0ULL);
235                 return;
236         }
237
238         err_rec = &err_data->err_addr[err_data->err_addr_cnt];
239         mc_umc_status = RREG64_PCIE((mc_umc_status_addr + umc_reg_offset) * 4);
240
241         /* calculate error address if ue/ce error is detected */
242         if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1 &&
243             (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC) == 1 ||
244             REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, CECC) == 1)) {
245
246                 err_addr = RREG64_PCIE((mc_umc_addrt0 + umc_reg_offset) * 4);
247                 /* the lowest lsb bits should be ignored */
248                 lsb = REG_GET_FIELD(err_addr, MCA_UMC_UMC0_MCUMC_ADDRT0, LSB);
249                 err_addr = REG_GET_FIELD(err_addr, MCA_UMC_UMC0_MCUMC_ADDRT0, ErrorAddr);
250                 err_addr &= ~((0x1ULL << lsb) - 1);
251
252                 /* translate umc channel address to soc pa, 3 parts are included */
253                 retired_page = ADDR_OF_8KB_BLOCK(err_addr) |
254                                 ADDR_OF_256B_BLOCK(channel_index) |
255                                 OFFSET_IN_256B_BLOCK(err_addr);
256
257                 /* we only save ue error information currently, ce is skipped */
258                 if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC)
259                                 == 1) {
260                         err_rec->address = err_addr;
261                         /* page frame address is saved */
262                         err_rec->retired_page = retired_page >> AMDGPU_GPU_PAGE_SHIFT;
263                         err_rec->ts = (uint64_t)ktime_get_real_seconds();
264                         err_rec->err_type = AMDGPU_RAS_EEPROM_ERR_NON_RECOVERABLE;
265                         err_rec->cu = 0;
266                         err_rec->mem_channel = channel_index;
267                         err_rec->mcumc_id = umc_inst;
268
269                         err_data->err_addr_cnt++;
270                 }
271         }
272
273         /* clear umc status */
274         WREG64_PCIE((mc_umc_status_addr + umc_reg_offset) * 4, 0x0ULL);
275 }
276
277 static void umc_v6_1_query_ras_error_address(struct amdgpu_device *adev,
278                                              void *ras_error_status)
279 {
280         struct ras_err_data* err_data = (struct ras_err_data*)ras_error_status;
281
282         uint32_t umc_inst        = 0;
283         uint32_t ch_inst         = 0;
284         uint32_t umc_reg_offset  = 0;
285
286         uint32_t rsmu_umc_index_state = umc_v6_1_get_umc_index_mode_state(adev);
287
288         if (rsmu_umc_index_state)
289                 umc_v6_1_disable_umc_index_mode(adev);
290
291         LOOP_UMC_INST_AND_CH(umc_inst, ch_inst) {
292                 umc_reg_offset = get_umc_6_reg_offset(adev,
293                                                       umc_inst,
294                                                       ch_inst);
295
296                 umc_v6_1_query_error_address(adev,
297                                              err_data,
298                                              umc_reg_offset,
299                                              ch_inst,
300                                              umc_inst);
301         }
302
303         if (rsmu_umc_index_state)
304                 umc_v6_1_enable_umc_index_mode(adev);
305 }
306
307 static void umc_v6_1_err_cnt_init_per_channel(struct amdgpu_device *adev,
308                                               uint32_t umc_reg_offset)
309 {
310         uint32_t ecc_err_cnt_sel, ecc_err_cnt_sel_addr;
311         uint32_t ecc_err_cnt_addr;
312
313         if (adev->asic_type == CHIP_ARCTURUS) {
314                 /* UMC 6_1_2 registers */
315                 ecc_err_cnt_sel_addr =
316                         SOC15_REG_OFFSET(UMC, 0, mmUMCCH0_0_EccErrCntSel_ARCT);
317                 ecc_err_cnt_addr =
318                         SOC15_REG_OFFSET(UMC, 0, mmUMCCH0_0_EccErrCnt_ARCT);
319         } else {
320                 /* UMC 6_1_1 registers */
321                 ecc_err_cnt_sel_addr =
322                         SOC15_REG_OFFSET(UMC, 0, mmUMCCH0_0_EccErrCntSel);
323                 ecc_err_cnt_addr =
324                         SOC15_REG_OFFSET(UMC, 0, mmUMCCH0_0_EccErrCnt);
325         }
326
327         /* select the lower chip and check the error count */
328         ecc_err_cnt_sel = RREG32_PCIE((ecc_err_cnt_sel_addr + umc_reg_offset) * 4);
329         ecc_err_cnt_sel = REG_SET_FIELD(ecc_err_cnt_sel, UMCCH0_0_EccErrCntSel,
330                                         EccErrCntCsSel, 0);
331         /* set ce error interrupt type to APIC based interrupt */
332         ecc_err_cnt_sel = REG_SET_FIELD(ecc_err_cnt_sel, UMCCH0_0_EccErrCntSel,
333                                         EccErrInt, 0x1);
334         WREG32_PCIE((ecc_err_cnt_sel_addr + umc_reg_offset) * 4, ecc_err_cnt_sel);
335         /* set error count to initial value */
336         WREG32_PCIE((ecc_err_cnt_addr + umc_reg_offset) * 4, UMC_V6_1_CE_CNT_INIT);
337
338         /* select the higher chip and check the err counter */
339         ecc_err_cnt_sel = REG_SET_FIELD(ecc_err_cnt_sel, UMCCH0_0_EccErrCntSel,
340                                         EccErrCntCsSel, 1);
341         WREG32_PCIE((ecc_err_cnt_sel_addr + umc_reg_offset) * 4, ecc_err_cnt_sel);
342         WREG32_PCIE((ecc_err_cnt_addr + umc_reg_offset) * 4, UMC_V6_1_CE_CNT_INIT);
343 }
344
345 static void umc_v6_1_err_cnt_init(struct amdgpu_device *adev)
346 {
347         uint32_t umc_inst        = 0;
348         uint32_t ch_inst         = 0;
349         uint32_t umc_reg_offset  = 0;
350
351         uint32_t rsmu_umc_index_state = umc_v6_1_get_umc_index_mode_state(adev);
352
353         if (rsmu_umc_index_state)
354                 umc_v6_1_disable_umc_index_mode(adev);
355
356         LOOP_UMC_INST_AND_CH(umc_inst, ch_inst) {
357                 umc_reg_offset = get_umc_6_reg_offset(adev,
358                                                       umc_inst,
359                                                       ch_inst);
360
361                 umc_v6_1_err_cnt_init_per_channel(adev, umc_reg_offset);
362         }
363
364         if (rsmu_umc_index_state)
365                 umc_v6_1_enable_umc_index_mode(adev);
366 }
367
368 const struct amdgpu_umc_funcs umc_v6_1_funcs = {
369         .err_cnt_init = umc_v6_1_err_cnt_init,
370         .ras_late_init = amdgpu_umc_ras_late_init,
371         .query_ras_error_count = umc_v6_1_query_ras_error_count,
372         .query_ras_error_address = umc_v6_1_query_ras_error_address,
373 };