13
13
#include "edac_module.h"
14
14
#include "skx_common.h"
15
15
16
- #define I10NM_REVISION "v0.0.4 "
16
+ #define I10NM_REVISION "v0.0.5 "
17
17
#define EDAC_MOD_STR "i10nm_edac"
18
18
19
19
/* Debug macros */
24
24
pci_read_config_dword((d)->uracu, 0xd0, &(reg))
25
25
#define I10NM_GET_IMC_BAR (d , i , reg ) \
26
26
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))
27
33
#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)
29
36
#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)
31
39
#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)
33
42
#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)
35
45
36
46
#define I10NM_GET_SCK_MMIO_BASE (reg ) (GET_BITFIELD(reg, 0, 28) << 23)
37
47
#define I10NM_GET_IMC_MMIO_OFFSET (reg ) (GET_BITFIELD(reg, 0, 10) << 12)
38
48
#define I10NM_GET_IMC_MMIO_SIZE (reg ) ((GET_BITFIELD(reg, 13, 23) - \
39
49
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)
40
60
41
61
static struct list_head * i10nm_edac_list ;
42
62
@@ -63,7 +83,32 @@ static struct pci_dev *pci_get_dev_wrapper(int dom, unsigned int bus,
63
83
return pdev ;
64
84
}
65
85
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 )
67
112
{
68
113
struct pci_dev * mdev ;
69
114
void __iomem * mbase ;
@@ -91,7 +136,7 @@ static int i10nm_get_all_munits(void)
91
136
edac_dbg (2 , "socket%d mmio base 0x%llx (reg 0x%x)\n" ,
92
137
j ++ , base , reg );
93
138
94
- for (i = 0 ; i < I10NM_NUM_IMC ; i ++ ) {
139
+ for (i = 0 ; i < I10NM_NUM_DDR_IMC ; i ++ ) {
95
140
mdev = pci_get_dev_wrapper (d -> seg , d -> bus [0 ],
96
141
12 + i , 0 );
97
142
if (i == 0 && !mdev ) {
@@ -127,26 +172,117 @@ static int i10nm_get_all_munits(void)
127
172
return 0 ;
128
173
}
129
174
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
+
130
259
static struct res_config i10nm_cfg0 = {
131
260
.type = I10NM ,
132
261
.decs_did = 0x3452 ,
133
262
.busno_cfg_offset = 0xcc ,
134
263
.ddr_chan_mmio_sz = 0x4000 ,
264
+ .sad_all_devfn = PCI_DEVFN (29 , 0 ),
265
+ .sad_all_offset = 0x108 ,
135
266
};
136
267
137
268
static struct res_config i10nm_cfg1 = {
138
269
.type = I10NM ,
139
270
.decs_did = 0x3452 ,
140
271
.busno_cfg_offset = 0xd0 ,
141
272
.ddr_chan_mmio_sz = 0x4000 ,
273
+ .sad_all_devfn = PCI_DEVFN (29 , 0 ),
274
+ .sad_all_offset = 0x108 ,
142
275
};
143
276
144
277
static struct res_config spr_cfg = {
145
278
.type = SPR ,
146
279
.decs_did = 0x3252 ,
147
280
.busno_cfg_offset = 0xd0 ,
148
281
.ddr_chan_mmio_sz = 0x8000 ,
282
+ .hbm_chan_mmio_sz = 0x4000 ,
149
283
.support_ddr5 = true,
284
+ .sad_all_devfn = PCI_DEVFN (10 , 0 ),
285
+ .sad_all_offset = 0x300 ,
150
286
};
151
287
152
288
static const struct x86_cpu_id i10nm_cpuids [] = {
@@ -179,13 +315,13 @@ static int i10nm_get_dimm_config(struct mem_ctl_info *mci,
179
315
struct dimm_info * dimm ;
180
316
int i , j , ndimms ;
181
317
182
- for (i = 0 ; i < I10NM_NUM_CHANNELS ; i ++ ) {
318
+ for (i = 0 ; i < imc -> num_channels ; i ++ ) {
183
319
if (!imc -> mbase )
184
320
continue ;
185
321
186
322
ndimms = 0 ;
187
323
amap = I10NM_GET_AMAP (imc , i );
188
- for (j = 0 ; j < I10NM_NUM_DIMMS ; j ++ ) {
324
+ for (j = 0 ; j < imc -> num_dimms ; j ++ ) {
189
325
dimm = edac_get_dimm (mci , i , j , 0 );
190
326
mtr = I10NM_GET_DIMMMTR (imc , i , j );
191
327
mcddrtcfg = I10NM_GET_MCDDRTCFG (imc , i , j );
@@ -278,6 +414,9 @@ static int __init i10nm_init(void)
278
414
if (owner && strncmp (owner , EDAC_MOD_STR , sizeof (EDAC_MOD_STR )))
279
415
return - EBUSY ;
280
416
417
+ if (cpu_feature_enabled (X86_FEATURE_HYPERVISOR ))
418
+ return - ENODEV ;
419
+
281
420
id = x86_match_cpu (i10nm_cpuids );
282
421
if (!id )
283
422
return - ENODEV ;
@@ -296,8 +435,11 @@ static int __init i10nm_init(void)
296
435
return - ENODEV ;
297
436
}
298
437
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 )
301
443
goto fail ;
302
444
303
445
list_for_each_entry (d , i10nm_edac_list , list ) {
@@ -318,7 +460,15 @@ static int __init i10nm_init(void)
318
460
d -> imc [i ].lmc = i ;
319
461
d -> imc [i ].src_id = src_id ;
320
462
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
+ }
322
472
323
473
rc = skx_register_mci (& d -> imc [i ], d -> imc [i ].mdev ,
324
474
"Intel_10nm Socket" , EDAC_MOD_STR ,
0 commit comments