Lines Matching full:link
3 * Enable PCIe link L0s/L1 state and Clock Power Management
51 struct pci_dev *pdev; /* Upstream component of the Link */
53 struct pcie_link_state *root; /* pointer to the root port link */
54 struct pcie_link_state *parent; /* pointer to the parent Link state */
56 struct list_head children; /* list of child link states */
57 struct list_head link; /* node in parent's children list */ member
119 static int policy_to_aspm_state(struct pcie_link_state *link) in policy_to_aspm_state() argument
132 return link->aspm_default; in policy_to_aspm_state()
137 static int policy_to_clkpm_state(struct pcie_link_state *link) in policy_to_clkpm_state() argument
148 return link->clkpm_default; in policy_to_clkpm_state()
153 static void pcie_set_clkpm_nocheck(struct pcie_link_state *link, int enable) in pcie_set_clkpm_nocheck() argument
156 struct pci_bus *linkbus = link->pdev->subordinate; in pcie_set_clkpm_nocheck()
163 link->clkpm_enabled = !!enable; in pcie_set_clkpm_nocheck()
166 static void pcie_set_clkpm(struct pcie_link_state *link, int enable) in pcie_set_clkpm() argument
169 * Don't enable Clock PM if the link is not Clock PM capable in pcie_set_clkpm()
172 if (!link->clkpm_capable || link->clkpm_disable) in pcie_set_clkpm()
175 if (link->clkpm_enabled == enable) in pcie_set_clkpm()
177 pcie_set_clkpm_nocheck(link, enable); in pcie_set_clkpm()
180 static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist) in pcie_clkpm_cap_init() argument
186 struct pci_bus *linkbus = link->pdev->subordinate; in pcie_clkpm_cap_init()
200 link->clkpm_enabled = enabled; in pcie_clkpm_cap_init()
201 link->clkpm_default = enabled; in pcie_clkpm_cap_init()
202 link->clkpm_capable = capable; in pcie_clkpm_cap_init()
203 link->clkpm_disable = blacklist ? 1 : 0; in pcie_clkpm_cap_init()
206 static bool pcie_retrain_link(struct pcie_link_state *link) in pcie_retrain_link() argument
208 struct pci_dev *parent = link->pdev; in pcie_retrain_link()
217 * Due to an erratum in some devices the Retrain Link bit in pcie_retrain_link()
218 * needs to be cleared again manually to allow the link in pcie_retrain_link()
225 /* Wait for link training end. Break out after waiting for timeout */ in pcie_retrain_link()
239 * pcie_aspm_configure_common_clock: check if the 2 ends of a link
243 static void pcie_aspm_configure_common_clock(struct pcie_link_state *link) in pcie_aspm_configure_common_clock() argument
247 struct pci_dev *child, *parent = link->pdev; in pcie_aspm_configure_common_clock()
304 if (pcie_retrain_link(link)) in pcie_aspm_configure_common_clock()
444 struct pcie_link_state *link; in pcie_aspm_check_latency() local
451 link = endpoint->bus->self->link_state; in pcie_aspm_check_latency()
452 acceptable = &link->acceptable[PCI_FUNC(endpoint->devfn)]; in pcie_aspm_check_latency()
454 while (link) { in pcie_aspm_check_latency()
456 if ((link->aspm_capable & ASPM_STATE_L0S_UP) && in pcie_aspm_check_latency()
457 (link->latency_up.l0s > acceptable->l0s)) in pcie_aspm_check_latency()
458 link->aspm_capable &= ~ASPM_STATE_L0S_UP; in pcie_aspm_check_latency()
461 if ((link->aspm_capable & ASPM_STATE_L0S_DW) && in pcie_aspm_check_latency()
462 (link->latency_dw.l0s > acceptable->l0s)) in pcie_aspm_check_latency()
463 link->aspm_capable &= ~ASPM_STATE_L0S_DW; in pcie_aspm_check_latency()
477 latency = max_t(u32, link->latency_up.l1, link->latency_dw.l1); in pcie_aspm_check_latency()
478 if ((link->aspm_capable & ASPM_STATE_L1) && in pcie_aspm_check_latency()
480 link->aspm_capable &= ~ASPM_STATE_L1; in pcie_aspm_check_latency()
483 link = link->parent; in pcie_aspm_check_latency()
502 static void aspm_calc_l1ss_info(struct pcie_link_state *link, in aspm_calc_l1ss_info() argument
509 link->l1ss.up_cap_ptr = upreg->l1ss_cap_ptr; in aspm_calc_l1ss_info()
510 link->l1ss.dw_cap_ptr = dwreg->l1ss_cap_ptr; in aspm_calc_l1ss_info()
511 link->l1ss.ctl1 = link->l1ss.ctl2 = 0; in aspm_calc_l1ss_info()
513 if (!(link->aspm_support & ASPM_STATE_L1_2_MASK)) in aspm_calc_l1ss_info()
527 if (calc_l1ss_pwron(link->pdev, scale1, val1) > in aspm_calc_l1ss_info()
528 calc_l1ss_pwron(link->downstream, scale2, val2)) { in aspm_calc_l1ss_info()
529 link->l1ss.ctl2 |= scale1 | (val1 << 3); in aspm_calc_l1ss_info()
530 t_power_on = calc_l1ss_pwron(link->pdev, scale1, val1); in aspm_calc_l1ss_info()
532 link->l1ss.ctl2 |= scale2 | (val2 << 3); in aspm_calc_l1ss_info()
533 t_power_on = calc_l1ss_pwron(link->downstream, scale2, val2); in aspm_calc_l1ss_info()
538 * Link from L0 to L1.2 and back to L0 so we enter L1.2 only if in aspm_calc_l1ss_info()
548 link->l1ss.ctl1 |= t_common_mode << 8 | scale << 29 | value << 16; in aspm_calc_l1ss_info()
551 static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist) in pcie_aspm_cap_init() argument
553 struct pci_dev *child = link->downstream, *parent = link->pdev; in pcie_aspm_cap_init()
559 link->aspm_enabled = ASPM_STATE_ALL; in pcie_aspm_cap_init()
560 link->aspm_disable = ASPM_STATE_ALL; in pcie_aspm_cap_init()
569 * If ASPM not supported, don't mess with the clocks and link, in pcie_aspm_cap_init()
576 pcie_aspm_configure_common_clock(link); in pcie_aspm_cap_init()
589 * given link unless components on both sides of the link each in pcie_aspm_cap_init()
593 link->aspm_support |= ASPM_STATE_L0S; in pcie_aspm_cap_init()
595 link->aspm_enabled |= ASPM_STATE_L0S_UP; in pcie_aspm_cap_init()
597 link->aspm_enabled |= ASPM_STATE_L0S_DW; in pcie_aspm_cap_init()
598 link->latency_up.l0s = calc_l0s_latency(upreg.latency_encoding_l0s); in pcie_aspm_cap_init()
599 link->latency_dw.l0s = calc_l0s_latency(dwreg.latency_encoding_l0s); in pcie_aspm_cap_init()
603 link->aspm_support |= ASPM_STATE_L1; in pcie_aspm_cap_init()
605 link->aspm_enabled |= ASPM_STATE_L1; in pcie_aspm_cap_init()
606 link->latency_up.l1 = calc_l1_latency(upreg.latency_encoding_l1); in pcie_aspm_cap_init()
607 link->latency_dw.l1 = calc_l1_latency(dwreg.latency_encoding_l1); in pcie_aspm_cap_init()
611 link->aspm_support |= ASPM_STATE_L1_1; in pcie_aspm_cap_init()
613 link->aspm_support |= ASPM_STATE_L1_2; in pcie_aspm_cap_init()
615 link->aspm_support |= ASPM_STATE_L1_1_PCIPM; in pcie_aspm_cap_init()
617 link->aspm_support |= ASPM_STATE_L1_2_PCIPM; in pcie_aspm_cap_init()
620 link->aspm_enabled |= ASPM_STATE_L1_1; in pcie_aspm_cap_init()
622 link->aspm_enabled |= ASPM_STATE_L1_2; in pcie_aspm_cap_init()
624 link->aspm_enabled |= ASPM_STATE_L1_1_PCIPM; in pcie_aspm_cap_init()
626 link->aspm_enabled |= ASPM_STATE_L1_2_PCIPM; in pcie_aspm_cap_init()
628 if (link->aspm_support & ASPM_STATE_L1SS) in pcie_aspm_cap_init()
629 aspm_calc_l1ss_info(link, &upreg, &dwreg); in pcie_aspm_cap_init()
632 link->aspm_default = link->aspm_enabled; in pcie_aspm_cap_init()
635 link->aspm_capable = link->aspm_support; in pcie_aspm_cap_init()
641 &link->acceptable[PCI_FUNC(child->devfn)]; in pcie_aspm_cap_init()
671 static void pcie_config_aspm_l1ss(struct pcie_link_state *link, u32 state) in pcie_config_aspm_l1ss() argument
674 struct pci_dev *child = link->downstream, *parent = link->pdev; in pcie_config_aspm_l1ss()
675 u32 up_cap_ptr = link->l1ss.up_cap_ptr; in pcie_config_aspm_l1ss()
676 u32 dw_cap_ptr = link->l1ss.dw_cap_ptr; in pcie_config_aspm_l1ss()
678 enable_req = (link->aspm_enabled ^ state) & state; in pcie_config_aspm_l1ss()
713 link->l1ss.ctl2); in pcie_config_aspm_l1ss()
715 link->l1ss.ctl2); in pcie_config_aspm_l1ss()
720 link->l1ss.ctl1); in pcie_config_aspm_l1ss()
726 link->l1ss.ctl1); in pcie_config_aspm_l1ss()
730 link->l1ss.ctl1); in pcie_config_aspm_l1ss()
756 static void pcie_config_aspm_link(struct pcie_link_state *link, u32 state) in pcie_config_aspm_link() argument
759 struct pci_dev *child = link->downstream, *parent = link->pdev; in pcie_config_aspm_link()
763 state &= (link->aspm_capable & ~link->aspm_disable); in pcie_config_aspm_link()
772 state |= (link->aspm_enabled & ASPM_STATE_L1_SS_PCIPM); in pcie_config_aspm_link()
775 /* Nothing to do if the link is already in the requested state */ in pcie_config_aspm_link()
776 if (link->aspm_enabled == state) in pcie_config_aspm_link()
788 if (link->aspm_capable & ASPM_STATE_L1SS) in pcie_config_aspm_link()
789 pcie_config_aspm_l1ss(link, state); in pcie_config_aspm_link()
804 link->aspm_enabled = state; in pcie_config_aspm_link()
807 static void pcie_config_aspm_path(struct pcie_link_state *link) in pcie_config_aspm_path() argument
809 while (link) { in pcie_config_aspm_path()
810 pcie_config_aspm_link(link, policy_to_aspm_state(link)); in pcie_config_aspm_path()
811 link = link->parent; in pcie_config_aspm_path()
815 static void free_link_state(struct pcie_link_state *link) in free_link_state() argument
817 link->pdev->link_state = NULL; in free_link_state()
818 kfree(link); in free_link_state()
858 struct pcie_link_state *link; in alloc_pcie_link_state() local
860 link = kzalloc(sizeof(*link), GFP_KERNEL); in alloc_pcie_link_state()
861 if (!link) in alloc_pcie_link_state()
864 INIT_LIST_HEAD(&link->sibling); in alloc_pcie_link_state()
865 INIT_LIST_HEAD(&link->children); in alloc_pcie_link_state()
866 INIT_LIST_HEAD(&link->link); in alloc_pcie_link_state()
867 link->pdev = pdev; in alloc_pcie_link_state()
868 link->downstream = pci_function_0(pdev->subordinate); in alloc_pcie_link_state()
874 * a switch may become the root of the link state chain for all in alloc_pcie_link_state()
880 link->root = link; in alloc_pcie_link_state()
886 kfree(link); in alloc_pcie_link_state()
890 link->parent = parent; in alloc_pcie_link_state()
891 link->root = link->parent->root; in alloc_pcie_link_state()
892 list_add(&link->link, &parent->children); in alloc_pcie_link_state()
895 list_add(&link->sibling, &link_list); in alloc_pcie_link_state()
896 pdev->link_state = link; in alloc_pcie_link_state()
897 return link; in alloc_pcie_link_state()
901 * pcie_aspm_init_link_state: Initiate PCI express link state.
907 struct pcie_link_state *link; in pcie_aspm_init_link_state() local
918 * end of a Link, so there's nothing to do unless this device has a in pcie_aspm_init_link_state()
919 * Link on its secondary side. in pcie_aspm_init_link_state()
934 link = alloc_pcie_link_state(pdev); in pcie_aspm_init_link_state()
935 if (!link) in pcie_aspm_init_link_state()
942 pcie_aspm_cap_init(link, blacklist); in pcie_aspm_init_link_state()
945 pcie_clkpm_cap_init(link, blacklist); in pcie_aspm_init_link_state()
949 * link policy setting. Enabling ASPM on broken hardware can cripple in pcie_aspm_init_link_state()
957 pcie_config_aspm_path(link); in pcie_aspm_init_link_state()
958 pcie_set_clkpm(link, policy_to_clkpm_state(link)); in pcie_aspm_init_link_state()
970 struct pcie_link_state *link; in pcie_update_aspm_capable() local
972 list_for_each_entry(link, &link_list, sibling) { in pcie_update_aspm_capable()
973 if (link->root != root) in pcie_update_aspm_capable()
975 link->aspm_capable = link->aspm_support; in pcie_update_aspm_capable()
977 list_for_each_entry(link, &link_list, sibling) { in pcie_update_aspm_capable()
979 struct pci_bus *linkbus = link->pdev->subordinate; in pcie_update_aspm_capable()
980 if (link->root != root) in pcie_update_aspm_capable()
995 struct pcie_link_state *link, *root, *parent_link; in pcie_aspm_exit_link_state() local
1009 link = parent->link_state; in pcie_aspm_exit_link_state()
1010 root = link->root; in pcie_aspm_exit_link_state()
1011 parent_link = link->parent; in pcie_aspm_exit_link_state()
1013 /* All functions are removed, so just disable ASPM for the link */ in pcie_aspm_exit_link_state()
1014 pcie_config_aspm_link(link, 0); in pcie_aspm_exit_link_state()
1015 list_del(&link->sibling); in pcie_aspm_exit_link_state()
1016 list_del(&link->link); in pcie_aspm_exit_link_state()
1018 free_link_state(link); in pcie_aspm_exit_link_state()
1033 struct pcie_link_state *link = pdev->link_state; in pcie_aspm_pm_state_change() local
1035 if (aspm_disabled || !link) in pcie_aspm_pm_state_change()
1043 pcie_update_aspm_capable(link->root); in pcie_aspm_pm_state_change()
1044 pcie_config_aspm_path(link); in pcie_aspm_pm_state_change()
1051 struct pcie_link_state *link = pdev->link_state; in pcie_aspm_powersave_config_link() local
1053 if (aspm_disabled || !link) in pcie_aspm_powersave_config_link()
1062 pcie_config_aspm_path(link); in pcie_aspm_powersave_config_link()
1063 pcie_set_clkpm(link, policy_to_clkpm_state(link)); in pcie_aspm_powersave_config_link()
1071 struct pcie_link_state *link; in __pci_disable_link_state() local
1097 link = parent->link_state; in __pci_disable_link_state()
1099 link->aspm_disable |= ASPM_STATE_L0S; in __pci_disable_link_state()
1101 link->aspm_disable |= ASPM_STATE_L1; in __pci_disable_link_state()
1102 pcie_config_aspm_link(link, policy_to_aspm_state(link)); in __pci_disable_link_state()
1105 link->clkpm_disable = 1; in __pci_disable_link_state()
1106 pcie_set_clkpm(link, policy_to_clkpm_state(link)); in __pci_disable_link_state()
1119 * pci_disable_link_state - Disable device's link state, so the link will
1125 * @state: ASPM link state to disable
1137 struct pcie_link_state *link; in pcie_aspm_set_policy() local
1150 list_for_each_entry(link, &link_list, sibling) { in pcie_aspm_set_policy()
1151 pcie_config_aspm_link(link, policy_to_aspm_state(link)); in pcie_aspm_set_policy()
1152 pcie_set_clkpm(link, policy_to_clkpm_state(link)); in pcie_aspm_set_policy()
1191 struct pcie_link_state *link, *root = pdev->link_state->root; in link_state_store() local
1204 list_for_each_entry(link, &link_list, sibling) { in link_state_store()
1205 if (link->root != root) in link_state_store()
1207 pcie_config_aspm_link(link, state); in link_state_store()