@@ -49,6 +49,7 @@ struct aspm_latency {
49
49
50
50
struct pcie_link_state {
51
51
struct pci_dev * pdev ; /* Upstream component of the Link */
52
+ struct pci_dev * downstream ; /* Downstream component, function 0 */
52
53
struct pcie_link_state * root ; /* pointer to the root port link */
53
54
struct pcie_link_state * parent ; /* pointer to the parent Link state */
54
55
struct list_head sibling ; /* node in link_list */
@@ -300,6 +301,12 @@ struct aspm_register_info {
300
301
u32 enabled :2 ;
301
302
u32 latency_encoding_l0s ;
302
303
u32 latency_encoding_l1 ;
304
+
305
+ /* L1 substates */
306
+ u32 l1ss_cap_ptr ;
307
+ u32 l1ss_cap ;
308
+ u32 l1ss_ctl1 ;
309
+ u32 l1ss_ctl2 ;
303
310
};
304
311
305
312
static void pcie_get_aspm_reg (struct pci_dev * pdev ,
@@ -314,6 +321,22 @@ static void pcie_get_aspm_reg(struct pci_dev *pdev,
314
321
info -> latency_encoding_l1 = (reg32 & PCI_EXP_LNKCAP_L1EL ) >> 15 ;
315
322
pcie_capability_read_word (pdev , PCI_EXP_LNKCTL , & reg16 );
316
323
info -> enabled = reg16 & PCI_EXP_LNKCTL_ASPMC ;
324
+
325
+ /* Read L1 PM substate capabilities */
326
+ info -> l1ss_cap = info -> l1ss_ctl1 = info -> l1ss_ctl2 = 0 ;
327
+ info -> l1ss_cap_ptr = pci_find_ext_capability (pdev , PCI_EXT_CAP_ID_L1SS );
328
+ if (!info -> l1ss_cap_ptr )
329
+ return ;
330
+ pci_read_config_dword (pdev , info -> l1ss_cap_ptr + PCI_L1SS_CAP ,
331
+ & info -> l1ss_cap );
332
+ if (!(info -> l1ss_cap & PCI_L1SS_CAP_L1_PM_SS )) {
333
+ info -> l1ss_cap = 0 ;
334
+ return ;
335
+ }
336
+ pci_read_config_dword (pdev , info -> l1ss_cap_ptr + PCI_L1SS_CTL1 ,
337
+ & info -> l1ss_ctl1 );
338
+ pci_read_config_dword (pdev , info -> l1ss_cap_ptr + PCI_L1SS_CTL2 ,
339
+ & info -> l1ss_ctl2 );
317
340
}
318
341
319
342
static void pcie_aspm_check_latency (struct pci_dev * endpoint )
@@ -355,6 +378,20 @@ static void pcie_aspm_check_latency(struct pci_dev *endpoint)
355
378
}
356
379
}
357
380
381
+ /*
382
+ * The L1 PM substate capability is only implemented in function 0 in a
383
+ * multi function device.
384
+ */
385
+ static struct pci_dev * pci_function_0 (struct pci_bus * linkbus )
386
+ {
387
+ struct pci_dev * child ;
388
+
389
+ list_for_each_entry (child , & linkbus -> devices , bus_list )
390
+ if (PCI_FUNC (child -> devfn ) == 0 )
391
+ return child ;
392
+ return NULL ;
393
+ }
394
+
358
395
static void pcie_aspm_cap_init (struct pcie_link_state * link , int blacklist )
359
396
{
360
397
struct pci_dev * child , * parent = link -> pdev ;
@@ -370,8 +407,9 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
370
407
371
408
/* Get upstream/downstream components' register state */
372
409
pcie_get_aspm_reg (parent , & upreg );
373
- child = list_entry (linkbus -> devices . next , struct pci_dev , bus_list );
410
+ child = pci_function_0 (linkbus );
374
411
pcie_get_aspm_reg (child , & dwreg );
412
+ link -> downstream = child ;
375
413
376
414
/*
377
415
* If ASPM not supported, don't mess with the clocks and link,
@@ -414,6 +452,25 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
414
452
link -> latency_up .l1 = calc_l1_latency (upreg .latency_encoding_l1 );
415
453
link -> latency_dw .l1 = calc_l1_latency (dwreg .latency_encoding_l1 );
416
454
455
+ /* Setup L1 substate */
456
+ if (upreg .l1ss_cap & dwreg .l1ss_cap & PCI_L1SS_CAP_ASPM_L1_1 )
457
+ link -> aspm_support |= ASPM_STATE_L1_1 ;
458
+ if (upreg .l1ss_cap & dwreg .l1ss_cap & PCI_L1SS_CAP_ASPM_L1_2 )
459
+ link -> aspm_support |= ASPM_STATE_L1_2 ;
460
+ if (upreg .l1ss_cap & dwreg .l1ss_cap & PCI_L1SS_CAP_PCIPM_L1_1 )
461
+ link -> aspm_support |= ASPM_STATE_L1_1_PCIPM ;
462
+ if (upreg .l1ss_cap & dwreg .l1ss_cap & PCI_L1SS_CAP_PCIPM_L1_2 )
463
+ link -> aspm_support |= ASPM_STATE_L1_2_PCIPM ;
464
+
465
+ if (upreg .l1ss_ctl1 & dwreg .l1ss_ctl1 & PCI_L1SS_CTL1_ASPM_L1_1 )
466
+ link -> aspm_enabled |= ASPM_STATE_L1_1 ;
467
+ if (upreg .l1ss_ctl1 & dwreg .l1ss_ctl1 & PCI_L1SS_CTL1_ASPM_L1_2 )
468
+ link -> aspm_enabled |= ASPM_STATE_L1_2 ;
469
+ if (upreg .l1ss_ctl1 & dwreg .l1ss_ctl1 & PCI_L1SS_CTL1_PCIPM_L1_1 )
470
+ link -> aspm_enabled |= ASPM_STATE_L1_1_PCIPM ;
471
+ if (upreg .l1ss_ctl1 & dwreg .l1ss_ctl1 & PCI_L1SS_CTL1_PCIPM_L1_2 )
472
+ link -> aspm_enabled |= ASPM_STATE_L1_2_PCIPM ;
473
+
417
474
/* Save default state */
418
475
link -> aspm_default = link -> aspm_enabled ;
419
476
0 commit comments