[04/15] secboot: start LS firmware in post-run hook

Submitted by Alexandre Courbot on March 29, 2017, 9:31 a.m.

Details

Message ID 20170329093123.24656-5-acourbot@nvidia.com
State New
Headers show
Series "Support for GP10B chipset" ( rev: 1 ) in Nouveau

Not browsing as part of any series.

Commit Message

Alexandre Courbot March 29, 2017, 9:31 a.m.
The LS firmware post-run hook is the right place to start said LS
firmware. Moving it here also allows to remove special handling in the
ACR code.

Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
 drm/nouveau/nvkm/subdev/secboot/acr_r352.c         | 46 --------------------
 .../nvkm/subdev/secboot/ls_ucode_msgqueue.c        | 49 +++++++++++++++++++++-
 2 files changed, 47 insertions(+), 48 deletions(-)

Patch hide | download patch | download mbox

diff --git a/drm/nouveau/nvkm/subdev/secboot/acr_r352.c b/drm/nouveau/nvkm/subdev/secboot/acr_r352.c
index afd35027fd3a..a721354249ce 100644
--- a/drm/nouveau/nvkm/subdev/secboot/acr_r352.c
+++ b/drm/nouveau/nvkm/subdev/secboot/acr_r352.c
@@ -26,8 +26,6 @@ 
 #include <core/gpuobj.h>
 #include <core/firmware.h>
 #include <engine/falcon.h>
-#include <subdev/mc.h>
-#include <subdev/timer.h>
 #include <subdev/pmu.h>
 #include <core/msgqueue.h>
 #include <engine/sec2.h>
@@ -885,7 +883,6 @@  acr_r352_bootstrap(struct acr_r352 *acr, struct nvkm_secboot *sb)
 {
 	const struct nvkm_subdev *subdev = &sb->subdev;
 	unsigned long managed_falcons = acr->base.managed_falcons;
-	u32 reg;
 	int falcon_id;
 	int ret;
 
@@ -924,52 +921,9 @@  acr_r352_bootstrap(struct acr_r352 *acr, struct nvkm_secboot *sb)
 			ret = func->post_run(&acr->base, sb);
 			if (ret)
 				return ret;
-	}
-
-	/* Re-start ourselves if we are managed */
-	if (!nvkm_secboot_is_managed(sb, acr->base.boot_falcon))
-		return 0;
-
-	/* Enable interrupts */
-	nvkm_falcon_wr32(sb->boot_falcon, 0x10, 0xff);
-	nvkm_mc_intr_mask(subdev->device, sb->boot_falcon->owner->index, true);
-
-	/* Start LS firmware on boot falcon */
-	nvkm_falcon_start(sb->boot_falcon);
-
-	/*
-	 * There is a bug where the LS firmware sometimes require to be started
-	 * twice (this happens only on SEC). Detect and workaround that
-	 * condition.
-	 *
-	 * Once started, the falcon will end up in STOPPED condition (bit 5)
-	 * if successful, or in HALT condition (bit 4) if not.
-	 */
-	nvkm_msec(subdev->device, 1,
-		  if ((reg = nvkm_rd32(subdev->device,
-				       sb->boot_falcon->addr + 0x100)
-		       & 0x30) != 0)
-			  break;
-	);
-	if (reg & BIT(4)) {
-		nvkm_debug(subdev, "applying workaround for start bug...");
-		nvkm_falcon_start(sb->boot_falcon);
-		nvkm_msec(subdev->device, 1,
-			if ((reg = nvkm_rd32(subdev->device,
-					     sb->boot_falcon->addr + 0x100)
-			     & 0x30) != 0)
-				break;
-		);
-		if (reg & BIT(4)) {
-			nvkm_error(subdev, "%s failed to start\n",
-			       nvkm_secboot_falcon_name[acr->base.boot_falcon]);
-			return -EINVAL;
 		}
 	}
 
-	nvkm_debug(subdev, "%s started\n",
-		   nvkm_secboot_falcon_name[acr->base.boot_falcon]);
-
 	return 0;
 }
 
diff --git a/drm/nouveau/nvkm/subdev/secboot/ls_ucode_msgqueue.c b/drm/nouveau/nvkm/subdev/secboot/ls_ucode_msgqueue.c
index a4dd5f198d55..ee989210725e 100644
--- a/drm/nouveau/nvkm/subdev/secboot/ls_ucode_msgqueue.c
+++ b/drm/nouveau/nvkm/subdev/secboot/ls_ucode_msgqueue.c
@@ -28,6 +28,8 @@ 
 #include <core/msgqueue.h>
 #include <subdev/pmu.h>
 #include <engine/sec2.h>
+#include <subdev/mc.h>
+#include <subdev/timer.h>
 
 /**
  * acr_ls_ucode_load_msgqueue - load and prepare a ucode img for a msgqueue fw
@@ -77,6 +79,7 @@  static int
 acr_ls_msgqueue_post_run(struct nvkm_msgqueue *queue,
 			 struct nvkm_falcon *falcon, u32 addr_args)
 {
+	struct nvkm_device *device = falcon->owner->device;
 	u32 cmdline_size = NVKM_MSGQUEUE_CMDLINE_SIZE;
 	u8 buf[cmdline_size];
 
@@ -86,6 +89,13 @@  acr_ls_msgqueue_post_run(struct nvkm_msgqueue *queue,
 	/* rearm the queue so it will wait for the init message */
 	nvkm_msgqueue_reinit(queue);
 
+	/* Enable interrupts */
+	nvkm_falcon_wr32(falcon, 0x10, 0xff);
+	nvkm_mc_intr_mask(device, falcon->owner->index, true);
+
+	/* Start LS firmware on boot falcon */
+	nvkm_falcon_start(falcon);
+
 	return 0;
 }
 
@@ -120,6 +130,9 @@  acr_ls_pmu_post_run(const struct nvkm_acr *acr, const struct nvkm_secboot *sb)
 	if (ret)
 		return ret;
 
+	nvkm_debug(&sb->subdev, "%s started\n",
+		   nvkm_secboot_falcon_name[acr->boot_falcon]);
+
 	return 0;
 }
 
@@ -145,16 +158,48 @@  acr_ls_ucode_load_sec2(const struct nvkm_secboot *sb, struct ls_ucode_img *img)
 int
 acr_ls_sec2_post_run(const struct nvkm_acr *acr, const struct nvkm_secboot *sb)
 {
-	struct nvkm_device *device = sb->subdev.device;
+	const struct nvkm_subdev *subdev = &sb->subdev;
+	struct nvkm_device *device = subdev->device;
 	struct nvkm_sec2 *sec = device->sec2;
 	/* on SEC arguments are always at the beginning of EMEM */
-	u32 addr_args = 0x01000000;
+	const u32 addr_args = 0x01000000;
+	u32 reg;
 	int ret;
 
 	ret = acr_ls_msgqueue_post_run(sec->queue, sec->falcon, addr_args);
 	if (ret)
 		return ret;
 
+	/*
+	 * There is a bug where the LS firmware sometimes require to be started
+	 * twice (this happens only on SEC). Detect and workaround that
+	 * condition.
+	 *
+	 * Once started, the falcon will end up in STOPPED condition (bit 5)
+	 * if successful, or in HALT condition (bit 4) if not.
+	 */
+	nvkm_msec(device, 1,
+		  if ((reg = nvkm_falcon_rd32(sb->boot_falcon, 0x100) & 0x30) != 0)
+			  break;
+	);
+	if (reg & BIT(4)) {
+		nvkm_debug(subdev, "applying workaround for start bug...");
+		nvkm_falcon_start(sb->boot_falcon);
+		nvkm_msec(subdev->device, 1,
+			if ((reg = nvkm_rd32(subdev->device,
+					     sb->boot_falcon->addr + 0x100)
+			     & 0x30) != 0)
+				break;
+		);
+		if (reg & BIT(4)) {
+			nvkm_error(subdev, "%s failed to start\n",
+			       nvkm_secboot_falcon_name[acr->boot_falcon]);
+			return -EINVAL;
+		}
+	}
+
+	nvkm_debug(&sb->subdev, "%s started\n",
+		   nvkm_secboot_falcon_name[acr->boot_falcon]);
 
 	return 0;
 }