LCOV - code coverage report
Current view: top level - drivers/gpu/drm/i915/gt/uc - intel_uc.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 265 0.0 %
Date: 2022-04-01 13:59:58 Functions: 0 26 0.0 %
Branches: 0 138 0.0 %

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

Generated by: LCOV version 1.14