[v2,1/2] drm/amdgpu: Fix pci platform speed and width

Submitted by Kasiviswanathan, Harish on Feb. 5, 2019, 9:37 p.m.

Details

Message ID 1549402669-22313-1-git-send-email-Harish.Kasiviswanathan@amd.com
State Accepted
Commit c53134577c185533ca7e0b958bafc77539d41fd9
Headers show
Series "Series without cover letter" ( rev: 1 ) in AMD X.Org drivers

Not browsing as part of any series.

Commit Message

Kasiviswanathan, Harish Feb. 5, 2019, 9:37 p.m.
The new Vega series GPU cards have in-built bridges. To get the pcie
speed and width supported by the platform walk the hierarchy and get the
slowest link.

Change-Id: I3196d158b0c614cbb5d7a34c793a58cb95322d32
Signed-off-by: Harish Kasiviswanathan <Harish.Kasiviswanathan@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 58 +++++++++++++++++++++++-------
 1 file changed, 46 insertions(+), 12 deletions(-)

Patch hide | download patch | download mbox

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index d7dddb9..fcab1fe 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -3618,6 +3618,38 @@  int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
 	return r;
 }
 
+static void amdgpu_device_get_min_pci_speed_width(struct amdgpu_device *adev,
+						  enum pci_bus_speed *speed,
+						  enum pcie_link_width *width)
+{
+	struct pci_dev *pdev = adev->pdev;
+	enum pci_bus_speed cur_speed;
+	enum pcie_link_width cur_width;
+
+	*speed = PCI_SPEED_UNKNOWN;
+	*width = PCIE_LNK_WIDTH_UNKNOWN;
+
+	while (pdev) {
+		cur_speed = pcie_get_speed_cap(pdev);
+		cur_width = pcie_get_width_cap(pdev);
+
+		if (cur_speed != PCI_SPEED_UNKNOWN) {
+			if (*speed == PCI_SPEED_UNKNOWN)
+				*speed = cur_speed;
+			else if (cur_speed < *speed)
+				*speed = cur_speed;
+		}
+
+		if (cur_width != PCIE_LNK_WIDTH_UNKNOWN) {
+			if (*width == PCIE_LNK_WIDTH_UNKNOWN)
+				*width = cur_width;
+			else if (cur_width < *width)
+				*width = cur_width;
+		}
+		pdev = pci_upstream_bridge(pdev);
+	}
+}
+
 /**
  * amdgpu_device_get_pcie_info - fence pcie info about the PCIE slot
  *
@@ -3630,8 +3662,8 @@  int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
 static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev)
 {
 	struct pci_dev *pdev;
-	enum pci_bus_speed speed_cap;
-	enum pcie_link_width link_width;
+	enum pci_bus_speed speed_cap, platform_speed_cap;
+	enum pcie_link_width platform_link_width;
 
 	if (amdgpu_pcie_gen_cap)
 		adev->pm.pcie_gen_mask = amdgpu_pcie_gen_cap;
@@ -3648,6 +3680,12 @@  static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev)
 		return;
 	}
 
+	if (adev->pm.pcie_gen_mask && adev->pm.pcie_mlw_mask)
+		return;
+
+	amdgpu_device_get_min_pci_speed_width(adev, &platform_speed_cap,
+					      &platform_link_width);
+
 	if (adev->pm.pcie_gen_mask == 0) {
 		/* asic caps */
 		pdev = adev->pdev;
@@ -3673,22 +3711,20 @@  static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev)
 				adev->pm.pcie_gen_mask |= CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN1;
 		}
 		/* platform caps */
-		pdev = adev->ddev->pdev->bus->self;
-		speed_cap = pcie_get_speed_cap(pdev);
-		if (speed_cap == PCI_SPEED_UNKNOWN) {
+		if (platform_speed_cap == PCI_SPEED_UNKNOWN) {
 			adev->pm.pcie_gen_mask |= (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1 |
 						   CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2);
 		} else {
-			if (speed_cap == PCIE_SPEED_16_0GT)
+			if (platform_speed_cap == PCIE_SPEED_16_0GT)
 				adev->pm.pcie_gen_mask |= (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1 |
 							   CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 |
 							   CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3 |
 							   CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4);
-			else if (speed_cap == PCIE_SPEED_8_0GT)
+			else if (platform_speed_cap == PCIE_SPEED_8_0GT)
 				adev->pm.pcie_gen_mask |= (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1 |
 							   CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 |
 							   CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3);
-			else if (speed_cap == PCIE_SPEED_5_0GT)
+			else if (platform_speed_cap == PCIE_SPEED_5_0GT)
 				adev->pm.pcie_gen_mask |= (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1 |
 							   CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2);
 			else
@@ -3697,12 +3733,10 @@  static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev)
 		}
 	}
 	if (adev->pm.pcie_mlw_mask == 0) {
-		pdev = adev->ddev->pdev->bus->self;
-		link_width = pcie_get_width_cap(pdev);
-		if (link_width == PCIE_LNK_WIDTH_UNKNOWN) {
+		if (platform_link_width == PCIE_LNK_WIDTH_UNKNOWN) {
 			adev->pm.pcie_mlw_mask |= AMDGPU_DEFAULT_PCIE_MLW_MASK;
 		} else {
-			switch (link_width) {
+			switch (platform_link_width) {
 			case PCIE_LNK_X32:
 				adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_X32 |
 							  CAIL_PCIE_LINK_WIDTH_SUPPORT_X16 |

Comments

On Tue, Feb 5, 2019 at 4:38 PM Kasiviswanathan, Harish
<Harish.Kasiviswanathan@amd.com> wrote:
>
> The new Vega series GPU cards have in-built bridges. To get the pcie
> speed and width supported by the platform walk the hierarchy and get the
> slowest link.
>
> Change-Id: I3196d158b0c614cbb5d7a34c793a58cb95322d32
> Signed-off-by: Harish Kasiviswanathan <Harish.Kasiviswanathan@amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 58 +++++++++++++++++++++++-------
>  1 file changed, 46 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index d7dddb9..fcab1fe 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -3618,6 +3618,38 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
>         return r;
>  }
>
> +static void amdgpu_device_get_min_pci_speed_width(struct amdgpu_device *adev,
> +                                                 enum pci_bus_speed *speed,
> +                                                 enum pcie_link_width *width)
> +{
> +       struct pci_dev *pdev = adev->pdev;
> +       enum pci_bus_speed cur_speed;
> +       enum pcie_link_width cur_width;
> +
> +       *speed = PCI_SPEED_UNKNOWN;
> +       *width = PCIE_LNK_WIDTH_UNKNOWN;
> +
> +       while (pdev) {
> +               cur_speed = pcie_get_speed_cap(pdev);
> +               cur_width = pcie_get_width_cap(pdev);
> +
> +               if (cur_speed != PCI_SPEED_UNKNOWN) {
> +                       if (*speed == PCI_SPEED_UNKNOWN)
> +                               *speed = cur_speed;
> +                       else if (cur_speed < *speed)
> +                               *speed = cur_speed;
> +               }
> +
> +               if (cur_width != PCIE_LNK_WIDTH_UNKNOWN) {
> +                       if (*width == PCIE_LNK_WIDTH_UNKNOWN)
> +                               *width = cur_width;
> +                       else if (cur_width < *width)
> +                               *width = cur_width;
> +               }
> +               pdev = pci_upstream_bridge(pdev);
> +       }
> +}
> +
>  /**
>   * amdgpu_device_get_pcie_info - fence pcie info about the PCIE slot
>   *
> @@ -3630,8 +3662,8 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
>  static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev)
>  {
>         struct pci_dev *pdev;
> -       enum pci_bus_speed speed_cap;
> -       enum pcie_link_width link_width;
> +       enum pci_bus_speed speed_cap, platform_speed_cap;
> +       enum pcie_link_width platform_link_width;
>
>         if (amdgpu_pcie_gen_cap)
>                 adev->pm.pcie_gen_mask = amdgpu_pcie_gen_cap;
> @@ -3648,6 +3680,12 @@ static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev)
>                 return;
>         }
>
> +       if (adev->pm.pcie_gen_mask && adev->pm.pcie_mlw_mask)
> +               return;

I think you can drop this check, but I guess it doesn't hurt.  Either
way, series is:
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

> +
> +       amdgpu_device_get_min_pci_speed_width(adev, &platform_speed_cap,
> +                                             &platform_link_width);
> +
>         if (adev->pm.pcie_gen_mask == 0) {
>                 /* asic caps */
>                 pdev = adev->pdev;
> @@ -3673,22 +3711,20 @@ static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev)
>                                 adev->pm.pcie_gen_mask |= CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN1;
>                 }
>                 /* platform caps */
> -               pdev = adev->ddev->pdev->bus->self;
> -               speed_cap = pcie_get_speed_cap(pdev);
> -               if (speed_cap == PCI_SPEED_UNKNOWN) {
> +               if (platform_speed_cap == PCI_SPEED_UNKNOWN) {
>                         adev->pm.pcie_gen_mask |= (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1 |
>                                                    CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2);
>                 } else {
> -                       if (speed_cap == PCIE_SPEED_16_0GT)
> +                       if (platform_speed_cap == PCIE_SPEED_16_0GT)
>                                 adev->pm.pcie_gen_mask |= (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1 |
>                                                            CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 |
>                                                            CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3 |
>                                                            CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4);
> -                       else if (speed_cap == PCIE_SPEED_8_0GT)
> +                       else if (platform_speed_cap == PCIE_SPEED_8_0GT)
>                                 adev->pm.pcie_gen_mask |= (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1 |
>                                                            CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 |
>                                                            CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3);
> -                       else if (speed_cap == PCIE_SPEED_5_0GT)
> +                       else if (platform_speed_cap == PCIE_SPEED_5_0GT)
>                                 adev->pm.pcie_gen_mask |= (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1 |
>                                                            CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2);
>                         else
> @@ -3697,12 +3733,10 @@ static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev)
>                 }
>         }
>         if (adev->pm.pcie_mlw_mask == 0) {
> -               pdev = adev->ddev->pdev->bus->self;
> -               link_width = pcie_get_width_cap(pdev);
> -               if (link_width == PCIE_LNK_WIDTH_UNKNOWN) {
> +               if (platform_link_width == PCIE_LNK_WIDTH_UNKNOWN) {
>                         adev->pm.pcie_mlw_mask |= AMDGPU_DEFAULT_PCIE_MLW_MASK;
>                 } else {
> -                       switch (link_width) {
> +                       switch (platform_link_width) {
>                         case PCIE_LNK_X32:
>                                 adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_X32 |
>                                                           CAIL_PCIE_LINK_WIDTH_SUPPORT_X16 |
> --
> 2.7.4
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Am 06.02.19 um 02:13 schrieb Alex Deucher:
> On Tue, Feb 5, 2019 at 4:38 PM Kasiviswanathan, Harish
> <Harish.Kasiviswanathan@amd.com> wrote:
>> The new Vega series GPU cards have in-built bridges. To get the pcie
>> speed and width supported by the platform walk the hierarchy and get the
>> slowest link.
>>
>> Change-Id: I3196d158b0c614cbb5d7a34c793a58cb95322d32
>> Signed-off-by: Harish Kasiviswanathan <Harish.Kasiviswanathan@amd.com>
>> ---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 58 +++++++++++++++++++++++-------
>>   1 file changed, 46 insertions(+), 12 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>> index d7dddb9..fcab1fe 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>> @@ -3618,6 +3618,38 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
>>          return r;
>>   }
>>
>> +static void amdgpu_device_get_min_pci_speed_width(struct amdgpu_device *adev,
>> +                                                 enum pci_bus_speed *speed,
>> +                                                 enum pcie_link_width *width)
>> +{
>> +       struct pci_dev *pdev = adev->pdev;
>> +       enum pci_bus_speed cur_speed;
>> +       enum pcie_link_width cur_width;
>> +
>> +       *speed = PCI_SPEED_UNKNOWN;
>> +       *width = PCIE_LNK_WIDTH_UNKNOWN;
>> +
>> +       while (pdev) {
>> +               cur_speed = pcie_get_speed_cap(pdev);
>> +               cur_width = pcie_get_width_cap(pdev);
>> +
>> +               if (cur_speed != PCI_SPEED_UNKNOWN) {
>> +                       if (*speed == PCI_SPEED_UNKNOWN)
>> +                               *speed = cur_speed;
>> +                       else if (cur_speed < *speed)
>> +                               *speed = cur_speed;
>> +               }
>> +
>> +               if (cur_width != PCIE_LNK_WIDTH_UNKNOWN) {
>> +                       if (*width == PCIE_LNK_WIDTH_UNKNOWN)
>> +                               *width = cur_width;
>> +                       else if (cur_width < *width)
>> +                               *width = cur_width;
>> +               }
>> +               pdev = pci_upstream_bridge(pdev);
>> +       }
>> +}
>> +

That should probably rather be some helper function in the PCIe subsystem.

But for now it should be ok to have it here instead. Feel free to add an 
Acked-by: Christian König <christian.koenig@amd.com> as well.

Christian.

>>   /**
>>    * amdgpu_device_get_pcie_info - fence pcie info about the PCIE slot
>>    *
>> @@ -3630,8 +3662,8 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
>>   static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev)
>>   {
>>          struct pci_dev *pdev;
>> -       enum pci_bus_speed speed_cap;
>> -       enum pcie_link_width link_width;
>> +       enum pci_bus_speed speed_cap, platform_speed_cap;
>> +       enum pcie_link_width platform_link_width;
>>
>>          if (amdgpu_pcie_gen_cap)
>>                  adev->pm.pcie_gen_mask = amdgpu_pcie_gen_cap;
>> @@ -3648,6 +3680,12 @@ static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev)
>>                  return;
>>          }
>>
>> +       if (adev->pm.pcie_gen_mask && adev->pm.pcie_mlw_mask)
>> +               return;
> I think you can drop this check, but I guess it doesn't hurt.  Either
> way, series is:
> Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
>
>> +
>> +       amdgpu_device_get_min_pci_speed_width(adev, &platform_speed_cap,
>> +                                             &platform_link_width);
>> +
>>          if (adev->pm.pcie_gen_mask == 0) {
>>                  /* asic caps */
>>                  pdev = adev->pdev;
>> @@ -3673,22 +3711,20 @@ static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev)
>>                                  adev->pm.pcie_gen_mask |= CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN1;
>>                  }
>>                  /* platform caps */
>> -               pdev = adev->ddev->pdev->bus->self;
>> -               speed_cap = pcie_get_speed_cap(pdev);
>> -               if (speed_cap == PCI_SPEED_UNKNOWN) {
>> +               if (platform_speed_cap == PCI_SPEED_UNKNOWN) {
>>                          adev->pm.pcie_gen_mask |= (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1 |
>>                                                     CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2);
>>                  } else {
>> -                       if (speed_cap == PCIE_SPEED_16_0GT)
>> +                       if (platform_speed_cap == PCIE_SPEED_16_0GT)
>>                                  adev->pm.pcie_gen_mask |= (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1 |
>>                                                             CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 |
>>                                                             CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3 |
>>                                                             CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4);
>> -                       else if (speed_cap == PCIE_SPEED_8_0GT)
>> +                       else if (platform_speed_cap == PCIE_SPEED_8_0GT)
>>                                  adev->pm.pcie_gen_mask |= (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1 |
>>                                                             CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 |
>>                                                             CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3);
>> -                       else if (speed_cap == PCIE_SPEED_5_0GT)
>> +                       else if (platform_speed_cap == PCIE_SPEED_5_0GT)
>>                                  adev->pm.pcie_gen_mask |= (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1 |
>>                                                             CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2);
>>                          else
>> @@ -3697,12 +3733,10 @@ static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev)
>>                  }
>>          }
>>          if (adev->pm.pcie_mlw_mask == 0) {
>> -               pdev = adev->ddev->pdev->bus->self;
>> -               link_width = pcie_get_width_cap(pdev);
>> -               if (link_width == PCIE_LNK_WIDTH_UNKNOWN) {
>> +               if (platform_link_width == PCIE_LNK_WIDTH_UNKNOWN) {
>>                          adev->pm.pcie_mlw_mask |= AMDGPU_DEFAULT_PCIE_MLW_MASK;
>>                  } else {
>> -                       switch (link_width) {
>> +                       switch (platform_link_width) {
>>                          case PCIE_LNK_X32:
>>                                  adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_X32 |
>>                                                            CAIL_PCIE_LINK_WIDTH_SUPPORT_X16 |
>> --
>> 2.7.4
>>
>> _______________________________________________
>> amd-gfx mailing list
>> amd-gfx@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx