]> Git Repo - linux.git/blobdiff - drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
ASoC: simple-card: Use snd_soc_of_parse_aux_devs()
[linux.git] / drivers / gpu / drm / amd / amdgpu / amdgpu_ras.c
index 8b14aee370c86ca143377990b9fd9b1b0874ba5e..bcce4c0be4623fd0b758c1078fe0b90a832f2deb 100644 (file)
@@ -86,7 +86,7 @@ void amdgpu_ras_set_error_query_ready(struct amdgpu_device *adev, bool ready)
                amdgpu_ras_get_context(adev)->error_query_ready = ready;
 }
 
-bool amdgpu_ras_get_error_query_ready(struct amdgpu_device *adev)
+static bool amdgpu_ras_get_error_query_ready(struct amdgpu_device *adev)
 {
        if (adev && amdgpu_ras_get_context(adev))
                return amdgpu_ras_get_context(adev)->error_query_ready;
@@ -318,6 +318,9 @@ static ssize_t amdgpu_ras_debugfs_ctrl_write(struct file *f, const char __user *
        case 2:
                if ((data.inject.address >= adev->gmc.mc_vram_size) ||
                    (data.inject.address >= RAS_UMC_INJECT_ADDR_LIMIT)) {
+                       dev_warn(adev->dev, "RAS WARN: input address "
+                                       "0x%llx is invalid.",
+                                       data.inject.address);
                        ret = -EINVAL;
                        break;
                }
@@ -502,6 +505,29 @@ struct ras_manager *amdgpu_ras_find_obj(struct amdgpu_device *adev,
 }
 /* obj end */
 
+static void amdgpu_ras_parse_status_code(struct amdgpu_device *adev,
+                                 const char*           invoke_type,
+                                 const char*           block_name,
+                                 enum ta_ras_status    ret)
+{
+       switch (ret) {
+       case TA_RAS_STATUS__SUCCESS:
+               return;
+       case TA_RAS_STATUS__ERROR_RAS_NOT_AVAILABLE:
+               dev_warn(adev->dev,
+                       "RAS WARN: %s %s currently unavailable\n",
+                       invoke_type,
+                       block_name);
+               break;
+       default:
+               dev_err(adev->dev,
+                       "RAS ERROR: %s %s error failed ret 0x%X\n",
+                       invoke_type,
+                       block_name,
+                       ret);
+       }
+}
+
 /* feature ctl begin */
 static int amdgpu_ras_is_feature_allowed(struct amdgpu_device *adev,
                struct ras_common_if *head)
@@ -565,19 +591,23 @@ int amdgpu_ras_feature_enable(struct amdgpu_device *adev,
                struct ras_common_if *head, bool enable)
 {
        struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
-       union ta_ras_cmd_input info;
+       union ta_ras_cmd_input *info;
        int ret;
 
        if (!con)
                return -EINVAL;
 
+        info = kzalloc(sizeof(union ta_ras_cmd_input), GFP_KERNEL);
+       if (!info)
+               return -ENOMEM;
+
        if (!enable) {
-               info.disable_features = (struct ta_ras_disable_features_input) {
+               info->disable_features = (struct ta_ras_disable_features_input) {
                        .block_id =  amdgpu_ras_block_to_ta(head->block),
                        .error_type = amdgpu_ras_error_to_ta(head->type),
                };
        } else {
-               info.enable_features = (struct ta_ras_enable_features_input) {
+               info->enable_features = (struct ta_ras_enable_features_input) {
                        .block_id =  amdgpu_ras_block_to_ta(head->block),
                        .error_type = amdgpu_ras_error_to_ta(head->type),
                };
@@ -586,27 +616,33 @@ int amdgpu_ras_feature_enable(struct amdgpu_device *adev,
        /* Do not enable if it is not allowed. */
        WARN_ON(enable && !amdgpu_ras_is_feature_allowed(adev, head));
        /* Are we alerady in that state we are going to set? */
-       if (!(!!enable ^ !!amdgpu_ras_is_feature_enabled(adev, head)))
-               return 0;
+       if (!(!!enable ^ !!amdgpu_ras_is_feature_enabled(adev, head))) {
+               ret = 0;
+               goto out;
+       }
 
        if (!amdgpu_ras_intr_triggered()) {
-               ret = psp_ras_enable_features(&adev->psp, &info, enable);
+               ret = psp_ras_enable_features(&adev->psp, info, enable);
                if (ret) {
-                       dev_err(adev->dev, "RAS ERROR: %s %s feature "
-                                       "failed ret %d\n",
-                                       enable ? "enable":"disable",
-                                       ras_block_str(head->block),
-                                       ret);
+                       amdgpu_ras_parse_status_code(adev,
+                                                    enable ? "enable":"disable",
+                                                    ras_block_str(head->block),
+                                                   (enum ta_ras_status)ret);
                        if (ret == TA_RAS_STATUS__RESET_NEEDED)
-                               return -EAGAIN;
-                       return -EINVAL;
+                               ret = -EAGAIN;
+                       else
+                               ret = -EINVAL;
+
+                       goto out;
                }
        }
 
        /* setup the obj */
        __amdgpu_ras_feature_enable(adev, head, enable);
-
-       return 0;
+       ret = 0;
+out:
+       kfree(info);
+       return ret;
 }
 
 /* Only used in device probe stage and called only once. */
@@ -778,6 +814,32 @@ int amdgpu_ras_error_query(struct amdgpu_device *adev,
        return 0;
 }
 
+/* Trigger XGMI/WAFL error */
+static int amdgpu_ras_error_inject_xgmi(struct amdgpu_device *adev,
+                                struct ta_ras_trigger_error_input *block_info)
+{
+       int ret;
+
+       if (amdgpu_dpm_set_df_cstate(adev, DF_CSTATE_DISALLOW))
+               dev_warn(adev->dev, "Failed to disallow df cstate");
+
+       if (amdgpu_dpm_allow_xgmi_power_down(adev, false))
+               dev_warn(adev->dev, "Failed to disallow XGMI power down");
+
+       ret = psp_ras_trigger_error(&adev->psp, block_info);
+
+       if (amdgpu_ras_intr_triggered())
+               return ret;
+
+       if (amdgpu_dpm_allow_xgmi_power_down(adev, true))
+               dev_warn(adev->dev, "Failed to allow XGMI power down");
+
+       if (amdgpu_dpm_set_df_cstate(adev, DF_CSTATE_DISALLOW))
+               dev_warn(adev->dev, "Failed to allow df cstate");
+
+       return ret;
+}
+
 /* wrapper of psp_ras_trigger_error */
 int amdgpu_ras_error_inject(struct amdgpu_device *adev,
                struct ras_inject_if *info)
@@ -811,20 +873,22 @@ int amdgpu_ras_error_inject(struct amdgpu_device *adev,
                break;
        case AMDGPU_RAS_BLOCK__UMC:
        case AMDGPU_RAS_BLOCK__MMHUB:
-       case AMDGPU_RAS_BLOCK__XGMI_WAFL:
        case AMDGPU_RAS_BLOCK__PCIE_BIF:
                ret = psp_ras_trigger_error(&adev->psp, &block_info);
                break;
+       case AMDGPU_RAS_BLOCK__XGMI_WAFL:
+               ret = amdgpu_ras_error_inject_xgmi(adev, &block_info);
+               break;
        default:
                dev_info(adev->dev, "%s error injection is not supported yet\n",
                         ras_block_str(info->head.block));
                ret = -EINVAL;
        }
 
-       if (ret)
-               dev_err(adev->dev, "RAS ERROR: inject %s error failed ret %d\n",
-                               ras_block_str(info->head.block),
-                               ret);
+       amdgpu_ras_parse_status_code(adev,
+                                    "inject",
+                                    ras_block_str(info->head.block),
+                                    (enum ta_ras_status)ret);
 
        return ret;
 }
@@ -1554,7 +1618,7 @@ static int amdgpu_ras_save_bad_pages(struct amdgpu_device *adev)
        data = con->eh_data;
        save_count = data->count - control->num_recs;
        /* only new entries are saved */
-       if (save_count > 0)
+       if (save_count > 0) {
                if (amdgpu_ras_eeprom_process_recods(control,
                                                        &data->bps[control->num_recs],
                                                        true,
@@ -1563,6 +1627,9 @@ static int amdgpu_ras_save_bad_pages(struct amdgpu_device *adev)
                        return -EIO;
                }
 
+               dev_info(adev->dev, "Saved %d pages to EEPROM table.\n", save_count);
+       }
+
        return 0;
 }
 
@@ -1853,9 +1920,8 @@ int amdgpu_ras_init(struct amdgpu_device *adev)
        amdgpu_ras_check_supported(adev, &con->hw_supported,
                        &con->supported);
        if (!con->hw_supported) {
-               amdgpu_ras_set_context(adev, NULL);
-               kfree(con);
-               return 0;
+               r = 0;
+               goto err_out;
        }
 
        con->features = 0;
@@ -1866,29 +1932,29 @@ int amdgpu_ras_init(struct amdgpu_device *adev)
        if (adev->nbio.funcs->init_ras_controller_interrupt) {
                r = adev->nbio.funcs->init_ras_controller_interrupt(adev);
                if (r)
-                       return r;
+                       goto err_out;
        }
 
        if (adev->nbio.funcs->init_ras_err_event_athub_interrupt) {
                r = adev->nbio.funcs->init_ras_err_event_athub_interrupt(adev);
                if (r)
-                       return r;
+                       goto err_out;
        }
 
-       amdgpu_ras_mask &= AMDGPU_RAS_BLOCK_MASK;
-
-       if (amdgpu_ras_fs_init(adev))
-               goto fs_out;
+       if (amdgpu_ras_fs_init(adev)) {
+               r = -EINVAL;
+               goto err_out;
+       }
 
        dev_info(adev->dev, "RAS INFO: ras initialized successfully, "
                        "hardware ability[%x] ras_mask[%x]\n",
                        con->hw_supported, con->supported);
        return 0;
-fs_out:
+err_out:
        amdgpu_ras_set_context(adev, NULL);
        kfree(con);
 
-       return -EINVAL;
+       return r;
 }
 
 /* helper function to handle common stuff in ip late init phase */
@@ -2068,3 +2134,14 @@ void amdgpu_ras_global_ras_isr(struct amdgpu_device *adev)
                amdgpu_ras_reset_gpu(adev);
        }
 }
+
+bool amdgpu_ras_need_emergency_restart(struct amdgpu_device *adev)
+{
+       if (adev->asic_type == CHIP_VEGA20 &&
+           adev->pm.fw_version <= 0x283400) {
+               return !(amdgpu_asic_reset_method(adev) == AMD_RESET_METHOD_BACO) &&
+                               amdgpu_ras_intr_triggered();
+       }
+
+       return false;
+}
This page took 0.043568 seconds and 4 git commands to generate.