8484#define PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_9 0x3ec6
8585#define PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_10 0x3eca
8686
87- /* Test if HB is for Skylake or later. */
88- #define DEVICE_ID_SKYLAKE_OR_LATER (did ) \
89- (((did) == PCI_DEVICE_ID_INTEL_IE31200_HB_8) || \
90- ((did) == PCI_DEVICE_ID_INTEL_IE31200_HB_9) || \
91- ((did) == PCI_DEVICE_ID_INTEL_IE31200_HB_10) || \
92- ((did) == PCI_DEVICE_ID_INTEL_IE31200_HB_11) || \
93- ((did) == PCI_DEVICE_ID_INTEL_IE31200_HB_12) || \
94- (((did) & PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_MASK) == \
95- PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_MASK))
96-
9787#define IE31200_RANKS_PER_CHANNEL 4
9888#define IE31200_DIMMS_PER_CHANNEL 2
9989#define IE31200_CHANNELS 2
118108#define IE31200_CAPID0_DDPCD BIT(6)
119109#define IE31200_CAPID0_ECC BIT(1)
120110
121- /* Skylake reports 1GB increments, everything else is 256MB */
122- #define IE31200_PAGES (n , skl ) \
123- (n << (28 + (2 * skl) - PAGE_SHIFT))
124-
125111/* Non-constant mask variant of FIELD_GET() */
126112#define field_get (_mask , _reg ) (((_reg) & (_mask)) >> (ffs(_mask) - 1))
127113
@@ -141,6 +127,7 @@ struct res_config {
141127 u64 reg_eccerrlog_rank_mask ;
142128 u64 reg_eccerrlog_syndrome_mask ;
143129 /* DIMM characteristics register */
130+ u64 reg_mad_dimm_size_granularity ;
144131 u64 reg_mad_dimm_offset [IE31200_CHANNELS ];
145132 u32 reg_mad_dimm_size_mask [IE31200_DIMMS_PER_CHANNEL ];
146133 u32 reg_mad_dimm_rank_mask [IE31200_DIMMS_PER_CHANNEL ];
@@ -175,9 +162,9 @@ static const struct ie31200_dev_info ie31200_devs[] = {
175162};
176163
177164struct dimm_data {
178- u8 size ; /* in multiples of 256MB, except Skylake is 1GB */
179- u8 dual_rank : 1 ,
180- x16_width : 2 ; /* 0 means x8 width */
165+ u64 size ; /* in bytes */
166+ u8 ranks ;
167+ enum dev_type dtype ;
181168};
182169
183170static int how_many_channels (struct pci_dev * pdev )
@@ -340,26 +327,20 @@ static void __iomem *ie31200_map_mchbar(struct pci_dev *pdev, struct res_config
340327static void populate_dimm_info (struct dimm_data * dd , u32 addr_decode , int dimm ,
341328 struct res_config * cfg )
342329{
343- dd -> size = field_get (cfg -> reg_mad_dimm_size_mask [dimm ], addr_decode );
344- dd -> dual_rank = field_get (cfg -> reg_mad_dimm_rank_mask [dimm ], addr_decode );
345- dd -> x16_width = field_get (cfg -> reg_mad_dimm_width_mask [dimm ], addr_decode );
330+ dd -> size = field_get (cfg -> reg_mad_dimm_size_mask [dimm ], addr_decode ) * cfg -> reg_mad_dimm_size_granularity ;
331+ dd -> ranks = field_get (cfg -> reg_mad_dimm_rank_mask [dimm ], addr_decode ) + 1 ;
332+ dd -> dtype = field_get (cfg -> reg_mad_dimm_width_mask [dimm ], addr_decode ) + DEV_X8 ;
346333}
347334
348335static int ie31200_probe1 (struct pci_dev * pdev , struct res_config * cfg )
349336{
350- int i , j , ret ;
337+ int i , j , k , ret ;
351338 struct mem_ctl_info * mci = NULL ;
352339 struct edac_mc_layer layers [2 ];
353340 void __iomem * window ;
354341 struct ie31200_priv * priv ;
355342 u32 addr_decode [IE31200_CHANNELS ];
356343
357- /*
358- * Kaby Lake, Coffee Lake seem to work like Skylake. Please re-visit
359- * this logic when adding new CPU support.
360- */
361- bool skl = DEVICE_ID_SKYLAKE_OR_LATER (pdev -> device );
362-
363344 edac_dbg (0 , "MC:\n" );
364345
365346 if (!ecc_capable (pdev )) {
@@ -419,32 +400,25 @@ static int ie31200_probe1(struct pci_dev *pdev, struct res_config *cfg)
419400 unsigned long nr_pages ;
420401
421402 populate_dimm_info (& dimm_info , addr_decode [j ], i , cfg );
422- edac_dbg (0 , "size: 0x%x, rank : %d, width : %d\n" ,
423- dimm_info .size ,
424- dimm_info .dual_rank ,
425- dimm_info .x16_width );
403+ edac_dbg (0 , "channel: %d, dimm: %d, size: %lld MiB, ranks : %d, DRAM chip type : %d\n" ,
404+ j , i , dimm_info .size >> 20 ,
405+ dimm_info .ranks ,
406+ dimm_info .dtype );
426407
427- nr_pages = IE31200_PAGES (dimm_info .size , skl );
408+ nr_pages = MiB_TO_PAGES (dimm_info .size >> 20 );
428409 if (nr_pages == 0 )
429410 continue ;
430411
431- if ( dimm_info .dual_rank ) {
432- nr_pages = nr_pages / 2 ;
433- dimm = edac_get_dimm (mci , (i * 2 ) + 1 , j , 0 );
412+ nr_pages = nr_pages / dimm_info .ranks ;
413+ for ( k = 0 ; k < dimm_info . ranks ; k ++ ) {
414+ dimm = edac_get_dimm (mci , (i * dimm_info . ranks ) + k , j , 0 );
434415 dimm -> nr_pages = nr_pages ;
435416 edac_dbg (0 , "set nr pages: 0x%lx\n" , nr_pages );
436417 dimm -> grain = 8 ; /* just a guess */
437418 dimm -> mtype = cfg -> mtype ;
438- dimm -> dtype = DEV_UNKNOWN ;
419+ dimm -> dtype = dimm_info . dtype ;
439420 dimm -> edac_mode = EDAC_UNKNOWN ;
440421 }
441- dimm = edac_get_dimm (mci , i * 2 , j , 0 );
442- dimm -> nr_pages = nr_pages ;
443- edac_dbg (0 , "set nr pages: 0x%lx\n" , nr_pages );
444- dimm -> grain = 8 ; /* same guess */
445- dimm -> mtype = cfg -> mtype ;
446- dimm -> dtype = DEV_UNKNOWN ;
447- dimm -> edac_mode = EDAC_UNKNOWN ;
448422 }
449423 }
450424
@@ -510,6 +484,7 @@ static struct res_config snb_cfg = {
510484 .reg_eccerrlog_ue_mask = BIT_ULL (1 ),
511485 .reg_eccerrlog_rank_mask = GENMASK_ULL (28 , 27 ),
512486 .reg_eccerrlog_syndrome_mask = GENMASK_ULL (23 , 16 ),
487+ .reg_mad_dimm_size_granularity = BIT_ULL (28 ),
513488 .reg_mad_dimm_offset [0 ] = 0x5004 ,
514489 .reg_mad_dimm_offset [1 ] = 0x5008 ,
515490 .reg_mad_dimm_size_mask [0 ] = GENMASK (7 , 0 ),
@@ -530,6 +505,7 @@ static struct res_config skl_cfg = {
530505 .reg_eccerrlog_ue_mask = BIT_ULL (1 ),
531506 .reg_eccerrlog_rank_mask = GENMASK_ULL (28 , 27 ),
532507 .reg_eccerrlog_syndrome_mask = GENMASK_ULL (23 , 16 ),
508+ .reg_mad_dimm_size_granularity = BIT_ULL (30 ),
533509 .reg_mad_dimm_offset [0 ] = 0x500c ,
534510 .reg_mad_dimm_offset [1 ] = 0x5010 ,
535511 .reg_mad_dimm_size_mask [0 ] = GENMASK (5 , 0 ),
0 commit comments