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

Alex Deucher alexdeucher at gmail.com
Wed Apr 17 13:17:22 PDT 2013


On Wed, Apr 17, 2013 at 4:11 PM, Bjorn Helgaas <bhelgaas at google.com> wrote:
> 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.

Ah, ok.  Thanks.  The previous comments about PCI_SPEED_UNKNOWN being
set in pci_alloc_bus() and never updated confused me.

Alex


More information about the dri-devel mailing list