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 */
26
26
pci_read_config_dword((d)->uracu, 0xd8 + (i) * 4, &(reg))
27
27
#define I10NM_GET_SAD (d , offset , i , reg )\
28
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))
29
33
#define I10NM_GET_DIMMMTR (m , i , j ) \
30
- 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)
31
36
#define I10NM_GET_MCDDRTCFG (m , i , j ) \
32
- 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)
33
39
#define I10NM_GET_MCMTR (m , i ) \
34
- readl((m)->mbase + 0x20ef8 + (i) * (m)->chan_mmio_sz)
40
+ readl((m)->mbase + ((m)->hbm_mc ? 0xef8 : 0x20ef8) + \
41
+ (i) * (m)->chan_mmio_sz)
35
42
#define I10NM_GET_AMAP (m , i ) \
36
- readl((m)->mbase + 0x20814 + (i) * (m)->chan_mmio_sz)
43
+ readl((m)->mbase + ((m)->hbm_mc ? 0x814 : 0x20814) + \
44
+ (i) * (m)->chan_mmio_sz)
37
45
38
46
#define I10NM_GET_SCK_MMIO_BASE (reg ) (GET_BITFIELD(reg, 0, 28) << 23)
39
47
#define I10NM_GET_IMC_MMIO_OFFSET (reg ) (GET_BITFIELD(reg, 0, 10) << 12)
40
48
#define I10NM_GET_IMC_MMIO_SIZE (reg ) ((GET_BITFIELD(reg, 13, 23) - \
41
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)
42
56
43
57
#define I10NM_MAX_SAD 16
44
58
#define I10NM_SAD_ENABLE (reg ) GET_BITFIELD(reg, 0, 0)
@@ -94,7 +108,7 @@ static bool i10nm_check_2lm(struct res_config *cfg)
94
108
return false;
95
109
}
96
110
97
- static int i10nm_get_all_munits (void )
111
+ static int i10nm_get_ddr_munits (void )
98
112
{
99
113
struct pci_dev * mdev ;
100
114
void __iomem * mbase ;
@@ -122,7 +136,7 @@ static int i10nm_get_all_munits(void)
122
136
edac_dbg (2 , "socket%d mmio base 0x%llx (reg 0x%x)\n" ,
123
137
j ++ , base , reg );
124
138
125
- for (i = 0 ; i < I10NM_NUM_IMC ; i ++ ) {
139
+ for (i = 0 ; i < I10NM_NUM_DDR_IMC ; i ++ ) {
126
140
mdev = pci_get_dev_wrapper (d -> seg , d -> bus [0 ],
127
141
12 + i , 0 );
128
142
if (i == 0 && !mdev ) {
@@ -158,6 +172,90 @@ static int i10nm_get_all_munits(void)
158
172
return 0 ;
159
173
}
160
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
+
161
259
static struct res_config i10nm_cfg0 = {
162
260
.type = I10NM ,
163
261
.decs_did = 0x3452 ,
@@ -181,6 +279,7 @@ static struct res_config spr_cfg = {
181
279
.decs_did = 0x3252 ,
182
280
.busno_cfg_offset = 0xd0 ,
183
281
.ddr_chan_mmio_sz = 0x8000 ,
282
+ .hbm_chan_mmio_sz = 0x4000 ,
184
283
.support_ddr5 = true,
185
284
.sad_all_devfn = PCI_DEVFN (10 , 0 ),
186
285
.sad_all_offset = 0x300 ,
@@ -216,13 +315,13 @@ static int i10nm_get_dimm_config(struct mem_ctl_info *mci,
216
315
struct dimm_info * dimm ;
217
316
int i , j , ndimms ;
218
317
219
- for (i = 0 ; i < I10NM_NUM_CHANNELS ; i ++ ) {
318
+ for (i = 0 ; i < imc -> num_channels ; i ++ ) {
220
319
if (!imc -> mbase )
221
320
continue ;
222
321
223
322
ndimms = 0 ;
224
323
amap = I10NM_GET_AMAP (imc , i );
225
- for (j = 0 ; j < I10NM_NUM_DIMMS ; j ++ ) {
324
+ for (j = 0 ; j < imc -> num_dimms ; j ++ ) {
226
325
dimm = edac_get_dimm (mci , i , j , 0 );
227
326
mtr = I10NM_GET_DIMMMTR (imc , i , j );
228
327
mcddrtcfg = I10NM_GET_MCDDRTCFG (imc , i , j );
@@ -335,8 +434,9 @@ static int __init i10nm_init(void)
335
434
336
435
skx_set_mem_cfg (i10nm_check_2lm (cfg ));
337
436
338
- rc = i10nm_get_all_munits ();
339
- if (rc < 0 )
437
+ rc = i10nm_get_ddr_munits ();
438
+
439
+ if (i10nm_get_hbm_munits () && rc )
340
440
goto fail ;
341
441
342
442
list_for_each_entry (d , i10nm_edac_list , list ) {
@@ -357,7 +457,15 @@ static int __init i10nm_init(void)
357
457
d -> imc [i ].lmc = i ;
358
458
d -> imc [i ].src_id = src_id ;
359
459
d -> imc [i ].node_id = node_id ;
360
- d -> imc [i ].chan_mmio_sz = cfg -> ddr_chan_mmio_sz ;
460
+ if (d -> imc [i ].hbm_mc ) {
461
+ d -> imc [i ].chan_mmio_sz = cfg -> hbm_chan_mmio_sz ;
462
+ d -> imc [i ].num_channels = I10NM_NUM_HBM_CHANNELS ;
463
+ d -> imc [i ].num_dimms = I10NM_NUM_HBM_DIMMS ;
464
+ } else {
465
+ d -> imc [i ].chan_mmio_sz = cfg -> ddr_chan_mmio_sz ;
466
+ d -> imc [i ].num_channels = I10NM_NUM_DDR_CHANNELS ;
467
+ d -> imc [i ].num_dimms = I10NM_NUM_DDR_DIMMS ;
468
+ }
361
469
362
470
rc = skx_register_mci (& d -> imc [i ], d -> imc [i ].mdev ,
363
471
"Intel_10nm Socket" , EDAC_MOD_STR ,
0 commit comments