PCI/ASPM: Remove struct aspm_register_info.l1ss_cap
[linux-2.6-microblaze.git] / drivers / pci / pcie / aspm.c
index 3654087..d76f239 100644 (file)
@@ -77,8 +77,6 @@ struct pcie_link_state {
 
        /* L1 PM Substate info */
        struct {
-               u32 up_cap_ptr;         /* L1SS cap ptr in upstream dev */
-               u32 dw_cap_ptr;         /* L1SS cap ptr in downstream dev */
                u32 ctl1;               /* value to be programmed in ctl1 */
                u32 ctl2;               /* value to be programmed in ctl2 */
        } l1ss;
@@ -308,8 +306,10 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link)
 }
 
 /* Convert L0s latency encoding to ns */
-static u32 calc_l0s_latency(u32 encoding)
+static u32 calc_l0s_latency(u32 lnkcap)
 {
+       u32 encoding = (lnkcap & PCI_EXP_LNKCAP_L0SEL) >> 12;
+
        if (encoding == 0x7)
                return (5 * 1000);      /* > 4us */
        return (64 << encoding);
@@ -324,8 +324,10 @@ static u32 calc_l0s_acceptable(u32 encoding)
 }
 
 /* Convert L1 latency encoding to ns */
-static u32 calc_l1_latency(u32 encoding)
+static u32 calc_l1_latency(u32 lnkcap)
 {
+       u32 encoding = (lnkcap & PCI_EXP_LNKCAP_L1EL) >> 15;
+
        if (encoding == 0x7)
                return (65 * 1000);     /* > 64us */
        return (1000 << encoding);
@@ -380,43 +382,6 @@ static void encode_l12_threshold(u32 threshold_us, u32 *scale, u32 *value)
        }
 }
 
-struct aspm_register_info {
-       u32 latency_encoding_l0s;
-       u32 latency_encoding_l1;
-       /* L1 substates */
-       u32 l1ss_cap_ptr;
-       u32 l1ss_cap;
-       u32 l1ss_ctl1;
-       u32 l1ss_ctl2;
-};
-
-static void pcie_get_aspm_reg(struct pci_dev *pdev,
-                             struct aspm_register_info *info)
-{
-       u32 reg32;
-
-       pcie_capability_read_dword(pdev, PCI_EXP_LNKCAP, &reg32);
-       info->latency_encoding_l0s = (reg32 & PCI_EXP_LNKCAP_L0SEL) >> 12;
-       info->latency_encoding_l1  = (reg32 & PCI_EXP_LNKCAP_L1EL) >> 15;
-
-       /* Read L1 PM substate capabilities */
-       info->l1ss_cap = info->l1ss_ctl1 = info->l1ss_ctl2 = 0;
-       info->l1ss_cap_ptr = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS);
-       if (!info->l1ss_cap_ptr)
-               return;
-       pci_read_config_dword(pdev, info->l1ss_cap_ptr + PCI_L1SS_CAP,
-                             &info->l1ss_cap);
-       if (!(info->l1ss_cap & PCI_L1SS_CAP_L1_PM_SS)) {
-               info->l1ss_cap = 0;
-               return;
-       }
-
-       pci_read_config_dword(pdev, info->l1ss_cap_ptr + PCI_L1SS_CTL1,
-                             &info->l1ss_ctl1);
-       pci_read_config_dword(pdev, info->l1ss_cap_ptr + PCI_L1SS_CTL2,
-                             &info->l1ss_ctl2);
-}
-
 static void pcie_aspm_check_latency(struct pci_dev *endpoint)
 {
        u32 latency, l1_switch_latency = 0;
@@ -491,30 +456,27 @@ static void pci_clear_and_set_dword(struct pci_dev *pdev, int pos,
 
 /* Calculate L1.2 PM substate timing parameters */
 static void aspm_calc_l1ss_info(struct pcie_link_state *link,
-                               struct aspm_register_info *upreg,
-                               struct aspm_register_info *dwreg)
+                               u32 parent_l1ss_cap, u32 child_l1ss_cap)
 {
        struct pci_dev *child = link->downstream, *parent = link->pdev;
        u32 val1, val2, scale1, scale2;
        u32 t_common_mode, t_power_on, l1_2_threshold, scale, value;
 
-       link->l1ss.up_cap_ptr = upreg->l1ss_cap_ptr;
-       link->l1ss.dw_cap_ptr = dwreg->l1ss_cap_ptr;
        link->l1ss.ctl1 = link->l1ss.ctl2 = 0;
 
        if (!(link->aspm_support & ASPM_STATE_L1_2_MASK))
                return;
 
        /* Choose the greater of the two Port Common_Mode_Restore_Times */
-       val1 = (upreg->l1ss_cap & PCI_L1SS_CAP_CM_RESTORE_TIME) >> 8;
-       val2 = (dwreg->l1ss_cap & PCI_L1SS_CAP_CM_RESTORE_TIME) >> 8;
+       val1 = (parent_l1ss_cap & PCI_L1SS_CAP_CM_RESTORE_TIME) >> 8;
+       val2 = (child_l1ss_cap & PCI_L1SS_CAP_CM_RESTORE_TIME) >> 8;
        t_common_mode = max(val1, val2);
 
        /* Choose the greater of the two Port T_POWER_ON times */
-       val1   = (upreg->l1ss_cap & PCI_L1SS_CAP_P_PWR_ON_VALUE) >> 19;
-       scale1 = (upreg->l1ss_cap & PCI_L1SS_CAP_P_PWR_ON_SCALE) >> 16;
-       val2   = (dwreg->l1ss_cap & PCI_L1SS_CAP_P_PWR_ON_VALUE) >> 19;
-       scale2 = (dwreg->l1ss_cap & PCI_L1SS_CAP_P_PWR_ON_SCALE) >> 16;
+       val1   = (parent_l1ss_cap & PCI_L1SS_CAP_P_PWR_ON_VALUE) >> 19;
+       scale1 = (parent_l1ss_cap & PCI_L1SS_CAP_P_PWR_ON_SCALE) >> 16;
+       val2   = (child_l1ss_cap & PCI_L1SS_CAP_P_PWR_ON_VALUE) >> 19;
+       scale2 = (child_l1ss_cap & PCI_L1SS_CAP_P_PWR_ON_SCALE) >> 16;
 
        if (calc_l1ss_pwron(parent, scale1, val1) >
            calc_l1ss_pwron(child, scale2, val2)) {
@@ -545,8 +507,9 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
        struct pci_dev *child = link->downstream, *parent = link->pdev;
        u32 parent_lnkcap, child_lnkcap;
        u16 parent_lnkctl, child_lnkctl;
+       u32 parent_l1ss_cap, child_l1ss_cap;
+       u32 parent_l1ss_ctl1 = 0, child_l1ss_ctl1 = 0;
        struct pci_bus *linkbus = parent->subordinate;
-       struct aspm_register_info upreg, dwreg;
 
        if (blacklist) {
                /* Set enabled/disable so that we will disable ASPM later */
@@ -577,8 +540,6 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
        pcie_capability_read_dword(child, PCI_EXP_LNKCAP, &child_lnkcap);
        pcie_capability_read_word(parent, PCI_EXP_LNKCTL, &parent_lnkctl);
        pcie_capability_read_word(child, PCI_EXP_LNKCTL, &child_lnkctl);
-       pcie_get_aspm_reg(parent, &upreg);
-       pcie_get_aspm_reg(child, &dwreg);
 
        /*
         * Setup L0s state
@@ -594,8 +555,8 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
                link->aspm_enabled |= ASPM_STATE_L0S_UP;
        if (parent_lnkctl & PCI_EXP_LNKCTL_ASPM_L0S)
                link->aspm_enabled |= ASPM_STATE_L0S_DW;
-       link->latency_up.l0s = calc_l0s_latency(upreg.latency_encoding_l0s);
-       link->latency_dw.l0s = calc_l0s_latency(dwreg.latency_encoding_l0s);
+       link->latency_up.l0s = calc_l0s_latency(parent_lnkcap);
+       link->latency_dw.l0s = calc_l0s_latency(child_lnkcap);
 
        /* Setup L1 state */
        if (parent_lnkcap & child_lnkcap & PCI_EXP_LNKCAP_ASPM_L1)
@@ -603,37 +564,55 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
 
        if (parent_lnkctl & child_lnkctl & PCI_EXP_LNKCTL_ASPM_L1)
                link->aspm_enabled |= ASPM_STATE_L1;
-       link->latency_up.l1 = calc_l1_latency(upreg.latency_encoding_l1);
-       link->latency_dw.l1 = calc_l1_latency(dwreg.latency_encoding_l1);
+       link->latency_up.l1 = calc_l1_latency(parent_lnkcap);
+       link->latency_dw.l1 = calc_l1_latency(child_lnkcap);
 
-       /* Setup L1 substate
+       /* Setup L1 substate */
+       pci_read_config_dword(parent, parent->l1ss + PCI_L1SS_CAP,
+                             &parent_l1ss_cap);
+       pci_read_config_dword(child, child->l1ss + PCI_L1SS_CAP,
+                             &child_l1ss_cap);
+
+       if (!(parent_l1ss_cap & PCI_L1SS_CAP_L1_PM_SS))
+               parent_l1ss_cap = 0;
+       if (!(child_l1ss_cap & PCI_L1SS_CAP_L1_PM_SS))
+               child_l1ss_cap = 0;
+
+       /*
         * If we don't have LTR for the entire path from the Root Complex
         * to this device, we can't use ASPM L1.2 because it relies on the
         * LTR_L1.2_THRESHOLD.  See PCIe r4.0, secs 5.5.4, 6.18.
         */
        if (!child->ltr_path)
-               dwreg.l1ss_cap &= ~PCI_L1SS_CAP_ASPM_L1_2;
+               child_l1ss_cap &= ~PCI_L1SS_CAP_ASPM_L1_2;
 
-       if (upreg.l1ss_cap & dwreg.l1ss_cap & PCI_L1SS_CAP_ASPM_L1_1)
+       if (parent_l1ss_cap & child_l1ss_cap & PCI_L1SS_CAP_ASPM_L1_1)
                link->aspm_support |= ASPM_STATE_L1_1;
-       if (upreg.l1ss_cap & dwreg.l1ss_cap & PCI_L1SS_CAP_ASPM_L1_2)
+       if (parent_l1ss_cap & child_l1ss_cap & PCI_L1SS_CAP_ASPM_L1_2)
                link->aspm_support |= ASPM_STATE_L1_2;
-       if (upreg.l1ss_cap & dwreg.l1ss_cap & PCI_L1SS_CAP_PCIPM_L1_1)
+       if (parent_l1ss_cap & child_l1ss_cap & PCI_L1SS_CAP_PCIPM_L1_1)
                link->aspm_support |= ASPM_STATE_L1_1_PCIPM;
-       if (upreg.l1ss_cap & dwreg.l1ss_cap & PCI_L1SS_CAP_PCIPM_L1_2)
+       if (parent_l1ss_cap & child_l1ss_cap & PCI_L1SS_CAP_PCIPM_L1_2)
                link->aspm_support |= ASPM_STATE_L1_2_PCIPM;
 
-       if (upreg.l1ss_ctl1 & dwreg.l1ss_ctl1 & PCI_L1SS_CTL1_ASPM_L1_1)
+       if (parent_l1ss_cap)
+               pci_read_config_dword(parent, parent->l1ss + PCI_L1SS_CTL1,
+                                     &parent_l1ss_ctl1);
+       if (child_l1ss_cap)
+               pci_read_config_dword(child, child->l1ss + PCI_L1SS_CTL1,
+                                     &child_l1ss_ctl1);
+
+       if (parent_l1ss_ctl1 & child_l1ss_ctl1 & PCI_L1SS_CTL1_ASPM_L1_1)
                link->aspm_enabled |= ASPM_STATE_L1_1;
-       if (upreg.l1ss_ctl1 & dwreg.l1ss_ctl1 & PCI_L1SS_CTL1_ASPM_L1_2)
+       if (parent_l1ss_ctl1 & child_l1ss_ctl1 & PCI_L1SS_CTL1_ASPM_L1_2)
                link->aspm_enabled |= ASPM_STATE_L1_2;
-       if (upreg.l1ss_ctl1 & dwreg.l1ss_ctl1 & PCI_L1SS_CTL1_PCIPM_L1_1)
+       if (parent_l1ss_ctl1 & child_l1ss_ctl1 & PCI_L1SS_CTL1_PCIPM_L1_1)
                link->aspm_enabled |= ASPM_STATE_L1_1_PCIPM;
-       if (upreg.l1ss_ctl1 & dwreg.l1ss_ctl1 & PCI_L1SS_CTL1_PCIPM_L1_2)
+       if (parent_l1ss_ctl1 & child_l1ss_ctl1 & PCI_L1SS_CTL1_PCIPM_L1_2)
                link->aspm_enabled |= ASPM_STATE_L1_2_PCIPM;
 
        if (link->aspm_support & ASPM_STATE_L1SS)
-               aspm_calc_l1ss_info(link, &upreg, &dwreg);
+               aspm_calc_l1ss_info(link, parent_l1ss_cap, child_l1ss_cap);
 
        /* Save default state */
        link->aspm_default = link->aspm_enabled;
@@ -668,8 +647,6 @@ static void pcie_config_aspm_l1ss(struct pcie_link_state *link, u32 state)
 {
        u32 val, enable_req;
        struct pci_dev *child = link->downstream, *parent = link->pdev;
-       u32 up_cap_ptr = link->l1ss.up_cap_ptr;
-       u32 dw_cap_ptr = link->l1ss.dw_cap_ptr;
 
        enable_req = (link->aspm_enabled ^ state) & state;
 
@@ -687,9 +664,9 @@ static void pcie_config_aspm_l1ss(struct pcie_link_state *link, u32 state)
         */
 
        /* Disable all L1 substates */
-       pci_clear_and_set_dword(child, dw_cap_ptr + PCI_L1SS_CTL1,
+       pci_clear_and_set_dword(child, child->l1ss + PCI_L1SS_CTL1,
                                PCI_L1SS_CTL1_L1SS_MASK, 0);
-       pci_clear_and_set_dword(parent, up_cap_ptr + PCI_L1SS_CTL1,
+       pci_clear_and_set_dword(parent, parent->l1ss + PCI_L1SS_CTL1,
                                PCI_L1SS_CTL1_L1SS_MASK, 0);
        /*
         * If needed, disable L1, and it gets enabled later
@@ -705,22 +682,22 @@ static void pcie_config_aspm_l1ss(struct pcie_link_state *link, u32 state)
        if (enable_req & ASPM_STATE_L1_2_MASK) {
 
                /* Program T_POWER_ON times in both ports */
-               pci_write_config_dword(parent, up_cap_ptr + PCI_L1SS_CTL2,
+               pci_write_config_dword(parent, parent->l1ss + PCI_L1SS_CTL2,
                                       link->l1ss.ctl2);
-               pci_write_config_dword(child, dw_cap_ptr + PCI_L1SS_CTL2,
+               pci_write_config_dword(child, child->l1ss + PCI_L1SS_CTL2,
                                       link->l1ss.ctl2);
 
                /* Program Common_Mode_Restore_Time in upstream device */
-               pci_clear_and_set_dword(parent, up_cap_ptr + PCI_L1SS_CTL1,
+               pci_clear_and_set_dword(parent, parent->l1ss + PCI_L1SS_CTL1,
                                        PCI_L1SS_CTL1_CM_RESTORE_TIME,
                                        link->l1ss.ctl1);
 
                /* Program LTR_L1.2_THRESHOLD time in both ports */
-               pci_clear_and_set_dword(parent, up_cap_ptr + PCI_L1SS_CTL1,
+               pci_clear_and_set_dword(parent, parent->l1ss + PCI_L1SS_CTL1,
                                        PCI_L1SS_CTL1_LTR_L12_TH_VALUE |
                                        PCI_L1SS_CTL1_LTR_L12_TH_SCALE,
                                        link->l1ss.ctl1);
-               pci_clear_and_set_dword(child, dw_cap_ptr + PCI_L1SS_CTL1,
+               pci_clear_and_set_dword(child, child->l1ss + PCI_L1SS_CTL1,
                                        PCI_L1SS_CTL1_LTR_L12_TH_VALUE |
                                        PCI_L1SS_CTL1_LTR_L12_TH_SCALE,
                                        link->l1ss.ctl1);
@@ -737,9 +714,9 @@ static void pcie_config_aspm_l1ss(struct pcie_link_state *link, u32 state)
                val |= PCI_L1SS_CTL1_PCIPM_L1_2;
 
        /* Enable what we need to enable */
-       pci_clear_and_set_dword(parent, up_cap_ptr + PCI_L1SS_CTL1,
+       pci_clear_and_set_dword(parent, parent->l1ss + PCI_L1SS_CTL1,
                                PCI_L1SS_CTL1_L1SS_MASK, val);
-       pci_clear_and_set_dword(child, dw_cap_ptr + PCI_L1SS_CTL1,
+       pci_clear_and_set_dword(child, child->l1ss + PCI_L1SS_CTL1,
                                PCI_L1SS_CTL1_L1SS_MASK, val);
 }