1313#include "edac_module.h"
1414#include "skx_common.h"
1515
16- #define I10NM_REVISION "v0.0.4 "
16+ #define I10NM_REVISION "v0.0.5 "
1717#define EDAC_MOD_STR "i10nm_edac"
1818
1919/* Debug macros */
2424 pci_read_config_dword((d)->uracu, 0xd0, &(reg))
2525#define I10NM_GET_IMC_BAR (d , i , reg ) \
2626 pci_read_config_dword((d)->uracu, 0xd8 + (i) * 4, &(reg))
27+ #define I10NM_GET_SAD (d , offset , i , reg )\
28+ pci_read_config_dword((d)->sad_all, (offset) + (i) * 8, &(reg))
29+ #define I10NM_GET_HBM_IMC_BAR (d , reg ) \
30+ pci_read_config_dword((d)->uracu, 0xd4, &(reg))
31+ #define I10NM_GET_CAPID3_CFG (d , reg ) \
32+ pci_read_config_dword((d)->pcu_cr3, 0x90, &(reg))
2733#define I10NM_GET_DIMMMTR (m , i , j ) \
28- readl((m)->mbase + 0x2080c + (i) * (m)->chan_mmio_sz + (j) * 4)
34+ readl((m)->mbase + ((m)->hbm_mc ? 0x80c : 0x2080c) + \
35+ (i) * (m)->chan_mmio_sz + (j) * 4)
2936#define I10NM_GET_MCDDRTCFG (m , i , j ) \
30- readl((m)->mbase + 0x20970 + (i) * (m)->chan_mmio_sz + (j) * 4)
37+ readl((m)->mbase + ((m)->hbm_mc ? 0x970 : 0x20970) + \
38+ (i) * (m)->chan_mmio_sz + (j) * 4)
3139#define I10NM_GET_MCMTR (m , i ) \
32- readl((m)->mbase + 0x20ef8 + (i) * (m)->chan_mmio_sz)
40+ readl((m)->mbase + ((m)->hbm_mc ? 0xef8 : 0x20ef8) + \
41+ (i) * (m)->chan_mmio_sz)
3342#define I10NM_GET_AMAP (m , i ) \
34- readl((m)->mbase + 0x20814 + (i) * (m)->chan_mmio_sz)
43+ readl((m)->mbase + ((m)->hbm_mc ? 0x814 : 0x20814) + \
44+ (i) * (m)->chan_mmio_sz)
3545
3646#define I10NM_GET_SCK_MMIO_BASE (reg ) (GET_BITFIELD(reg, 0, 28) << 23)
3747#define I10NM_GET_IMC_MMIO_OFFSET (reg ) (GET_BITFIELD(reg, 0, 10) << 12)
3848#define I10NM_GET_IMC_MMIO_SIZE (reg ) ((GET_BITFIELD(reg, 13, 23) - \
3949 GET_BITFIELD(reg, 0, 10) + 1) << 12)
50+ #define I10NM_GET_HBM_IMC_MMIO_OFFSET (reg ) \
51+ ((GET_BITFIELD(reg, 0, 10) << 12) + 0x140000)
52+
53+ #define I10NM_HBM_IMC_MMIO_SIZE 0x9000
54+ #define I10NM_IS_HBM_PRESENT (reg ) GET_BITFIELD(reg, 27, 30)
55+ #define I10NM_IS_HBM_IMC (reg ) GET_BITFIELD(reg, 29, 29)
56+
57+ #define I10NM_MAX_SAD 16
58+ #define I10NM_SAD_ENABLE (reg ) GET_BITFIELD(reg, 0, 0)
59+ #define I10NM_SAD_NM_CACHEABLE (reg ) GET_BITFIELD(reg, 5, 5)
4060
4161static struct list_head * i10nm_edac_list ;
4262
@@ -63,7 +83,32 @@ static struct pci_dev *pci_get_dev_wrapper(int dom, unsigned int bus,
6383 return pdev ;
6484}
6585
66- static int i10nm_get_all_munits (void )
86+ static bool i10nm_check_2lm (struct res_config * cfg )
87+ {
88+ struct skx_dev * d ;
89+ u32 reg ;
90+ int i ;
91+
92+ list_for_each_entry (d , i10nm_edac_list , list ) {
93+ d -> sad_all = pci_get_dev_wrapper (d -> seg , d -> bus [1 ],
94+ PCI_SLOT (cfg -> sad_all_devfn ),
95+ PCI_FUNC (cfg -> sad_all_devfn ));
96+ if (!d -> sad_all )
97+ continue ;
98+
99+ for (i = 0 ; i < I10NM_MAX_SAD ; i ++ ) {
100+ I10NM_GET_SAD (d , cfg -> sad_all_offset , i , reg );
101+ if (I10NM_SAD_ENABLE (reg ) && I10NM_SAD_NM_CACHEABLE (reg )) {
102+ edac_dbg (2 , "2-level memory configuration.\n" );
103+ return true;
104+ }
105+ }
106+ }
107+
108+ return false;
109+ }
110+
111+ static int i10nm_get_ddr_munits (void )
67112{
68113 struct pci_dev * mdev ;
69114 void __iomem * mbase ;
@@ -91,7 +136,7 @@ static int i10nm_get_all_munits(void)
91136 edac_dbg (2 , "socket%d mmio base 0x%llx (reg 0x%x)\n" ,
92137 j ++ , base , reg );
93138
94- for (i = 0 ; i < I10NM_NUM_IMC ; i ++ ) {
139+ for (i = 0 ; i < I10NM_NUM_DDR_IMC ; i ++ ) {
95140 mdev = pci_get_dev_wrapper (d -> seg , d -> bus [0 ],
96141 12 + i , 0 );
97142 if (i == 0 && !mdev ) {
@@ -127,26 +172,117 @@ static int i10nm_get_all_munits(void)
127172 return 0 ;
128173}
129174
175+ static bool i10nm_check_hbm_imc (struct skx_dev * d )
176+ {
177+ u32 reg ;
178+
179+ if (I10NM_GET_CAPID3_CFG (d , reg )) {
180+ i10nm_printk (KERN_ERR , "Failed to get capid3_cfg\n" );
181+ return false;
182+ }
183+
184+ return I10NM_IS_HBM_PRESENT (reg ) != 0 ;
185+ }
186+
187+ static int i10nm_get_hbm_munits (void )
188+ {
189+ struct pci_dev * mdev ;
190+ void __iomem * mbase ;
191+ u32 reg , off , mcmtr ;
192+ struct skx_dev * d ;
193+ int i , lmc ;
194+ u64 base ;
195+
196+ list_for_each_entry (d , i10nm_edac_list , list ) {
197+ d -> pcu_cr3 = pci_get_dev_wrapper (d -> seg , d -> bus [1 ], 30 , 3 );
198+ if (!d -> pcu_cr3 )
199+ return - ENODEV ;
200+
201+ if (!i10nm_check_hbm_imc (d )) {
202+ i10nm_printk (KERN_DEBUG , "No hbm memory\n" );
203+ return - ENODEV ;
204+ }
205+
206+ if (I10NM_GET_SCK_BAR (d , reg )) {
207+ i10nm_printk (KERN_ERR , "Failed to get socket bar\n" );
208+ return - ENODEV ;
209+ }
210+ base = I10NM_GET_SCK_MMIO_BASE (reg );
211+
212+ if (I10NM_GET_HBM_IMC_BAR (d , reg )) {
213+ i10nm_printk (KERN_ERR , "Failed to get hbm mc bar\n" );
214+ return - ENODEV ;
215+ }
216+ base += I10NM_GET_HBM_IMC_MMIO_OFFSET (reg );
217+
218+ lmc = I10NM_NUM_DDR_IMC ;
219+
220+ for (i = 0 ; i < I10NM_NUM_HBM_IMC ; i ++ ) {
221+ mdev = pci_get_dev_wrapper (d -> seg , d -> bus [0 ],
222+ 12 + i / 4 , 1 + i % 4 );
223+ if (i == 0 && !mdev ) {
224+ i10nm_printk (KERN_ERR , "No hbm mc found\n" );
225+ return - ENODEV ;
226+ }
227+ if (!mdev )
228+ continue ;
229+
230+ d -> imc [lmc ].mdev = mdev ;
231+ off = i * I10NM_HBM_IMC_MMIO_SIZE ;
232+
233+ edac_dbg (2 , "hbm mc%d mmio base 0x%llx size 0x%x\n" ,
234+ lmc , base + off , I10NM_HBM_IMC_MMIO_SIZE );
235+
236+ mbase = ioremap (base + off , I10NM_HBM_IMC_MMIO_SIZE );
237+ if (!mbase ) {
238+ i10nm_printk (KERN_ERR , "Failed to ioremap for hbm mc 0x%llx\n" ,
239+ base + off );
240+ return - ENOMEM ;
241+ }
242+
243+ d -> imc [lmc ].mbase = mbase ;
244+ d -> imc [lmc ].hbm_mc = true;
245+
246+ mcmtr = I10NM_GET_MCMTR (& d -> imc [lmc ], 0 );
247+ if (!I10NM_IS_HBM_IMC (mcmtr )) {
248+ i10nm_printk (KERN_ERR , "This isn't an hbm mc!\n" );
249+ return - ENODEV ;
250+ }
251+
252+ lmc ++ ;
253+ }
254+ }
255+
256+ return 0 ;
257+ }
258+
130259static struct res_config i10nm_cfg0 = {
131260 .type = I10NM ,
132261 .decs_did = 0x3452 ,
133262 .busno_cfg_offset = 0xcc ,
134263 .ddr_chan_mmio_sz = 0x4000 ,
264+ .sad_all_devfn = PCI_DEVFN (29 , 0 ),
265+ .sad_all_offset = 0x108 ,
135266};
136267
137268static struct res_config i10nm_cfg1 = {
138269 .type = I10NM ,
139270 .decs_did = 0x3452 ,
140271 .busno_cfg_offset = 0xd0 ,
141272 .ddr_chan_mmio_sz = 0x4000 ,
273+ .sad_all_devfn = PCI_DEVFN (29 , 0 ),
274+ .sad_all_offset = 0x108 ,
142275};
143276
144277static struct res_config spr_cfg = {
145278 .type = SPR ,
146279 .decs_did = 0x3252 ,
147280 .busno_cfg_offset = 0xd0 ,
148281 .ddr_chan_mmio_sz = 0x8000 ,
282+ .hbm_chan_mmio_sz = 0x4000 ,
149283 .support_ddr5 = true,
284+ .sad_all_devfn = PCI_DEVFN (10 , 0 ),
285+ .sad_all_offset = 0x300 ,
150286};
151287
152288static const struct x86_cpu_id i10nm_cpuids [] = {
@@ -179,13 +315,13 @@ static int i10nm_get_dimm_config(struct mem_ctl_info *mci,
179315 struct dimm_info * dimm ;
180316 int i , j , ndimms ;
181317
182- for (i = 0 ; i < I10NM_NUM_CHANNELS ; i ++ ) {
318+ for (i = 0 ; i < imc -> num_channels ; i ++ ) {
183319 if (!imc -> mbase )
184320 continue ;
185321
186322 ndimms = 0 ;
187323 amap = I10NM_GET_AMAP (imc , i );
188- for (j = 0 ; j < I10NM_NUM_DIMMS ; j ++ ) {
324+ for (j = 0 ; j < imc -> num_dimms ; j ++ ) {
189325 dimm = edac_get_dimm (mci , i , j , 0 );
190326 mtr = I10NM_GET_DIMMMTR (imc , i , j );
191327 mcddrtcfg = I10NM_GET_MCDDRTCFG (imc , i , j );
@@ -278,6 +414,9 @@ static int __init i10nm_init(void)
278414 if (owner && strncmp (owner , EDAC_MOD_STR , sizeof (EDAC_MOD_STR )))
279415 return - EBUSY ;
280416
417+ if (cpu_feature_enabled (X86_FEATURE_HYPERVISOR ))
418+ return - ENODEV ;
419+
281420 id = x86_match_cpu (i10nm_cpuids );
282421 if (!id )
283422 return - ENODEV ;
@@ -296,8 +435,11 @@ static int __init i10nm_init(void)
296435 return - ENODEV ;
297436 }
298437
299- rc = i10nm_get_all_munits ();
300- if (rc < 0 )
438+ skx_set_mem_cfg (i10nm_check_2lm (cfg ));
439+
440+ rc = i10nm_get_ddr_munits ();
441+
442+ if (i10nm_get_hbm_munits () && rc )
301443 goto fail ;
302444
303445 list_for_each_entry (d , i10nm_edac_list , list ) {
@@ -318,7 +460,15 @@ static int __init i10nm_init(void)
318460 d -> imc [i ].lmc = i ;
319461 d -> imc [i ].src_id = src_id ;
320462 d -> imc [i ].node_id = node_id ;
321- d -> imc [i ].chan_mmio_sz = cfg -> ddr_chan_mmio_sz ;
463+ if (d -> imc [i ].hbm_mc ) {
464+ d -> imc [i ].chan_mmio_sz = cfg -> hbm_chan_mmio_sz ;
465+ d -> imc [i ].num_channels = I10NM_NUM_HBM_CHANNELS ;
466+ d -> imc [i ].num_dimms = I10NM_NUM_HBM_DIMMS ;
467+ } else {
468+ d -> imc [i ].chan_mmio_sz = cfg -> ddr_chan_mmio_sz ;
469+ d -> imc [i ].num_channels = I10NM_NUM_DDR_CHANNELS ;
470+ d -> imc [i ].num_dimms = I10NM_NUM_DDR_DIMMS ;
471+ }
322472
323473 rc = skx_register_mci (& d -> imc [i ], d -> imc [i ].mdev ,
324474 "Intel_10nm Socket" , EDAC_MOD_STR ,
0 commit comments