drm/amdkfd: reflect atomic support in IO link properties
authorEric Huang <JinHuiEric.Huang@amd.com>
Mon, 4 Jun 2018 19:22:24 +0000 (15:22 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 27 Sep 2018 02:09:13 +0000 (21:09 -0500)
Add the flags of properties according to Asic type and pcie
capabilities.

Signed-off-by: Eric Huang <JinHuiEric.Huang@amd.com>
Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdkfd/kfd_device.c
drivers/gpu/drm/amd/amdkfd/kfd_priv.h
drivers/gpu/drm/amd/amdkfd/kfd_topology.c

index 9b4e6ad..b2abae0 100644 (file)
@@ -366,6 +366,10 @@ struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd,
                return NULL;
        }
 
+       kfd = kzalloc(sizeof(*kfd), GFP_KERNEL);
+       if (!kfd)
+               return NULL;
+
        /* Allow BIF to recode atomics to PCIe 3.0 AtomicOps.
         * 32 and 64-bit requests are possible and must be
         * supported.
@@ -377,12 +381,10 @@ struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd,
                dev_info(kfd_device,
                         "skipped device %x:%x, PCI rejects atomics\n",
                         pdev->vendor, pdev->device);
+               kfree(kfd);
                return NULL;
-       }
-
-       kfd = kzalloc(sizeof(*kfd), GFP_KERNEL);
-       if (!kfd)
-               return NULL;
+       } else if (!ret)
+               kfd->pci_atomic_requested = true;
 
        kfd->kgd = kgd;
        kfd->device_info = device_info;
index b0064b0..a07e57d 100644 (file)
@@ -257,6 +257,8 @@ struct kfd_dev {
 
        /* xGMI */
        uint64_t hive_id;
+
+       bool pci_atomic_requested;
 };
 
 /* KGD2KFD callbacks */
index 0dff66b..fbba1fe 100644 (file)
@@ -1127,17 +1127,40 @@ static void kfd_fill_mem_clk_max_info(struct kfd_topology_device *dev)
 
 static void kfd_fill_iolink_non_crat_info(struct kfd_topology_device *dev)
 {
-       struct kfd_iolink_properties *link;
+       struct kfd_iolink_properties *link, *cpu_link;
+       struct kfd_topology_device *cpu_dev;
+       uint32_t cap;
+       uint32_t cpu_flag = CRAT_IOLINK_FLAGS_ENABLED;
+       uint32_t flag = CRAT_IOLINK_FLAGS_ENABLED;
 
        if (!dev || !dev->gpu)
                return;
 
-       /* GPU only creates direck links so apply flags setting to all */
-       if (dev->gpu->device_info->asic_family == CHIP_HAWAII)
-               list_for_each_entry(link, &dev->io_link_props, list)
-                       link->flags = CRAT_IOLINK_FLAGS_ENABLED |
-                               CRAT_IOLINK_FLAGS_NO_ATOMICS_32_BIT |
-                               CRAT_IOLINK_FLAGS_NO_ATOMICS_64_BIT;
+       pcie_capability_read_dword(dev->gpu->pdev,
+                       PCI_EXP_DEVCAP2, &cap);
+
+       if (!(cap & (PCI_EXP_DEVCAP2_ATOMIC_COMP32 |
+                    PCI_EXP_DEVCAP2_ATOMIC_COMP64)))
+               cpu_flag |= CRAT_IOLINK_FLAGS_NO_ATOMICS_32_BIT |
+                       CRAT_IOLINK_FLAGS_NO_ATOMICS_64_BIT;
+
+       if (!dev->gpu->pci_atomic_requested ||
+           dev->gpu->device_info->asic_family == CHIP_HAWAII)
+               flag |= CRAT_IOLINK_FLAGS_NO_ATOMICS_32_BIT |
+                       CRAT_IOLINK_FLAGS_NO_ATOMICS_64_BIT;
+
+       /* GPU only creates direct links so apply flags setting to all */
+       list_for_each_entry(link, &dev->io_link_props, list) {
+               link->flags = flag;
+               cpu_dev = kfd_topology_device_by_proximity_domain(
+                               link->node_to);
+               if (cpu_dev) {
+                       list_for_each_entry(cpu_link,
+                                           &cpu_dev->io_link_props, list)
+                               if (cpu_link->node_to == link->node_from)
+                                       cpu_link->flags = cpu_flag;
+               }
+       }
 }
 
 int kfd_topology_add_device(struct kfd_dev *gpu)