On 06/07/15 15:28, Daniel Vetter wrote:
On Fri, Jul 03, 2015 at 01:30:27PM +0100, Dave Gordon wrote:
From: Alex Dai <yu.dai@xxxxxxxxx>
This uses the common firmware loader to fetch the firmware image,
then loads it into the GuC's memory via a dedicated DMA engine.
This patch is derived from GuC loading work originally done by
Vinit Azad and Ben Widawsky. It has been reconstructed to accord
with the common firmware loading mechanism by Dave Gordon as well
as new firmware layout etc.
v2:
Various improvements per review comments by Chris Wilson
v3:
Removed 'wait' parameter to intel_guc_ucode_load() as prefetch
is no longer supported in the common firmware loader, per
Daniel Vetter's request.
F/w checker callback fn now returns errno rather than bool.
Issue: VIZ-4884
Signed-off-by: Alex Dai <yu.dai@xxxxxxxxx>
Signed-off-by: Dave Gordon <david.s.gordon@xxxxxxxxx>
---
drivers/gpu/drm/i915/Makefile | 3 +
drivers/gpu/drm/i915/i915_dma.c | 4 +
drivers/gpu/drm/i915/i915_drv.h | 11 +
drivers/gpu/drm/i915/i915_gem.c | 8 +
drivers/gpu/drm/i915/i915_reg.h | 4 +-
drivers/gpu/drm/i915/intel_guc.h | 49 ++++
drivers/gpu/drm/i915/intel_guc_loader.c | 448 ++++++++++++++++++++++++++++++++
7 files changed, 526 insertions(+), 1 deletion(-)
create mode 100644 drivers/gpu/drm/i915/intel_guc.h
create mode 100644 drivers/gpu/drm/i915/intel_guc_loader.c
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index f1f80fc..62a8c83 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -42,6 +42,9 @@ i915-y += i915_cmd_parser.o \
# generic ancilliary microcontroller support
i915-y += intel_uc_loader.o
+# general-purpose microcontroller (GuC) support
+i915-y += intel_guc_loader.o
+
# autogenerated null render state
i915-y += intel_renderstate_gen6.o \
intel_renderstate_gen7.o \
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index c5349fa..730d91b 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -469,6 +469,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
cleanup_gem:
mutex_lock(&dev->struct_mutex);
+ intel_guc_ucode_fini(dev);
i915_gem_cleanup_ringbuffer(dev);
i915_gem_context_fini(dev);
mutex_unlock(&dev->struct_mutex);
@@ -866,6 +867,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
intel_uncore_init(dev);
+ intel_guc_ucode_init(dev);
+
/* Load CSR Firmware for SKL */
intel_csr_ucode_init(dev);
@@ -1117,6 +1120,7 @@ int i915_driver_unload(struct drm_device *dev)
flush_workqueue(dev_priv->wq);
mutex_lock(&dev->struct_mutex);
+ intel_guc_ucode_fini(dev);
i915_gem_cleanup_ringbuffer(dev);
i915_gem_context_fini(dev);
mutex_unlock(&dev->struct_mutex);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 9618f57..a7ccac5 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -50,6 +50,7 @@
#include <linux/intel-iommu.h>
#include <linux/kref.h>
#include <linux/pm_qos.h>
+#include "intel_guc.h"
/* General customization:
*/
@@ -1687,6 +1688,8 @@ struct drm_i915_private {
struct i915_virtual_gpu vgpu;
+ struct intel_guc guc;
+
struct intel_csr csr;
/* Display CSR-related protection */
@@ -1931,6 +1934,11 @@ static inline struct drm_i915_private *dev_to_i915(struct device *dev)
return to_i915(dev_get_drvdata(dev));
}
+static inline struct drm_i915_private *guc_to_i915(struct intel_guc *guc)
+{
+ return container_of(guc, struct drm_i915_private, guc);
+}
+
/* Iterate over initialised rings */
#define for_each_ring(ring__, dev_priv__, i__) \
for ((i__) = 0; (i__) < I915_NUM_RINGS; (i__)++) \
@@ -2539,6 +2547,9 @@ struct drm_i915_cmd_table {
#define HAS_CSR(dev) (IS_SKYLAKE(dev))
+#define HAS_GUC_UCODE(dev) (IS_GEN9(dev))
+#define HAS_GUC_SCHED(dev) (IS_GEN9(dev))
+
#define INTEL_PCH_DEVICE_ID_MASK 0xff00
#define INTEL_PCH_IBX_DEVICE_ID_TYPE 0x3b00
#define INTEL_PCH_CPT_DEVICE_ID_TYPE 0x1c00
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index aa8f4c3..80d7890 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -5076,6 +5076,14 @@ i915_gem_init_hw(struct drm_device *dev)
goto out;
}
+ /*
+ * We can't enable contexts until all firmware is loaded; if this
+ * fails, disable GuC submissions and fall back to execlist mode
+ */
+ ret = intel_guc_ucode_load(dev);
+ if (ret)
+ i915.enable_guc_submission = false;
I want an -EIO or similar here since runtime fallbacks to other modes
really aren't great from a maintainance perspective, see my comments on
the irq routing code.
Yes we can make this work, but givin our stellar track record with keeping
disabled features working it won't work for long. And it will impact us
with additional constraints until we give up and rip it out again. Not
worth it imo - if we decide to use the guc on a given platform we should
imo require it and stick to that decision for at least as long as the
driver is loaded. Developers can still change the option when reloading the
driver, users won't have a chance to cause trouble.
-Daniel
Again, this isn't really "runtime" -- we're still in the driver loading
stage here. This is analogous to the various "sanitize" functions where
we cross-check what options have been set and decide which to override,
except that here we can't determine whether we're going to respect the
default or user-specified request for GuC submission mode until we know
whether we have valid firmware for the GuC.
At this point, we haven't submitted any batches, so the main point of
use of this flag -- in the submission path, to switch between execlist
and GuC modes -- has never yet been executed. So there should be no
problem with changing the value before it's first used.
And this is a one-way switch; you (or the default config) asked for GuC
submission, but we can't support it so we disable the option. There's no
way to switch it back on without reloading the driver. So this /is/ the
point at which we decide to use the GuC on a given platform and then
stick to that decision for at least as long as the driver is loaded.
We have to support execlist mode for the foreseeable future anyway, so
using it on a machine which (we think) ought to be GuC-capable doesn't
add /any/ extra maintenance overhead at all.
Why break the user's machine unnecessarily? With real "end-users",
especially those who have never used Linux before, you only get one
chance. Sometimes I've installed Linux on a (Windows-using) friend's
machine, and it hasn't worked first time. Then I switch to another VT,
type some magic incantations, and 10 minutes later we have a usable
login screen. Will they adopt Linux? Unlikely :( No matter how good it
looks thereafter, if the machine's hardware doesn't work with the distro
straight out of the box, they're just not going to believe it's
something they can use. So it's very important that everything essential
to the first-time experience works even when misconfigured -- and
nothing is more essential than the display driver (networking and wi-fi
are the next things that will put the user off if they don't work -- and
they're also drivers that commonly rely on firmware blobs).
.Dave.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/intel-gfx