Loading drivers/hwtracing/coresight/coresight-tmc.c +80 −1 Original line number Diff line number Diff line // 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 */ Loading @@ -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 */ Loading Loading @@ -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) Loading Loading @@ -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; Loading drivers/hwtracing/coresight/coresight-tmc.h +1 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading drivers/soc/qcom/memory_dump_v2.c +39 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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) Loading Loading @@ -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 */ Loading Loading @@ -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; Loading include/soc/qcom/memory_dump.h +15 −1 Original line number Diff line number Diff line /* 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 Loading Loading @@ -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, Loading Loading @@ -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 Loading
drivers/hwtracing/coresight/coresight-tmc.c +80 −1 Original line number Diff line number Diff line // 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 */ Loading @@ -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 */ Loading Loading @@ -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) Loading Loading @@ -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; Loading
drivers/hwtracing/coresight/coresight-tmc.h +1 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading
drivers/soc/qcom/memory_dump_v2.c +39 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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) Loading Loading @@ -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 */ Loading Loading @@ -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; Loading
include/soc/qcom/memory_dump.h +15 −1 Original line number Diff line number Diff line /* 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 Loading Loading @@ -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, Loading Loading @@ -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