linux/drivers/gpu/drm/i915/gt/uc/intel_uc.c
<<
>>
Prefs
   1// SPDX-License-Identifier: MIT
   2/*
   3 * Copyright © 2016-2019 Intel Corporation
   4 */
   5
   6#include "gt/intel_gt.h"
   7#include "gt/intel_reset.h"
   8#include "intel_guc.h"
   9#include "intel_guc_ads.h"
  10#include "intel_guc_submission.h"
  11#include "intel_uc.h"
  12
  13#include "i915_drv.h"
  14
  15static const struct intel_uc_ops uc_ops_off;
  16static const struct intel_uc_ops uc_ops_on;
  17
  18/* Reset GuC providing us with fresh state for both GuC and HuC.
  19 */
  20static int __intel_uc_reset_hw(struct intel_uc *uc)
  21{
  22        struct intel_gt *gt = uc_to_gt(uc);
  23        int ret;
  24        u32 guc_status;
  25
  26        ret = i915_inject_probe_error(gt->i915, -ENXIO);
  27        if (ret)
  28                return ret;
  29
  30        ret = intel_reset_guc(gt);
  31        if (ret) {
  32                DRM_ERROR("Failed to reset GuC, ret = %d\n", ret);
  33                return ret;
  34        }
  35
  36        guc_status = intel_uncore_read(gt->uncore, GUC_STATUS);
  37        WARN(!(guc_status & GS_MIA_IN_RESET),
  38             "GuC status: 0x%x, MIA core expected to be in reset\n",
  39             guc_status);
  40
  41        return ret;
  42}
  43
  44static void __confirm_options(struct intel_uc *uc)
  45{
  46        struct drm_i915_private *i915 = uc_to_gt(uc)->i915;
  47
  48        DRM_DEV_DEBUG_DRIVER(i915->drm.dev,
  49                             "enable_guc=%d (guc:%s submission:%s huc:%s)\n",
  50                             i915_modparams.enable_guc,
  51                             yesno(intel_uc_wants_guc(uc)),
  52                             yesno(intel_uc_wants_guc_submission(uc)),
  53                             yesno(intel_uc_wants_huc(uc)));
  54
  55        if (i915_modparams.enable_guc == -1)
  56                return;
  57
  58        if (i915_modparams.enable_guc == 0) {
  59                GEM_BUG_ON(intel_uc_wants_guc(uc));
  60                GEM_BUG_ON(intel_uc_wants_guc_submission(uc));
  61                GEM_BUG_ON(intel_uc_wants_huc(uc));
  62                return;
  63        }
  64
  65        if (!intel_uc_supports_guc(uc))
  66                dev_info(i915->drm.dev,
  67                         "Incompatible option enable_guc=%d - %s\n",
  68                         i915_modparams.enable_guc, "GuC is not supported!");
  69
  70        if (i915_modparams.enable_guc & ENABLE_GUC_LOAD_HUC &&
  71            !intel_uc_supports_huc(uc))
  72                dev_info(i915->drm.dev,
  73                         "Incompatible option enable_guc=%d - %s\n",
  74                         i915_modparams.enable_guc, "HuC is not supported!");
  75
  76        if (i915_modparams.enable_guc & ENABLE_GUC_SUBMISSION &&
  77            !intel_uc_supports_guc_submission(uc))
  78                dev_info(i915->drm.dev,
  79                         "Incompatible option enable_guc=%d - %s\n",
  80                         i915_modparams.enable_guc, "GuC submission is N/A");
  81
  82        if (i915_modparams.enable_guc & ~(ENABLE_GUC_SUBMISSION |
  83                                          ENABLE_GUC_LOAD_HUC))
  84                dev_info(i915->drm.dev,
  85                         "Incompatible option enable_guc=%d - %s\n",
  86                         i915_modparams.enable_guc, "undocumented flag");
  87}
  88
  89void intel_uc_init_early(struct intel_uc *uc)
  90{
  91        intel_guc_init_early(&uc->guc);
  92        intel_huc_init_early(&uc->huc);
  93
  94        __confirm_options(uc);
  95
  96        if (intel_uc_wants_guc(uc))
  97                uc->ops = &uc_ops_on;
  98        else
  99                uc->ops = &uc_ops_off;
 100}
 101
 102void intel_uc_driver_late_release(struct intel_uc *uc)
 103{
 104}
 105
 106/**
 107 * intel_uc_init_mmio - setup uC MMIO access
 108 * @uc: the intel_uc structure
 109 *
 110 * Setup minimal state necessary for MMIO accesses later in the
 111 * initialization sequence.
 112 */
 113void intel_uc_init_mmio(struct intel_uc *uc)
 114{
 115        intel_guc_init_send_regs(&uc->guc);
 116}
 117
 118static void __uc_capture_load_err_log(struct intel_uc *uc)
 119{
 120        struct intel_guc *guc = &uc->guc;
 121
 122        if (guc->log.vma && !uc->load_err_log)
 123                uc->load_err_log = i915_gem_object_get(guc->log.vma->obj);
 124}
 125
 126static void __uc_free_load_err_log(struct intel_uc *uc)
 127{
 128        struct drm_i915_gem_object *log = fetch_and_zero(&uc->load_err_log);
 129
 130        if (log)
 131                i915_gem_object_put(log);
 132}
 133
 134static inline bool guc_communication_enabled(struct intel_guc *guc)
 135{
 136        return intel_guc_ct_enabled(&guc->ct);
 137}
 138
 139/*
 140 * Events triggered while CT buffers are disabled are logged in the SCRATCH_15
 141 * register using the same bits used in the CT message payload. Since our
 142 * communication channel with guc is turned off at this point, we can save the
 143 * message and handle it after we turn it back on.
 144 */
 145static void guc_clear_mmio_msg(struct intel_guc *guc)
 146{
 147        intel_uncore_write(guc_to_gt(guc)->uncore, SOFT_SCRATCH(15), 0);
 148}
 149
 150static void guc_get_mmio_msg(struct intel_guc *guc)
 151{
 152        u32 val;
 153
 154        spin_lock_irq(&guc->irq_lock);
 155
 156        val = intel_uncore_read(guc_to_gt(guc)->uncore, SOFT_SCRATCH(15));
 157        guc->mmio_msg |= val & guc->msg_enabled_mask;
 158
 159        /*
 160         * clear all events, including the ones we're not currently servicing,
 161         * to make sure we don't try to process a stale message if we enable
 162         * handling of more events later.
 163         */
 164        guc_clear_mmio_msg(guc);
 165
 166        spin_unlock_irq(&guc->irq_lock);
 167}
 168
 169static void guc_handle_mmio_msg(struct intel_guc *guc)
 170{
 171        struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
 172
 173        /* we need communication to be enabled to reply to GuC */
 174        GEM_BUG_ON(!guc_communication_enabled(guc));
 175
 176        if (!guc->mmio_msg)
 177                return;
 178
 179        spin_lock_irq(&i915->irq_lock);
 180        intel_guc_to_host_process_recv_msg(guc, &guc->mmio_msg, 1);
 181        spin_unlock_irq(&i915->irq_lock);
 182
 183        guc->mmio_msg = 0;
 184}
 185
 186static void guc_reset_interrupts(struct intel_guc *guc)
 187{
 188        guc->interrupts.reset(guc);
 189}
 190
 191static void guc_enable_interrupts(struct intel_guc *guc)
 192{
 193        guc->interrupts.enable(guc);
 194}
 195
 196static void guc_disable_interrupts(struct intel_guc *guc)
 197{
 198        guc->interrupts.disable(guc);
 199}
 200
 201static int guc_enable_communication(struct intel_guc *guc)
 202{
 203        struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
 204        int ret;
 205
 206        GEM_BUG_ON(guc_communication_enabled(guc));
 207
 208        ret = i915_inject_probe_error(i915, -ENXIO);
 209        if (ret)
 210                return ret;
 211
 212        ret = intel_guc_ct_enable(&guc->ct);
 213        if (ret)
 214                return ret;
 215
 216        /* check for mmio messages received before/during the CT enable */
 217        guc_get_mmio_msg(guc);
 218        guc_handle_mmio_msg(guc);
 219
 220        guc_enable_interrupts(guc);
 221
 222        /* check for CT messages received before we enabled interrupts */
 223        spin_lock_irq(&i915->irq_lock);
 224        intel_guc_ct_event_handler(&guc->ct);
 225        spin_unlock_irq(&i915->irq_lock);
 226
 227        DRM_INFO("GuC communication enabled\n");
 228
 229        return 0;
 230}
 231
 232static void guc_disable_communication(struct intel_guc *guc)
 233{
 234        /*
 235         * Events generated during or after CT disable are logged by guc in
 236         * via mmio. Make sure the register is clear before disabling CT since
 237         * all events we cared about have already been processed via CT.
 238         */
 239        guc_clear_mmio_msg(guc);
 240
 241        guc_disable_interrupts(guc);
 242
 243        intel_guc_ct_disable(&guc->ct);
 244
 245        /*
 246         * Check for messages received during/after the CT disable. We do not
 247         * expect any messages to have arrived via CT between the interrupt
 248         * disable and the CT disable because GuC should've been idle until we
 249         * triggered the CT disable protocol.
 250         */
 251        guc_get_mmio_msg(guc);
 252
 253        DRM_INFO("GuC communication disabled\n");
 254}
 255
 256static void __uc_fetch_firmwares(struct intel_uc *uc)
 257{
 258        int err;
 259
 260        GEM_BUG_ON(!intel_uc_wants_guc(uc));
 261
 262        err = intel_uc_fw_fetch(&uc->guc.fw);
 263        if (err)
 264                return;
 265
 266        if (intel_uc_wants_huc(uc))
 267                intel_uc_fw_fetch(&uc->huc.fw);
 268}
 269
 270static void __uc_cleanup_firmwares(struct intel_uc *uc)
 271{
 272        intel_uc_fw_cleanup_fetch(&uc->huc.fw);
 273        intel_uc_fw_cleanup_fetch(&uc->guc.fw);
 274}
 275
 276static int __uc_init(struct intel_uc *uc)
 277{
 278        struct intel_guc *guc = &uc->guc;
 279        struct intel_huc *huc = &uc->huc;
 280        int ret;
 281
 282        GEM_BUG_ON(!intel_uc_wants_guc(uc));
 283
 284        if (!intel_uc_uses_guc(uc))
 285                return 0;
 286
 287        if (i915_inject_probe_failure(uc_to_gt(uc)->i915))
 288                return -ENOMEM;
 289
 290        /* XXX: GuC submission is unavailable for now */
 291        GEM_BUG_ON(intel_uc_uses_guc_submission(uc));
 292
 293        ret = intel_guc_init(guc);
 294        if (ret)
 295                return ret;
 296
 297        if (intel_uc_uses_huc(uc)) {
 298                ret = intel_huc_init(huc);
 299                if (ret)
 300                        goto out_guc;
 301        }
 302
 303        return 0;
 304
 305out_guc:
 306        intel_guc_fini(guc);
 307        return ret;
 308}
 309
 310static void __uc_fini(struct intel_uc *uc)
 311{
 312        intel_huc_fini(&uc->huc);
 313        intel_guc_fini(&uc->guc);
 314
 315        __uc_free_load_err_log(uc);
 316}
 317
 318static int __uc_sanitize(struct intel_uc *uc)
 319{
 320        struct intel_guc *guc = &uc->guc;
 321        struct intel_huc *huc = &uc->huc;
 322
 323        GEM_BUG_ON(!intel_uc_supports_guc(uc));
 324
 325        intel_huc_sanitize(huc);
 326        intel_guc_sanitize(guc);
 327
 328        return __intel_uc_reset_hw(uc);
 329}
 330
 331/* Initialize and verify the uC regs related to uC positioning in WOPCM */
 332static int uc_init_wopcm(struct intel_uc *uc)
 333{
 334        struct intel_gt *gt = uc_to_gt(uc);
 335        struct intel_uncore *uncore = gt->uncore;
 336        u32 base = intel_wopcm_guc_base(&gt->i915->wopcm);
 337        u32 size = intel_wopcm_guc_size(&gt->i915->wopcm);
 338        u32 huc_agent = intel_uc_uses_huc(uc) ? HUC_LOADING_AGENT_GUC : 0;
 339        u32 mask;
 340        int err;
 341
 342        if (unlikely(!base || !size)) {
 343                i915_probe_error(gt->i915, "Unsuccessful WOPCM partitioning\n");
 344                return -E2BIG;
 345        }
 346
 347        GEM_BUG_ON(!intel_uc_supports_guc(uc));
 348        GEM_BUG_ON(!(base & GUC_WOPCM_OFFSET_MASK));
 349        GEM_BUG_ON(base & ~GUC_WOPCM_OFFSET_MASK);
 350        GEM_BUG_ON(!(size & GUC_WOPCM_SIZE_MASK));
 351        GEM_BUG_ON(size & ~GUC_WOPCM_SIZE_MASK);
 352
 353        err = i915_inject_probe_error(gt->i915, -ENXIO);
 354        if (err)
 355                return err;
 356
 357        mask = GUC_WOPCM_SIZE_MASK | GUC_WOPCM_SIZE_LOCKED;
 358        err = intel_uncore_write_and_verify(uncore, GUC_WOPCM_SIZE, size, mask,
 359                                            size | GUC_WOPCM_SIZE_LOCKED);
 360        if (err)
 361                goto err_out;
 362
 363        mask = GUC_WOPCM_OFFSET_MASK | GUC_WOPCM_OFFSET_VALID | huc_agent;
 364        err = intel_uncore_write_and_verify(uncore, DMA_GUC_WOPCM_OFFSET,
 365                                            base | huc_agent, mask,
 366                                            base | huc_agent |
 367                                            GUC_WOPCM_OFFSET_VALID);
 368        if (err)
 369                goto err_out;
 370
 371        return 0;
 372
 373err_out:
 374        i915_probe_error(gt->i915, "Failed to init uC WOPCM registers!\n");
 375        i915_probe_error(gt->i915, "%s(%#x)=%#x\n", "DMA_GUC_WOPCM_OFFSET",
 376                         i915_mmio_reg_offset(DMA_GUC_WOPCM_OFFSET),
 377                         intel_uncore_read(uncore, DMA_GUC_WOPCM_OFFSET));
 378        i915_probe_error(gt->i915, "%s(%#x)=%#x\n", "GUC_WOPCM_SIZE",
 379                         i915_mmio_reg_offset(GUC_WOPCM_SIZE),
 380                         intel_uncore_read(uncore, GUC_WOPCM_SIZE));
 381
 382        return err;
 383}
 384
 385static bool uc_is_wopcm_locked(struct intel_uc *uc)
 386{
 387        struct intel_gt *gt = uc_to_gt(uc);
 388        struct intel_uncore *uncore = gt->uncore;
 389
 390        return (intel_uncore_read(uncore, GUC_WOPCM_SIZE) & GUC_WOPCM_SIZE_LOCKED) ||
 391               (intel_uncore_read(uncore, DMA_GUC_WOPCM_OFFSET) & GUC_WOPCM_OFFSET_VALID);
 392}
 393
 394static int __uc_check_hw(struct intel_uc *uc)
 395{
 396        if (!intel_uc_supports_guc(uc))
 397                return 0;
 398
 399        /*
 400         * We can silently continue without GuC only if it was never enabled
 401         * before on this system after reboot, otherwise we risk GPU hangs.
 402         * To check if GuC was loaded before we look at WOPCM registers.
 403         */
 404        if (uc_is_wopcm_locked(uc))
 405                return -EIO;
 406
 407        return 0;
 408}
 409
 410static int __uc_init_hw(struct intel_uc *uc)
 411{
 412        struct drm_i915_private *i915 = uc_to_gt(uc)->i915;
 413        struct intel_guc *guc = &uc->guc;
 414        struct intel_huc *huc = &uc->huc;
 415        int ret, attempts;
 416
 417        GEM_BUG_ON(!intel_uc_supports_guc(uc));
 418        GEM_BUG_ON(!intel_uc_wants_guc(uc));
 419
 420        if (!intel_uc_fw_is_loadable(&guc->fw)) {
 421                ret = __uc_check_hw(uc) ||
 422                      intel_uc_fw_is_overridden(&guc->fw) ||
 423                      intel_uc_wants_guc_submission(uc) ?
 424                      intel_uc_fw_status_to_error(guc->fw.status) : 0;
 425                goto err_out;
 426        }
 427
 428        ret = uc_init_wopcm(uc);
 429        if (ret)
 430                goto err_out;
 431
 432        guc_reset_interrupts(guc);
 433
 434        /* WaEnableuKernelHeaderValidFix:skl */
 435        /* WaEnableGuCBootHashCheckNotSet:skl,bxt,kbl */
 436        if (IS_GEN(i915, 9))
 437                attempts = 3;
 438        else
 439                attempts = 1;
 440
 441        while (attempts--) {
 442                /*
 443                 * Always reset the GuC just before (re)loading, so
 444                 * that the state and timing are fairly predictable
 445                 */
 446                ret = __uc_sanitize(uc);
 447                if (ret)
 448                        goto err_out;
 449
 450                intel_huc_fw_upload(huc);
 451                intel_guc_ads_reset(guc);
 452                intel_guc_write_params(guc);
 453                ret = intel_guc_fw_upload(guc);
 454                if (ret == 0)
 455                        break;
 456
 457                DRM_DEBUG_DRIVER("GuC fw load failed: %d; will reset and "
 458                                 "retry %d more time(s)\n", ret, attempts);
 459        }
 460
 461        /* Did we succeded or run out of retries? */
 462        if (ret)
 463                goto err_log_capture;
 464
 465        ret = guc_enable_communication(guc);
 466        if (ret)
 467                goto err_log_capture;
 468
 469        intel_huc_auth(huc);
 470
 471        ret = intel_guc_sample_forcewake(guc);
 472        if (ret)
 473                goto err_communication;
 474
 475        if (intel_uc_uses_guc_submission(uc))
 476                intel_guc_submission_enable(guc);
 477
 478        dev_info(i915->drm.dev, "%s firmware %s version %u.%u %s:%s\n",
 479                 intel_uc_fw_type_repr(INTEL_UC_FW_TYPE_GUC), guc->fw.path,
 480                 guc->fw.major_ver_found, guc->fw.minor_ver_found,
 481                 "submission",
 482                 enableddisabled(intel_uc_uses_guc_submission(uc)));
 483
 484        if (intel_uc_uses_huc(uc)) {
 485                dev_info(i915->drm.dev, "%s firmware %s version %u.%u %s:%s\n",
 486                         intel_uc_fw_type_repr(INTEL_UC_FW_TYPE_HUC),
 487                         huc->fw.path,
 488                         huc->fw.major_ver_found, huc->fw.minor_ver_found,
 489                         "authenticated",
 490                         yesno(intel_huc_is_authenticated(huc)));
 491        }
 492
 493        return 0;
 494
 495        /*
 496         * We've failed to load the firmware :(
 497         */
 498err_communication:
 499        guc_disable_communication(guc);
 500err_log_capture:
 501        __uc_capture_load_err_log(uc);
 502err_out:
 503        __uc_sanitize(uc);
 504
 505        if (!ret) {
 506                dev_notice(i915->drm.dev, "GuC is uninitialized\n");
 507                /* We want to run without GuC submission */
 508                return 0;
 509        }
 510
 511        i915_probe_error(i915, "GuC initialization failed %d\n", ret);
 512
 513        /* We want to keep KMS alive */
 514        return -EIO;
 515}
 516
 517static void __uc_fini_hw(struct intel_uc *uc)
 518{
 519        struct intel_guc *guc = &uc->guc;
 520
 521        if (!intel_guc_is_fw_running(guc))
 522                return;
 523
 524        if (intel_uc_uses_guc_submission(uc))
 525                intel_guc_submission_disable(guc);
 526
 527        if (guc_communication_enabled(guc))
 528                guc_disable_communication(guc);
 529
 530        __uc_sanitize(uc);
 531}
 532
 533/**
 534 * intel_uc_reset_prepare - Prepare for reset
 535 * @uc: the intel_uc structure
 536 *
 537 * Preparing for full gpu reset.
 538 */
 539void intel_uc_reset_prepare(struct intel_uc *uc)
 540{
 541        struct intel_guc *guc = &uc->guc;
 542
 543        if (!intel_guc_is_ready(guc))
 544                return;
 545
 546        guc_disable_communication(guc);
 547        __uc_sanitize(uc);
 548}
 549
 550void intel_uc_runtime_suspend(struct intel_uc *uc)
 551{
 552        struct intel_guc *guc = &uc->guc;
 553        int err;
 554
 555        if (!intel_guc_is_ready(guc))
 556                return;
 557
 558        err = intel_guc_suspend(guc);
 559        if (err)
 560                DRM_DEBUG_DRIVER("Failed to suspend GuC, err=%d", err);
 561
 562        guc_disable_communication(guc);
 563}
 564
 565void intel_uc_suspend(struct intel_uc *uc)
 566{
 567        struct intel_guc *guc = &uc->guc;
 568        intel_wakeref_t wakeref;
 569
 570        if (!intel_guc_is_ready(guc))
 571                return;
 572
 573        with_intel_runtime_pm(uc_to_gt(uc)->uncore->rpm, wakeref)
 574                intel_uc_runtime_suspend(uc);
 575}
 576
 577static int __uc_resume(struct intel_uc *uc, bool enable_communication)
 578{
 579        struct intel_guc *guc = &uc->guc;
 580        int err;
 581
 582        if (!intel_guc_is_fw_running(guc))
 583                return 0;
 584
 585        /* Make sure we enable communication if and only if it's disabled */
 586        GEM_BUG_ON(enable_communication == guc_communication_enabled(guc));
 587
 588        if (enable_communication)
 589                guc_enable_communication(guc);
 590
 591        err = intel_guc_resume(guc);
 592        if (err) {
 593                DRM_DEBUG_DRIVER("Failed to resume GuC, err=%d", err);
 594                return err;
 595        }
 596
 597        return 0;
 598}
 599
 600int intel_uc_resume(struct intel_uc *uc)
 601{
 602        /*
 603         * When coming out of S3/S4 we sanitize and re-init the HW, so
 604         * communication is already re-enabled at this point.
 605         */
 606        return __uc_resume(uc, false);
 607}
 608
 609int intel_uc_runtime_resume(struct intel_uc *uc)
 610{
 611        /*
 612         * During runtime resume we don't sanitize, so we need to re-init
 613         * communication as well.
 614         */
 615        return __uc_resume(uc, true);
 616}
 617
 618static const struct intel_uc_ops uc_ops_off = {
 619        .init_hw = __uc_check_hw,
 620};
 621
 622static const struct intel_uc_ops uc_ops_on = {
 623        .sanitize = __uc_sanitize,
 624
 625        .init_fw = __uc_fetch_firmwares,
 626        .fini_fw = __uc_cleanup_firmwares,
 627
 628        .init = __uc_init,
 629        .fini = __uc_fini,
 630
 631        .init_hw = __uc_init_hw,
 632        .fini_hw = __uc_fini_hw,
 633};
 634