7272#define I10NM_SAD_ENABLE (reg ) GET_BITFIELD(reg, 0, 0)
7373#define I10NM_SAD_NM_CACHEABLE (reg ) GET_BITFIELD(reg, 5, 5)
7474
75- #define RETRY_RD_ERR_LOG_OVER_UC_V (BIT(2) | BIT(1) | BIT(0))
76-
7775static struct list_head * i10nm_edac_list ;
7876
7977static struct res_config * res_cfg ;
@@ -83,59 +81,87 @@ static bool mem_cfg_2lm;
8381
8482static struct reg_rrl icx_reg_rrl_ddr = {
8583 .set_num = 2 ,
84+ .reg_num = 6 ,
8685 .modes = {LRE_SCRUB , LRE_DEMAND },
8786 .offsets = {
8887 {0x22c60 , 0x22c54 , 0x22c5c , 0x22c58 , 0x22c28 , 0x20ed8 },
8988 {0x22e54 , 0x22e60 , 0x22e64 , 0x22e58 , 0x22e5c , 0x20ee0 },
9089 },
9190 .widths = {4 , 4 , 4 , 4 , 4 , 8 },
91+ .v_mask = BIT (0 ),
9292 .uc_mask = BIT (1 ),
93+ .over_mask = BIT (2 ),
9394 .en_patspr_mask = BIT (13 ),
9495 .noover_mask = BIT (14 ),
9596 .en_mask = BIT (15 ),
97+
98+ .cecnt_num = 4 ,
99+ .cecnt_offsets = {0x22c18 , 0x22c1c , 0x22c20 , 0x22c24 },
100+ .cecnt_widths = {4 , 4 , 4 , 4 },
96101};
97102
98103static struct reg_rrl spr_reg_rrl_ddr = {
99104 .set_num = 3 ,
105+ .reg_num = 6 ,
100106 .modes = {LRE_SCRUB , LRE_DEMAND , FRE_DEMAND },
101107 .offsets = {
102108 {0x22c60 , 0x22c54 , 0x22f08 , 0x22c58 , 0x22c28 , 0x20ed8 },
103109 {0x22e54 , 0x22e60 , 0x22f10 , 0x22e58 , 0x22e5c , 0x20ee0 },
104110 {0x22c70 , 0x22d80 , 0x22f18 , 0x22d58 , 0x22c64 , 0x20f10 },
105111 },
106112 .widths = {4 , 4 , 8 , 4 , 4 , 8 },
113+ .v_mask = BIT (0 ),
107114 .uc_mask = BIT (1 ),
115+ .over_mask = BIT (2 ),
108116 .en_patspr_mask = BIT (13 ),
109117 .noover_mask = BIT (14 ),
110118 .en_mask = BIT (15 ),
119+
120+ .cecnt_num = 4 ,
121+ .cecnt_offsets = {0x22c18 , 0x22c1c , 0x22c20 , 0x22c24 },
122+ .cecnt_widths = {4 , 4 , 4 , 4 },
111123};
112124
113125static struct reg_rrl spr_reg_rrl_hbm_pch0 = {
114126 .set_num = 2 ,
127+ .reg_num = 6 ,
115128 .modes = {LRE_SCRUB , LRE_DEMAND },
116129 .offsets = {
117130 {0x2860 , 0x2854 , 0x2b08 , 0x2858 , 0x2828 , 0x0ed8 },
118131 {0x2a54 , 0x2a60 , 0x2b10 , 0x2a58 , 0x2a5c , 0x0ee0 },
119132 },
120133 .widths = {4 , 4 , 8 , 4 , 4 , 8 },
134+ .v_mask = BIT (0 ),
121135 .uc_mask = BIT (1 ),
136+ .over_mask = BIT (2 ),
122137 .en_patspr_mask = BIT (13 ),
123138 .noover_mask = BIT (14 ),
124139 .en_mask = BIT (15 ),
140+
141+ .cecnt_num = 4 ,
142+ .cecnt_offsets = {0x2818 , 0x281c , 0x2820 , 0x2824 },
143+ .cecnt_widths = {4 , 4 , 4 , 4 },
125144};
126145
127146static struct reg_rrl spr_reg_rrl_hbm_pch1 = {
128147 .set_num = 2 ,
148+ .reg_num = 6 ,
129149 .modes = {LRE_SCRUB , LRE_DEMAND },
130150 .offsets = {
131151 {0x2c60 , 0x2c54 , 0x2f08 , 0x2c58 , 0x2c28 , 0x0fa8 },
132152 {0x2e54 , 0x2e60 , 0x2f10 , 0x2e58 , 0x2e5c , 0x0fb0 },
133153 },
134154 .widths = {4 , 4 , 8 , 4 , 4 , 8 },
155+ .v_mask = BIT (0 ),
135156 .uc_mask = BIT (1 ),
157+ .over_mask = BIT (2 ),
136158 .en_patspr_mask = BIT (13 ),
137159 .noover_mask = BIT (14 ),
138160 .en_mask = BIT (15 ),
161+
162+ .cecnt_num = 4 ,
163+ .cecnt_offsets = {0x2c18 , 0x2c1c , 0x2c20 , 0x2c24 },
164+ .cecnt_widths = {4 , 4 , 4 , 4 },
139165};
140166
141167static 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)
276302static void show_retry_rd_err_log (struct decoded_addr * res , char * msg ,
277303 int len , bool scrub_err )
278304{
305+ int i , j , n , ch = res -> channel , pch = res -> cs & 1 ;
279306 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 ;
288312
289313 if (!imc -> mbase )
290314 return ;
291315
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 ;
294317
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 ;
310320
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 ;
324322
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 ;
329328
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 );
344333
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 );
356342 }
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 );
362343 }
363344
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 );
378355
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 );
382358 }
359+
360+ /* Move back one space. */
361+ n -- ;
362+ n += snprintf (msg + n , len - n , "]" );
383363 }
384364}
385365
0 commit comments