summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCNSS_WLAN Service <cnssbldsw@qualcomm.com>2017-09-25 22:17:20 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2017-09-25 22:17:20 -0700
commitdbe526fe2f298adcd81ba461d28af4c41cd18afe (patch)
tree9aeccb17e114a7b8b33a540ba78500e40fffc19b
parentf310a41d85e3c5ec98c15a0f9bd40e72cc6d4633 (diff)
parentb0fd3a6f966207004662b378ad2f92bf25b6d2ea (diff)
Merge "qcacld-3.0: Enable IRAM Dump" into wlan-cld3.driver.lnx.1.1
-rw-r--r--core/bmi/src/i_bmi.h19
-rw-r--r--core/bmi/src/ol_fw.c206
2 files changed, 165 insertions, 60 deletions
diff --git a/core/bmi/src/i_bmi.h b/core/bmi/src/i_bmi.h
index fe0bbee85b18..47686aca4064 100644
--- a/core/bmi/src/i_bmi.h
+++ b/core/bmi/src/i_bmi.h
@@ -49,15 +49,34 @@
#define REGISTER_LOCATION 0x00000800
#define DRAM_LOCATION 0x00400000
+#ifdef HIF_PCI
#define DRAM_SIZE 0x000a8000
+#else
+#define DRAM_SIZE 0x00098000
+#endif
/* The local base addr is used to read the target dump using pcie I/O reads */
#define DRAM_LOCAL_BASE_ADDR (0x100000)
+/* Target IRAM config */
+#define FW_RAM_CONFIG_ADDRESS 0x0018
+#define IRAM1_LOCATION 0x00980000
+#define IRAM1_SIZE 0x00080000
+#define IRAM2_LOCATION 0x00a00000
+#define IRAM2_SIZE 0x00040000
+#ifdef HIF_SDIO
+#define IRAM_LOCATION 0x00980000
+#define IRAM_SIZE 0x000C0000
+#else
#define IRAM_LOCATION 0x00980000
#define IRAM_SIZE 0x00038000
+#endif
#define AXI_LOCATION 0x000a0000
+#ifdef HIF_PCI
#define AXI_SIZE 0x00018000
+#else
+#define AXI_SIZE 0x00020000
+#endif
#define PCIE_READ_LIMIT 0x00005000
diff --git a/core/bmi/src/ol_fw.c b/core/bmi/src/ol_fw.c
index a17e17d6672e..48a0dc0068cb 100644
--- a/core/bmi/src/ol_fw.c
+++ b/core/bmi/src/ol_fw.c
@@ -1437,7 +1437,8 @@ static int ol_diag_read(struct hif_opaque_softc *scn, uint8_t *buffer,
return -EIO;
}
-static int ol_ath_get_reg_table(uint32_t target_version,
+static int ol_ath_get_reg_table(struct hif_opaque_softc *scn,
+ uint32_t target_version,
struct tgt_reg_table *reg_table)
{
int section_len = 0;
@@ -1447,6 +1448,10 @@ static int ol_ath_get_reg_table(uint32_t target_version,
return section_len;
}
+ if (hif_get_bus_type(scn) != QDF_BUS_TYPE_PCI &&
+ hif_get_bus_type(scn) != QDF_BUS_TYPE_SDIO)
+ return section_len;
+
switch (target_version) {
case AR6320_REV2_1_VERSION:
reg_table->section = ar6320v2_reg_table;
@@ -1480,7 +1485,7 @@ static int ol_diag_read_reg_loc(struct hif_opaque_softc *scn, uint8_t *buffer,
struct hif_target_info *tgt_info = hif_get_target_info_handle(scn);
uint32_t target_version = tgt_info->target_version;
- section_len = ol_ath_get_reg_table(target_version, &reg_table);
+ section_len = ol_ath_get_reg_table(scn, target_version, &reg_table);
if (!reg_table.section || !reg_table.section_size || !section_len) {
BMI_ERR("%s: failed to get reg table", __func__);
@@ -1534,23 +1539,6 @@ out:
return result;
}
-#ifdef CONFIG_HL_SUPPORT
-
-/**
- * ol_dump_ce_register() - cannot read the section
- * @scn: ol_softc handler
- * @memory_block: non-NULL reserved memory location
- *
- * Return: -EACCES for LL and not apllicable for HL
- */
-static inline int
-ol_dump_ce_register(struct hif_opaque_softc *scn, void *memory_block)
-{
- return 0;
-}
-
-#else
-
static
void ol_dump_target_memory(struct hif_opaque_softc *scn, void *memory_block)
{
@@ -1587,6 +1575,10 @@ ol_dump_ce_register(struct hif_opaque_softc *scn, void *memory_block)
BMI_ERR("Could not read dump section!");
+ if (hif_get_bus_type(scn) == QDF_BUS_TYPE_SDIO ||
+ hif_get_bus_type(scn) == QDF_BUS_TYPE_USB)
+ return 0;
+
if (hif_dump_registers(scn))
BMI_ERR("Failed to dump bus registers");
@@ -1595,7 +1587,103 @@ ol_dump_ce_register(struct hif_opaque_softc *scn, void *memory_block)
return ret;
}
-#endif
+
+static inline uint32_t
+ol_get_max_section_count(struct hif_opaque_softc *scn)
+{
+ if (hif_get_bus_type(scn) == QDF_BUS_TYPE_PCI)
+ return 5;
+ else
+ return 4;
+}
+
+/**
+ * ol_set_ram_config_reg() - set target RAM configuration register
+ * @sc: pointer of hif_softc context
+ * @config: value to be written to the register
+ *
+ * This function will write the given value to target RAM configuration
+ * register which is bit[23-20] of target CPU inbound address in order to
+ * provide correct address mapping.
+ *
+ * Return: 0 for success or reasons for failure
+ */
+static int ol_set_ram_config_reg(struct hif_opaque_softc *scn, uint32_t config)
+{
+ QDF_STATUS status;
+ uint32_t val;
+ struct targetdef_s *targetdef =
+ (struct targetdef_s *)hif_get_targetdef(scn);
+ uint32_t ram_config_addr =
+ targetdef->d_SOC_CORE_BASE_ADDRESS + FW_RAM_CONFIG_ADDRESS;
+
+ if (hif_get_bus_type(scn) != QDF_BUS_TYPE_PCI)
+ return -EACCES;
+
+ status = hif_diag_write_access(scn, ram_config_addr, config);
+ if (QDF_IS_STATUS_ERROR(status)) {
+ return -EACCES;
+ }
+ status = hif_diag_read_access(scn, ram_config_addr, &val);
+ if (QDF_IS_STATUS_ERROR(status)) {
+ return -EACCES;
+ }
+ if (val != config) {
+ BMI_ERR("%s: Failed to set RAM config reg from 0x%x to 0x%x",
+ __func__, val, config);
+ return -EACCES;
+ }
+ return 0;
+}
+
+static int
+ol_get_iram_len_and_pos(struct hif_opaque_softc *scn, uint32_t *pos,
+ uint32_t *len, uint32_t section)
+{
+ enum hif_target_status status;
+ uint32_t iram_addr, iram_size;
+ int ret;
+
+ if (hif_get_bus_type(scn) != QDF_BUS_TYPE_PCI) {
+ *pos = IRAM_LOCATION;
+ *len = IRAM_SIZE;
+ BMI_ERR("%s: Dumping IRAM Section", __func__);
+ return 0;
+ }
+
+ status = hif_get_target_status(scn);
+ if (status != TARGET_STATUS_RESET) {
+ BMI_ERR("%s: Target status invalid: %d", __func__, status);
+ return -EBUSY;
+ }
+
+ switch (section) {
+ case 3:
+ BMI_ERR("%s: Dumping IRAM1 section", __func__);
+ iram_addr = IRAM1_LOCATION;
+ iram_size = IRAM1_SIZE;
+ break;
+ case 4:
+ BMI_ERR("%s: Dumping IRAM2 section", __func__);
+ iram_addr = IRAM2_LOCATION;
+ iram_size = IRAM2_SIZE;
+ break;
+ default:
+ BMI_ERR("%s: Invalid input iram section %d",
+ __func__, section);
+ return A_EINVAL;
+ }
+
+ ret = ol_set_ram_config_reg(scn, iram_addr >> 20);
+ if (ret) {
+ BMI_ERR("%s: Skip IRAM1 ret:%d", __func__, ret);
+ return -EBUSY;
+ }
+
+ *pos = iram_addr;
+ *len = iram_size;
+ return 0;
+}
/**
* ol_target_coredump() - API to collect target ramdump
@@ -1618,67 +1706,65 @@ static int ol_target_coredump(void *inst, void *memory_block,
uint32_t section_count = 0;
uint32_t pos = 0;
uint32_t read_len = 0;
+ uint32_t max_count = ol_get_max_section_count(scn);
- /*
- * SECTION = DRAM
- * START = 0x00400000
- * LENGTH = 0x000a8000
- *
- * SECTION = AXI
- * START = 0x000a0000
- * LENGTH = 0x00018000
- *
- * SECTION = REG
- * START = 0x00000800
- * LENGTH = 0x0007F820
- */
-
- while ((section_count < 3) && (amount_read < block_len)) {
+ while ((section_count < max_count) && (amount_read < block_len)) {
switch (section_count) {
case 0:
- /* DRAM SECTION */
pos = DRAM_LOCATION;
read_len = DRAM_SIZE;
BMI_ERR("%s: Dumping DRAM section...", __func__);
break;
case 1:
- /* AXI SECTION */
pos = AXI_LOCATION;
read_len = AXI_SIZE;
BMI_ERR("%s: Dumping AXI section...", __func__);
break;
case 2:
- /* REG SECTION */
pos = REGISTER_LOCATION;
/* ol_diag_read_reg_loc checks for buffer overrun */
read_len = 0;
BMI_ERR("%s: Dumping Register section...", __func__);
break;
+ case 3:
+ case 4:
+ ret = ol_get_iram_len_and_pos(scn, &pos, &read_len,
+ section_count);
+ if (ret) {
+ BMI_ERR("%s: Fail to Dump IRAM Section "
+ "ret:%d", __func__, ret);
+ return ret;
+ }
+ break;
+ default:
+ BMI_ERR("%s: INVALID SECTION_:%d", __func__,
+ section_count);
+ return 0;
}
- if ((block_len - amount_read) >= read_len) {
- if (((hif_get_bus_type(scn) == QDF_BUS_TYPE_PCI) ||
- (hif_get_bus_type(scn) == QDF_BUS_TYPE_SDIO)) &&
- (pos == REGISTER_LOCATION)) {
- result = ol_diag_read_reg_loc(scn,
- buffer_loc,
- block_len - amount_read);
- } else {
- result = ol_diag_read(scn, buffer_loc,
- pos, read_len);
- }
- if (result != -EIO) {
- amount_read += result;
- buffer_loc += result;
- section_count++;
- } else {
- ret = ol_dump_ce_register(scn, memory_block);
- break; /* Could not read the section */
- }
- } else {
- BMI_ERR("Insufficient room in dump buffer!");
- break; /* Insufficient room in buffer */
+ if (block_len - amount_read < read_len) {
+ BMI_ERR("%s: No memory to dump section:%d buffer!",
+ __func__, section_count);
+ return -ENOMEM;
}
+
+ if (((hif_get_bus_type(scn) == QDF_BUS_TYPE_PCI) ||
+ (hif_get_bus_type(scn) == QDF_BUS_TYPE_SDIO)) &&
+ pos == REGISTER_LOCATION)
+ result = ol_diag_read_reg_loc(scn, buffer_loc,
+ block_len - amount_read);
+ else
+ result = ol_diag_read(scn, buffer_loc, pos, read_len);
+
+ if (result == -EIO)
+ return ol_dump_ce_register(scn, memory_block);
+
+ BMI_INFO("%s: Section:%d Bytes Read:%0x", __func__,
+ section_count, result);
+
+ amount_read += result;
+ buffer_loc += result;
+ section_count++;
}
return ret;
}