284
{
285
int caps = 0;
286
287
- /*
288
- * In CXL 2.0 the capabilities required for each CXL component are such
289
- * that, with the ordering chosen here, a single number can be used to
290
- * define which capabilities should be provided.
291
- */
292
- switch (type) {
293
- case CXL2_DOWNSTREAM_PORT:
294
- case CXL2_DEVICE:
295
- /* RAS, Link */
296
- caps = 2;
297
- break;
298
- case CXL2_UPSTREAM_PORT:
299
- case CXL2_TYPE3_DEVICE:
300
- case CXL2_LOGICAL_DEVICE:
301
- /* + HDM */
302
- caps = 3;
303
- break;
304
- case CXL2_ROOT_PORT:
305
- case CXL2_RC:
306
- /* + Extended Security, + Snoop */
307
- caps = 5;
308
- break;
309
- default:
310
- abort();
311
- }
312
-
287
memset(reg_state, 0, CXL2_COMPONENT_CM_REGION_SIZE);
288
289
/* CXL Capability Header Register */
291
ARRAY_FIELD_DP32(reg_state, CXL_CAPABILITY_HEADER, VERSION,
292
CXL_CAPABILITY_VERSION);
293
ARRAY_FIELD_DP32(reg_state, CXL_CAPABILITY_HEADER, CACHE_MEM_VERSION, 1);
320
- ARRAY_FIELD_DP32(reg_state, CXL_CAPABILITY_HEADER, ARRAY_SIZE, caps);
294
295
#define init_cap_reg(reg, id, version) \
296
do { \
324
- int which = R_CXL_##reg##_CAPABILITY_HEADER; \
297
+ int which = CXL_##reg##_CAP_HDR_IDX; \
298
+ if (CXL_##reg##_CAP_HDR_IDX > caps) \
299
+ caps = CXL_##reg##_CAP_HDR_IDX; \
300
reg_state[which] = FIELD_DP32(reg_state[which], \
301
CXL_##reg##_CAPABILITY_HEADER, ID, id); \
302
reg_state[which] = \
307
CXL_##reg##_REGISTERS_OFFSET); \
308
} while (0)
309
310
+ /* CXL r3.2 8.2.4 Table 8-22 */
311
switch (type) {
336
- case CXL2_DEVICE:
337
- case CXL2_TYPE3_DEVICE:
338
- case CXL2_LOGICAL_DEVICE:
312
case CXL2_ROOT_PORT:
313
+ case CXL2_RC:
314
+ /* + Extended Security, + Snoop */
315
+ init_cap_reg(EXTSEC, 6, 1);
316
+ init_cap_reg(SNOOP, 8, 1);
317
+ /* fallthrough */
318
case CXL2_UPSTREAM_PORT:
319
+ case CXL2_TYPE3_DEVICE:
320
+ case CXL2_LOGICAL_DEVICE:
321
+ /* + HDM */
322
+ init_cap_reg(HDM, 5, 1);
323
+ hdm_init_common(reg_state, write_msk, type);
324
+ /* fallthrough */
325
case CXL2_DOWNSTREAM_PORT:
342
- init_cap_reg(RAS, 2, CXL_RAS_CAPABILITY_VERSION);
343
- ras_init_common(reg_state, write_msk);
326
+ case CXL2_DEVICE:
327
+ /* RAS, Link */
328
+ if (type != CXL2_RC) {
329
+ init_cap_reg(RAS, 2, 2);
330
+ ras_init_common(reg_state, write_msk);
331
+ }
332
+ init_cap_reg(LINK, 4, 2);
333
break;
334
default:
346
- break;
347
- }
348
-
349
- init_cap_reg(LINK, 4, CXL_LINK_CAPABILITY_VERSION);
350
-
351
- if (caps < 3) {
352
- return;
353
- }
354
-
355
- if (type != CXL2_ROOT_PORT) {
356
- init_cap_reg(HDM, 5, CXL_HDM_CAPABILITY_VERSION);
357
- hdm_init_common(reg_state, write_msk, type);
358
- }
359
- if (caps < 5) {
360
- return;
335
+ abort();
336
}
337
363
- init_cap_reg(EXTSEC, 6, CXL_EXTSEC_CAP_VERSION);
364
- init_cap_reg(SNOOP, 8, CXL_SNOOP_CAP_VERSION);
365
-
338
+ ARRAY_FIELD_DP32(reg_state, CXL_CAPABILITY_HEADER, ARRAY_SIZE, caps);
339
#undef init_cap_reg
340
}
341