Commit 4cfd5afc authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull PCI fixes from Bjorn Helgaas:

 - Move to a shared PCI git tree (Bjorn Helgaas)

 - Add Krzysztof Wilczyński as another PCI maintainer (Lorenzo
   Pieralisi)

 - Revert a couple ASPM patches to fix suspend/resume regressions (Bjorn
   Helgaas)

* tag 'pci-v6.2-fixes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci:
  Revert "PCI/ASPM: Refactor L1 PM Substates Control Register programming"
  Revert "PCI/ASPM: Save L1 PM Substates Capability for suspend/resume"
  MAINTAINERS: Promote Krzysztof to PCI controller maintainer
  MAINTAINERS: Move to shared PCI tree
parents 4f72a263 ff209ecc
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -16120,7 +16120,7 @@ F: drivers/pci/controller/pci-v3-semi.c
PCI ENDPOINT SUBSYSTEM
M:	Lorenzo Pieralisi <lpieralisi@kernel.org>
R:	Krzysztof Wilczyński <kw@linux.com>
M:	Krzysztof Wilczyński <kw@linux.com>
R:	Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
R:	Kishon Vijay Abraham I <kishon@kernel.org>
L:	linux-pci@vger.kernel.org
@@ -16128,7 +16128,7 @@ S: Supported
Q:	https://patchwork.kernel.org/project/linux-pci/list/
B:	https://bugzilla.kernel.org
C:	irc://irc.oftc.net/linux-pci
T:	git git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/pci.git
T:	git git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git
F:	Documentation/PCI/endpoint/*
F:	Documentation/misc-devices/pci-endpoint-test.rst
F:	drivers/misc/pci_endpoint_test.c
@@ -16163,7 +16163,7 @@ S: Supported
Q:	https://patchwork.kernel.org/project/linux-pci/list/
B:	https://bugzilla.kernel.org
C:	irc://irc.oftc.net/linux-pci
T:	git git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git
T:	git git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git
F:	Documentation/driver-api/pci/p2pdma.rst
F:	drivers/pci/p2pdma.c
F:	include/linux/pci-p2pdma.h
@@ -16185,14 +16185,14 @@ F: drivers/pci/controller/pci-xgene-msi.c
PCI NATIVE HOST BRIDGE AND ENDPOINT DRIVERS
M:	Lorenzo Pieralisi <lpieralisi@kernel.org>
M:	Krzysztof Wilczyński <kw@linux.com>
R:	Rob Herring <robh@kernel.org>
R:	Krzysztof Wilczyński <kw@linux.com>
L:	linux-pci@vger.kernel.org
S:	Supported
Q:	https://patchwork.kernel.org/project/linux-pci/list/
B:	https://bugzilla.kernel.org
C:	irc://irc.oftc.net/linux-pci
T:	git git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/pci.git
T:	git git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git
F:	Documentation/devicetree/bindings/pci/
F:	drivers/pci/controller/
F:	drivers/pci/pci-bridge-emul.c
@@ -16205,7 +16205,7 @@ S: Supported
Q:	https://patchwork.kernel.org/project/linux-pci/list/
B:	https://bugzilla.kernel.org
C:	irc://irc.oftc.net/linux-pci
T:	git git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git
T:	git git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git
F:	Documentation/PCI/
F:	Documentation/devicetree/bindings/pci/
F:	arch/x86/kernel/early-quirks.c
+0 −7
Original line number Diff line number Diff line
@@ -1665,7 +1665,6 @@ int pci_save_state(struct pci_dev *dev)
		return i;

	pci_save_ltr_state(dev);
	pci_save_aspm_l1ss_state(dev);
	pci_save_dpc_state(dev);
	pci_save_aer_state(dev);
	pci_save_ptm_state(dev);
@@ -1772,7 +1771,6 @@ void pci_restore_state(struct pci_dev *dev)
	 * LTR itself (in the PCIe capability).
	 */
	pci_restore_ltr_state(dev);
	pci_restore_aspm_l1ss_state(dev);

	pci_restore_pcie_state(dev);
	pci_restore_pasid_state(dev);
@@ -3465,11 +3463,6 @@ void pci_allocate_cap_save_buffers(struct pci_dev *dev)
	if (error)
		pci_err(dev, "unable to allocate suspend buffer for LTR\n");

	error = pci_add_ext_cap_save_buffer(dev, PCI_EXT_CAP_ID_L1SS,
					    2 * sizeof(u32));
	if (error)
		pci_err(dev, "unable to allocate suspend buffer for ASPM-L1SS\n");

	pci_allocate_vc_save_buffers(dev);
}

+0 −4
Original line number Diff line number Diff line
@@ -566,14 +566,10 @@ bool pcie_wait_for_link(struct pci_dev *pdev, bool active);
void pcie_aspm_init_link_state(struct pci_dev *pdev);
void pcie_aspm_exit_link_state(struct pci_dev *pdev);
void pcie_aspm_powersave_config_link(struct pci_dev *pdev);
void pci_save_aspm_l1ss_state(struct pci_dev *dev);
void pci_restore_aspm_l1ss_state(struct pci_dev *dev);
#else
static inline void pcie_aspm_init_link_state(struct pci_dev *pdev) { }
static inline void pcie_aspm_exit_link_state(struct pci_dev *pdev) { }
static inline void pcie_aspm_powersave_config_link(struct pci_dev *pdev) { }
static inline void pci_save_aspm_l1ss_state(struct pci_dev *dev) { }
static inline void pci_restore_aspm_l1ss_state(struct pci_dev *dev) { }
#endif

#ifdef CONFIG_PCIE_ECRC
+34 −77
Original line number Diff line number Diff line
@@ -470,31 +470,6 @@ static void pci_clear_and_set_dword(struct pci_dev *pdev, int pos,
	pci_write_config_dword(pdev, pos, val);
}

static void aspm_program_l1ss(struct pci_dev *dev, u32 ctl1, u32 ctl2)
{
	u16 l1ss = dev->l1ss;
	u32 l1_2_enable;

	/*
	 * Per PCIe r6.0, sec 5.5.4, T_POWER_ON in PCI_L1SS_CTL2 must be
	 * programmed prior to setting the L1.2 enable bits in PCI_L1SS_CTL1.
	 */
	pci_write_config_dword(dev, l1ss + PCI_L1SS_CTL2, ctl2);

	/*
	 * In addition, Common_Mode_Restore_Time and LTR_L1.2_THRESHOLD in
	 * PCI_L1SS_CTL1 must be programmed *before* setting the L1.2
	 * enable bits, even though they're all in PCI_L1SS_CTL1.
	 */
	l1_2_enable = ctl1 & PCI_L1SS_CTL1_L1_2_MASK;
	ctl1 &= ~PCI_L1SS_CTL1_L1_2_MASK;

	pci_write_config_dword(dev, l1ss + PCI_L1SS_CTL1, ctl1);
	if (l1_2_enable)
		pci_write_config_dword(dev, l1ss + PCI_L1SS_CTL1,
				       ctl1 | l1_2_enable);
}

/* Calculate L1.2 PM substate timing parameters */
static void aspm_calc_l1ss_info(struct pcie_link_state *link,
				u32 parent_l1ss_cap, u32 child_l1ss_cap)
@@ -504,6 +479,7 @@ static void aspm_calc_l1ss_info(struct pcie_link_state *link,
	u32 t_common_mode, t_power_on, l1_2_threshold, scale, value;
	u32 ctl1 = 0, ctl2 = 0;
	u32 pctl1, pctl2, cctl1, cctl2;
	u32 pl1_2_enables, cl1_2_enables;

	if (!(link->aspm_support & ASPM_STATE_L1_2_MASK))
		return;
@@ -552,21 +528,39 @@ static void aspm_calc_l1ss_info(struct pcie_link_state *link,
	    ctl2 == pctl2 && ctl2 == cctl2)
		return;

	pctl1 &= ~(PCI_L1SS_CTL1_CM_RESTORE_TIME |
		   PCI_L1SS_CTL1_LTR_L12_TH_VALUE |
		   PCI_L1SS_CTL1_LTR_L12_TH_SCALE);
	pctl1 |= (ctl1 & (PCI_L1SS_CTL1_CM_RESTORE_TIME |
			  PCI_L1SS_CTL1_LTR_L12_TH_VALUE |
			  PCI_L1SS_CTL1_LTR_L12_TH_SCALE));
	aspm_program_l1ss(parent, pctl1, ctl2);
	/* Disable L1.2 while updating.  See PCIe r5.0, sec 5.5.4, 7.8.3.3 */
	pl1_2_enables = pctl1 & PCI_L1SS_CTL1_L1_2_MASK;
	cl1_2_enables = cctl1 & PCI_L1SS_CTL1_L1_2_MASK;

	if (pl1_2_enables || cl1_2_enables) {
		pci_clear_and_set_dword(child, child->l1ss + PCI_L1SS_CTL1,
					PCI_L1SS_CTL1_L1_2_MASK, 0);
		pci_clear_and_set_dword(parent, parent->l1ss + PCI_L1SS_CTL1,
					PCI_L1SS_CTL1_L1_2_MASK, 0);
	}

	/* Program T_POWER_ON times in both ports */
	pci_write_config_dword(parent, parent->l1ss + PCI_L1SS_CTL2, ctl2);
	pci_write_config_dword(child, child->l1ss + PCI_L1SS_CTL2, ctl2);

	cctl1 &= ~(PCI_L1SS_CTL1_CM_RESTORE_TIME |
	/* Program Common_Mode_Restore_Time in upstream device */
	pci_clear_and_set_dword(parent, parent->l1ss + PCI_L1SS_CTL1,
				PCI_L1SS_CTL1_CM_RESTORE_TIME, ctl1);

	/* Program LTR_L1.2_THRESHOLD time in both ports */
	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);
	cctl1 |= (ctl1 & (PCI_L1SS_CTL1_CM_RESTORE_TIME |
				PCI_L1SS_CTL1_LTR_L12_TH_SCALE, 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));
	aspm_program_l1ss(child, cctl1, ctl2);
				PCI_L1SS_CTL1_LTR_L12_TH_SCALE, ctl1);

	if (pl1_2_enables || cl1_2_enables) {
		pci_clear_and_set_dword(parent, parent->l1ss + PCI_L1SS_CTL1, 0,
					pl1_2_enables);
		pci_clear_and_set_dword(child, child->l1ss + PCI_L1SS_CTL1, 0,
					cl1_2_enables);
	}
}

static void aspm_l1ss_init(struct pcie_link_state *link)
@@ -757,43 +751,6 @@ static void pcie_config_aspm_l1ss(struct pcie_link_state *link, u32 state)
				PCI_L1SS_CTL1_L1SS_MASK, val);
}

void pci_save_aspm_l1ss_state(struct pci_dev *dev)
{
	struct pci_cap_saved_state *save_state;
	u16 l1ss = dev->l1ss;
	u32 *cap;

	if (!l1ss)
		return;

	save_state = pci_find_saved_ext_cap(dev, PCI_EXT_CAP_ID_L1SS);
	if (!save_state)
		return;

	cap = (u32 *)&save_state->cap.data[0];
	pci_read_config_dword(dev, l1ss + PCI_L1SS_CTL2, cap++);
	pci_read_config_dword(dev, l1ss + PCI_L1SS_CTL1, cap++);
}

void pci_restore_aspm_l1ss_state(struct pci_dev *dev)
{
	struct pci_cap_saved_state *save_state;
	u32 *cap, ctl1, ctl2;
	u16 l1ss = dev->l1ss;

	if (!l1ss)
		return;

	save_state = pci_find_saved_ext_cap(dev, PCI_EXT_CAP_ID_L1SS);
	if (!save_state)
		return;

	cap = (u32 *)&save_state->cap.data[0];
	ctl2 = *cap++;
	ctl1 = *cap;
	aspm_program_l1ss(dev, ctl1, ctl2);
}

static void pcie_config_aspm_dev(struct pci_dev *pdev, u32 val)
{
	pcie_capability_clear_and_set_word(pdev, PCI_EXP_LNKCTL,