drm/amdgpu: store pcie gen mask and link width
authorAlex Deucher <alexander.deucher@amd.com>
Thu, 12 Nov 2015 00:45:06 +0000 (19:45 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 21 Dec 2015 21:42:32 +0000 (16:42 -0500)
We'll need this later for pcie dpm.

Reviewed-by: Jammy Zhou <Jammy.Zhou@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu.h
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/amdgpu/cik.c
drivers/gpu/drm/amd/amdgpu/vi.c

index 637eff393bc7b6dc8afd11a128c92b29f6c9e26a..26d9134f7c0d2234fcecebba34fb57931666a843 100644 (file)
@@ -1637,8 +1637,12 @@ struct amdgpu_pm {
        const struct firmware   *fw;    /* SMC firmware */
        uint32_t                fw_version;
        const struct amdgpu_dpm_funcs *funcs;
+       uint32_t                pcie_gen_mask;
+       uint32_t                pcie_mlw_mask;
 };
 
+void amdgpu_get_pcie_info(struct amdgpu_device *adev);
+
 /*
  * UVD
  */
index 587ff71453617b521e7248347b0a2d643500f1cf..65531463f88e5b9eb736fdd5e9df357f2f191680 100644 (file)
@@ -38,6 +38,7 @@
 #include "amdgpu_i2c.h"
 #include "atom.h"
 #include "amdgpu_atombios.h"
+#include "amd_pcie.h"
 #ifdef CONFIG_DRM_AMDGPU_CIK
 #include "cik.h"
 #endif
@@ -1932,6 +1933,83 @@ retry:
        return r;
 }
 
+void amdgpu_get_pcie_info(struct amdgpu_device *adev)
+{
+       u32 mask;
+       int ret;
+
+       if (pci_is_root_bus(adev->pdev->bus))
+               return;
+
+       if (amdgpu_pcie_gen2 == 0)
+               return;
+
+       if (adev->flags & AMD_IS_APU)
+               return;
+
+       ret = drm_pcie_get_speed_cap_mask(adev->ddev, &mask);
+       if (!ret) {
+               adev->pm.pcie_gen_mask = (CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN1 |
+                                         CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN2 |
+                                         CAIL_ASIC_PCIE_LINK_SPEED_SUPPORT_GEN3);
+
+               if (mask & DRM_PCIE_SPEED_25)
+                       adev->pm.pcie_gen_mask |= CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1;
+               if (mask & DRM_PCIE_SPEED_50)
+                       adev->pm.pcie_gen_mask |= CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2;
+               if (mask & DRM_PCIE_SPEED_80)
+                       adev->pm.pcie_gen_mask |= CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3;
+       }
+       ret = drm_pcie_get_max_link_width(adev->ddev, &mask);
+       if (!ret) {
+               switch (mask) {
+               case 32:
+                       adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_X32 |
+                                                 CAIL_PCIE_LINK_WIDTH_SUPPORT_X16 |
+                                                 CAIL_PCIE_LINK_WIDTH_SUPPORT_X12 |
+                                                 CAIL_PCIE_LINK_WIDTH_SUPPORT_X8 |
+                                                 CAIL_PCIE_LINK_WIDTH_SUPPORT_X4 |
+                                                 CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 |
+                                                 CAIL_PCIE_LINK_WIDTH_SUPPORT_X1);
+                       break;
+               case 16:
+                       adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_X16 |
+                                                 CAIL_PCIE_LINK_WIDTH_SUPPORT_X12 |
+                                                 CAIL_PCIE_LINK_WIDTH_SUPPORT_X8 |
+                                                 CAIL_PCIE_LINK_WIDTH_SUPPORT_X4 |
+                                                 CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 |
+                                                 CAIL_PCIE_LINK_WIDTH_SUPPORT_X1);
+                       break;
+               case 12:
+                       adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_X12 |
+                                                 CAIL_PCIE_LINK_WIDTH_SUPPORT_X8 |
+                                                 CAIL_PCIE_LINK_WIDTH_SUPPORT_X4 |
+                                                 CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 |
+                                                 CAIL_PCIE_LINK_WIDTH_SUPPORT_X1);
+                       break;
+               case 8:
+                       adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_X8 |
+                                                 CAIL_PCIE_LINK_WIDTH_SUPPORT_X4 |
+                                                 CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 |
+                                                 CAIL_PCIE_LINK_WIDTH_SUPPORT_X1);
+                       break;
+               case 4:
+                       adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_X4 |
+                                                 CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 |
+                                                 CAIL_PCIE_LINK_WIDTH_SUPPORT_X1);
+                       break;
+               case 2:
+                       adev->pm.pcie_mlw_mask = (CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 |
+                                                 CAIL_PCIE_LINK_WIDTH_SUPPORT_X1);
+                       break;
+               case 1:
+                       adev->pm.pcie_mlw_mask = CAIL_PCIE_LINK_WIDTH_SUPPORT_X1;
+                       break;
+               default:
+                       break;
+               }
+       }
+}
 
 /*
  * Debugfs
index c7c298b881702212b8797431215de236db215dc6..fd9c9588ef46335d7a154e664bce8275d62f3ae9 100644 (file)
@@ -32,6 +32,7 @@
 #include "amdgpu_vce.h"
 #include "cikd.h"
 #include "atom.h"
+#include "amd_pcie.h"
 
 #include "cik.h"
 #include "gmc_v7_0.h"
@@ -1595,8 +1596,8 @@ static void cik_pcie_gen3_enable(struct amdgpu_device *adev)
 {
        struct pci_dev *root = adev->pdev->bus->self;
        int bridge_pos, gpu_pos;
-       u32 speed_cntl, mask, current_data_rate;
-       int ret, i;
+       u32 speed_cntl, current_data_rate;
+       int i;
        u16 tmp16;
 
        if (pci_is_root_bus(adev->pdev->bus))
@@ -1608,23 +1609,20 @@ static void cik_pcie_gen3_enable(struct amdgpu_device *adev)
        if (adev->flags & AMD_IS_APU)
                return;
 
-       ret = drm_pcie_get_speed_cap_mask(adev->ddev, &mask);
-       if (ret != 0)
-               return;
-
-       if (!(mask & (DRM_PCIE_SPEED_50 | DRM_PCIE_SPEED_80)))
+       if (!(adev->pm.pcie_gen_mask & (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 |
+                                       CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)))
                return;
 
        speed_cntl = RREG32_PCIE(ixPCIE_LC_SPEED_CNTL);
        current_data_rate = (speed_cntl & PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK) >>
                PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT;
-       if (mask & DRM_PCIE_SPEED_80) {
+       if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) {
                if (current_data_rate == 2) {
                        DRM_INFO("PCIE gen 3 link speeds already enabled\n");
                        return;
                }
                DRM_INFO("enabling PCIE gen 3 link speeds, disable with amdgpu.pcie_gen2=0\n");
-       } else if (mask & DRM_PCIE_SPEED_50) {
+       } else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) {
                if (current_data_rate == 1) {
                        DRM_INFO("PCIE gen 2 link speeds already enabled\n");
                        return;
@@ -1640,7 +1638,7 @@ static void cik_pcie_gen3_enable(struct amdgpu_device *adev)
        if (!gpu_pos)
                return;
 
-       if (mask & DRM_PCIE_SPEED_80) {
+       if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) {
                /* re-try equalization if gen3 is not already enabled */
                if (current_data_rate != 2) {
                        u16 bridge_cfg, gpu_cfg;
@@ -1735,9 +1733,9 @@ static void cik_pcie_gen3_enable(struct amdgpu_device *adev)
 
        pci_read_config_word(adev->pdev, gpu_pos + PCI_EXP_LNKCTL2, &tmp16);
        tmp16 &= ~0xf;
-       if (mask & DRM_PCIE_SPEED_80)
+       if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)
                tmp16 |= 3; /* gen3 */
-       else if (mask & DRM_PCIE_SPEED_50)
+       else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2)
                tmp16 |= 2; /* gen2 */
        else
                tmp16 |= 1; /* gen1 */
@@ -2450,6 +2448,8 @@ static int cik_common_early_init(void *handle)
                return -EINVAL;
        }
 
+       amdgpu_get_pcie_info(adev);
+
        return 0;
 }
 
index e51070e9697a99e8bbc94ae2ce70841f1fd23291..25d62079060766964b48bbcfdd76aa247403525f 100644 (file)
@@ -31,6 +31,7 @@
 #include "amdgpu_vce.h"
 #include "amdgpu_ucode.h"
 #include "atom.h"
+#include "amd_pcie.h"
 
 #include "gmc/gmc_8_1_d.h"
 #include "gmc/gmc_8_1_sh_mask.h"
@@ -1052,9 +1053,6 @@ static int vi_set_vce_clocks(struct amdgpu_device *adev, u32 evclk, u32 ecclk)
 
 static void vi_pcie_gen3_enable(struct amdgpu_device *adev)
 {
-       u32 mask;
-       int ret;
-
        if (pci_is_root_bus(adev->pdev->bus))
                return;
 
@@ -1064,11 +1062,8 @@ static void vi_pcie_gen3_enable(struct amdgpu_device *adev)
        if (adev->flags & AMD_IS_APU)
                return;
 
-       ret = drm_pcie_get_speed_cap_mask(adev->ddev, &mask);
-       if (ret != 0)
-               return;
-
-       if (!(mask & (DRM_PCIE_SPEED_50 | DRM_PCIE_SPEED_80)))
+       if (!(adev->pm.pcie_gen_mask & (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 |
+                                       CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)))
                return;
 
        /* todo */
@@ -1473,6 +1468,8 @@ static int vi_common_early_init(void *handle)
        if (amdgpu_smc_load_fw && smc_enabled)
                adev->firmware.smu_load = true;
 
+       amdgpu_get_pcie_info(adev);
+
        return 0;
 }