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

Bjorn Helgaas bhelgaas at google.com
Wed Apr 17 13:11:21 PDT 2013


On Wed, Apr 17, 2013 at 2:04 PM, Alex Deucher <alexdeucher at gmail.com> wrote:
> On Wed, Apr 17, 2013 at 8:38 AM, Lucas Kannebley Tavares
> <lucaskt at linux.vnet.ibm.com> wrote:
>> On 04/12/2013 01:38 PM, Bjorn Helgaas wrote:
>>>
>>> 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.
>>
>>
>> You're right here, of course. I'll test for it being different from 5_0GT
>> and 8_0GT instead. Though at some point I suppose someone will want to
>> tackle Gen3 speeds.
>
> drm_pcie_get_speed_cap_mask() actually checked the pci bridge to see
> what speeds it supported.  If the new code doesn't actually check the
> bridge caps then the new code does not seem like a valid replacement
> unless I'm missing something.

The max_bus_speed in struct pci_bus is set in pci_set_bus_speed()
based on the PCIe, PCI-X, or AGP capabilities.  This happens when we
enumerate the bridge device.  Or, in this case, Lucas added
powerpc-specific code to set max_bus_speed for the root bus based on
platform-specific host bridge knowledge.

So it still does check the PCI bridge capabilities, just not as
directly as it did before.

Bjorn


More information about the dri-devel mailing list