1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2022 Intel Corporation 4 */ 5 6 #include <linux/types.h> 7 8 #include "gt/intel_gt.h" 9 #include "gt/intel_gt_print.h" 10 #include "intel_gsc_uc.h" 11 #include "intel_gsc_fw.h" 12 #include "i915_drv.h" 13 #include "intel_gsc_proxy.h" 14 15 static void gsc_work(struct work_struct *work) 16 { 17 struct intel_gsc_uc *gsc = container_of(work, typeof(*gsc), work); 18 struct intel_gt *gt = gsc_uc_to_gt(gsc); 19 intel_wakeref_t wakeref; 20 u32 actions; 21 int ret; 22 23 wakeref = intel_runtime_pm_get(gt->uncore->rpm); 24 25 spin_lock_irq(gt->irq_lock); 26 actions = gsc->gsc_work_actions; 27 gsc->gsc_work_actions = 0; 28 spin_unlock_irq(gt->irq_lock); 29 30 if (actions & GSC_ACTION_FW_LOAD) { 31 ret = intel_gsc_uc_fw_upload(gsc); 32 if (ret == -EEXIST) /* skip proxy if not a new load */ 33 actions &= ~GSC_ACTION_FW_LOAD; 34 else if (ret) 35 goto out_put; 36 } 37 38 if (actions & (GSC_ACTION_FW_LOAD | GSC_ACTION_SW_PROXY)) { 39 if (!intel_gsc_uc_fw_init_done(gsc)) { 40 gt_err(gt, "Proxy request received with GSC not loaded!\n"); 41 goto out_put; 42 } 43 44 ret = intel_gsc_proxy_request_handler(gsc); 45 if (ret) 46 goto out_put; 47 48 /* mark the GSC FW init as done the first time we run this */ 49 if (actions & GSC_ACTION_FW_LOAD) { 50 /* 51 * If there is a proxy establishment error, the GSC might still 52 * complete the request handling cleanly, so we need to check the 53 * status register to check if the proxy init was actually successful 54 */ 55 if (intel_gsc_uc_fw_proxy_init_done(gsc)) { 56 drm_dbg(>->i915->drm, "GSC Proxy initialized\n"); 57 intel_uc_fw_change_status(&gsc->fw, INTEL_UC_FIRMWARE_RUNNING); 58 } else { 59 drm_err(>->i915->drm, 60 "GSC status reports proxy init not complete\n"); 61 } 62 } 63 } 64 65 out_put: 66 intel_runtime_pm_put(gt->uncore->rpm, wakeref); 67 } 68 69 static bool gsc_engine_supported(struct intel_gt *gt) 70 { 71 intel_engine_mask_t mask; 72 73 /* 74 * We reach here from i915_driver_early_probe for the primary GT before 75 * its engine mask is set, so we use the device info engine mask for it. 76 * For other GTs we expect the GT-specific mask to be set before we 77 * call this function. 78 */ 79 GEM_BUG_ON(!gt_is_root(gt) && !gt->info.engine_mask); 80 81 if (gt_is_root(gt)) 82 mask = RUNTIME_INFO(gt->i915)->platform_engine_mask; 83 else 84 mask = gt->info.engine_mask; 85 86 return __HAS_ENGINE(mask, GSC0); 87 } 88 89 void intel_gsc_uc_init_early(struct intel_gsc_uc *gsc) 90 { 91 struct intel_gt *gt = gsc_uc_to_gt(gsc); 92 93 intel_uc_fw_init_early(&gsc->fw, INTEL_UC_FW_TYPE_GSC); 94 INIT_WORK(&gsc->work, gsc_work); 95 96 /* we can arrive here from i915_driver_early_probe for primary 97 * GT with it being not fully setup hence check device info's 98 * engine mask 99 */ 100 if (!gsc_engine_supported(gt)) { 101 intel_uc_fw_change_status(&gsc->fw, INTEL_UC_FIRMWARE_NOT_SUPPORTED); 102 return; 103 } 104 105 gsc->wq = alloc_ordered_workqueue("i915_gsc", 0); 106 if (!gsc->wq) { 107 gt_err(gt, "failed to allocate WQ for GSC, disabling FW\n"); 108 intel_uc_fw_change_status(&gsc->fw, INTEL_UC_FIRMWARE_NOT_SUPPORTED); 109 } 110 } 111 112 int intel_gsc_uc_init(struct intel_gsc_uc *gsc) 113 { 114 static struct lock_class_key gsc_lock; 115 struct intel_gt *gt = gsc_uc_to_gt(gsc); 116 struct intel_engine_cs *engine = gt->engine[GSC0]; 117 struct intel_context *ce; 118 struct i915_vma *vma; 119 int err; 120 121 err = intel_uc_fw_init(&gsc->fw); 122 if (err) 123 goto out; 124 125 vma = intel_guc_allocate_vma(>->uc.guc, SZ_8M); 126 if (IS_ERR(vma)) { 127 err = PTR_ERR(vma); 128 goto out_fw; 129 } 130 131 gsc->local = vma; 132 133 ce = intel_engine_create_pinned_context(engine, engine->gt->vm, SZ_4K, 134 I915_GEM_HWS_GSC_ADDR, 135 &gsc_lock, "gsc_context"); 136 if (IS_ERR(ce)) { 137 gt_err(gt, "failed to create GSC CS ctx for FW communication\n"); 138 err = PTR_ERR(ce); 139 goto out_vma; 140 } 141 142 gsc->ce = ce; 143 144 /* if we fail to init proxy we still want to load GSC for PM */ 145 intel_gsc_proxy_init(gsc); 146 147 intel_uc_fw_change_status(&gsc->fw, INTEL_UC_FIRMWARE_LOADABLE); 148 149 return 0; 150 151 out_vma: 152 i915_vma_unpin_and_release(&gsc->local, 0); 153 out_fw: 154 intel_uc_fw_fini(&gsc->fw); 155 out: 156 gt_probe_error(gt, "GSC init failed %pe\n", ERR_PTR(err)); 157 return err; 158 } 159 160 void intel_gsc_uc_fini(struct intel_gsc_uc *gsc) 161 { 162 if (!intel_uc_fw_is_loadable(&gsc->fw)) 163 return; 164 165 flush_work(&gsc->work); 166 if (gsc->wq) { 167 destroy_workqueue(gsc->wq); 168 gsc->wq = NULL; 169 } 170 171 intel_gsc_proxy_fini(gsc); 172 173 if (gsc->ce) 174 intel_engine_destroy_pinned_context(fetch_and_zero(&gsc->ce)); 175 176 i915_vma_unpin_and_release(&gsc->local, 0); 177 178 intel_uc_fw_fini(&gsc->fw); 179 } 180 181 void intel_gsc_uc_flush_work(struct intel_gsc_uc *gsc) 182 { 183 if (!intel_uc_fw_is_loadable(&gsc->fw)) 184 return; 185 186 flush_work(&gsc->work); 187 } 188 189 void intel_gsc_uc_resume(struct intel_gsc_uc *gsc) 190 { 191 if (!intel_uc_fw_is_loadable(&gsc->fw)) 192 return; 193 194 /* 195 * we only want to start the GSC worker from here in the actual resume 196 * flow and not during driver load. This is because GSC load is slow and 197 * therefore we want to make sure that the default state init completes 198 * first to not slow down the init thread. A separate call to 199 * intel_gsc_uc_load_start will ensure that the GSC is loaded during 200 * driver load. 201 */ 202 if (!gsc_uc_to_gt(gsc)->engine[GSC0]->default_state) 203 return; 204 205 intel_gsc_uc_load_start(gsc); 206 } 207 208 void intel_gsc_uc_load_start(struct intel_gsc_uc *gsc) 209 { 210 struct intel_gt *gt = gsc_uc_to_gt(gsc); 211 212 if (!intel_uc_fw_is_loadable(&gsc->fw)) 213 return; 214 215 if (intel_gsc_uc_fw_init_done(gsc)) 216 return; 217 218 spin_lock_irq(gt->irq_lock); 219 gsc->gsc_work_actions |= GSC_ACTION_FW_LOAD; 220 spin_unlock_irq(gt->irq_lock); 221 222 queue_work(gsc->wq, &gsc->work); 223 } 224