Explorar o código

cnss2: Add code to dump SRAM on MHI power on failure for QCA6490

Add code to dump SRAM on MHI power-on failure. To avoid CPU hog
relinquish CPU after dumping 256Kb chunks.

Change-Id: I2c9c64424c8ae4612e67b78fcabc1f872fefea81
Mohammed Siddiq %!s(int64=2) %!d(string=hai) anos
pai
achega
334ef0ec36
Modificáronse 4 ficheiros con 44 adicións e 0 borrados
  1. 4 0
      cnss2/main.c
  2. 1 0
      cnss2/main.h
  3. 38 0
      cnss2/pci.c
  4. 1 0
      cnss2/reg.h

+ 4 - 0
cnss2/main.c

@@ -31,6 +31,7 @@
 #include "bus.h"
 #include "debug.h"
 #include "genl.h"
+#include "reg.h"
 
 #define CNSS_DUMP_FORMAT_VER		0x11
 #define CNSS_DUMP_FORMAT_VER_V2		0x22
@@ -3627,6 +3628,8 @@ static int cnss_misc_init(struct cnss_plat_data *plat_priv)
 		cnss_pr_err("QMI IPC connection call back register failed, err = %d\n",
 			    ret);
 
+	plat_priv->sram_dump = kcalloc(SRAM_DUMP_SIZE, 1, GFP_KERNEL);
+
 	return 0;
 }
 
@@ -3645,6 +3648,7 @@ static void cnss_misc_deinit(struct cnss_plat_data *plat_priv)
 	del_timer(&plat_priv->fw_boot_timer);
 	wakeup_source_unregister(plat_priv->recovery_ws);
 	cnss_deinit_sol_gpio(plat_priv);
+	kfree(plat_priv->sram_dump);
 }
 
 static void cnss_init_control_params(struct cnss_plat_data *plat_priv)

+ 1 - 0
cnss2/main.h

@@ -511,6 +511,7 @@ struct cnss_plat_data {
 	u8 use_fw_path_with_prefix;
 	char firmware_name[MAX_FIRMWARE_NAME_LEN];
 	char fw_fallback_name[MAX_FIRMWARE_NAME_LEN];
+	u8 *sram_dump;
 	struct completion rddm_complete;
 	struct completion recovery_complete;
 	struct cnss_control_params ctrl_params;

+ 38 - 0
cnss2/pci.c

@@ -15,6 +15,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/suspend.h>
 #include <linux/version.h>
+#include <linux/sched.h>
 
 #include "main.h"
 #include "bus.h"
@@ -61,6 +62,7 @@
 #endif
 
 #define RAMDUMP_SIZE_DEFAULT		0x420000
+#define CNSS_256KB_SIZE			0x40000
 #define DEVICE_RDDM_COOKIE		0xCAFECACE
 
 static DEFINE_SPINLOCK(pci_link_down_lock);
@@ -1488,6 +1490,41 @@ static void cnss_pci_dump_bl_sram_mem(struct cnss_pci_data *pci_priv)
 	}
 }
 
+static void cnss_pci_dump_sram(struct cnss_pci_data *pci_priv)
+{
+	struct cnss_plat_data *plat_priv;
+	u32 i, mem_addr;
+	u32 *dump_ptr;
+
+	plat_priv = pci_priv->plat_priv;
+
+	if (plat_priv->device_id != QCA6490_DEVICE_ID ||
+	    cnss_get_host_build_type() != QMI_HOST_BUILD_TYPE_PRIMARY_V01)
+		return;
+
+	if (!plat_priv->sram_dump) {
+		cnss_pr_err("SRAM dump memory is not allocated\n");
+		return;
+	}
+
+	if (cnss_pci_check_link_status(pci_priv))
+		return;
+
+	cnss_pr_dbg("Dumping SRAM at 0x%lx\n", plat_priv->sram_dump);
+
+	for (i = 0; i < SRAM_DUMP_SIZE; i += sizeof(u32)) {
+		mem_addr = SRAM_START + i;
+		dump_ptr = (u32 *)(plat_priv->sram_dump + i);
+		if (cnss_pci_reg_read(pci_priv, mem_addr, dump_ptr)) {
+			cnss_pr_err("SRAM Dump failed at 0x%x\n", mem_addr);
+			break;
+		}
+		/* Relinquish CPU after dumping 256KB chunks*/
+		if (!(i % CNSS_256KB_SIZE))
+			cond_resched();
+	}
+}
+
 static int cnss_pci_handle_mhi_poweron_timeout(struct cnss_pci_data *pci_priv)
 {
 	struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
@@ -1511,6 +1548,7 @@ static int cnss_pci_handle_mhi_poweron_timeout(struct cnss_pci_data *pci_priv)
 		cnss_pci_soc_scratch_reg_dump(pci_priv);
 		/* Dump PBL/SBL error log if RDDM cookie is not set */
 		cnss_pci_dump_bl_sram_mem(pci_priv);
+		cnss_pci_dump_sram(pci_priv);
 		return -ETIMEDOUT;
 	}
 

+ 1 - 0
cnss2/reg.h

@@ -100,6 +100,7 @@
 #define PBL_BOOTSTRAP_STATUS			0x01910008
 #define SRAM_START				0x01400000
 #define SRAM_END				0x01800000
+#define SRAM_DUMP_SIZE				0x400000
 
 #define QCA6390_PCIE_SOC_WDOG_DISC_BAD_DATA_LOW_CFG_SOC_PCIE_REG 0x01E04234
 #define QCA6390_PCIE_SOC_WDOG_DISC_BAD_DATA_LOW_CFG_SOC_PCIE_REG_VAL 0xDEAD1234