xref: /linux/drivers/crypto/intel/qat/qat_common/adf_gen6_ras.c (revision 14418ddcc2c2055743ac7ee53d5ac2cf8a8660a7)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright(c) 2025 Intel Corporation */
3 #include <linux/bitfield.h>
4 #include <linux/types.h>
5 
6 #include "adf_common_drv.h"
7 #include "adf_gen6_ras.h"
8 #include "adf_sysfs_ras_counters.h"
9 
10 static void enable_errsou_reporting(void __iomem *csr)
11 {
12 	/* Enable correctable error reporting in ERRSOU0 */
13 	ADF_CSR_WR(csr, ADF_GEN6_ERRMSK0, 0);
14 
15 	/* Enable uncorrectable error reporting in ERRSOU1 */
16 	ADF_CSR_WR(csr, ADF_GEN6_ERRMSK1, 0);
17 
18 	/*
19 	 * Enable uncorrectable error reporting in ERRSOU2
20 	 * but disable PM interrupt by default
21 	 */
22 	ADF_CSR_WR(csr, ADF_GEN6_ERRMSK2, ADF_GEN6_ERRSOU2_PM_INT_BIT);
23 
24 	/* Enable uncorrectable error reporting in ERRSOU3 */
25 	ADF_CSR_WR(csr, ADF_GEN6_ERRMSK3, 0);
26 }
27 
28 static void enable_ae_error_reporting(struct adf_accel_dev *accel_dev, void __iomem *csr)
29 {
30 	u32 ae_mask = GET_HW_DATA(accel_dev)->ae_mask;
31 
32 	/* Enable acceleration engine correctable error reporting */
33 	ADF_CSR_WR(csr, ADF_GEN6_HIAECORERRLOGENABLE_CPP0, ae_mask);
34 
35 	/* Enable acceleration engine uncorrectable error reporting */
36 	ADF_CSR_WR(csr, ADF_GEN6_HIAEUNCERRLOGENABLE_CPP0, ae_mask);
37 }
38 
39 static void enable_cpp_error_reporting(struct adf_accel_dev *accel_dev, void __iomem *csr)
40 {
41 	/* Enable HI CPP agents command parity error reporting */
42 	ADF_CSR_WR(csr, ADF_GEN6_HICPPAGENTCMDPARERRLOGENABLE,
43 		   ADF_6XXX_HICPPAGENTCMDPARERRLOG_MASK);
44 
45 	ADF_CSR_WR(csr, ADF_GEN6_CPP_CFC_ERR_CTRL, ADF_GEN6_CPP_CFC_ERR_CTRL_MASK);
46 }
47 
48 static void enable_ti_ri_error_reporting(void __iomem *csr)
49 {
50 	u32 reg, mask;
51 
52 	/* Enable RI memory error reporting */
53 	mask = ADF_GEN6_RIMEM_PARERR_FATAL_MASK | ADF_GEN6_RIMEM_PARERR_CERR_MASK;
54 	ADF_CSR_WR(csr, ADF_GEN6_RI_MEM_PAR_ERR_EN0, mask);
55 
56 	/* Enable IOSF primary command parity error reporting */
57 	ADF_CSR_WR(csr, ADF_GEN6_RIMISCCTL, ADF_GEN6_RIMISCSTS_BIT);
58 
59 	/* Enable TI internal memory parity error reporting */
60 	reg = ADF_CSR_RD(csr, ADF_GEN6_TI_CI_PAR_ERR_MASK);
61 	reg &= ~ADF_GEN6_TI_CI_PAR_STS_MASK;
62 	ADF_CSR_WR(csr, ADF_GEN6_TI_CI_PAR_ERR_MASK, reg);
63 
64 	reg = ADF_CSR_RD(csr, ADF_GEN6_TI_PULL0FUB_PAR_ERR_MASK);
65 	reg &= ~ADF_GEN6_TI_PULL0FUB_PAR_STS_MASK;
66 	ADF_CSR_WR(csr, ADF_GEN6_TI_PULL0FUB_PAR_ERR_MASK, reg);
67 
68 	reg = ADF_CSR_RD(csr, ADF_GEN6_TI_PUSHFUB_PAR_ERR_MASK);
69 	reg &= ~ADF_GEN6_TI_PUSHFUB_PAR_STS_MASK;
70 	ADF_CSR_WR(csr, ADF_GEN6_TI_PUSHFUB_PAR_ERR_MASK, reg);
71 
72 	reg = ADF_CSR_RD(csr, ADF_GEN6_TI_CD_PAR_ERR_MASK);
73 	reg &= ~ADF_GEN6_TI_CD_PAR_STS_MASK;
74 	ADF_CSR_WR(csr, ADF_GEN6_TI_CD_PAR_ERR_MASK, reg);
75 
76 	reg = ADF_CSR_RD(csr, ADF_GEN6_TI_TRNSB_PAR_ERR_MASK);
77 	reg &= ~ADF_GEN6_TI_TRNSB_PAR_STS_MASK;
78 	ADF_CSR_WR(csr, ADF_GEN6_TI_TRNSB_PAR_ERR_MASK, reg);
79 
80 	/* Enable error handling in RI, TI CPP interface control registers */
81 	ADF_CSR_WR(csr, ADF_GEN6_RICPPINTCTL, ADF_GEN6_RICPPINTCTL_MASK);
82 	ADF_CSR_WR(csr, ADF_GEN6_TICPPINTCTL, ADF_GEN6_TICPPINTCTL_MASK);
83 
84 	/*
85 	 * Enable error detection and reporting in TIMISCSTS
86 	 * with bits 1, 2 and 30 value preserved
87 	 */
88 	reg = ADF_CSR_RD(csr, ADF_GEN6_TIMISCCTL);
89 	reg &= ADF_GEN6_TIMSCCTL_RELAY_MASK;
90 	reg |= ADF_GEN6_TIMISCCTL_BIT;
91 	ADF_CSR_WR(csr, ADF_GEN6_TIMISCCTL, reg);
92 }
93 
94 static void enable_ssm_error_reporting(struct adf_accel_dev *accel_dev,
95 				       void __iomem *csr)
96 {
97 	/* Enable SSM interrupts */
98 	ADF_CSR_WR(csr, ADF_GEN6_INTMASKSSM, 0);
99 }
100 
101 static void adf_gen6_enable_ras(struct adf_accel_dev *accel_dev)
102 {
103 	void __iomem *csr = adf_get_pmisc_base(accel_dev);
104 
105 	enable_errsou_reporting(csr);
106 	enable_ae_error_reporting(accel_dev, csr);
107 	enable_cpp_error_reporting(accel_dev, csr);
108 	enable_ti_ri_error_reporting(csr);
109 	enable_ssm_error_reporting(accel_dev, csr);
110 }
111 
112 static void disable_errsou_reporting(void __iomem *csr)
113 {
114 	u32 val;
115 
116 	/* Disable correctable error reporting in ERRSOU0 */
117 	ADF_CSR_WR(csr, ADF_GEN6_ERRMSK0, ADF_GEN6_ERRSOU0_MASK);
118 
119 	/* Disable uncorrectable error reporting in ERRSOU1 */
120 	ADF_CSR_WR(csr, ADF_GEN6_ERRMSK1, ADF_GEN6_ERRMSK1_MASK);
121 
122 	/* Disable uncorrectable error reporting in ERRSOU2 */
123 	val = ADF_CSR_RD(csr, ADF_GEN6_ERRMSK2);
124 	val |= ADF_GEN6_ERRSOU2_DIS_MASK;
125 	ADF_CSR_WR(csr, ADF_GEN6_ERRMSK2, val);
126 
127 	/* Disable uncorrectable error reporting in ERRSOU3 */
128 	ADF_CSR_WR(csr, ADF_GEN6_ERRMSK3, ADF_GEN6_ERRSOU3_DIS_MASK);
129 }
130 
131 static void disable_ae_error_reporting(void __iomem *csr)
132 {
133 	/* Disable acceleration engine correctable error reporting */
134 	ADF_CSR_WR(csr, ADF_GEN6_HIAECORERRLOGENABLE_CPP0, 0);
135 
136 	/* Disable acceleration engine uncorrectable error reporting */
137 	ADF_CSR_WR(csr, ADF_GEN6_HIAEUNCERRLOGENABLE_CPP0, 0);
138 }
139 
140 static void disable_cpp_error_reporting(void __iomem *csr)
141 {
142 	/* Disable HI CPP agents command parity error reporting */
143 	ADF_CSR_WR(csr, ADF_GEN6_HICPPAGENTCMDPARERRLOGENABLE, 0);
144 
145 	ADF_CSR_WR(csr, ADF_GEN6_CPP_CFC_ERR_CTRL, ADF_GEN6_CPP_CFC_ERR_CTRL_DIS_MASK);
146 }
147 
148 static void disable_ti_ri_error_reporting(void __iomem *csr)
149 {
150 	u32 reg;
151 
152 	/* Disable RI memory error reporting */
153 	ADF_CSR_WR(csr, ADF_GEN6_RI_MEM_PAR_ERR_EN0, 0);
154 
155 	/* Disable IOSF primary command parity error reporting */
156 	reg = ADF_CSR_RD(csr, ADF_GEN6_RIMISCCTL);
157 	reg &= ~ADF_GEN6_RIMISCSTS_BIT;
158 	ADF_CSR_WR(csr, ADF_GEN6_RIMISCCTL, reg);
159 
160 	/* Disable TI internal memory parity error reporting */
161 	ADF_CSR_WR(csr, ADF_GEN6_TI_CI_PAR_ERR_MASK, ADF_GEN6_TI_CI_PAR_STS_MASK);
162 	ADF_CSR_WR(csr, ADF_GEN6_TI_PULL0FUB_PAR_ERR_MASK, ADF_GEN6_TI_PULL0FUB_PAR_STS_MASK);
163 	ADF_CSR_WR(csr, ADF_GEN6_TI_PUSHFUB_PAR_ERR_MASK, ADF_GEN6_TI_PUSHFUB_PAR_STS_MASK);
164 	ADF_CSR_WR(csr, ADF_GEN6_TI_CD_PAR_ERR_MASK, ADF_GEN6_TI_CD_PAR_STS_MASK);
165 	ADF_CSR_WR(csr, ADF_GEN6_TI_TRNSB_PAR_ERR_MASK, ADF_GEN6_TI_TRNSB_PAR_STS_MASK);
166 
167 	/* Disable error handling in RI, TI CPP interface control registers */
168 	reg = ADF_CSR_RD(csr, ADF_GEN6_RICPPINTCTL);
169 	reg &= ~ADF_GEN6_RICPPINTCTL_MASK;
170 	ADF_CSR_WR(csr, ADF_GEN6_RICPPINTCTL, reg);
171 
172 	reg = ADF_CSR_RD(csr, ADF_GEN6_TICPPINTCTL);
173 	reg &= ~ADF_GEN6_TICPPINTCTL_MASK;
174 	ADF_CSR_WR(csr, ADF_GEN6_TICPPINTCTL, reg);
175 
176 	/*
177 	 * Disable error detection and reporting in TIMISCSTS
178 	 * with bits 1, 2 and 30 value preserved
179 	 */
180 	reg = ADF_CSR_RD(csr, ADF_GEN6_TIMISCCTL);
181 	reg &= ADF_GEN6_TIMSCCTL_RELAY_MASK;
182 	ADF_CSR_WR(csr, ADF_GEN6_TIMISCCTL, reg);
183 }
184 
185 static void disable_ssm_error_reporting(void __iomem *csr)
186 {
187 	/* Disable SSM interrupts */
188 	ADF_CSR_WR(csr, ADF_GEN6_INTMASKSSM, ADF_GEN6_INTMASKSSM_MASK);
189 }
190 
191 static void adf_gen6_disable_ras(struct adf_accel_dev *accel_dev)
192 {
193 	void __iomem *csr = adf_get_pmisc_base(accel_dev);
194 
195 	disable_errsou_reporting(csr);
196 	disable_ae_error_reporting(csr);
197 	disable_cpp_error_reporting(csr);
198 	disable_ti_ri_error_reporting(csr);
199 	disable_ssm_error_reporting(csr);
200 }
201 
202 static void adf_gen6_process_errsou0(struct adf_accel_dev *accel_dev, void __iomem *csr)
203 {
204 	u32 ae, errsou;
205 
206 	ae = ADF_CSR_RD(csr, ADF_GEN6_HIAECORERRLOG_CPP0);
207 	ae &= GET_HW_DATA(accel_dev)->ae_mask;
208 
209 	dev_warn(&GET_DEV(accel_dev), "Correctable error detected: %#x\n", ae);
210 
211 	ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_CORR);
212 
213 	/* Clear interrupt from ERRSOU0 */
214 	ADF_CSR_WR(csr, ADF_GEN6_HIAECORERRLOG_CPP0, ae);
215 
216 	errsou = ADF_CSR_RD(csr, ADF_GEN6_ERRSOU0);
217 	if (errsou & ADF_GEN6_ERRSOU0_MASK)
218 		dev_warn(&GET_DEV(accel_dev), "errsou0 still set: %#x\n", errsou);
219 }
220 
221 static void adf_handle_cpp_ae_unc(struct adf_accel_dev *accel_dev, void __iomem *csr,
222 				  u32 errsou)
223 {
224 	u32 ae;
225 
226 	if (!(errsou & ADF_GEN6_ERRSOU1_CPP0_MEUNC_BIT))
227 		return;
228 
229 	ae = ADF_CSR_RD(csr, ADF_GEN6_HIAEUNCERRLOG_CPP0);
230 	ae &= GET_HW_DATA(accel_dev)->ae_mask;
231 	if (ae) {
232 		dev_err(&GET_DEV(accel_dev), "Uncorrectable error detected: %#x\n", ae);
233 		ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR);
234 		ADF_CSR_WR(csr, ADF_GEN6_HIAEUNCERRLOG_CPP0, ae);
235 	}
236 }
237 
238 static void adf_handle_cpp_cmd_par_err(struct adf_accel_dev *accel_dev, void __iomem *csr,
239 				       u32 errsou)
240 {
241 	u32 cmd_par_err;
242 
243 	if (!(errsou & ADF_GEN6_ERRSOU1_CPP_CMDPARERR_BIT))
244 		return;
245 
246 	cmd_par_err = ADF_CSR_RD(csr, ADF_GEN6_HICPPAGENTCMDPARERRLOG);
247 	cmd_par_err &= ADF_6XXX_HICPPAGENTCMDPARERRLOG_MASK;
248 	if (cmd_par_err) {
249 		dev_err(&GET_DEV(accel_dev), "HI CPP agent command parity error: %#x\n",
250 			cmd_par_err);
251 		ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL);
252 		ADF_CSR_WR(csr, ADF_GEN6_HICPPAGENTCMDPARERRLOG, cmd_par_err);
253 	}
254 }
255 
256 static void adf_handle_ri_mem_par_err(struct adf_accel_dev *accel_dev, void __iomem *csr,
257 				      u32 errsou)
258 {
259 	u32 rimem_parerr_sts;
260 
261 	if (!(errsou & ADF_GEN6_ERRSOU1_RIMEM_PARERR_STS_BIT))
262 		return;
263 
264 	rimem_parerr_sts = ADF_CSR_RD(csr, ADF_GEN6_RIMEM_PARERR_STS);
265 	rimem_parerr_sts &= ADF_GEN6_RIMEM_PARERR_CERR_MASK |
266 			    ADF_GEN6_RIMEM_PARERR_FATAL_MASK;
267 	if (rimem_parerr_sts & ADF_GEN6_RIMEM_PARERR_CERR_MASK) {
268 		dev_err(&GET_DEV(accel_dev), "RI memory parity correctable error: %#x\n",
269 			rimem_parerr_sts);
270 		ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_CORR);
271 	}
272 
273 	if (rimem_parerr_sts & ADF_GEN6_RIMEM_PARERR_FATAL_MASK) {
274 		dev_err(&GET_DEV(accel_dev), "RI memory parity fatal error: %#x\n",
275 			rimem_parerr_sts);
276 		ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL);
277 	}
278 
279 	ADF_CSR_WR(csr, ADF_GEN6_RIMEM_PARERR_STS, rimem_parerr_sts);
280 }
281 
282 static void adf_handle_ti_ci_par_sts(struct adf_accel_dev *accel_dev, void __iomem *csr)
283 {
284 	u32 ti_ci_par_sts;
285 
286 	ti_ci_par_sts = ADF_CSR_RD(csr, ADF_GEN6_TI_CI_PAR_STS);
287 	ti_ci_par_sts &= ADF_GEN6_TI_CI_PAR_STS_MASK;
288 	if (ti_ci_par_sts) {
289 		dev_err(&GET_DEV(accel_dev), "TI memory parity error: %#x\n", ti_ci_par_sts);
290 		ADF_CSR_WR(csr, ADF_GEN6_TI_CI_PAR_STS, ti_ci_par_sts);
291 		ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR);
292 	}
293 }
294 
295 static void adf_handle_ti_pullfub_par_sts(struct adf_accel_dev *accel_dev, void __iomem *csr)
296 {
297 	u32 ti_pullfub_par_sts;
298 
299 	ti_pullfub_par_sts = ADF_CSR_RD(csr, ADF_GEN6_TI_PULL0FUB_PAR_STS);
300 	ti_pullfub_par_sts &= ADF_GEN6_TI_PULL0FUB_PAR_STS_MASK;
301 	if (ti_pullfub_par_sts) {
302 		dev_err(&GET_DEV(accel_dev), "TI pull parity error: %#x\n", ti_pullfub_par_sts);
303 		ADF_CSR_WR(csr, ADF_GEN6_TI_PULL0FUB_PAR_STS, ti_pullfub_par_sts);
304 		ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR);
305 	}
306 }
307 
308 static void adf_handle_ti_pushfub_par_sts(struct adf_accel_dev *accel_dev, void __iomem *csr)
309 {
310 	u32 ti_pushfub_par_sts;
311 
312 	ti_pushfub_par_sts = ADF_CSR_RD(csr, ADF_GEN6_TI_PUSHFUB_PAR_STS);
313 	ti_pushfub_par_sts &= ADF_GEN6_TI_PUSHFUB_PAR_STS_MASK;
314 	if (ti_pushfub_par_sts) {
315 		dev_err(&GET_DEV(accel_dev), "TI push parity error: %#x\n", ti_pushfub_par_sts);
316 		ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR);
317 		ADF_CSR_WR(csr, ADF_GEN6_TI_PUSHFUB_PAR_STS, ti_pushfub_par_sts);
318 	}
319 }
320 
321 static void adf_handle_ti_cd_par_sts(struct adf_accel_dev *accel_dev, void __iomem *csr)
322 {
323 	u32 ti_cd_par_sts;
324 
325 	ti_cd_par_sts = ADF_CSR_RD(csr, ADF_GEN6_TI_CD_PAR_STS);
326 	ti_cd_par_sts &= ADF_GEN6_TI_CD_PAR_STS_MASK;
327 	if (ti_cd_par_sts) {
328 		dev_err(&GET_DEV(accel_dev), "TI CD parity error: %#x\n", ti_cd_par_sts);
329 		ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR);
330 		ADF_CSR_WR(csr, ADF_GEN6_TI_CD_PAR_STS, ti_cd_par_sts);
331 	}
332 }
333 
334 static void adf_handle_ti_trnsb_par_sts(struct adf_accel_dev *accel_dev, void __iomem *csr)
335 {
336 	u32 ti_trnsb_par_sts;
337 
338 	ti_trnsb_par_sts = ADF_CSR_RD(csr, ADF_GEN6_TI_TRNSB_PAR_STS);
339 	ti_trnsb_par_sts &= ADF_GEN6_TI_TRNSB_PAR_STS_MASK;
340 	if (ti_trnsb_par_sts) {
341 		dev_err(&GET_DEV(accel_dev), "TI TRNSB parity error: %#x\n", ti_trnsb_par_sts);
342 		ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR);
343 		ADF_CSR_WR(csr, ADF_GEN6_TI_TRNSB_PAR_STS, ti_trnsb_par_sts);
344 	}
345 }
346 
347 static void adf_handle_iosfp_cmd_parerr(struct adf_accel_dev *accel_dev, void __iomem *csr)
348 {
349 	u32 rimiscsts;
350 
351 	rimiscsts = ADF_CSR_RD(csr, ADF_GEN6_RIMISCSTS);
352 	rimiscsts &= ADF_GEN6_RIMISCSTS_BIT;
353 	if (rimiscsts) {
354 		dev_err(&GET_DEV(accel_dev), "Command parity error detected on IOSFP: %#x\n",
355 			rimiscsts);
356 		ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL);
357 		ADF_CSR_WR(csr, ADF_GEN6_RIMISCSTS, rimiscsts);
358 	}
359 }
360 
361 static void adf_handle_ti_err(struct adf_accel_dev *accel_dev, void __iomem *csr,
362 			      u32 errsou)
363 {
364 	if (!(errsou & ADF_GEN6_ERRSOU1_TIMEM_PARERR_STS_BIT))
365 		return;
366 
367 	adf_handle_ti_ci_par_sts(accel_dev, csr);
368 	adf_handle_ti_pullfub_par_sts(accel_dev, csr);
369 	adf_handle_ti_pushfub_par_sts(accel_dev, csr);
370 	adf_handle_ti_cd_par_sts(accel_dev, csr);
371 	adf_handle_ti_trnsb_par_sts(accel_dev, csr);
372 	adf_handle_iosfp_cmd_parerr(accel_dev, csr);
373 }
374 
375 static void adf_handle_sfi_cmd_parerr(struct adf_accel_dev *accel_dev, void __iomem *csr,
376 				      u32 errsou)
377 {
378 	if (!(errsou & ADF_GEN6_ERRSOU1_SFICMD_PARERR_BIT))
379 		return;
380 
381 	dev_err(&GET_DEV(accel_dev),
382 		"Command parity error detected on streaming fabric interface\n");
383 
384 	ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL);
385 }
386 
387 static void adf_gen6_process_errsou1(struct adf_accel_dev *accel_dev, void __iomem *csr,
388 				     u32 errsou)
389 {
390 	adf_handle_cpp_ae_unc(accel_dev, csr, errsou);
391 	adf_handle_cpp_cmd_par_err(accel_dev, csr, errsou);
392 	adf_handle_ri_mem_par_err(accel_dev, csr, errsou);
393 	adf_handle_ti_err(accel_dev, csr, errsou);
394 	adf_handle_sfi_cmd_parerr(accel_dev, csr, errsou);
395 
396 	errsou = ADF_CSR_RD(csr, ADF_GEN6_ERRSOU1);
397 	if (errsou & ADF_GEN6_ERRSOU1_MASK)
398 		dev_warn(&GET_DEV(accel_dev), "errsou1 still set: %#x\n", errsou);
399 }
400 
401 static void adf_handle_cerrssmsh(struct adf_accel_dev *accel_dev, void __iomem *csr)
402 {
403 	u32 reg;
404 
405 	reg = ADF_CSR_RD(csr, ADF_GEN6_CERRSSMSH);
406 	reg &= ADF_GEN6_CERRSSMSH_ERROR_BIT;
407 	if (reg) {
408 		dev_warn(&GET_DEV(accel_dev),
409 			 "Correctable error on ssm shared memory: %#x\n", reg);
410 		ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_CORR);
411 		ADF_CSR_WR(csr, ADF_GEN6_CERRSSMSH, reg);
412 	}
413 }
414 
415 static void adf_handle_uerrssmsh(struct adf_accel_dev *accel_dev, void __iomem *csr,
416 				 u32 iastatssm)
417 {
418 	u32 reg;
419 
420 	if (!(iastatssm & ADF_GEN6_IAINTSTATSSM_SH_ERR_BIT))
421 		return;
422 
423 	reg = ADF_CSR_RD(csr, ADF_GEN6_UERRSSMSH);
424 	reg &= ADF_GEN6_UERRSSMSH_MASK;
425 	if (reg) {
426 		dev_err(&GET_DEV(accel_dev),
427 			"Fatal error on ssm shared memory: %#x\n", reg);
428 		ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL);
429 		ADF_CSR_WR(csr, ADF_GEN6_UERRSSMSH, reg);
430 	}
431 }
432 
433 static void adf_handle_pperr_err(struct adf_accel_dev *accel_dev, void __iomem *csr,
434 				 u32 iastatssm)
435 {
436 	u32 reg;
437 
438 	if (!(iastatssm & ADF_GEN6_IAINTSTATSSM_PPERR_BIT))
439 		return;
440 
441 	reg = ADF_CSR_RD(csr, ADF_GEN6_PPERR);
442 	reg &= ADF_GEN6_PPERR_MASK;
443 	if (reg) {
444 		dev_err(&GET_DEV(accel_dev),
445 			"Fatal push or pull data error: %#x\n", reg);
446 		ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL);
447 		ADF_CSR_WR(csr, ADF_GEN6_PPERR, reg);
448 	}
449 }
450 
451 static void adf_handle_scmpar_err(struct adf_accel_dev *accel_dev, void __iomem *csr,
452 				  u32 iastatssm)
453 {
454 	u32 reg;
455 
456 	if (!(iastatssm & ADF_GEN6_IAINTSTATSSM_SCMPAR_ERR_BIT))
457 		return;
458 
459 	reg = ADF_CSR_RD(csr, ADF_GEN6_SSM_FERR_STATUS);
460 	reg &= ADF_GEN6_SCM_PAR_ERR_MASK;
461 	if (reg) {
462 		dev_err(&GET_DEV(accel_dev), "Fatal error on SCM: %#x\n", reg);
463 		ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL);
464 		ADF_CSR_WR(csr, ADF_GEN6_SSM_FERR_STATUS, reg);
465 	}
466 }
467 
468 static void adf_handle_cpppar_err(struct adf_accel_dev *accel_dev, void __iomem *csr,
469 				  u32 iastatssm)
470 {
471 	u32 reg;
472 
473 	if (!(iastatssm & ADF_GEN6_IAINTSTATSSM_CPPPAR_ERR_BIT))
474 		return;
475 
476 	reg = ADF_CSR_RD(csr, ADF_GEN6_SSM_FERR_STATUS);
477 	reg &= ADF_GEN6_CPP_PAR_ERR_MASK;
478 	if (reg) {
479 		dev_err(&GET_DEV(accel_dev), "Fatal error on CPP: %#x\n", reg);
480 		ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL);
481 		ADF_CSR_WR(csr, ADF_GEN6_SSM_FERR_STATUS, reg);
482 	}
483 }
484 
485 static void adf_handle_rfpar_err(struct adf_accel_dev *accel_dev, void __iomem *csr,
486 				 u32 iastatssm)
487 {
488 	u32 reg;
489 
490 	if (!(iastatssm & ADF_GEN6_IAINTSTATSSM_RFPAR_ERR_BIT))
491 		return;
492 
493 	reg = ADF_CSR_RD(csr, ADF_GEN6_SSM_FERR_STATUS);
494 	reg &= ADF_GEN6_RF_PAR_ERR_MASK;
495 	if (reg) {
496 		dev_err(&GET_DEV(accel_dev), "Fatal error on RF Parity: %#x\n", reg);
497 		ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL);
498 		ADF_CSR_WR(csr, ADF_GEN6_SSM_FERR_STATUS, reg);
499 	}
500 }
501 
502 static void adf_handle_unexp_cpl_err(struct adf_accel_dev *accel_dev, void __iomem *csr,
503 				     u32 iastatssm)
504 {
505 	u32 reg;
506 
507 	if (!(iastatssm & ADF_GEN6_IAINTSTATSSM_UNEXP_CPL_ERR_BIT))
508 		return;
509 
510 	reg = ADF_CSR_RD(csr, ADF_GEN6_SSM_FERR_STATUS);
511 	reg &= ADF_GEN6_UNEXP_CPL_ERR_MASK;
512 	if (reg) {
513 		dev_err(&GET_DEV(accel_dev),
514 			"Fatal error for AXI unexpected tag/length: %#x\n", reg);
515 		ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL);
516 		ADF_CSR_WR(csr, ADF_GEN6_SSM_FERR_STATUS, reg);
517 	}
518 }
519 
520 static void adf_handle_iaintstatssm(struct adf_accel_dev *accel_dev, void __iomem *csr)
521 {
522 	u32 iastatssm = ADF_CSR_RD(csr, ADF_GEN6_IAINTSTATSSM);
523 
524 	iastatssm &= ADF_GEN6_IAINTSTATSSM_MASK;
525 	if (!iastatssm)
526 		return;
527 
528 	adf_handle_uerrssmsh(accel_dev, csr, iastatssm);
529 	adf_handle_pperr_err(accel_dev, csr, iastatssm);
530 	adf_handle_scmpar_err(accel_dev, csr, iastatssm);
531 	adf_handle_cpppar_err(accel_dev, csr, iastatssm);
532 	adf_handle_rfpar_err(accel_dev, csr, iastatssm);
533 	adf_handle_unexp_cpl_err(accel_dev, csr, iastatssm);
534 
535 	ADF_CSR_WR(csr, ADF_GEN6_IAINTSTATSSM, iastatssm);
536 }
537 
538 static void adf_handle_ssm(struct adf_accel_dev *accel_dev, void __iomem *csr, u32 errsou)
539 {
540 	if (!(errsou & ADF_GEN6_ERRSOU2_SSM_ERR_BIT))
541 		return;
542 
543 	adf_handle_cerrssmsh(accel_dev, csr);
544 	adf_handle_iaintstatssm(accel_dev, csr);
545 }
546 
547 static void adf_handle_cpp_cfc_err(struct adf_accel_dev *accel_dev, void __iomem *csr,
548 				   u32 errsou)
549 {
550 	u32 reg;
551 
552 	if (!(errsou & ADF_GEN6_ERRSOU2_CPP_CFC_ERR_STATUS_BIT))
553 		return;
554 
555 	reg = ADF_CSR_RD(csr, ADF_GEN6_CPP_CFC_ERR_STATUS);
556 	if (reg & ADF_GEN6_CPP_CFC_ERR_STATUS_DATAPAR_BIT) {
557 		dev_err(&GET_DEV(accel_dev), "CPP_CFC_ERR: data parity: %#x", reg);
558 		ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR);
559 	}
560 
561 	if (reg & ADF_GEN6_CPP_CFC_ERR_STATUS_CMDPAR_BIT) {
562 		dev_err(&GET_DEV(accel_dev), "CPP_CFC_ERR: command parity: %#x", reg);
563 		ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL);
564 	}
565 
566 	if (reg & ADF_GEN6_CPP_CFC_FATAL_ERR_BIT) {
567 		dev_err(&GET_DEV(accel_dev), "CPP_CFC_ERR: errors: %#x", reg);
568 		ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL);
569 	}
570 
571 	ADF_CSR_WR(csr, ADF_GEN6_CPP_CFC_ERR_STATUS_CLR,
572 		   ADF_GEN6_CPP_CFC_ERR_STATUS_CLR_MASK);
573 }
574 
575 static void adf_gen6_process_errsou2(struct adf_accel_dev *accel_dev, void __iomem *csr,
576 				     u32 errsou)
577 {
578 	adf_handle_ssm(accel_dev, csr, errsou);
579 	adf_handle_cpp_cfc_err(accel_dev, csr, errsou);
580 
581 	errsou = ADF_CSR_RD(csr, ADF_GEN6_ERRSOU2);
582 	if (errsou & ADF_GEN6_ERRSOU2_MASK)
583 		dev_warn(&GET_DEV(accel_dev), "errsou2 still set: %#x\n", errsou);
584 }
585 
586 static void adf_handle_timiscsts(struct adf_accel_dev *accel_dev, void __iomem *csr,
587 				 u32 errsou)
588 {
589 	u32 timiscsts;
590 
591 	if (!(errsou & ADF_GEN6_ERRSOU3_TIMISCSTS_BIT))
592 		return;
593 
594 	timiscsts = ADF_CSR_RD(csr, ADF_GEN6_TIMISCSTS);
595 	if (timiscsts) {
596 		dev_err(&GET_DEV(accel_dev), "Fatal error in transmit interface: %#x\n",
597 			timiscsts);
598 		ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL);
599 	}
600 }
601 
602 static void adf_handle_ricppintsts(struct adf_accel_dev *accel_dev, void __iomem *csr,
603 				   u32 errsou)
604 {
605 	u32 ricppintsts;
606 
607 	if (!(errsou & ADF_GEN6_ERRSOU3_RICPPINTSTS_MASK))
608 		return;
609 
610 	ricppintsts = ADF_CSR_RD(csr, ADF_GEN6_RICPPINTSTS);
611 	ricppintsts &= ADF_GEN6_RICPPINTSTS_MASK;
612 	if (ricppintsts) {
613 		dev_err(&GET_DEV(accel_dev), "RI push pull error: %#x\n", ricppintsts);
614 		ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR);
615 		ADF_CSR_WR(csr, ADF_GEN6_RICPPINTSTS, ricppintsts);
616 	}
617 }
618 
619 static void adf_handle_ticppintsts(struct adf_accel_dev *accel_dev, void __iomem *csr,
620 				   u32 errsou)
621 {
622 	u32 ticppintsts;
623 
624 	if (!(errsou & ADF_GEN6_ERRSOU3_TICPPINTSTS_MASK))
625 		return;
626 
627 	ticppintsts = ADF_CSR_RD(csr, ADF_GEN6_TICPPINTSTS);
628 	ticppintsts &= ADF_GEN6_TICPPINTSTS_MASK;
629 	if (ticppintsts) {
630 		dev_err(&GET_DEV(accel_dev), "TI push pull error: %#x\n", ticppintsts);
631 		ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL);
632 		ADF_CSR_WR(csr, ADF_GEN6_TICPPINTSTS, ticppintsts);
633 	}
634 }
635 
636 static void adf_handle_atufaultstatus(struct adf_accel_dev *accel_dev, void __iomem *csr,
637 				      u32 errsou)
638 {
639 	u32 max_rp_num = GET_HW_DATA(accel_dev)->num_banks;
640 	u32 atufaultstatus;
641 	u32 i;
642 
643 	if (!(errsou & ADF_GEN6_ERRSOU3_ATUFAULTSTATUS_BIT))
644 		return;
645 
646 	for (i = 0; i < max_rp_num; i++) {
647 		atufaultstatus = ADF_CSR_RD(csr, ADF_GEN6_ATUFAULTSTATUS(i));
648 
649 		atufaultstatus &= ADF_GEN6_ATUFAULTSTATUS_BIT;
650 		if (atufaultstatus) {
651 			dev_err(&GET_DEV(accel_dev), "Ring pair (%u) ATU detected fault: %#x\n", i,
652 				atufaultstatus);
653 			ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR);
654 			ADF_CSR_WR(csr, ADF_GEN6_ATUFAULTSTATUS(i), atufaultstatus);
655 		}
656 	}
657 }
658 
659 static void adf_handle_rlterror(struct adf_accel_dev *accel_dev, void __iomem *csr,
660 				u32 errsou)
661 {
662 	u32 rlterror;
663 
664 	if (!(errsou & ADF_GEN6_ERRSOU3_RLTERROR_BIT))
665 		return;
666 
667 	rlterror = ADF_CSR_RD(csr, ADF_GEN6_RLT_ERRLOG);
668 	rlterror &= ADF_GEN6_RLT_ERRLOG_MASK;
669 	if (rlterror) {
670 		dev_err(&GET_DEV(accel_dev), "Error in rate limiting block: %#x\n", rlterror);
671 		ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR);
672 		ADF_CSR_WR(csr, ADF_GEN6_RLT_ERRLOG, rlterror);
673 	}
674 }
675 
676 static void adf_handle_vflr(struct adf_accel_dev *accel_dev, void __iomem *csr, u32 errsou)
677 {
678 	if (!(errsou & ADF_GEN6_ERRSOU3_VFLRNOTIFY_BIT))
679 		return;
680 
681 	dev_err(&GET_DEV(accel_dev), "Uncorrectable error in VF\n");
682 	ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR);
683 }
684 
685 static void adf_handle_tc_vc_map_error(struct adf_accel_dev *accel_dev, void __iomem *csr,
686 				       u32 errsou)
687 {
688 	if (!(errsou & ADF_GEN6_ERRSOU3_TC_VC_MAP_ERROR_BIT))
689 		return;
690 
691 	dev_err(&GET_DEV(accel_dev), "Violation of PCIe TC VC mapping\n");
692 	ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL);
693 }
694 
695 static void adf_handle_pcie_devhalt(struct adf_accel_dev *accel_dev, void __iomem *csr,
696 				    u32 errsou)
697 {
698 	if (!(errsou & ADF_GEN6_ERRSOU3_PCIE_DEVHALT_BIT))
699 		return;
700 
701 	dev_err(&GET_DEV(accel_dev),
702 		"DEVHALT due to an error in an incoming transaction\n");
703 	ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL);
704 }
705 
706 static void adf_handle_pg_req_devhalt(struct adf_accel_dev *accel_dev, void __iomem *csr,
707 				      u32 errsou)
708 {
709 	if (!(errsou & ADF_GEN6_ERRSOU3_PG_REQ_DEVHALT_BIT))
710 		return;
711 
712 	dev_err(&GET_DEV(accel_dev),
713 		"Error due to response failure in response to a page request\n");
714 	ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL);
715 }
716 
717 static void adf_handle_xlt_cpl_devhalt(struct adf_accel_dev *accel_dev, void __iomem *csr,
718 				       u32 errsou)
719 {
720 	if (!(errsou & ADF_GEN6_ERRSOU3_XLT_CPL_DEVHALT_BIT))
721 		return;
722 
723 	dev_err(&GET_DEV(accel_dev), "Error status for a address translation request\n");
724 	ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL);
725 }
726 
727 static void adf_handle_ti_int_err_devhalt(struct adf_accel_dev *accel_dev, void __iomem *csr,
728 					  u32 errsou)
729 {
730 	if (!(errsou & ADF_GEN6_ERRSOU3_TI_INT_ERR_DEVHALT_BIT))
731 		return;
732 
733 	dev_err(&GET_DEV(accel_dev), "DEVHALT due to a TI internal memory error\n");
734 	ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL);
735 }
736 
737 static void adf_gen6_process_errsou3(struct adf_accel_dev *accel_dev, void __iomem *csr,
738 				     u32 errsou)
739 {
740 	adf_handle_timiscsts(accel_dev, csr, errsou);
741 	adf_handle_ricppintsts(accel_dev, csr, errsou);
742 	adf_handle_ticppintsts(accel_dev, csr, errsou);
743 	adf_handle_atufaultstatus(accel_dev, csr, errsou);
744 	adf_handle_rlterror(accel_dev, csr, errsou);
745 	adf_handle_vflr(accel_dev, csr, errsou);
746 	adf_handle_tc_vc_map_error(accel_dev, csr, errsou);
747 	adf_handle_pcie_devhalt(accel_dev, csr, errsou);
748 	adf_handle_pg_req_devhalt(accel_dev, csr, errsou);
749 	adf_handle_xlt_cpl_devhalt(accel_dev, csr, errsou);
750 	adf_handle_ti_int_err_devhalt(accel_dev, csr, errsou);
751 
752 	errsou = ADF_CSR_RD(csr, ADF_GEN6_ERRSOU3);
753 	if (errsou & ADF_GEN6_ERRSOU3_MASK)
754 		dev_warn(&GET_DEV(accel_dev), "errsou3 still set: %#x\n", errsou);
755 }
756 
757 static void adf_gen6_is_reset_required(struct adf_accel_dev *accel_dev, void __iomem *csr,
758 				       bool *reset_required)
759 {
760 	u8 reset, dev_state;
761 	u32 gensts;
762 
763 	gensts = ADF_CSR_RD(csr, ADF_GEN6_GENSTS);
764 	dev_state = FIELD_GET(ADF_GEN6_GENSTS_DEVICE_STATE_MASK, gensts);
765 	reset = FIELD_GET(ADF_GEN6_GENSTS_RESET_TYPE_MASK, gensts);
766 	if (dev_state == ADF_GEN6_GENSTS_DEVHALT && reset == ADF_GEN6_GENSTS_PFLR) {
767 		*reset_required = true;
768 		return;
769 	}
770 
771 	if (reset == ADF_GEN6_GENSTS_COLD_RESET)
772 		dev_err(&GET_DEV(accel_dev), "Fatal error, cold reset required\n");
773 
774 	*reset_required = false;
775 }
776 
777 static bool adf_gen6_handle_interrupt(struct adf_accel_dev *accel_dev, bool *reset_required)
778 {
779 	void __iomem *csr = adf_get_pmisc_base(accel_dev);
780 	bool handled = false;
781 	u32 errsou;
782 
783 	errsou = ADF_CSR_RD(csr, ADF_GEN6_ERRSOU0);
784 	if (errsou & ADF_GEN6_ERRSOU0_MASK) {
785 		adf_gen6_process_errsou0(accel_dev, csr);
786 		handled = true;
787 	}
788 
789 	errsou = ADF_CSR_RD(csr, ADF_GEN6_ERRSOU1);
790 	if (errsou & ADF_GEN6_ERRSOU1_MASK) {
791 		adf_gen6_process_errsou1(accel_dev, csr, errsou);
792 		handled = true;
793 	}
794 
795 	errsou = ADF_CSR_RD(csr, ADF_GEN6_ERRSOU2);
796 	if (errsou & ADF_GEN6_ERRSOU2_MASK) {
797 		adf_gen6_process_errsou2(accel_dev, csr, errsou);
798 		handled = true;
799 	}
800 
801 	errsou = ADF_CSR_RD(csr, ADF_GEN6_ERRSOU3);
802 	if (errsou & ADF_GEN6_ERRSOU3_MASK) {
803 		adf_gen6_process_errsou3(accel_dev, csr, errsou);
804 		handled = true;
805 	}
806 
807 	adf_gen6_is_reset_required(accel_dev, csr, reset_required);
808 
809 	return handled;
810 }
811 
812 void adf_gen6_init_ras_ops(struct adf_ras_ops *ras_ops)
813 {
814 	ras_ops->enable_ras_errors = adf_gen6_enable_ras;
815 	ras_ops->disable_ras_errors = adf_gen6_disable_ras;
816 	ras_ops->handle_interrupt = adf_gen6_handle_interrupt;
817 }
818 EXPORT_SYMBOL_GPL(adf_gen6_init_ras_ops);
819