Loading arch/arm64/boot/dts/qcom/qcs405-coresight.dtsi +3 −0 Original line number Diff line number Diff line Loading @@ -70,6 +70,7 @@ reg-names = "tmc-base", "bam-base"; arm,buffer-size = <0x400000>; qcom,force-reg-dump; coresight-name = "coresight-tmc-etr"; coresight-ctis = <&cti0 &cti0>; Loading Loading @@ -100,6 +101,8 @@ coresight-name = "coresight-tmc-etf"; coresight-ctis = <&cti0 &cti0>; arm,default-sink; qcom,force-reg-dump; coresight-csr = <&csr>; clocks = <&clock_rpmcc RPM_QDSS_CLK>, Loading drivers/hwtracing/coresight/coresight-tmc.c +79 −0 Original line number Diff line number Diff line Loading @@ -30,10 +30,13 @@ #include <linux/amba/bus.h> #include <linux/iommu.h> #include <asm/dma-iommu.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 @@ -63,11 +66,85 @@ 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; drvdata->sticky_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 @@ -744,6 +821,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 @@ -240,6 +240,7 @@ struct tmc_drvdata { const char *csr_name; struct byte_cntr *byte_cntr; struct dma_iommu_mapping *iommu_mapping; bool force_reg_dump; }; /* Generic functions */ Loading drivers/soc/qcom/memory_dump_v2.c +36 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ struct msm_memory_dump { }; static struct msm_memory_dump memdump; static struct msm_mem_dump_vaddr_tbl vaddr_tbl; uint32_t msm_dump_table_version(void) { Loading Loading @@ -145,6 +146,28 @@ int msm_dump_data_register(enum msm_dump_table_ids id, } EXPORT_SYMBOL(msm_dump_data_register); 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); static int __init init_memory_dump(void) { struct msm_dump_table *table; Loading Loading @@ -236,6 +259,14 @@ static int mem_dump_probe(struct platform_device *pdev) struct msm_dump_entry dump_entry; int ret; u32 size, id; 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"); for_each_available_child_of_node(node, child_node) { ret = of_property_read_u32(child_node, "qcom,dump-size", &size); Loading Loading @@ -284,6 +315,11 @@ static int mem_dump_probe(struct platform_device *pdev) dma_free_coherent(&pdev->dev, size, dump_vaddr, dump_addr); devm_kfree(&pdev->dev, dump_data); } else if (vaddr_tbl.entries) { vaddr_tbl.entries[i].id = id; vaddr_tbl.entries[i].dump_vaddr = dump_vaddr; vaddr_tbl.entries[i].dump_data_vaddr = dump_data; i++; } } return 0; Loading include/soc/qcom/memory_dump.h +16 −1 Original line number Diff line number Diff line /* Copyright (c) 2012, 2014-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2012, 2014-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -85,6 +85,8 @@ enum msm_dump_data_ids { MSM_DUMP_DATA_RPMH = 0xEC, MSM_DUMP_DATA_TMC_ETF = 0xF0, MSM_DUMP_DATA_TMC_REG = 0x100, MSM_DUMP_DATA_TMC_ETR_REG = 0x100, MSM_DUMP_DATA_TMC_ETF_REG = 0x101, MSM_DUMP_DATA_LOG_BUF = 0x110, MSM_DUMP_DATA_LOG_BUF_FIRST_IDX = 0x111, MSM_DUMP_DATA_SCANDUMP_PER_CPU = 0x130, Loading Loading @@ -118,9 +120,22 @@ 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 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
arch/arm64/boot/dts/qcom/qcs405-coresight.dtsi +3 −0 Original line number Diff line number Diff line Loading @@ -70,6 +70,7 @@ reg-names = "tmc-base", "bam-base"; arm,buffer-size = <0x400000>; qcom,force-reg-dump; coresight-name = "coresight-tmc-etr"; coresight-ctis = <&cti0 &cti0>; Loading Loading @@ -100,6 +101,8 @@ coresight-name = "coresight-tmc-etf"; coresight-ctis = <&cti0 &cti0>; arm,default-sink; qcom,force-reg-dump; coresight-csr = <&csr>; clocks = <&clock_rpmcc RPM_QDSS_CLK>, Loading
drivers/hwtracing/coresight/coresight-tmc.c +79 −0 Original line number Diff line number Diff line Loading @@ -30,10 +30,13 @@ #include <linux/amba/bus.h> #include <linux/iommu.h> #include <asm/dma-iommu.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 @@ -63,11 +66,85 @@ 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; drvdata->sticky_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 @@ -744,6 +821,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 @@ -240,6 +240,7 @@ struct tmc_drvdata { const char *csr_name; struct byte_cntr *byte_cntr; struct dma_iommu_mapping *iommu_mapping; bool force_reg_dump; }; /* Generic functions */ Loading
drivers/soc/qcom/memory_dump_v2.c +36 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ struct msm_memory_dump { }; static struct msm_memory_dump memdump; static struct msm_mem_dump_vaddr_tbl vaddr_tbl; uint32_t msm_dump_table_version(void) { Loading Loading @@ -145,6 +146,28 @@ int msm_dump_data_register(enum msm_dump_table_ids id, } EXPORT_SYMBOL(msm_dump_data_register); 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); static int __init init_memory_dump(void) { struct msm_dump_table *table; Loading Loading @@ -236,6 +259,14 @@ static int mem_dump_probe(struct platform_device *pdev) struct msm_dump_entry dump_entry; int ret; u32 size, id; 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"); for_each_available_child_of_node(node, child_node) { ret = of_property_read_u32(child_node, "qcom,dump-size", &size); Loading Loading @@ -284,6 +315,11 @@ static int mem_dump_probe(struct platform_device *pdev) dma_free_coherent(&pdev->dev, size, dump_vaddr, dump_addr); devm_kfree(&pdev->dev, dump_data); } else if (vaddr_tbl.entries) { vaddr_tbl.entries[i].id = id; vaddr_tbl.entries[i].dump_vaddr = dump_vaddr; vaddr_tbl.entries[i].dump_data_vaddr = dump_data; i++; } } return 0; Loading
include/soc/qcom/memory_dump.h +16 −1 Original line number Diff line number Diff line /* Copyright (c) 2012, 2014-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2012, 2014-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -85,6 +85,8 @@ enum msm_dump_data_ids { MSM_DUMP_DATA_RPMH = 0xEC, MSM_DUMP_DATA_TMC_ETF = 0xF0, MSM_DUMP_DATA_TMC_REG = 0x100, MSM_DUMP_DATA_TMC_ETR_REG = 0x100, MSM_DUMP_DATA_TMC_ETF_REG = 0x101, MSM_DUMP_DATA_LOG_BUF = 0x110, MSM_DUMP_DATA_LOG_BUF_FIRST_IDX = 0x111, MSM_DUMP_DATA_SCANDUMP_PER_CPU = 0x130, Loading Loading @@ -118,9 +120,22 @@ 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 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