@@ -1212,7 +1212,9 @@ static int umc_get_cs_mode(int dimm, u8 ctrl, struct amd64_pvt *pvt)
12121212 if (csrow_enabled (2 * dimm + 1 , ctrl , pvt ))
12131213 cs_mode |= CS_ODD_PRIMARY ;
12141214
1215- /* Asymmetric dual-rank DIMM support. */
1215+ if (csrow_sec_enabled (2 * dimm , ctrl , pvt ))
1216+ cs_mode |= CS_EVEN_SECONDARY ;
1217+
12161218 if (csrow_sec_enabled (2 * dimm + 1 , ctrl , pvt ))
12171219 cs_mode |= CS_ODD_SECONDARY ;
12181220
@@ -1233,12 +1235,13 @@ static int umc_get_cs_mode(int dimm, u8 ctrl, struct amd64_pvt *pvt)
12331235 return cs_mode ;
12341236}
12351237
1236- static int __addr_mask_to_cs_size (u32 addr_mask_orig , unsigned int cs_mode ,
1237- int csrow_nr , int dimm )
1238+ static int calculate_cs_size (u32 mask , unsigned int cs_mode )
12381239{
1239- u32 msb , weight , num_zero_bits ;
1240- u32 addr_mask_deinterleaved ;
1241- int size = 0 ;
1240+ int msb , weight , num_zero_bits ;
1241+ u32 deinterleaved_mask ;
1242+
1243+ if (!mask )
1244+ return 0 ;
12421245
12431246 /*
12441247 * The number of zero bits in the mask is equal to the number of bits
@@ -1251,19 +1254,30 @@ static int __addr_mask_to_cs_size(u32 addr_mask_orig, unsigned int cs_mode,
12511254 * without swapping with the most significant bit. This can be handled
12521255 * by keeping the MSB where it is and ignoring the single zero bit.
12531256 */
1254- msb = fls (addr_mask_orig ) - 1 ;
1255- weight = hweight_long (addr_mask_orig );
1257+ msb = fls (mask ) - 1 ;
1258+ weight = hweight_long (mask );
12561259 num_zero_bits = msb - weight - !!(cs_mode & CS_3R_INTERLEAVE );
12571260
12581261 /* Take the number of zero bits off from the top of the mask. */
1259- addr_mask_deinterleaved = GENMASK_ULL (msb - num_zero_bits , 1 );
1262+ deinterleaved_mask = GENMASK (msb - num_zero_bits , 1 );
1263+ edac_dbg (1 , " Deinterleaved AddrMask: 0x%x\n" , deinterleaved_mask );
1264+
1265+ return (deinterleaved_mask >> 2 ) + 1 ;
1266+ }
1267+
1268+ static int __addr_mask_to_cs_size (u32 addr_mask , u32 addr_mask_sec ,
1269+ unsigned int cs_mode , int csrow_nr , int dimm )
1270+ {
1271+ int size ;
12601272
12611273 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 );
1274+ edac_dbg (1 , " Primary AddrMask: 0x%x\n" , addr_mask );
12641275
12651276 /* Register [31:1] = Address [39:9]. Size is in kBs here. */
1266- size = (addr_mask_deinterleaved >> 2 ) + 1 ;
1277+ size = calculate_cs_size (addr_mask , cs_mode );
1278+
1279+ edac_dbg (1 , " Secondary AddrMask: 0x%x\n" , addr_mask_sec );
1280+ size += calculate_cs_size (addr_mask_sec , cs_mode );
12671281
12681282 /* Return size in MBs. */
12691283 return size >> 10 ;
@@ -1272,8 +1286,8 @@ static int __addr_mask_to_cs_size(u32 addr_mask_orig, unsigned int cs_mode,
12721286static int umc_addr_mask_to_cs_size (struct amd64_pvt * pvt , u8 umc ,
12731287 unsigned int cs_mode , int csrow_nr )
12741288{
1289+ u32 addr_mask = 0 , addr_mask_sec = 0 ;
12751290 int cs_mask_nr = csrow_nr ;
1276- u32 addr_mask_orig ;
12771291 int dimm , size = 0 ;
12781292
12791293 /* No Chip Selects are enabled. */
@@ -1311,13 +1325,13 @@ static int umc_addr_mask_to_cs_size(struct amd64_pvt *pvt, u8 umc,
13111325 if (!pvt -> flags .zn_regs_v2 )
13121326 cs_mask_nr >>= 1 ;
13131327
1314- /* Asymmetric dual-rank DIMM support. */
1315- if (( csrow_nr & 1 ) && ( cs_mode & CS_ODD_SECONDARY ))
1316- addr_mask_orig = pvt -> csels [ umc ]. csmasks_sec [ cs_mask_nr ];
1317- else
1318- addr_mask_orig = pvt -> csels [umc ].csmasks [cs_mask_nr ];
1328+ if ( cs_mode & ( CS_EVEN_PRIMARY | CS_ODD_PRIMARY ))
1329+ addr_mask = pvt -> csels [ umc ]. csmasks [ cs_mask_nr ];
1330+
1331+ if ( cs_mode & ( CS_EVEN_SECONDARY | CS_ODD_SECONDARY ))
1332+ addr_mask_sec = pvt -> csels [umc ].csmasks_sec [cs_mask_nr ];
13191333
1320- return __addr_mask_to_cs_size (addr_mask_orig , cs_mode , csrow_nr , dimm );
1334+ return __addr_mask_to_cs_size (addr_mask , addr_mask_sec , cs_mode , csrow_nr , dimm );
13211335}
13221336
13231337static void umc_debug_display_dimm_sizes (struct amd64_pvt * pvt , u8 ctrl )
@@ -3519,9 +3533,10 @@ static void gpu_get_err_info(struct mce *m, struct err_info *err)
35193533static int gpu_addr_mask_to_cs_size (struct amd64_pvt * pvt , u8 umc ,
35203534 unsigned int cs_mode , int csrow_nr )
35213535{
3522- u32 addr_mask_orig = pvt -> csels [umc ].csmasks [csrow_nr ];
3536+ u32 addr_mask = pvt -> csels [umc ].csmasks [csrow_nr ];
3537+ u32 addr_mask_sec = pvt -> csels [umc ].csmasks_sec [csrow_nr ];
35233538
3524- return __addr_mask_to_cs_size (addr_mask_orig , cs_mode , csrow_nr , csrow_nr >> 1 );
3539+ return __addr_mask_to_cs_size (addr_mask , addr_mask_sec , cs_mode , csrow_nr , csrow_nr >> 1 );
35253540}
35263541
35273542static void gpu_debug_display_dimm_sizes (struct amd64_pvt * pvt , u8 ctrl )
0 commit comments