1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2022 Intel Corporation 4 */ 5 6 #include "gt/intel_engine_pm.h" 7 #include "gt/intel_gpu_commands.h" 8 #include "gt/intel_gt.h" 9 #include "gt/intel_gt_print.h" 10 #include "gt/intel_ring.h" 11 #include "intel_gsc_fw.h" 12 13 #define GSC_FW_STATUS_REG _MMIO(0x116C40) 14 #define GSC_FW_CURRENT_STATE REG_GENMASK(3, 0) 15 #define GSC_FW_CURRENT_STATE_RESET 0 16 #define GSC_FW_INIT_COMPLETE_BIT REG_BIT(9) 17 18 static bool gsc_is_in_reset(struct intel_uncore *uncore) 19 { 20 u32 fw_status = intel_uncore_read(uncore, GSC_FW_STATUS_REG); 21 22 return REG_FIELD_GET(GSC_FW_CURRENT_STATE, fw_status) == 23 GSC_FW_CURRENT_STATE_RESET; 24 } 25 26 bool intel_gsc_uc_fw_init_done(struct intel_gsc_uc *gsc) 27 { 28 struct intel_uncore *uncore = gsc_uc_to_gt(gsc)->uncore; 29 u32 fw_status = intel_uncore_read(uncore, GSC_FW_STATUS_REG); 30 31 return fw_status & GSC_FW_INIT_COMPLETE_BIT; 32 } 33 34 static int emit_gsc_fw_load(struct i915_request *rq, struct intel_gsc_uc *gsc) 35 { 36 u32 offset = i915_ggtt_offset(gsc->local); 37 u32 *cs; 38 39 cs = intel_ring_begin(rq, 4); 40 if (IS_ERR(cs)) 41 return PTR_ERR(cs); 42 43 *cs++ = GSC_FW_LOAD; 44 *cs++ = lower_32_bits(offset); 45 *cs++ = upper_32_bits(offset); 46 *cs++ = (gsc->local->size / SZ_4K) | HECI1_FW_LIMIT_VALID; 47 48 intel_ring_advance(rq, cs); 49 50 return 0; 51 } 52 53 static int gsc_fw_load(struct intel_gsc_uc *gsc) 54 { 55 struct intel_context *ce = gsc->ce; 56 struct i915_request *rq; 57 int err; 58 59 if (!ce) 60 return -ENODEV; 61 62 rq = i915_request_create(ce); 63 if (IS_ERR(rq)) 64 return PTR_ERR(rq); 65 66 if (ce->engine->emit_init_breadcrumb) { 67 err = ce->engine->emit_init_breadcrumb(rq); 68 if (err) 69 goto out_rq; 70 } 71 72 err = emit_gsc_fw_load(rq, gsc); 73 if (err) 74 goto out_rq; 75 76 err = ce->engine->emit_flush(rq, 0); 77 78 out_rq: 79 i915_request_get(rq); 80 81 if (unlikely(err)) 82 i915_request_set_error_once(rq, err); 83 84 i915_request_add(rq); 85 86 if (!err && i915_request_wait(rq, 0, msecs_to_jiffies(500)) < 0) 87 err = -ETIME; 88 89 i915_request_put(rq); 90 91 if (err) 92 gt_err(gsc_uc_to_gt(gsc), "Request submission for GSC load failed %pe\n", 93 ERR_PTR(err)); 94 95 return err; 96 } 97 98 static int gsc_fw_load_prepare(struct intel_gsc_uc *gsc) 99 { 100 struct intel_gt *gt = gsc_uc_to_gt(gsc); 101 struct drm_i915_private *i915 = gt->i915; 102 struct drm_i915_gem_object *obj; 103 void *src, *dst; 104 105 if (!gsc->local) 106 return -ENODEV; 107 108 obj = gsc->local->obj; 109 110 if (obj->base.size < gsc->fw.size) 111 return -ENOSPC; 112 113 dst = i915_gem_object_pin_map_unlocked(obj, 114 i915_coherent_map_type(i915, obj, true)); 115 if (IS_ERR(dst)) 116 return PTR_ERR(dst); 117 118 src = i915_gem_object_pin_map_unlocked(gsc->fw.obj, 119 i915_coherent_map_type(i915, gsc->fw.obj, true)); 120 if (IS_ERR(src)) { 121 i915_gem_object_unpin_map(obj); 122 return PTR_ERR(src); 123 } 124 125 memset(dst, 0, obj->base.size); 126 memcpy(dst, src, gsc->fw.size); 127 128 i915_gem_object_unpin_map(gsc->fw.obj); 129 i915_gem_object_unpin_map(obj); 130 131 return 0; 132 } 133 134 static int gsc_fw_wait(struct intel_gt *gt) 135 { 136 return intel_wait_for_register(gt->uncore, 137 GSC_FW_STATUS_REG, 138 GSC_FW_INIT_COMPLETE_BIT, 139 GSC_FW_INIT_COMPLETE_BIT, 140 500); 141 } 142 143 int intel_gsc_uc_fw_upload(struct intel_gsc_uc *gsc) 144 { 145 struct intel_gt *gt = gsc_uc_to_gt(gsc); 146 struct intel_uc_fw *gsc_fw = &gsc->fw; 147 int err; 148 149 /* check current fw status */ 150 if (intel_gsc_uc_fw_init_done(gsc)) { 151 if (GEM_WARN_ON(!intel_uc_fw_is_loaded(gsc_fw))) 152 intel_uc_fw_change_status(gsc_fw, INTEL_UC_FIRMWARE_TRANSFERRED); 153 return -EEXIST; 154 } 155 156 if (!intel_uc_fw_is_loadable(gsc_fw)) 157 return -ENOEXEC; 158 159 /* FW blob is ok, so clean the status */ 160 intel_uc_fw_sanitize(&gsc->fw); 161 162 if (!gsc_is_in_reset(gt->uncore)) 163 return -EIO; 164 165 err = gsc_fw_load_prepare(gsc); 166 if (err) 167 goto fail; 168 169 /* 170 * GSC is only killed by an FLR, so we need to trigger one on unload to 171 * make sure we stop it. This is because we assign a chunk of memory to 172 * the GSC as part of the FW load , so we need to make sure it stops 173 * using it when we release it to the system on driver unload. Note that 174 * this is not a problem of the unload per-se, because the GSC will not 175 * touch that memory unless there are requests for it coming from the 176 * driver; therefore, no accesses will happen while i915 is not loaded, 177 * but if we re-load the driver then the GSC might wake up and try to 178 * access that old memory location again. 179 * Given that an FLR is a very disruptive action (see the FLR function 180 * for details), we want to do it as the last action before releasing 181 * the access to the MMIO bar, which means we need to do it as part of 182 * the primary uncore cleanup. 183 * An alternative approach to the FLR would be to use a memory location 184 * that survives driver unload, like e.g. stolen memory, and keep the 185 * GSC loaded across reloads. However, this requires us to make sure we 186 * preserve that memory location on unload and then determine and 187 * reserve its offset on each subsequent load, which is not trivial, so 188 * it is easier to just kill everything and start fresh. 189 */ 190 intel_uncore_set_flr_on_fini(>->i915->uncore); 191 192 err = gsc_fw_load(gsc); 193 if (err) 194 goto fail; 195 196 err = gsc_fw_wait(gt); 197 if (err) 198 goto fail; 199 200 /* FW is not fully operational until we enable SW proxy */ 201 intel_uc_fw_change_status(gsc_fw, INTEL_UC_FIRMWARE_TRANSFERRED); 202 203 gt_info(gt, "Loaded GSC firmware %s\n", gsc_fw->file_selected.path); 204 205 return 0; 206 207 fail: 208 return intel_uc_fw_mark_load_failed(gsc_fw, err); 209 } 210