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:
Tingwei Zhang 2018-03-05 19:28:08 +08:00 committed by Gerrit - the friendly Code Review server
parent 2e5299cd17
commit 157fb3045c
4 changed files with 135 additions and 3 deletions

View File

@ -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;

View File

@ -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 {

View File

@ -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;

View File

@ -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)