soc: qcom: memory_dump: Support ETB/ETR register dump
Add support to dump the ETB/ETR register when enabling ETB/ETR. Change-Id: Ia4d4d49fe313adb4d1fe15413495909bc5f226fc Signed-off-by: Tingwei Zhang <tingwei@codeaurora.org> Signed-off-by: Saranya Chidura <schidura@codeaurora.org> Signed-off-by: Shilpa Suresh <sbsure@codeaurora.org>
This commit is contained in:
parent
2e5299cd17
commit
157fb3045c
@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) 2012,2017-2019, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2012,2017-2019,2021, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Description: CoreSight Trace Memory Controller driver
|
||||
*/
|
||||
@ -23,10 +23,13 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/coresight.h>
|
||||
#include <linux/amba/bus.h>
|
||||
#include <soc/qcom/memory_dump.h>
|
||||
|
||||
#include "coresight-priv.h"
|
||||
#include "coresight-tmc.h"
|
||||
|
||||
#define TMC_REG_DUMP_MAGIC 0x42445953
|
||||
|
||||
void tmc_wait_for_tmcready(struct tmc_drvdata *drvdata)
|
||||
{
|
||||
/* Ensure formatter, unformatter and hardware fifo are empty */
|
||||
@ -56,10 +59,84 @@ void tmc_flush_and_stop(struct tmc_drvdata *drvdata)
|
||||
tmc_wait_for_tmcready(drvdata);
|
||||
}
|
||||
|
||||
static void __tmc_reg_dump(struct tmc_drvdata *drvdata)
|
||||
{
|
||||
struct dump_vaddr_entry *dump_entry;
|
||||
struct msm_dump_data *dump_data;
|
||||
uint32_t *reg_buf;
|
||||
|
||||
if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) {
|
||||
dump_entry = get_msm_dump_ptr(MSM_DUMP_DATA_TMC_ETR_REG);
|
||||
dev_dbg(drvdata->dev, "%s: TMC ETR dump entry ptr is %pK\n",
|
||||
__func__, dump_entry);
|
||||
} else if (drvdata->config_type == TMC_CONFIG_TYPE_ETB ||
|
||||
drvdata->config_type == TMC_CONFIG_TYPE_ETF) {
|
||||
dump_entry = get_msm_dump_ptr(MSM_DUMP_DATA_TMC_ETF_REG);
|
||||
dev_dbg(drvdata->dev, "%s: TMC ETF dump entry ptr is %pK\n",
|
||||
__func__, dump_entry);
|
||||
} else
|
||||
return;
|
||||
|
||||
if (dump_entry == NULL)
|
||||
return;
|
||||
|
||||
reg_buf = (uint32_t *)(dump_entry->dump_vaddr);
|
||||
dump_data = dump_entry->dump_data_vaddr;
|
||||
|
||||
if (reg_buf == NULL || dump_data == NULL)
|
||||
return;
|
||||
|
||||
dev_dbg(drvdata->dev, "%s: TMC dump reg ptr is %pK, dump_data is %pK\n",
|
||||
__func__, reg_buf, dump_data);
|
||||
|
||||
reg_buf[1] = readl_relaxed(drvdata->base + TMC_RSZ);
|
||||
reg_buf[3] = readl_relaxed(drvdata->base + TMC_STS);
|
||||
reg_buf[5] = readl_relaxed(drvdata->base + TMC_RRP);
|
||||
reg_buf[6] = readl_relaxed(drvdata->base + TMC_RWP);
|
||||
reg_buf[7] = readl_relaxed(drvdata->base + TMC_TRG);
|
||||
reg_buf[8] = readl_relaxed(drvdata->base + TMC_CTL);
|
||||
reg_buf[10] = readl_relaxed(drvdata->base + TMC_MODE);
|
||||
reg_buf[11] = readl_relaxed(drvdata->base + TMC_LBUFLEVEL);
|
||||
reg_buf[12] = readl_relaxed(drvdata->base + TMC_CBUFLEVEL);
|
||||
reg_buf[13] = readl_relaxed(drvdata->base + TMC_BUFWM);
|
||||
if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) {
|
||||
reg_buf[14] = readl_relaxed(drvdata->base + TMC_RRPHI);
|
||||
reg_buf[15] = readl_relaxed(drvdata->base + TMC_RWPHI);
|
||||
reg_buf[68] = readl_relaxed(drvdata->base + TMC_AXICTL);
|
||||
reg_buf[70] = readl_relaxed(drvdata->base + TMC_DBALO);
|
||||
reg_buf[71] = readl_relaxed(drvdata->base + TMC_DBAHI);
|
||||
}
|
||||
reg_buf[192] = readl_relaxed(drvdata->base + TMC_FFSR);
|
||||
reg_buf[193] = readl_relaxed(drvdata->base + TMC_FFCR);
|
||||
reg_buf[194] = readl_relaxed(drvdata->base + TMC_PSCR);
|
||||
reg_buf[1000] = readl_relaxed(drvdata->base + CORESIGHT_CLAIMSET);
|
||||
reg_buf[1001] = readl_relaxed(drvdata->base + CORESIGHT_CLAIMCLR);
|
||||
reg_buf[1005] = readl_relaxed(drvdata->base + CORESIGHT_LSR);
|
||||
reg_buf[1006] = readl_relaxed(drvdata->base + CORESIGHT_AUTHSTATUS);
|
||||
reg_buf[1010] = readl_relaxed(drvdata->base + CORESIGHT_DEVID);
|
||||
reg_buf[1011] = readl_relaxed(drvdata->base + CORESIGHT_DEVTYPE);
|
||||
reg_buf[1012] = readl_relaxed(drvdata->base + CORESIGHT_PERIPHIDR4);
|
||||
reg_buf[1013] = readl_relaxed(drvdata->base + CORESIGHT_PERIPHIDR5);
|
||||
reg_buf[1014] = readl_relaxed(drvdata->base + CORESIGHT_PERIPHIDR6);
|
||||
reg_buf[1015] = readl_relaxed(drvdata->base + CORESIGHT_PERIPHIDR7);
|
||||
reg_buf[1016] = readl_relaxed(drvdata->base + CORESIGHT_PERIPHIDR0);
|
||||
reg_buf[1017] = readl_relaxed(drvdata->base + CORESIGHT_PERIPHIDR1);
|
||||
reg_buf[1018] = readl_relaxed(drvdata->base + CORESIGHT_PERIPHIDR2);
|
||||
reg_buf[1019] = readl_relaxed(drvdata->base + CORESIGHT_PERIPHIDR3);
|
||||
reg_buf[1020] = readl_relaxed(drvdata->base + CORESIGHT_COMPIDR0);
|
||||
reg_buf[1021] = readl_relaxed(drvdata->base + CORESIGHT_COMPIDR1);
|
||||
reg_buf[1022] = readl_relaxed(drvdata->base + CORESIGHT_COMPIDR2);
|
||||
reg_buf[1023] = readl_relaxed(drvdata->base + CORESIGHT_COMPIDR3);
|
||||
|
||||
dump_data->magic = TMC_REG_DUMP_MAGIC;
|
||||
}
|
||||
|
||||
void tmc_enable_hw(struct tmc_drvdata *drvdata)
|
||||
{
|
||||
drvdata->enable = true;
|
||||
writel_relaxed(TMC_CTL_CAPT_EN, drvdata->base + TMC_CTL);
|
||||
if (drvdata->force_reg_dump)
|
||||
__tmc_reg_dump(drvdata);
|
||||
}
|
||||
|
||||
void tmc_disable_hw(struct tmc_drvdata *drvdata)
|
||||
@ -650,6 +727,8 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
}
|
||||
if (of_property_read_bool(drvdata->dev->of_node, "qcom,force-reg-dump"))
|
||||
drvdata->force_reg_dump = true;
|
||||
|
||||
desc.pdata = pdata;
|
||||
desc.dev = dev;
|
||||
|
@ -268,6 +268,7 @@ struct tmc_drvdata {
|
||||
struct idr idr;
|
||||
struct mutex idr_mutex;
|
||||
struct etr_buf *perf_buf;
|
||||
bool force_reg_dump;
|
||||
};
|
||||
|
||||
struct etr_buf_operations {
|
||||
|
@ -82,6 +82,7 @@ struct msm_memory_dump {
|
||||
};
|
||||
|
||||
static struct msm_memory_dump memdump;
|
||||
static struct msm_mem_dump_vaddr_tbl vaddr_tbl;
|
||||
|
||||
/**
|
||||
* update_reg_dump_table - update the register dump table
|
||||
@ -699,6 +700,28 @@ int msm_dump_data_register_nominidump(enum msm_dump_table_ids id,
|
||||
}
|
||||
EXPORT_SYMBOL(msm_dump_data_register_nominidump);
|
||||
|
||||
struct dump_vaddr_entry *get_msm_dump_ptr(enum msm_dump_data_ids id)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!vaddr_tbl.entries)
|
||||
return NULL;
|
||||
|
||||
if (id > MSM_DUMP_DATA_MAX)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < vaddr_tbl.num_node; i++) {
|
||||
if (vaddr_tbl.entries[i].id == id)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == vaddr_tbl.num_node)
|
||||
return NULL;
|
||||
|
||||
return &vaddr_tbl.entries[i];
|
||||
}
|
||||
EXPORT_SYMBOL(get_msm_dump_ptr);
|
||||
|
||||
#define MSM_DUMP_TOTAL_SIZE_OFFSET 0x724
|
||||
static int init_memory_dump(void *dump_vaddr, phys_addr_t phys_addr,
|
||||
size_t size)
|
||||
@ -787,6 +810,14 @@ static int mem_dump_alloc(struct platform_device *pdev)
|
||||
uint32_t ns_vmids[] = {VMID_HLOS};
|
||||
uint32_t ns_vm_perms[] = {PERM_READ | PERM_WRITE};
|
||||
u64 shm_bridge_handle;
|
||||
int i = 0;
|
||||
|
||||
vaddr_tbl.num_node = of_get_child_count(node);
|
||||
vaddr_tbl.entries = devm_kcalloc(&pdev->dev, vaddr_tbl.num_node,
|
||||
sizeof(struct dump_vaddr_entry),
|
||||
GFP_KERNEL);
|
||||
if (!vaddr_tbl.entries)
|
||||
dev_err(&pdev->dev, "Unable to allocate mem for ptr addr\n");
|
||||
|
||||
total_size = size = ret = no_of_nodes = 0;
|
||||
/* For dump table registration with IMEM */
|
||||
@ -862,9 +893,16 @@ static int mem_dump_alloc(struct platform_device *pdev)
|
||||
dump_entry.addr = phys_addr;
|
||||
ret = msm_dump_data_register_nominidump(MSM_DUMP_TABLE_APPS,
|
||||
&dump_entry);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Data dump setup failed, id = %d\n",
|
||||
id);
|
||||
} else if (vaddr_tbl.entries) {
|
||||
vaddr_tbl.entries[i].id = id;
|
||||
vaddr_tbl.entries[i].dump_vaddr =
|
||||
dump_vaddr + MSM_DUMP_DATA_SIZE;
|
||||
vaddr_tbl.entries[i].dump_data_vaddr = dump_data;
|
||||
i++;
|
||||
}
|
||||
|
||||
md_entry.phys_addr = dump_data->addr;
|
||||
md_entry.virt_addr = (uintptr_t)dump_vaddr + MSM_DUMP_DATA_SIZE;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2012, 2014-2017, 2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2012, 2014-2017, 2019, 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __MSM_MEMORY_DUMP_H
|
||||
@ -79,6 +79,8 @@ enum msm_dump_data_ids {
|
||||
MSM_DUMP_DATA_TMC_ETF = 0xF0,
|
||||
MSM_DUMP_DATA_TMC_ETF_SWAO = 0xF1,
|
||||
MSM_DUMP_DATA_TMC_REG = 0x100,
|
||||
MSM_DUMP_DATA_TMC_ETR_REG = 0x100,
|
||||
MSM_DUMP_DATA_TMC_ETF_REG = 0x101,
|
||||
MSM_DUMP_DATA_TMC_ETF_SWAO_REG = 0x102,
|
||||
MSM_DUMP_DATA_LOG_BUF = 0x110,
|
||||
MSM_DUMP_DATA_LOG_BUF_FIRST_IDX = 0x111,
|
||||
@ -113,11 +115,23 @@ struct msm_dump_entry {
|
||||
uint64_t addr;
|
||||
};
|
||||
|
||||
struct dump_vaddr_entry {
|
||||
uint32_t id;
|
||||
void *dump_vaddr;
|
||||
struct msm_dump_data *dump_data_vaddr;
|
||||
};
|
||||
|
||||
struct msm_mem_dump_vaddr_tbl {
|
||||
uint8_t num_node;
|
||||
struct dump_vaddr_entry *entries;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_QCOM_MEMORY_DUMP_V2
|
||||
extern int msm_dump_data_register(enum msm_dump_table_ids id,
|
||||
struct msm_dump_entry *entry);
|
||||
extern int msm_dump_data_register_nominidump(enum msm_dump_table_ids id,
|
||||
struct msm_dump_entry *entry);
|
||||
extern struct dump_vaddr_entry *get_msm_dump_ptr(enum msm_dump_data_ids id);
|
||||
#else
|
||||
static inline int msm_dump_data_register(enum msm_dump_table_ids id,
|
||||
struct msm_dump_entry *entry)
|
||||
|
Loading…
Reference in New Issue
Block a user