Skip to content

Commit 4502e9e

Browse files
mwajdeczjlahtine-intel
authored andcommitted
drm/i915/uc: Unify firmware loading
Firmware loading for GuC and HuC are similar. Move common code into generic function for maximum reuse. v2: change message levels (Chris) Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Cc: Sagar Arun Kamble <sagar.a.kamble@intel.com> Cc: Anusha Srivatsa <anusha.srivatsa@intel.com> Cc: Sujaritha Sundaresan <sujaritha.sundaresan@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20171016144724.17244-13-michal.wajdeczko@intel.com
1 parent f1e86ce commit 4502e9e

File tree

4 files changed

+93
-95
lines changed

4 files changed

+93
-95
lines changed

drivers/gpu/drm/i915/intel_guc_fw.c

Lines changed: 5 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -188,24 +188,13 @@ static int guc_ucode_xfer_dma(struct drm_i915_private *dev_priv,
188188
/*
189189
* Load the GuC firmware blob into the MinuteIA.
190190
*/
191-
static int guc_ucode_xfer(struct drm_i915_private *dev_priv)
191+
static int guc_ucode_xfer(struct intel_uc_fw *guc_fw, struct i915_vma *vma)
192192
{
193-
struct intel_uc_fw *guc_fw = &dev_priv->guc.fw;
194-
struct i915_vma *vma;
193+
struct intel_guc *guc = container_of(guc_fw, struct intel_guc, fw);
194+
struct drm_i915_private *dev_priv = guc_to_i915(guc);
195195
int ret;
196196

197-
ret = i915_gem_object_set_to_gtt_domain(guc_fw->obj, false);
198-
if (ret) {
199-
DRM_DEBUG_DRIVER("set-domain failed %d\n", ret);
200-
return ret;
201-
}
202-
203-
vma = i915_gem_object_ggtt_pin(guc_fw->obj, NULL, 0, 0,
204-
PIN_OFFSET_BIAS | GUC_WOPCM_TOP);
205-
if (IS_ERR(vma)) {
206-
DRM_DEBUG_DRIVER("pin failed %d\n", (int)PTR_ERR(vma));
207-
return PTR_ERR(vma);
208-
}
197+
GEM_BUG_ON(guc_fw->type != INTEL_UC_FW_TYPE_GUC);
209198

210199
intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
211200

@@ -240,12 +229,6 @@ static int guc_ucode_xfer(struct drm_i915_private *dev_priv)
240229

241230
intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
242231

243-
/*
244-
* We keep the object pages for reuse during resume. But we can unpin it
245-
* now that DMA has completed, so it doesn't continue to take up space.
246-
*/
247-
i915_vma_unpin(vma);
248-
249232
return ret;
250233
}
251234

@@ -264,30 +247,5 @@ static int guc_ucode_xfer(struct drm_i915_private *dev_priv)
264247
*/
265248
int intel_guc_fw_upload(struct intel_guc *guc)
266249
{
267-
struct drm_i915_private *dev_priv = guc_to_i915(guc);
268-
const char *fw_path = guc->fw.path;
269-
int ret;
270-
271-
DRM_DEBUG_DRIVER("GuC fw status: path %s, fetch %s, load %s\n",
272-
fw_path,
273-
intel_uc_fw_status_repr(guc->fw.fetch_status),
274-
intel_uc_fw_status_repr(guc->fw.load_status));
275-
276-
if (guc->fw.fetch_status != INTEL_UC_FIRMWARE_SUCCESS)
277-
return -EIO;
278-
279-
guc->fw.load_status = INTEL_UC_FIRMWARE_PENDING;
280-
281-
DRM_DEBUG_DRIVER("GuC fw status: fetch %s, load %s\n",
282-
intel_uc_fw_status_repr(guc->fw.fetch_status),
283-
intel_uc_fw_status_repr(guc->fw.load_status));
284-
285-
ret = guc_ucode_xfer(dev_priv);
286-
287-
if (ret)
288-
return -EAGAIN;
289-
290-
guc->fw.load_status = INTEL_UC_FIRMWARE_SUCCESS;
291-
292-
return 0;
250+
return intel_uc_fw_upload(&guc->fw, guc_ucode_xfer);
293251
}

drivers/gpu/drm/i915/intel_huc.c

Lines changed: 5 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -85,26 +85,15 @@ MODULE_FIRMWARE(I915_KBL_HUC_UCODE);
8585
*
8686
* Return: 0 on success, non-zero on failure
8787
*/
88-
static int huc_ucode_xfer(struct drm_i915_private *dev_priv)
88+
static int huc_ucode_xfer(struct intel_uc_fw *huc_fw, struct i915_vma *vma)
8989
{
90-
struct intel_uc_fw *huc_fw = &dev_priv->huc.fw;
91-
struct i915_vma *vma;
90+
struct intel_huc *huc = container_of(huc_fw, struct intel_huc, fw);
91+
struct drm_i915_private *dev_priv = huc_to_i915(huc);
9292
unsigned long offset = 0;
9393
u32 size;
9494
int ret;
9595

96-
ret = i915_gem_object_set_to_gtt_domain(huc_fw->obj, false);
97-
if (ret) {
98-
DRM_DEBUG_DRIVER("set-domain failed %d\n", ret);
99-
return ret;
100-
}
101-
102-
vma = i915_gem_object_ggtt_pin(huc_fw->obj, NULL, 0, 0,
103-
PIN_OFFSET_BIAS | GUC_WOPCM_TOP);
104-
if (IS_ERR(vma)) {
105-
DRM_DEBUG_DRIVER("pin failed %d\n", (int)PTR_ERR(vma));
106-
return PTR_ERR(vma);
107-
}
96+
GEM_BUG_ON(huc_fw->type != INTEL_UC_FW_TYPE_HUC);
10897

10998
intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
11099

@@ -135,12 +124,6 @@ static int huc_ucode_xfer(struct drm_i915_private *dev_priv)
135124

136125
intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
137126

138-
/*
139-
* We keep the object pages for reuse during resume. But we can unpin it
140-
* now that DMA has completed, so it doesn't continue to take up space.
141-
*/
142-
i915_vma_unpin(vma);
143-
144127
return ret;
145128
}
146129

@@ -194,33 +177,7 @@ void intel_huc_select_fw(struct intel_huc *huc)
194177
*/
195178
void intel_huc_init_hw(struct intel_huc *huc)
196179
{
197-
struct drm_i915_private *dev_priv = huc_to_i915(huc);
198-
int err;
199-
200-
DRM_DEBUG_DRIVER("%s fw status: fetch %s, load %s\n",
201-
huc->fw.path,
202-
intel_uc_fw_status_repr(huc->fw.fetch_status),
203-
intel_uc_fw_status_repr(huc->fw.load_status));
204-
205-
if (huc->fw.fetch_status != INTEL_UC_FIRMWARE_SUCCESS)
206-
return;
207-
208-
huc->fw.load_status = INTEL_UC_FIRMWARE_PENDING;
209-
210-
err = huc_ucode_xfer(dev_priv);
211-
212-
huc->fw.load_status = err ?
213-
INTEL_UC_FIRMWARE_FAIL : INTEL_UC_FIRMWARE_SUCCESS;
214-
215-
DRM_DEBUG_DRIVER("%s fw status: fetch %s, load %s\n",
216-
huc->fw.path,
217-
intel_uc_fw_status_repr(huc->fw.fetch_status),
218-
intel_uc_fw_status_repr(huc->fw.load_status));
219-
220-
if (huc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS)
221-
DRM_ERROR("Failed to complete HuC uCode load with ret %d\n", err);
222-
223-
return;
180+
intel_uc_fw_upload(&huc->fw, huc_ucode_xfer);
224181
}
225182

226183
/**

drivers/gpu/drm/i915/intel_uc_fw.c

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,85 @@ void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
194194
release_firmware(fw); /* OK even if fw is NULL */
195195
}
196196

197+
/**
198+
* intel_uc_fw_upload - load uC firmware using custom loader
199+
*
200+
* @uc_fw: uC firmware
201+
* @loader: custom uC firmware loader function
202+
*
203+
* Loads uC firmware using custom loader and updates internal flags.
204+
*/
205+
int intel_uc_fw_upload(struct intel_uc_fw *uc_fw,
206+
int (*xfer)(struct intel_uc_fw *uc_fw,
207+
struct i915_vma *vma))
208+
{
209+
struct i915_vma *vma;
210+
int err;
211+
212+
DRM_DEBUG_DRIVER("%s fw load %s\n",
213+
intel_uc_fw_type_repr(uc_fw->type), uc_fw->path);
214+
215+
if (uc_fw->fetch_status != INTEL_UC_FIRMWARE_SUCCESS)
216+
return -EIO;
217+
218+
uc_fw->load_status = INTEL_UC_FIRMWARE_PENDING;
219+
DRM_DEBUG_DRIVER("%s fw load %s\n",
220+
intel_uc_fw_type_repr(uc_fw->type),
221+
intel_uc_fw_status_repr(uc_fw->load_status));
222+
223+
/* Pin object with firmware */
224+
err = i915_gem_object_set_to_gtt_domain(uc_fw->obj, false);
225+
if (err) {
226+
DRM_DEBUG_DRIVER("%s fw set-domain err=%d\n",
227+
intel_uc_fw_type_repr(uc_fw->type), err);
228+
goto fail;
229+
}
230+
231+
vma = i915_gem_object_ggtt_pin(uc_fw->obj, NULL, 0, 0,
232+
PIN_OFFSET_BIAS | GUC_WOPCM_TOP);
233+
if (IS_ERR(vma)) {
234+
err = PTR_ERR(vma);
235+
DRM_DEBUG_DRIVER("%s fw ggtt-pin err=%d\n",
236+
intel_uc_fw_type_repr(uc_fw->type), err);
237+
goto fail;
238+
}
239+
240+
/* Call custom loader */
241+
err = xfer(uc_fw, vma);
242+
243+
/*
244+
* We keep the object pages for reuse during resume. But we can unpin it
245+
* now that DMA has completed, so it doesn't continue to take up space.
246+
*/
247+
i915_vma_unpin(vma);
248+
249+
if (err)
250+
goto fail;
251+
252+
uc_fw->load_status = INTEL_UC_FIRMWARE_SUCCESS;
253+
DRM_DEBUG_DRIVER("%s fw load %s\n",
254+
intel_uc_fw_type_repr(uc_fw->type),
255+
intel_uc_fw_status_repr(uc_fw->load_status));
256+
257+
DRM_INFO("%s: Loaded firmware %s (version %u.%u)\n",
258+
intel_uc_fw_type_repr(uc_fw->type),
259+
uc_fw->path,
260+
uc_fw->major_ver_found, uc_fw->minor_ver_found);
261+
262+
return 0;
263+
264+
fail:
265+
uc_fw->load_status = INTEL_UC_FIRMWARE_FAIL;
266+
DRM_DEBUG_DRIVER("%s fw load %s\n",
267+
intel_uc_fw_type_repr(uc_fw->type),
268+
intel_uc_fw_status_repr(uc_fw->load_status));
269+
270+
DRM_WARN("%s: Failed to load firmware %s (error %d)\n",
271+
intel_uc_fw_type_repr(uc_fw->type), uc_fw->path, err);
272+
273+
return err;
274+
}
275+
197276
/**
198277
* intel_uc_fw_fini - cleanup uC firmware
199278
*

drivers/gpu/drm/i915/intel_uc_fw.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#define _INTEL_UC_FW_H_
2727

2828
struct drm_i915_private;
29+
struct i915_vma;
2930

3031
/* Home of GuC, HuC and DMC firmwares */
3132
#define INTEL_UC_FIRMWARE_URL "https://01.org/linuxgraphics/downloads/firmware"
@@ -110,6 +111,9 @@ void intel_uc_fw_init(struct intel_uc_fw *uc_fw, enum intel_uc_fw_type type)
110111

111112
void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
112113
struct intel_uc_fw *uc_fw);
114+
int intel_uc_fw_upload(struct intel_uc_fw *uc_fw,
115+
int (*xfer)(struct intel_uc_fw *uc_fw,
116+
struct i915_vma *vma));
113117
void intel_uc_fw_fini(struct intel_uc_fw *uc_fw);
114118

115119
#endif

0 commit comments

Comments
 (0)