Message ID | 1430345615-5576-8-git-send-email-yu.dai@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 29/04/15 23:13, yu.dai@intel.com wrote: > From: Alex Dai <yu.dai@intel.com> > > All gem objects used by GuC are pinned to ggtt space out of range > [0, WOPCM size]. In GuC address space mapping, [0, WPOCM size] is > used internally for its Boot ROM, SRAM etc. Currently this WPOCM > size is 512K. This is done by using of PIN_OFFSET_BIAS. > > Issue: VIZ-4884 > Signed-off-by: Alex Dai <yu.dai@intel.com> > --- > drivers/gpu/drm/i915/intel_guc.h | 3 ++ > drivers/gpu/drm/i915/intel_guc_loader.c | 55 +++++++++++++++++++++++++++++++++ Code below looks fine but it doesn't belong in the loader.c file. Let's put it in the "scheduler" file (which will get renamed later). .Dave. > 2 files changed, 58 insertions(+) > > diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h > index c6886d1..3082a3e 100644 > --- a/drivers/gpu/drm/i915/intel_guc.h > +++ b/drivers/gpu/drm/i915/intel_guc.h > @@ -102,5 +102,8 @@ struct intel_guc { > extern int intel_guc_ucode_load(struct drm_device *dev, bool wait); > extern void intel_guc_ucode_fini(struct drm_device *dev); > extern void intel_guc_ucode_init(struct drm_device *dev); > +struct drm_i915_gem_object * > +intel_guc_allocate_gem_obj(struct drm_device *dev, u32 size); > +void intel_guc_release_gem_obj(struct drm_i915_gem_object *obj); > > #endif > diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c > index 0f13620..49f3730 100644 > --- a/drivers/gpu/drm/i915/intel_guc_loader.c > +++ b/drivers/gpu/drm/i915/intel_guc_loader.c > @@ -45,6 +45,12 @@ > * The firmware installation package will install (symbolic link) proper version > * of firmware. > * > + * GuC address space: > + * GuC does not allow any gfx GGTT address that falls into range [0, WOPCM_TOP), > + * which is reserved for Boot ROM, SRAM and WOPCM. Currently this top address is > + * 512K. In order to exclude 0-512K address space from GGTT, all gfx objects > + * used by GuC is pinned with PIN_OFFSET_BIAS along with size of WOPCM. > + * > */ > > #define I915_SKL_GUC_UCODE "i915/skl_guc_ver1.bin" > @@ -52,6 +58,55 @@ MODULE_FIRMWARE(I915_SKL_GUC_UCODE); > #define I915_BXT_GUC_UCODE "i915/bxt_guc_ver1.bin" > MODULE_FIRMWARE(I915_BXT_GUC_UCODE); > > +/** > + * intel_guc_allocate_gem_obj() - Allocate gem object for GuC usage > + * @dev: drm device > + * @size: size of object > + * > + * This is a wrapper to create a gem obj. In order to use it inside GuC, the > + * object needs to be pinned lifetime. Also we must pin it to gtt space other > + * than [0, GUC_WOPCM_SIZE] because this range is reserved inside GuC. > + * > + * Return: A drm_i915_gem_object if successful, otherwise NULL. > + */ > +struct drm_i915_gem_object * > +intel_guc_allocate_gem_obj(struct drm_device *dev, u32 size) > +{ > + struct drm_i915_gem_object *obj; > + > + obj = i915_gem_alloc_object(dev, size); > + if (!obj) > + return NULL; > + > + if (i915_gem_object_get_pages(obj)) { > + drm_gem_object_unreference(&obj->base); > + return NULL; > + } > + > + if (i915_gem_obj_ggtt_pin(obj, PAGE_SIZE, > + PIN_OFFSET_BIAS | GUC_WOPCM_SIZE_VALUE)) { > + drm_gem_object_unreference(&obj->base); > + return NULL; > + } > + > + return obj; > +} > + > +/** > + * intel_guc_release_gem_obj() - Release gem object allocated for GuC usage > + * @obj: gem obj to be released > + */ > +void intel_guc_release_gem_obj(struct drm_i915_gem_object *obj) > +{ > + if (!obj) > + return; > + > + if (i915_gem_obj_is_pinned(obj)) > + i915_gem_object_ggtt_unpin(obj); > + > + drm_gem_object_unreference(&obj->base); > +} > + > /* Read GuC status register (GUC_STATUS) > * Return true if get a success code from normal boot or RC6 boot > */ >
diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h index c6886d1..3082a3e 100644 --- a/drivers/gpu/drm/i915/intel_guc.h +++ b/drivers/gpu/drm/i915/intel_guc.h @@ -102,5 +102,8 @@ struct intel_guc { extern int intel_guc_ucode_load(struct drm_device *dev, bool wait); extern void intel_guc_ucode_fini(struct drm_device *dev); extern void intel_guc_ucode_init(struct drm_device *dev); +struct drm_i915_gem_object * +intel_guc_allocate_gem_obj(struct drm_device *dev, u32 size); +void intel_guc_release_gem_obj(struct drm_i915_gem_object *obj); #endif diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c index 0f13620..49f3730 100644 --- a/drivers/gpu/drm/i915/intel_guc_loader.c +++ b/drivers/gpu/drm/i915/intel_guc_loader.c @@ -45,6 +45,12 @@ * The firmware installation package will install (symbolic link) proper version * of firmware. * + * GuC address space: + * GuC does not allow any gfx GGTT address that falls into range [0, WOPCM_TOP), + * which is reserved for Boot ROM, SRAM and WOPCM. Currently this top address is + * 512K. In order to exclude 0-512K address space from GGTT, all gfx objects + * used by GuC is pinned with PIN_OFFSET_BIAS along with size of WOPCM. + * */ #define I915_SKL_GUC_UCODE "i915/skl_guc_ver1.bin" @@ -52,6 +58,55 @@ MODULE_FIRMWARE(I915_SKL_GUC_UCODE); #define I915_BXT_GUC_UCODE "i915/bxt_guc_ver1.bin" MODULE_FIRMWARE(I915_BXT_GUC_UCODE); +/** + * intel_guc_allocate_gem_obj() - Allocate gem object for GuC usage + * @dev: drm device + * @size: size of object + * + * This is a wrapper to create a gem obj. In order to use it inside GuC, the + * object needs to be pinned lifetime. Also we must pin it to gtt space other + * than [0, GUC_WOPCM_SIZE] because this range is reserved inside GuC. + * + * Return: A drm_i915_gem_object if successful, otherwise NULL. + */ +struct drm_i915_gem_object * +intel_guc_allocate_gem_obj(struct drm_device *dev, u32 size) +{ + struct drm_i915_gem_object *obj; + + obj = i915_gem_alloc_object(dev, size); + if (!obj) + return NULL; + + if (i915_gem_object_get_pages(obj)) { + drm_gem_object_unreference(&obj->base); + return NULL; + } + + if (i915_gem_obj_ggtt_pin(obj, PAGE_SIZE, + PIN_OFFSET_BIAS | GUC_WOPCM_SIZE_VALUE)) { + drm_gem_object_unreference(&obj->base); + return NULL; + } + + return obj; +} + +/** + * intel_guc_release_gem_obj() - Release gem object allocated for GuC usage + * @obj: gem obj to be released + */ +void intel_guc_release_gem_obj(struct drm_i915_gem_object *obj) +{ + if (!obj) + return; + + if (i915_gem_obj_is_pinned(obj)) + i915_gem_object_ggtt_unpin(obj); + + drm_gem_object_unreference(&obj->base); +} + /* Read GuC status register (GUC_STATUS) * Return true if get a success code from normal boot or RC6 boot */