[PATCHv3 2/2] radeon: use max_bus_speed to activate gen2 speeds

Bjorn Helgaas bhelgaas at google.com
Sat Apr 13 02:38:30 EST 2013


On Thu, Apr 11, 2013 at 7:13 AM, Lucas Kannebley Tavares
<lucaskt at linux.vnet.ibm.com> wrote:
> radeon currently uses a drm function to get the speed capabilities for
> the bus. However, this is a non-standard method of performing this
> detection and this patch changes it to use the max_bus_speed attribute.
> ---
>  drivers/gpu/drm/radeon/evergreen.c |    9 ++-------
>  drivers/gpu/drm/radeon/r600.c      |    8 +-------
>  drivers/gpu/drm/radeon/rv770.c     |    8 +-------
>  3 files changed, 4 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
> index 305a657..3291f62 100644
> --- a/drivers/gpu/drm/radeon/evergreen.c
> +++ b/drivers/gpu/drm/radeon/evergreen.c
> @@ -3855,8 +3855,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;
> @@ -3871,11 +3870,7 @@ 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)

For devices on a root bus, we previously dereferenced a NULL pointer
in drm_pcie_get_speed_cap_mask() because pdev->bus->self is NULL on a
root bus.  (I think this is the original problem you tripped over,
Lucas.)

These patches fix that problem.  On pseries, where the device *is* on
a root bus, your patches set max_bus_speed so this will work as
expected.  On most other systems, max_bus_speed for root buses will be
PCI_SPEED_UNKNOWN (set in pci_alloc_bus() and never updated because
most arches don't have code like the pseries code you're adding).

PCI_SPEED_UNKNOWN = 0xff, so if we see another machine with a GPU on
the root bus, we'll attempt to enable Gen2 on the device even though
we have no idea what the bus will support.

That's why I originally suggested skipping the Gen2 stuff if
"max_bus_speed == PCI_SPEED_UNKNOWN".  I was just being conservative,
thinking that it's better to have a functional but slow GPU rather
than the unknown (to me) effects of enabling Gen2 on a link that might
not support it.  But I'm fine with this being either way.

It would be nice if we could get rid of drm_pcie_get_speed_cap_mask()
altogether.  It is exported, but I have no idea of anybody else uses
it.  Maybe it could at least be marked __deprecated now?

I don't know who should take these patches.  They don't touch
drivers/pci, but I'd be happy to push them, given the appropriate ACKs
from DRM and powerpc folks.

Bjorn

>                 return;
>
>         speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL);
> diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
> index 0740db3..64b90c0 100644
> --- a/drivers/gpu/drm/radeon/r600.c
> +++ b/drivers/gpu/drm/radeon/r600.c
> @@ -4351,8 +4351,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;
> @@ -4371,11 +4369,7 @@ 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)
>                 return;
>
>         speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL);
> diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
> index d63fe1d..c683c36 100644
> --- a/drivers/gpu/drm/radeon/rv770.c
> +++ b/drivers/gpu/drm/radeon/rv770.c
> @@ -1238,8 +1238,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;
> @@ -1254,11 +1252,7 @@ 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)
>                 return;
>
>         DRM_INFO("enabling PCIE gen 2 link speeds, disable with radeon.pcie_gen2=0\n");
> --
> 1.7.4.4
>


More information about the Linuxppc-dev mailing list