[kernel/f19] Add radeon fixes for PCI-e gen2 speed issues (rhbz 961527)

Josh Boyer jwboyer at fedoraproject.org
Mon May 13 14:14:58 UTC 2013


commit 59f427f918687883b08adf670adc0e841e0db30d
Author: Josh Boyer <jwboyer at redhat.com>
Date:   Mon May 13 10:11:10 2013 -0400

    Add radeon fixes for PCI-e gen2 speed issues (rhbz 961527)

 kernel.spec                                        |   13 ++-
 ...ries-Perform-proper-max_bus_speed-detecti.patch |  153 ++++++++++++++++++++
 ...use-max_bus-speed-to-activate-gen2-speeds.patch |   99 +++++++++++++
 3 files changed, 264 insertions(+), 1 deletions(-)
---
diff --git a/kernel.spec b/kernel.spec
index bf5a42d..7bf6d28 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -62,7 +62,7 @@ Summary: The Linux kernel
 # For non-released -rc kernels, this will be appended after the rcX and
 # gitX tags, so a 3 here would become part of release "0.rcX.gitX.3"
 #
-%global baserelease 301
+%global baserelease 302
 %global fedora_build %{baserelease}
 
 # base_sublevel is the kernel version we're starting with and patching
@@ -749,6 +749,10 @@ Patch23008: forcedeth-dma-error-check.patch
 Patch25018: pci-Set-dev-dev.type-in-alloc_pci_dev.patch
 Patch25019: powerpc-Set-default-VGA-device.patch
 
+#rhbz 961527
+Patch25020: powerpc-pseries-Perform-proper-max_bus_speed-detecti.patch
+Patch25021: radeon-use-max_bus-speed-to-activate-gen2-speeds.patch
+
 # END OF PATCH DEFINITIONS
 
 %endif
@@ -1447,6 +1451,10 @@ ApplyPatch forcedeth-dma-error-check.patch
 ApplyPatch pci-Set-dev-dev.type-in-alloc_pci_dev.patch
 ApplyPatch powerpc-Set-default-VGA-device.patch
 
+#rhbz 961527
+ApplyPatch powerpc-pseries-Perform-proper-max_bus_speed-detecti.patch
+ApplyPatch radeon-use-max_bus-speed-to-activate-gen2-speeds.patch
+
 # END OF PATCH APPLICATIONS
 
 %endif
@@ -2274,6 +2282,9 @@ fi
 # and build.
 
 %changelog
+* Mon May 13 2013 Josh Boyer <jwboyer at redhat.com>
+- Add radeon fixes for PCI-e gen2 speed issues (rhbz 961527)
+
 * Mon May 13 2013 Josh Boyer <jwboyer at redhat.com> - 3.9.2-301
 - Linux v3.9.2
 
diff --git a/powerpc-pseries-Perform-proper-max_bus_speed-detecti.patch b/powerpc-pseries-Perform-proper-max_bus_speed-detecti.patch
new file mode 100644
index 0000000..5701a87
--- /dev/null
+++ b/powerpc-pseries-Perform-proper-max_bus_speed-detecti.patch
@@ -0,0 +1,153 @@
+From d82fb31abc46620b7c22758c75707069f2763646 Mon Sep 17 00:00:00 2001
+From: Kleber Sacilotto de Souza <klebers at linux.vnet.ibm.com>
+Date: Fri, 3 May 2013 12:43:12 +0000
+Subject: [PATCH] powerpc/pseries: Perform proper max_bus_speed detection
+
+On pseries machines the detection for max_bus_speed should be done
+through an OpenFirmware property. This patch adds a function to perform
+this detection and a hook to perform dynamic adding of the function only
+for pseries. This is done by overwriting the weak
+pcibios_root_bridge_prepare function which is called by
+pci_create_root_bus().
+
+From: Lucas Kannebley Tavares <lucaskt at linux.vnet.ibm.com>
+Signed-off-by: Kleber Sacilotto de Souza <klebers at linux.vnet.ibm.com>
+Signed-off-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>
+---
+ arch/powerpc/include/asm/machdep.h       |  3 ++
+ arch/powerpc/kernel/pci-common.c         |  8 +++++
+ arch/powerpc/platforms/pseries/pci.c     | 53 ++++++++++++++++++++++++++++++++
+ arch/powerpc/platforms/pseries/pseries.h |  4 +++
+ arch/powerpc/platforms/pseries/setup.c   |  2 ++
+ 5 files changed, 70 insertions(+)
+
+diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
+index 3f3f691..92386fc 100644
+--- a/arch/powerpc/include/asm/machdep.h
++++ b/arch/powerpc/include/asm/machdep.h
+@@ -29,6 +29,7 @@ struct rtc_time;
+ struct file;
+ struct pci_controller;
+ struct kimage;
++struct pci_host_bridge;
+ 
+ struct machdep_calls {
+ 	char		*name;
+@@ -108,6 +109,8 @@ struct machdep_calls {
+ 	void		(*pcibios_fixup)(void);
+ 	int		(*pci_probe_mode)(struct pci_bus *);
+ 	void		(*pci_irq_fixup)(struct pci_dev *dev);
++	int		(*pcibios_root_bridge_prepare)(struct pci_host_bridge
++				*bridge);
+ 
+ 	/* To setup PHBs when using automatic OF platform driver for PCI */
+ 	int		(*pci_setup_phb)(struct pci_controller *host);
+diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
+index f325dc9..d5811d8 100644
+--- a/arch/powerpc/kernel/pci-common.c
++++ b/arch/powerpc/kernel/pci-common.c
+@@ -845,6 +845,14 @@ int pci_proc_domain(struct pci_bus *bus)
+ 	return 1;
+ }
+ 
++int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
++{
++	if (ppc_md.pcibios_root_bridge_prepare)
++		return ppc_md.pcibios_root_bridge_prepare(bridge);
++
++	return 0;
++}
++
+ /* This header fixup will do the resource fixup for all devices as they are
+  * probed, but not for bridge ranges
+  */
+diff --git a/arch/powerpc/platforms/pseries/pci.c b/arch/powerpc/platforms/pseries/pci.c
+index 0b580f4..5f93856 100644
+--- a/arch/powerpc/platforms/pseries/pci.c
++++ b/arch/powerpc/platforms/pseries/pci.c
+@@ -108,3 +108,56 @@ static void fixup_winbond_82c105(struct pci_dev* dev)
+ }
+ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105,
+ 			 fixup_winbond_82c105);
++
++int pseries_root_bridge_prepare(struct pci_host_bridge *bridge)
++{
++	struct device_node *dn, *pdn;
++	struct pci_bus *bus;
++	const uint32_t *pcie_link_speed_stats;
++
++	bus = bridge->bus;
++
++	dn = pcibios_get_phb_of_node(bus);
++	if (!dn)
++		return 0;
++
++	for (pdn = dn; pdn != NULL; pdn = of_get_next_parent(pdn)) {
++		pcie_link_speed_stats = (const uint32_t *) of_get_property(pdn,
++			"ibm,pcie-link-speed-stats", NULL);
++		if (pcie_link_speed_stats)
++			break;
++	}
++
++	of_node_put(pdn);
++
++	if (!pcie_link_speed_stats) {
++		pr_err("no ibm,pcie-link-speed-stats property\n");
++		return 0;
++	}
++
++	switch (pcie_link_speed_stats[0]) {
++	case 0x01:
++		bus->max_bus_speed = PCIE_SPEED_2_5GT;
++		break;
++	case 0x02:
++		bus->max_bus_speed = PCIE_SPEED_5_0GT;
++		break;
++	default:
++		bus->max_bus_speed = PCI_SPEED_UNKNOWN;
++		break;
++	}
++
++	switch (pcie_link_speed_stats[1]) {
++	case 0x01:
++		bus->cur_bus_speed = PCIE_SPEED_2_5GT;
++		break;
++	case 0x02:
++		bus->cur_bus_speed = PCIE_SPEED_5_0GT;
++		break;
++	default:
++		bus->cur_bus_speed = PCI_SPEED_UNKNOWN;
++		break;
++	}
++
++	return 0;
++}
+diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h
+index 8af71e4..c2a3a25 100644
+--- a/arch/powerpc/platforms/pseries/pseries.h
++++ b/arch/powerpc/platforms/pseries/pseries.h
+@@ -63,4 +63,8 @@ extern int dlpar_detach_node(struct device_node *);
+ /* Snooze Delay, pseries_idle */
+ DECLARE_PER_CPU(long, smt_snooze_delay);
+ 
++/* PCI root bridge prepare function override for pseries */
++struct pci_host_bridge;
++int pseries_root_bridge_prepare(struct pci_host_bridge *bridge);
++
+ #endif /* _PSERIES_PSERIES_H */
+diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
+index ac932a9..c11c823 100644
+--- a/arch/powerpc/platforms/pseries/setup.c
++++ b/arch/powerpc/platforms/pseries/setup.c
+@@ -466,6 +466,8 @@ static void __init pSeries_setup_arch(void)
+ 	else
+ 		ppc_md.enable_pmcs = power4_enable_pmcs;
+ 
++	ppc_md.pcibios_root_bridge_prepare = pseries_root_bridge_prepare;
++
+ 	if (firmware_has_feature(FW_FEATURE_SET_MODE)) {
+ 		long rc;
+ 		if ((rc = pSeries_enable_reloc_on_exc()) != H_SUCCESS) {
+-- 
+1.8.1.4
+
diff --git a/radeon-use-max_bus-speed-to-activate-gen2-speeds.patch b/radeon-use-max_bus-speed-to-activate-gen2-speeds.patch
new file mode 100644
index 0000000..f9a1199
--- /dev/null
+++ b/radeon-use-max_bus-speed-to-activate-gen2-speeds.patch
@@ -0,0 +1,99 @@
+radeon: use max_bus_speed to activate gen2 speeds
+
+radeon currently uses a drm function to get the speed capabilities for
+the bus, drm_pcie_get_speed_cap_mask. However, this is a non-standard
+method of performing this detection and this patch changes it to use
+the max_bus_speed attribute.
+
+From: Lucas Kannebley Tavares <lucaskt at linux.vnet.ibm.com>
+Signed-off-by: Kleber Sacilotto de Souza <klebers at linux.vnet.ibm.com>
+---
+ drivers/gpu/drm/radeon/evergreen.c |   10 +++-------
+ drivers/gpu/drm/radeon/r600.c      |    9 ++-------
+ drivers/gpu/drm/radeon/rv770.c     |    9 ++-------
+ 3 files changed, 7 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
+index 105bafb..3966696 100644
+--- a/drivers/gpu/drm/radeon/evergreen.c
++++ b/drivers/gpu/drm/radeon/evergreen.c
+@@ -4992,8 +4992,7 @@ void evergreen_fini(struct radeon_device *rdev)
+ 
+ void evergreen_pcie_gen2_enable(struct radeon_device *rdev)
+ {
+-	u32 link_width_cntl, speed_cntl, mask;
+-	int ret;
++	u32 link_width_cntl, speed_cntl;
+ 
+ 	if (radeon_pcie_gen2 == 0)
+ 		return;
+@@ -5008,11 +5007,8 @@ void evergreen_pcie_gen2_enable(struct radeon_device *rdev)
+ 	if (ASIC_IS_X2(rdev))
+ 		return;
+ 
+-	ret = drm_pcie_get_speed_cap_mask(rdev->ddev, &mask);
+-	if (ret != 0)
+-		return;
+-
+-	if (!(mask & DRM_PCIE_SPEED_50))
++	if ((rdev->pdev->bus->max_bus_speed != PCIE_SPEED_5_0GT) &&
++		(rdev->pdev->bus->max_bus_speed != PCIE_SPEED_8_0GT))
+ 		return;
+ 
+ 	speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
+diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
+index 1a08008..b45e648 100644
+--- a/drivers/gpu/drm/radeon/r600.c
++++ b/drivers/gpu/drm/radeon/r600.c
+@@ -4631,8 +4631,6 @@ static void r600_pcie_gen2_enable(struct radeon_device *rdev)
+ {
+ 	u32 link_width_cntl, lanes, speed_cntl, training_cntl, tmp;
+ 	u16 link_cntl2;
+-	u32 mask;
+-	int ret;
+ 
+ 	if (radeon_pcie_gen2 == 0)
+ 		return;
+@@ -4651,11 +4649,8 @@ static void r600_pcie_gen2_enable(struct radeon_device *rdev)
+ 	if (rdev->family <= CHIP_R600)
+ 		return;
+ 
+-	ret = drm_pcie_get_speed_cap_mask(rdev->ddev, &mask);
+-	if (ret != 0)
+-		return;
+-
+-	if (!(mask & DRM_PCIE_SPEED_50))
++	if ((rdev->pdev->bus->max_bus_speed != PCIE_SPEED_5_0GT) &&
++		(rdev->pdev->bus->max_bus_speed != PCIE_SPEED_8_0GT))
+ 		return;
+ 
+ 	speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
+diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
+index 83f612a..a6af4aa 100644
+--- a/drivers/gpu/drm/radeon/rv770.c
++++ b/drivers/gpu/drm/radeon/rv770.c
+@@ -2113,8 +2113,6 @@ static void rv770_pcie_gen2_enable(struct radeon_device *rdev)
+ {
+ 	u32 link_width_cntl, lanes, speed_cntl, tmp;
+ 	u16 link_cntl2;
+-	u32 mask;
+-	int ret;
+ 
+ 	if (radeon_pcie_gen2 == 0)
+ 		return;
+@@ -2129,11 +2127,8 @@ static void rv770_pcie_gen2_enable(struct radeon_device *rdev)
+ 	if (ASIC_IS_X2(rdev))
+ 		return;
+ 
+-	ret = drm_pcie_get_speed_cap_mask(rdev->ddev, &mask);
+-	if (ret != 0)
+-		return;
+-
+-	if (!(mask & DRM_PCIE_SPEED_50))
++	if ((rdev->pdev->bus->max_bus_speed != PCIE_SPEED_5_0GT) &&
++		(rdev->pdev->bus->max_bus_speed != PCIE_SPEED_8_0GT))
+ 		return;
+ 
+ 	DRM_INFO("enabling PCIE gen 2 link speeds, disable with radeon.pcie_gen2=0\n");
+-- 
+1.7.1


More information about the scm-commits mailing list