72
72
#define I10NM_SAD_ENABLE (reg ) GET_BITFIELD(reg, 0, 0)
73
73
#define I10NM_SAD_NM_CACHEABLE (reg ) GET_BITFIELD(reg, 5, 5)
74
74
75
- #define RETRY_RD_ERR_LOG_OVER_UC_V (BIT(2) | BIT(1) | BIT(0))
76
-
77
75
static struct list_head * i10nm_edac_list ;
78
76
79
77
static struct res_config * res_cfg ;
@@ -83,59 +81,87 @@ static bool mem_cfg_2lm;
83
81
84
82
static struct reg_rrl icx_reg_rrl_ddr = {
85
83
.set_num = 2 ,
84
+ .reg_num = 6 ,
86
85
.modes = {LRE_SCRUB , LRE_DEMAND },
87
86
.offsets = {
88
87
{0x22c60 , 0x22c54 , 0x22c5c , 0x22c58 , 0x22c28 , 0x20ed8 },
89
88
{0x22e54 , 0x22e60 , 0x22e64 , 0x22e58 , 0x22e5c , 0x20ee0 },
90
89
},
91
90
.widths = {4 , 4 , 4 , 4 , 4 , 8 },
91
+ .v_mask = BIT (0 ),
92
92
.uc_mask = BIT (1 ),
93
+ .over_mask = BIT (2 ),
93
94
.en_patspr_mask = BIT (13 ),
94
95
.noover_mask = BIT (14 ),
95
96
.en_mask = BIT (15 ),
97
+
98
+ .cecnt_num = 4 ,
99
+ .cecnt_offsets = {0x22c18 , 0x22c1c , 0x22c20 , 0x22c24 },
100
+ .cecnt_widths = {4 , 4 , 4 , 4 },
96
101
};
97
102
98
103
static struct reg_rrl spr_reg_rrl_ddr = {
99
104
.set_num = 3 ,
105
+ .reg_num = 6 ,
100
106
.modes = {LRE_SCRUB , LRE_DEMAND , FRE_DEMAND },
101
107
.offsets = {
102
108
{0x22c60 , 0x22c54 , 0x22f08 , 0x22c58 , 0x22c28 , 0x20ed8 },
103
109
{0x22e54 , 0x22e60 , 0x22f10 , 0x22e58 , 0x22e5c , 0x20ee0 },
104
110
{0x22c70 , 0x22d80 , 0x22f18 , 0x22d58 , 0x22c64 , 0x20f10 },
105
111
},
106
112
.widths = {4 , 4 , 8 , 4 , 4 , 8 },
113
+ .v_mask = BIT (0 ),
107
114
.uc_mask = BIT (1 ),
115
+ .over_mask = BIT (2 ),
108
116
.en_patspr_mask = BIT (13 ),
109
117
.noover_mask = BIT (14 ),
110
118
.en_mask = BIT (15 ),
119
+
120
+ .cecnt_num = 4 ,
121
+ .cecnt_offsets = {0x22c18 , 0x22c1c , 0x22c20 , 0x22c24 },
122
+ .cecnt_widths = {4 , 4 , 4 , 4 },
111
123
};
112
124
113
125
static struct reg_rrl spr_reg_rrl_hbm_pch0 = {
114
126
.set_num = 2 ,
127
+ .reg_num = 6 ,
115
128
.modes = {LRE_SCRUB , LRE_DEMAND },
116
129
.offsets = {
117
130
{0x2860 , 0x2854 , 0x2b08 , 0x2858 , 0x2828 , 0x0ed8 },
118
131
{0x2a54 , 0x2a60 , 0x2b10 , 0x2a58 , 0x2a5c , 0x0ee0 },
119
132
},
120
133
.widths = {4 , 4 , 8 , 4 , 4 , 8 },
134
+ .v_mask = BIT (0 ),
121
135
.uc_mask = BIT (1 ),
136
+ .over_mask = BIT (2 ),
122
137
.en_patspr_mask = BIT (13 ),
123
138
.noover_mask = BIT (14 ),
124
139
.en_mask = BIT (15 ),
140
+
141
+ .cecnt_num = 4 ,
142
+ .cecnt_offsets = {0x2818 , 0x281c , 0x2820 , 0x2824 },
143
+ .cecnt_widths = {4 , 4 , 4 , 4 },
125
144
};
126
145
127
146
static struct reg_rrl spr_reg_rrl_hbm_pch1 = {
128
147
.set_num = 2 ,
148
+ .reg_num = 6 ,
129
149
.modes = {LRE_SCRUB , LRE_DEMAND },
130
150
.offsets = {
131
151
{0x2c60 , 0x2c54 , 0x2f08 , 0x2c58 , 0x2c28 , 0x0fa8 },
132
152
{0x2e54 , 0x2e60 , 0x2f10 , 0x2e58 , 0x2e5c , 0x0fb0 },
133
153
},
134
154
.widths = {4 , 4 , 8 , 4 , 4 , 8 },
155
+ .v_mask = BIT (0 ),
135
156
.uc_mask = BIT (1 ),
157
+ .over_mask = BIT (2 ),
136
158
.en_patspr_mask = BIT (13 ),
137
159
.noover_mask = BIT (14 ),
138
160
.en_mask = BIT (15 ),
161
+
162
+ .cecnt_num = 4 ,
163
+ .cecnt_offsets = {0x2c18 , 0x2c1c , 0x2c20 , 0x2c24 },
164
+ .cecnt_widths = {4 , 4 , 4 , 4 },
139
165
};
140
166
141
167
static u64 read_imc_reg (struct skx_imc * imc , int chan , u32 offset , u8 width )
@@ -276,110 +302,64 @@ static void enable_retry_rd_err_log(bool enable)
276
302
static void show_retry_rd_err_log (struct decoded_addr * res , char * msg ,
277
303
int len , bool scrub_err )
278
304
{
305
+ int i , j , n , ch = res -> channel , pch = res -> cs & 1 ;
279
306
struct skx_imc * imc = & res -> dev -> imc [res -> imc ];
280
- u32 log0 , log1 , log2 , log3 , log4 ;
281
- u32 corr0 , corr1 , corr2 , corr3 ;
282
- u32 lxg0 , lxg1 , lxg3 , lxg4 ;
283
- u32 * xffsets = NULL ;
284
- u64 log2a , log5 ;
285
- u64 lxg2a , lxg5 ;
286
- u32 * offsets ;
287
- int n , pch ;
307
+ u32 offset , status_mask ;
308
+ struct reg_rrl * rrl ;
309
+ u64 log , corr ;
310
+ bool scrub ;
311
+ u8 width ;
288
312
289
313
if (!imc -> mbase )
290
314
return ;
291
315
292
- if (imc -> hbm_mc ) {
293
- pch = res -> cs & 1 ;
316
+ rrl = imc -> hbm_mc ? res_cfg -> reg_rrl_hbm [pch ] : res_cfg -> reg_rrl_ddr ;
294
317
295
- if (pch )
296
- offsets = scrub_err ? res_cfg -> reg_rrl_hbm [1 ]-> offsets [0 ] :
297
- res_cfg -> reg_rrl_hbm [1 ]-> offsets [1 ];
298
- else
299
- offsets = scrub_err ? res_cfg -> reg_rrl_hbm [0 ]-> offsets [0 ] :
300
- res_cfg -> reg_rrl_hbm [0 ]-> offsets [1 ];
301
- } else {
302
- if (scrub_err ) {
303
- offsets = res_cfg -> reg_rrl_ddr -> offsets [0 ];
304
- } else {
305
- offsets = res_cfg -> reg_rrl_ddr -> offsets [1 ];
306
- if (res_cfg -> reg_rrl_ddr -> set_num > 2 )
307
- xffsets = res_cfg -> reg_rrl_ddr -> offsets [2 ];
308
- }
309
- }
318
+ if (!rrl )
319
+ return ;
310
320
311
- log0 = I10NM_GET_REG32 (imc , res -> channel , offsets [0 ]);
312
- log1 = I10NM_GET_REG32 (imc , res -> channel , offsets [1 ]);
313
- log3 = I10NM_GET_REG32 (imc , res -> channel , offsets [3 ]);
314
- log4 = I10NM_GET_REG32 (imc , res -> channel , offsets [4 ]);
315
- log5 = I10NM_GET_REG64 (imc , res -> channel , offsets [5 ]);
316
-
317
- if (xffsets ) {
318
- lxg0 = I10NM_GET_REG32 (imc , res -> channel , xffsets [0 ]);
319
- lxg1 = I10NM_GET_REG32 (imc , res -> channel , xffsets [1 ]);
320
- lxg3 = I10NM_GET_REG32 (imc , res -> channel , xffsets [3 ]);
321
- lxg4 = I10NM_GET_REG32 (imc , res -> channel , xffsets [4 ]);
322
- lxg5 = I10NM_GET_REG64 (imc , res -> channel , xffsets [5 ]);
323
- }
321
+ status_mask = rrl -> over_mask | rrl -> uc_mask | rrl -> v_mask ;
324
322
325
- if (res_cfg -> type == SPR ) {
326
- log2a = I10NM_GET_REG64 (imc , res -> channel , offsets [2 ]);
327
- n = snprintf (msg , len , " retry_rd_err_log[%.8x %.8x %.16llx %.8x %.8x %.16llx" ,
328
- log0 , log1 , log2a , log3 , log4 , log5 );
323
+ n = snprintf (msg , len , " retry_rd_err_log[" );
324
+ for (i = 0 ; i < rrl -> set_num ; i ++ ) {
325
+ scrub = (rrl -> modes [i ] == FRE_SCRUB || rrl -> modes [i ] == LRE_SCRUB );
326
+ if (scrub_err != scrub )
327
+ continue ;
329
328
330
- if (len - n > 0 ) {
331
- if (xffsets ) {
332
- lxg2a = I10NM_GET_REG64 (imc , res -> channel , xffsets [2 ]);
333
- n += snprintf (msg + n , len - n , " %.8x %.8x %.16llx %.8x %.8x %.16llx]" ,
334
- lxg0 , lxg1 , lxg2a , lxg3 , lxg4 , lxg5 );
335
- } else {
336
- n += snprintf (msg + n , len - n , "]" );
337
- }
338
- }
339
- } else {
340
- log2 = I10NM_GET_REG32 (imc , res -> channel , offsets [2 ]);
341
- n = snprintf (msg , len , " retry_rd_err_log[%.8x %.8x %.8x %.8x %.8x %.16llx]" ,
342
- log0 , log1 , log2 , log3 , log4 , log5 );
343
- }
329
+ for (j = 0 ; j < rrl -> reg_num && len - n > 0 ; j ++ ) {
330
+ offset = rrl -> offsets [i ][j ];
331
+ width = rrl -> widths [j ];
332
+ log = read_imc_reg (imc , ch , offset , width );
344
333
345
- if (imc -> hbm_mc ) {
346
- if (pch ) {
347
- corr0 = I10NM_GET_REG32 (imc , res -> channel , 0x2c18 );
348
- corr1 = I10NM_GET_REG32 (imc , res -> channel , 0x2c1c );
349
- corr2 = I10NM_GET_REG32 (imc , res -> channel , 0x2c20 );
350
- corr3 = I10NM_GET_REG32 (imc , res -> channel , 0x2c24 );
351
- } else {
352
- corr0 = I10NM_GET_REG32 (imc , res -> channel , 0x2818 );
353
- corr1 = I10NM_GET_REG32 (imc , res -> channel , 0x281c );
354
- corr2 = I10NM_GET_REG32 (imc , res -> channel , 0x2820 );
355
- corr3 = I10NM_GET_REG32 (imc , res -> channel , 0x2824 );
334
+ if (width == 4 )
335
+ n += snprintf (msg + n , len - n , "%.8llx " , log );
336
+ else
337
+ n += snprintf (msg + n , len - n , "%.16llx " , log );
338
+
339
+ /* Clear RRL status if RRL in Linux control mode. */
340
+ if (retry_rd_err_log == 2 && !j && (log & status_mask ))
341
+ write_imc_reg (imc , ch , offset , width , log & ~status_mask );
356
342
}
357
- } else {
358
- corr0 = I10NM_GET_REG32 (imc , res -> channel , 0x22c18 );
359
- corr1 = I10NM_GET_REG32 (imc , res -> channel , 0x22c1c );
360
- corr2 = I10NM_GET_REG32 (imc , res -> channel , 0x22c20 );
361
- corr3 = I10NM_GET_REG32 (imc , res -> channel , 0x22c24 );
362
343
}
363
344
364
- if (len - n > 0 )
365
- snprintf (msg + n , len - n ,
366
- " correrrcnt[%.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x]" ,
367
- corr0 & 0xffff , corr0 >> 16 ,
368
- corr1 & 0xffff , corr1 >> 16 ,
369
- corr2 & 0xffff , corr2 >> 16 ,
370
- corr3 & 0xffff , corr3 >> 16 );
371
-
372
- /* Clear status bits */
373
- if (retry_rd_err_log == 2 ) {
374
- if (log0 & RETRY_RD_ERR_LOG_OVER_UC_V ) {
375
- log0 &= ~RETRY_RD_ERR_LOG_OVER_UC_V ;
376
- I10NM_SET_REG32 (imc , res -> channel , offsets [0 ], log0 );
377
- }
345
+ /* Move back one space. */
346
+ n -- ;
347
+ n += snprintf (msg + n , len - n , "]" );
348
+
349
+ if (len - n > 0 ) {
350
+ n += snprintf (msg + n , len - n , " correrrcnt[" );
351
+ for (i = 0 ; i < rrl -> cecnt_num && len - n > 0 ; i ++ ) {
352
+ offset = rrl -> cecnt_offsets [i ];
353
+ width = rrl -> cecnt_widths [i ];
354
+ corr = read_imc_reg (imc , ch , offset , width );
378
355
379
- if (xffsets && (lxg0 & RETRY_RD_ERR_LOG_OVER_UC_V )) {
380
- lxg0 &= ~RETRY_RD_ERR_LOG_OVER_UC_V ;
381
- I10NM_SET_REG32 (imc , res -> channel , xffsets [0 ], lxg0 );
356
+ n += snprintf (msg + n , len - n , "%.4llx %.4llx " ,
357
+ corr & 0xffff , corr >> 16 );
382
358
}
359
+
360
+ /* Move back one space. */
361
+ n -- ;
362
+ n += snprintf (msg + n , len - n , "]" );
383
363
}
384
364
}
385
365
0 commit comments