linux/drivers/gpu/drm/i915/intel_uc.c
<<
>>
Prefs
   1/*
   2 * Copyright © 2016 Intel Corporation
   3 *
   4 * Permission is hereby granted, free of charge, to any person obtaining a
   5 * copy of this software and associated documentation files (the "Software"),
   6 * to deal in the Software without restriction, including without limitation
   7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8 * and/or sell copies of the Software, and to permit persons to whom the
   9 * Software is furnished to do so, subject to the following conditions:
  10 *
  11 * The above copyright notice and this permission notice (including the next
  12 * paragraph) shall be included in all copies or substantial portions of the
  13 * Software.
  14 *
  15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21 * IN THE SOFTWARE.
  22 *
  23 */
  24
  25#include "gt/intel_reset.h"
  26#include "intel_uc.h"
  27#include "intel_guc.h"
  28#include "intel_guc_ads.h"
  29#include "intel_guc_submission.h"
  30#include "i915_drv.h"
  31
  32static void guc_free_load_err_log(struct intel_guc *guc);
  33
  34/* Reset GuC providing us with fresh state for both GuC and HuC.
  35 */
  36static int __intel_uc_reset_hw(struct drm_i915_private *dev_priv)
  37{
  38        int ret;
  39        u32 guc_status;
  40
  41        ret = intel_reset_guc(dev_priv);
  42        if (ret) {
  43                DRM_ERROR("Failed to reset GuC, ret = %d\n", ret);
  44                return ret;
  45        }
  46
  47        guc_status = I915_READ(GUC_STATUS);
  48        WARN(!(guc_status & GS_MIA_IN_RESET),
  49             "GuC status: 0x%x, MIA core expected to be in reset\n",
  50             guc_status);
  51
  52        return ret;
  53}
  54
  55static int __get_platform_enable_guc(struct drm_i915_private *i915)
  56{
  57        struct intel_uc_fw *guc_fw = &i915->guc.fw;
  58        struct intel_uc_fw *huc_fw = &i915->huc.fw;
  59        int enable_guc = 0;
  60
  61        /* Default is to use HuC if we know GuC and HuC firmwares */
  62        if (intel_uc_fw_is_selected(guc_fw) && intel_uc_fw_is_selected(huc_fw))
  63                enable_guc |= ENABLE_GUC_LOAD_HUC;
  64
  65        /* Any platform specific fine-tuning can be done here */
  66
  67        return enable_guc;
  68}
  69
  70static int __get_default_guc_log_level(struct drm_i915_private *i915)
  71{
  72        int guc_log_level;
  73
  74        if (!HAS_GUC(i915) || !intel_uc_is_using_guc(i915))
  75                guc_log_level = GUC_LOG_LEVEL_DISABLED;
  76        else if (IS_ENABLED(CONFIG_DRM_I915_DEBUG) ||
  77                 IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM))
  78                guc_log_level = GUC_LOG_LEVEL_MAX;
  79        else
  80                guc_log_level = GUC_LOG_LEVEL_NON_VERBOSE;
  81
  82        /* Any platform specific fine-tuning can be done here */
  83
  84        return guc_log_level;
  85}
  86
  87/**
  88 * sanitize_options_early - sanitize uC related modparam options
  89 * @i915: device private
  90 *
  91 * In case of "enable_guc" option this function will attempt to modify
  92 * it only if it was initially set to "auto(-1)". Default value for this
  93 * modparam varies between platforms and it is hardcoded in driver code.
  94 * Any other modparam value is only monitored against availability of the
  95 * related hardware or firmware definitions.
  96 *
  97 * In case of "guc_log_level" option this function will attempt to modify
  98 * it only if it was initially set to "auto(-1)" or if initial value was
  99 * "enable(1..4)" on platforms without the GuC. Default value for this
 100 * modparam varies between platforms and is usually set to "disable(0)"
 101 * unless GuC is enabled on given platform and the driver is compiled with
 102 * debug config when this modparam will default to "enable(1..4)".
 103 */
 104static void sanitize_options_early(struct drm_i915_private *i915)
 105{
 106        struct intel_uc_fw *guc_fw = &i915->guc.fw;
 107        struct intel_uc_fw *huc_fw = &i915->huc.fw;
 108
 109        /* A negative value means "use platform default" */
 110        if (i915_modparams.enable_guc < 0)
 111                i915_modparams.enable_guc = __get_platform_enable_guc(i915);
 112
 113        DRM_DEBUG_DRIVER("enable_guc=%d (submission:%s huc:%s)\n",
 114                         i915_modparams.enable_guc,
 115                         yesno(intel_uc_is_using_guc_submission(i915)),
 116                         yesno(intel_uc_is_using_huc(i915)));
 117
 118        /* Verify GuC firmware availability */
 119        if (intel_uc_is_using_guc(i915) && !intel_uc_fw_is_selected(guc_fw)) {
 120                DRM_WARN("Incompatible option detected: %s=%d, %s!\n",
 121                         "enable_guc", i915_modparams.enable_guc,
 122                         !HAS_GUC(i915) ? "no GuC hardware" :
 123                                          "no GuC firmware");
 124        }
 125
 126        /* Verify HuC firmware availability */
 127        if (intel_uc_is_using_huc(i915) && !intel_uc_fw_is_selected(huc_fw)) {
 128                DRM_WARN("Incompatible option detected: %s=%d, %s!\n",
 129                         "enable_guc", i915_modparams.enable_guc,
 130                         !HAS_HUC(i915) ? "no HuC hardware" :
 131                                          "no HuC firmware");
 132        }
 133
 134        /* XXX: GuC submission is unavailable for now */
 135        if (intel_uc_is_using_guc_submission(i915)) {
 136                DRM_INFO("Incompatible option detected: %s=%d, %s!\n",
 137                         "enable_guc", i915_modparams.enable_guc,
 138                         "GuC submission not supported");
 139                DRM_INFO("Switching to non-GuC submission mode!\n");
 140                i915_modparams.enable_guc &= ~ENABLE_GUC_SUBMISSION;
 141        }
 142
 143        /* A negative value means "use platform/config default" */
 144        if (i915_modparams.guc_log_level < 0)
 145                i915_modparams.guc_log_level =
 146                        __get_default_guc_log_level(i915);
 147
 148        if (i915_modparams.guc_log_level > 0 && !intel_uc_is_using_guc(i915)) {
 149                DRM_WARN("Incompatible option detected: %s=%d, %s!\n",
 150                         "guc_log_level", i915_modparams.guc_log_level,
 151                         !HAS_GUC(i915) ? "no GuC hardware" :
 152                                          "GuC not enabled");
 153                i915_modparams.guc_log_level = 0;
 154        }
 155
 156        if (i915_modparams.guc_log_level > GUC_LOG_LEVEL_MAX) {
 157                DRM_WARN("Incompatible option detected: %s=%d, %s!\n",
 158                         "guc_log_level", i915_modparams.guc_log_level,
 159                         "verbosity too high");
 160                i915_modparams.guc_log_level = GUC_LOG_LEVEL_MAX;
 161        }
 162
 163        DRM_DEBUG_DRIVER("guc_log_level=%d (enabled:%s, verbose:%s, verbosity:%d)\n",
 164                         i915_modparams.guc_log_level,
 165                         yesno(i915_modparams.guc_log_level),
 166                         yesno(GUC_LOG_LEVEL_IS_VERBOSE(i915_modparams.guc_log_level)),
 167                         GUC_LOG_LEVEL_TO_VERBOSITY(i915_modparams.guc_log_level));
 168
 169        /* Make sure that sanitization was done */
 170        GEM_BUG_ON(i915_modparams.enable_guc < 0);
 171        GEM_BUG_ON(i915_modparams.guc_log_level < 0);
 172}
 173
 174void intel_uc_init_early(struct drm_i915_private *i915)
 175{
 176        struct intel_guc *guc = &i915->guc;
 177        struct intel_huc *huc = &i915->huc;
 178
 179        intel_guc_init_early(guc);
 180        intel_huc_init_early(huc);
 181
 182        sanitize_options_early(i915);
 183}
 184
 185void intel_uc_cleanup_early(struct drm_i915_private *i915)
 186{
 187        struct intel_guc *guc = &i915->guc;
 188
 189        guc_free_load_err_log(guc);
 190}
 191
 192/**
 193 * intel_uc_init_mmio - setup uC MMIO access
 194 * @i915: device private
 195 *
 196 * Setup minimal state necessary for MMIO accesses later in the
 197 * initialization sequence.
 198 */
 199void intel_uc_init_mmio(struct drm_i915_private *i915)
 200{
 201        intel_guc_init_send_regs(&i915->guc);
 202}
 203
 204static void guc_capture_load_err_log(struct intel_guc *guc)
 205{
 206        if (!guc->log.vma || !intel_guc_log_get_level(&guc->log))
 207                return;
 208
 209        if (!guc->load_err_log)
 210                guc->load_err_log = i915_gem_object_get(guc->log.vma->obj);
 211
 212        return;
 213}
 214
 215static void guc_free_load_err_log(struct intel_guc *guc)
 216{
 217        if (guc->load_err_log)
 218                i915_gem_object_put(guc->load_err_log);
 219}
 220
 221static void guc_reset_interrupts(struct intel_guc *guc)
 222{
 223        guc->interrupts.reset(guc_to_i915(guc));
 224}
 225
 226static void guc_enable_interrupts(struct intel_guc *guc)
 227{
 228        guc->interrupts.enable(guc_to_i915(guc));
 229}
 230
 231static void guc_disable_interrupts(struct intel_guc *guc)
 232{
 233        guc->interrupts.disable(guc_to_i915(guc));
 234}
 235
 236static int guc_enable_communication(struct intel_guc *guc)
 237{
 238        guc_enable_interrupts(guc);
 239
 240        return intel_guc_ct_enable(&guc->ct);
 241}
 242
 243static void guc_stop_communication(struct intel_guc *guc)
 244{
 245        intel_guc_ct_stop(&guc->ct);
 246
 247        guc->send = intel_guc_send_nop;
 248        guc->handler = intel_guc_to_host_event_handler_nop;
 249}
 250
 251static void guc_disable_communication(struct intel_guc *guc)
 252{
 253        intel_guc_ct_disable(&guc->ct);
 254
 255        guc_disable_interrupts(guc);
 256
 257        guc->send = intel_guc_send_nop;
 258        guc->handler = intel_guc_to_host_event_handler_nop;
 259}
 260
 261int intel_uc_init_misc(struct drm_i915_private *i915)
 262{
 263        struct intel_guc *guc = &i915->guc;
 264        struct intel_huc *huc = &i915->huc;
 265        int ret;
 266
 267        if (!USES_GUC(i915))
 268                return 0;
 269
 270        ret = intel_guc_init_misc(guc);
 271        if (ret)
 272                return ret;
 273
 274        if (USES_HUC(i915)) {
 275                ret = intel_huc_init_misc(huc);
 276                if (ret)
 277                        goto err_guc;
 278        }
 279
 280        return 0;
 281
 282err_guc:
 283        intel_guc_fini_misc(guc);
 284        return ret;
 285}
 286
 287void intel_uc_fini_misc(struct drm_i915_private *i915)
 288{
 289        struct intel_guc *guc = &i915->guc;
 290        struct intel_huc *huc = &i915->huc;
 291
 292        if (!USES_GUC(i915))
 293                return;
 294
 295        if (USES_HUC(i915))
 296                intel_huc_fini_misc(huc);
 297
 298        intel_guc_fini_misc(guc);
 299}
 300
 301int intel_uc_init(struct drm_i915_private *i915)
 302{
 303        struct intel_guc *guc = &i915->guc;
 304        struct intel_huc *huc = &i915->huc;
 305        int ret;
 306
 307        if (!USES_GUC(i915))
 308                return 0;
 309
 310        if (!HAS_GUC(i915))
 311                return -ENODEV;
 312
 313        /* XXX: GuC submission is unavailable for now */
 314        GEM_BUG_ON(USES_GUC_SUBMISSION(i915));
 315
 316        ret = intel_guc_init(guc);
 317        if (ret)
 318                return ret;
 319
 320        if (USES_HUC(i915)) {
 321                ret = intel_huc_init(huc);
 322                if (ret)
 323                        goto err_guc;
 324        }
 325
 326        if (USES_GUC_SUBMISSION(i915)) {
 327                /*
 328                 * This is stuff we need to have available at fw load time
 329                 * if we are planning to enable submission later
 330                 */
 331                ret = intel_guc_submission_init(guc);
 332                if (ret)
 333                        goto err_huc;
 334        }
 335
 336        return 0;
 337
 338err_huc:
 339        if (USES_HUC(i915))
 340                intel_huc_fini(huc);
 341err_guc:
 342        intel_guc_fini(guc);
 343        return ret;
 344}
 345
 346void intel_uc_fini(struct drm_i915_private *i915)
 347{
 348        struct intel_guc *guc = &i915->guc;
 349
 350        if (!USES_GUC(i915))
 351                return;
 352
 353        GEM_BUG_ON(!HAS_GUC(i915));
 354
 355        if (USES_GUC_SUBMISSION(i915))
 356                intel_guc_submission_fini(guc);
 357
 358        if (USES_HUC(i915))
 359                intel_huc_fini(&i915->huc);
 360
 361        intel_guc_fini(guc);
 362}
 363
 364static void __uc_sanitize(struct drm_i915_private *i915)
 365{
 366        struct intel_guc *guc = &i915->guc;
 367        struct intel_huc *huc = &i915->huc;
 368
 369        GEM_BUG_ON(!HAS_GUC(i915));
 370
 371        intel_huc_sanitize(huc);
 372        intel_guc_sanitize(guc);
 373
 374        __intel_uc_reset_hw(i915);
 375}
 376
 377void intel_uc_sanitize(struct drm_i915_private *i915)
 378{
 379        if (!USES_GUC(i915))
 380                return;
 381
 382        __uc_sanitize(i915);
 383}
 384
 385int intel_uc_init_hw(struct drm_i915_private *i915)
 386{
 387        struct intel_guc *guc = &i915->guc;
 388        struct intel_huc *huc = &i915->huc;
 389        int ret, attempts;
 390
 391        if (!USES_GUC(i915))
 392                return 0;
 393
 394        GEM_BUG_ON(!HAS_GUC(i915));
 395
 396        guc_reset_interrupts(guc);
 397
 398        /* WaEnableuKernelHeaderValidFix:skl */
 399        /* WaEnableGuCBootHashCheckNotSet:skl,bxt,kbl */
 400        if (IS_GEN(i915, 9))
 401                attempts = 3;
 402        else
 403                attempts = 1;
 404
 405        while (attempts--) {
 406                /*
 407                 * Always reset the GuC just before (re)loading, so
 408                 * that the state and timing are fairly predictable
 409                 */
 410                ret = __intel_uc_reset_hw(i915);
 411                if (ret)
 412                        goto err_out;
 413
 414                if (USES_HUC(i915)) {
 415                        ret = intel_huc_fw_upload(huc);
 416                        if (ret)
 417                                goto err_out;
 418                }
 419
 420                intel_guc_ads_reset(guc);
 421                intel_guc_init_params(guc);
 422                ret = intel_guc_fw_upload(guc);
 423                if (ret == 0)
 424                        break;
 425
 426                DRM_DEBUG_DRIVER("GuC fw load failed: %d; will reset and "
 427                                 "retry %d more time(s)\n", ret, attempts);
 428        }
 429
 430        /* Did we succeded or run out of retries? */
 431        if (ret)
 432                goto err_log_capture;
 433
 434        ret = guc_enable_communication(guc);
 435        if (ret)
 436                goto err_log_capture;
 437
 438        if (USES_HUC(i915)) {
 439                ret = intel_huc_auth(huc);
 440                if (ret)
 441                        goto err_communication;
 442        }
 443
 444        ret = intel_guc_sample_forcewake(guc);
 445        if (ret)
 446                goto err_communication;
 447
 448        if (USES_GUC_SUBMISSION(i915)) {
 449                ret = intel_guc_submission_enable(guc);
 450                if (ret)
 451                        goto err_communication;
 452        }
 453
 454        dev_info(i915->drm.dev, "GuC firmware version %u.%u\n",
 455                 guc->fw.major_ver_found, guc->fw.minor_ver_found);
 456        dev_info(i915->drm.dev, "GuC submission %s\n",
 457                 enableddisabled(USES_GUC_SUBMISSION(i915)));
 458        dev_info(i915->drm.dev, "HuC %s\n",
 459                 enableddisabled(USES_HUC(i915)));
 460
 461        return 0;
 462
 463        /*
 464         * We've failed to load the firmware :(
 465         */
 466err_communication:
 467        guc_disable_communication(guc);
 468err_log_capture:
 469        guc_capture_load_err_log(guc);
 470err_out:
 471        __uc_sanitize(i915);
 472
 473        /*
 474         * Note that there is no fallback as either user explicitly asked for
 475         * the GuC or driver default option was to run with the GuC enabled.
 476         */
 477        if (GEM_WARN_ON(ret == -EIO))
 478                ret = -EINVAL;
 479
 480        dev_err(i915->drm.dev, "GuC initialization failed %d\n", ret);
 481        return ret;
 482}
 483
 484void intel_uc_fini_hw(struct drm_i915_private *i915)
 485{
 486        struct intel_guc *guc = &i915->guc;
 487
 488        if (!intel_guc_is_loaded(guc))
 489                return;
 490
 491        GEM_BUG_ON(!HAS_GUC(i915));
 492
 493        if (USES_GUC_SUBMISSION(i915))
 494                intel_guc_submission_disable(guc);
 495
 496        guc_disable_communication(guc);
 497        __uc_sanitize(i915);
 498}
 499
 500/**
 501 * intel_uc_reset_prepare - Prepare for reset
 502 * @i915: device private
 503 *
 504 * Preparing for full gpu reset.
 505 */
 506void intel_uc_reset_prepare(struct drm_i915_private *i915)
 507{
 508        struct intel_guc *guc = &i915->guc;
 509
 510        if (!intel_guc_is_loaded(guc))
 511                return;
 512
 513        guc_stop_communication(guc);
 514        __uc_sanitize(i915);
 515}
 516
 517void intel_uc_runtime_suspend(struct drm_i915_private *i915)
 518{
 519        struct intel_guc *guc = &i915->guc;
 520        int err;
 521
 522        if (!intel_guc_is_loaded(guc))
 523                return;
 524
 525        err = intel_guc_suspend(guc);
 526        if (err)
 527                DRM_DEBUG_DRIVER("Failed to suspend GuC, err=%d", err);
 528
 529        guc_disable_communication(guc);
 530}
 531
 532void intel_uc_suspend(struct drm_i915_private *i915)
 533{
 534        struct intel_guc *guc = &i915->guc;
 535        intel_wakeref_t wakeref;
 536
 537        if (!intel_guc_is_loaded(guc))
 538                return;
 539
 540        with_intel_runtime_pm(&i915->runtime_pm, wakeref)
 541                intel_uc_runtime_suspend(i915);
 542}
 543
 544int intel_uc_resume(struct drm_i915_private *i915)
 545{
 546        struct intel_guc *guc = &i915->guc;
 547        int err;
 548
 549        if (!intel_guc_is_loaded(guc))
 550                return 0;
 551
 552        guc_enable_communication(guc);
 553
 554        err = intel_guc_resume(guc);
 555        if (err) {
 556                DRM_DEBUG_DRIVER("Failed to resume GuC, err=%d", err);
 557                return err;
 558        }
 559
 560        return 0;
 561}
 562