From: Gary King <gking@nvidia.com>
Date: Wed, 1 Sep 2010 20:19:38 +0000 (-0700)
Subject: [ARM] tegra: nvrm_transport: handshake AVP reset with kernel
X-Git-Tag: firefly_0821_release~9834^2~608
X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=e02c75201244202d6a9adc74c219c715b3f439b4;p=firefly-linux-kernel-4.4.55.git

[ARM] tegra: nvrm_transport: handshake AVP reset with kernel

the AVP kernel modifies the AVP reset vector after it starts to its
own value; poll this register to verify that the AVP kernel has
started properly.

Change-Id: I5d9f36dd2763c0df28576f3cb86de20f6aae0ef2
Signed-off-by: Gary King <gking@nvidia.com>
---

diff --git a/arch/arm/mach-tegra/nv/nvrm/core/common/nvrm_moduleloader.c b/arch/arm/mach-tegra/nv/nvrm/core/common/nvrm_moduleloader.c
index 22241b72a70e..695216c8fed3 100644
--- a/arch/arm/mach-tegra/nv/nvrm/core/common/nvrm_moduleloader.c
+++ b/arch/arm/mach-tegra/nv/nvrm/core/common/nvrm_moduleloader.c
@@ -516,6 +516,7 @@ static void NvRmPrivResetAvp(NvRmDeviceHandle hRm, unsigned long reset_va)
     u32 *stub_va = &_tegra_avp_launcher_stub_data[AVP_LAUNCHER_START_VA];
     unsigned long stub_addr = virt_to_phys(_tegra_avp_launcher_stub);
     unsigned int tmp;
+    unsigned long timeout;
 
     *stub_va = reset_va;
     __cpuc_flush_dcache_area(stub_va, sizeof(*stub_va));
@@ -526,8 +527,18 @@ static void NvRmPrivResetAvp(NvRmDeviceHandle hRm, unsigned long reset_va)
     barrier();
     NvRmModuleReset(hRm, NvRmModuleID_Avp);
     writel(0, IO_ADDRESS(TEGRA_FLOW_CTRL_BASE) + FLOW_CTRL_HALT_COP);
+
     barrier();
-    writel(tmp, _TEGRA_AVP_RESET_VECTOR_ADDR);
+    timeout = jiffies + HZ;
+    /* the AVP firmware will reprogram its reset vector as the kernel
+     * starts, so a dead kernel can be detected by polling this value */
+    while (time_before(jiffies, timeout)) {
+        if (readl(_TEGRA_AVP_RESET_VECTOR_ADDR) != stub_addr)
+            break;
+        cpu_relax();
+    }
+
+    WARN_ON(readl(_TEGRA_AVP_RESET_VECTOR_ADDR) == stub_addr);
 }
 
 void NvRmPrivXpcSendMsgAddress(void);