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