drm/amdgpu: Reset the devices in the XGMI hive duirng probe
[linux-2.6-block.git] / drivers / gpu / drm / amd / amdgpu / amdgpu_xgmi.c
index 541ef6be390f09d0bfe55872acb9ed39b8ef6284..33f748e5bbfc2c3a3b363bd1869f59b5fa2a4a95 100644 (file)
@@ -324,7 +324,7 @@ static void amdgpu_xgmi_sysfs_rem_dev_info(struct amdgpu_device *adev,
 
 struct amdgpu_hive_info *amdgpu_get_xgmi_hive(struct amdgpu_device *adev)
 {
-       struct amdgpu_hive_info *hive = NULL, *tmp = NULL;
+       struct amdgpu_hive_info *hive = NULL;
        int ret;
 
        if (!adev->gmc.xgmi.hive_id)
@@ -337,11 +337,9 @@ struct amdgpu_hive_info *amdgpu_get_xgmi_hive(struct amdgpu_device *adev)
 
        mutex_lock(&xgmi_mutex);
 
-       if (!list_empty(&xgmi_hive_list)) {
-               list_for_each_entry_safe(hive, tmp, &xgmi_hive_list, node)  {
-                       if (hive->hive_id == adev->gmc.xgmi.hive_id)
-                               goto pro_end;
-               }
+       list_for_each_entry(hive, &xgmi_hive_list, node)  {
+               if (hive->hive_id == adev->gmc.xgmi.hive_id)
+                       goto pro_end;
        }
 
        hive = kzalloc(sizeof(*hive), GFP_KERNEL);
@@ -470,15 +468,22 @@ int amdgpu_xgmi_update_topology(struct amdgpu_hive_info *hive, struct amdgpu_dev
 }
 
 
+/*
+ * NOTE psp_xgmi_node_info.num_hops layout is as follows:
+ * num_hops[7:6] = link type (0 = xGMI2, 1 = xGMI3, 2/3 = reserved)
+ * num_hops[5:3] = reserved
+ * num_hops[2:0] = number of hops
+ */
 int amdgpu_xgmi_get_hops_count(struct amdgpu_device *adev,
                struct amdgpu_device *peer_adev)
 {
        struct psp_xgmi_topology_info *top = &adev->psp.xgmi_context.top_info;
+       uint8_t num_hops_mask = 0x7;
        int i;
 
        for (i = 0 ; i < top->num_nodes; ++i)
                if (top->nodes[i].node_id == peer_adev->gmc.xgmi.node_id)
-                       return top->nodes[i].num_hops;
+                       return top->nodes[i].num_hops & num_hops_mask;
        return  -EINVAL;
 }
 
@@ -494,7 +499,8 @@ int amdgpu_xgmi_add_device(struct amdgpu_device *adev)
        if (!adev->gmc.xgmi.supported)
                return 0;
 
-       if (amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_PSP)) {
+       if (!adev->gmc.xgmi.pending_reset &&
+           amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_PSP)) {
                ret = psp_xgmi_initialize(&adev->psp);
                if (ret) {
                        dev_err(adev->dev,
@@ -540,7 +546,8 @@ int amdgpu_xgmi_add_device(struct amdgpu_device *adev)
 
        task_barrier_add_task(&hive->tb);
 
-       if (amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_PSP)) {
+       if (!adev->gmc.xgmi.pending_reset &&
+           amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_PSP)) {
                list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head) {
                        /* update node list for other device in the hive */
                        if (tmp_adev != adev) {
@@ -569,7 +576,7 @@ int amdgpu_xgmi_add_device(struct amdgpu_device *adev)
                }
        }
 
-       if (!ret)
+       if (!ret && !adev->gmc.xgmi.pending_reset)
                ret = amdgpu_xgmi_sysfs_add_dev_info(adev, hive);
 
 exit_unlock: