@@ -1209,7 +1209,9 @@ static int umc_get_cs_mode(int dimm, u8 ctrl, struct amd64_pvt *pvt)
1209
1209
if (csrow_enabled (2 * dimm + 1 , ctrl , pvt ))
1210
1210
cs_mode |= CS_ODD_PRIMARY ;
1211
1211
1212
- /* Asymmetric dual-rank DIMM support. */
1212
+ if (csrow_sec_enabled (2 * dimm , ctrl , pvt ))
1213
+ cs_mode |= CS_EVEN_SECONDARY ;
1214
+
1213
1215
if (csrow_sec_enabled (2 * dimm + 1 , ctrl , pvt ))
1214
1216
cs_mode |= CS_ODD_SECONDARY ;
1215
1217
@@ -1230,12 +1232,13 @@ static int umc_get_cs_mode(int dimm, u8 ctrl, struct amd64_pvt *pvt)
1230
1232
return cs_mode ;
1231
1233
}
1232
1234
1233
- static int __addr_mask_to_cs_size (u32 addr_mask_orig , unsigned int cs_mode ,
1234
- int csrow_nr , int dimm )
1235
+ static int calculate_cs_size (u32 mask , unsigned int cs_mode )
1235
1236
{
1236
- u32 msb , weight , num_zero_bits ;
1237
- u32 addr_mask_deinterleaved ;
1238
- int size = 0 ;
1237
+ int msb , weight , num_zero_bits ;
1238
+ u32 deinterleaved_mask ;
1239
+
1240
+ if (!mask )
1241
+ return 0 ;
1239
1242
1240
1243
/*
1241
1244
* The number of zero bits in the mask is equal to the number of bits
@@ -1248,19 +1251,30 @@ static int __addr_mask_to_cs_size(u32 addr_mask_orig, unsigned int cs_mode,
1248
1251
* without swapping with the most significant bit. This can be handled
1249
1252
* by keeping the MSB where it is and ignoring the single zero bit.
1250
1253
*/
1251
- msb = fls (addr_mask_orig ) - 1 ;
1252
- weight = hweight_long (addr_mask_orig );
1254
+ msb = fls (mask ) - 1 ;
1255
+ weight = hweight_long (mask );
1253
1256
num_zero_bits = msb - weight - !!(cs_mode & CS_3R_INTERLEAVE );
1254
1257
1255
1258
/* Take the number of zero bits off from the top of the mask. */
1256
- addr_mask_deinterleaved = GENMASK_ULL (msb - num_zero_bits , 1 );
1259
+ deinterleaved_mask = GENMASK (msb - num_zero_bits , 1 );
1260
+ edac_dbg (1 , " Deinterleaved AddrMask: 0x%x\n" , deinterleaved_mask );
1261
+
1262
+ return (deinterleaved_mask >> 2 ) + 1 ;
1263
+ }
1264
+
1265
+ static int __addr_mask_to_cs_size (u32 addr_mask , u32 addr_mask_sec ,
1266
+ unsigned int cs_mode , int csrow_nr , int dimm )
1267
+ {
1268
+ int size ;
1257
1269
1258
1270
edac_dbg (1 , "CS%d DIMM%d AddrMasks:\n" , csrow_nr , dimm );
1259
- edac_dbg (1 , " Original AddrMask: 0x%x\n" , addr_mask_orig );
1260
- edac_dbg (1 , " Deinterleaved AddrMask: 0x%x\n" , addr_mask_deinterleaved );
1271
+ edac_dbg (1 , " Primary AddrMask: 0x%x\n" , addr_mask );
1261
1272
1262
1273
/* Register [31:1] = Address [39:9]. Size is in kBs here. */
1263
- size = (addr_mask_deinterleaved >> 2 ) + 1 ;
1274
+ size = calculate_cs_size (addr_mask , cs_mode );
1275
+
1276
+ edac_dbg (1 , " Secondary AddrMask: 0x%x\n" , addr_mask_sec );
1277
+ size += calculate_cs_size (addr_mask_sec , cs_mode );
1264
1278
1265
1279
/* Return size in MBs. */
1266
1280
return size >> 10 ;
@@ -1269,8 +1283,8 @@ static int __addr_mask_to_cs_size(u32 addr_mask_orig, unsigned int cs_mode,
1269
1283
static int umc_addr_mask_to_cs_size (struct amd64_pvt * pvt , u8 umc ,
1270
1284
unsigned int cs_mode , int csrow_nr )
1271
1285
{
1286
+ u32 addr_mask = 0 , addr_mask_sec = 0 ;
1272
1287
int cs_mask_nr = csrow_nr ;
1273
- u32 addr_mask_orig ;
1274
1288
int dimm , size = 0 ;
1275
1289
1276
1290
/* No Chip Selects are enabled. */
@@ -1308,13 +1322,13 @@ static int umc_addr_mask_to_cs_size(struct amd64_pvt *pvt, u8 umc,
1308
1322
if (!pvt -> flags .zn_regs_v2 )
1309
1323
cs_mask_nr >>= 1 ;
1310
1324
1311
- /* Asymmetric dual-rank DIMM support. */
1312
- if (( csrow_nr & 1 ) && ( cs_mode & CS_ODD_SECONDARY ))
1313
- addr_mask_orig = pvt -> csels [ umc ]. csmasks_sec [ cs_mask_nr ];
1314
- else
1315
- addr_mask_orig = pvt -> csels [umc ].csmasks [cs_mask_nr ];
1325
+ if ( cs_mode & ( CS_EVEN_PRIMARY | CS_ODD_PRIMARY ))
1326
+ addr_mask = pvt -> csels [ umc ]. csmasks [ cs_mask_nr ];
1327
+
1328
+ if ( cs_mode & ( CS_EVEN_SECONDARY | CS_ODD_SECONDARY ))
1329
+ addr_mask_sec = pvt -> csels [umc ].csmasks_sec [cs_mask_nr ];
1316
1330
1317
- return __addr_mask_to_cs_size (addr_mask_orig , cs_mode , csrow_nr , dimm );
1331
+ return __addr_mask_to_cs_size (addr_mask , addr_mask_sec , cs_mode , csrow_nr , dimm );
1318
1332
}
1319
1333
1320
1334
static void umc_debug_display_dimm_sizes (struct amd64_pvt * pvt , u8 ctrl )
@@ -3512,9 +3526,10 @@ static void gpu_get_err_info(struct mce *m, struct err_info *err)
3512
3526
static int gpu_addr_mask_to_cs_size (struct amd64_pvt * pvt , u8 umc ,
3513
3527
unsigned int cs_mode , int csrow_nr )
3514
3528
{
3515
- u32 addr_mask_orig = pvt -> csels [umc ].csmasks [csrow_nr ];
3529
+ u32 addr_mask = pvt -> csels [umc ].csmasks [csrow_nr ];
3530
+ u32 addr_mask_sec = pvt -> csels [umc ].csmasks_sec [csrow_nr ];
3516
3531
3517
- return __addr_mask_to_cs_size (addr_mask_orig , cs_mode , csrow_nr , csrow_nr >> 1 );
3532
+ return __addr_mask_to_cs_size (addr_mask , addr_mask_sec , cs_mode , csrow_nr , csrow_nr >> 1 );
3518
3533
}
3519
3534
3520
3535
static void gpu_debug_display_dimm_sizes (struct amd64_pvt * pvt , u8 ctrl )
0 commit comments