Loading drivers/hwtracing/coresight/coresight-tmc.c +79 −0 Original line number Diff line number Diff line Loading @@ -28,10 +28,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 @@ -61,11 +64,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 @@ -626,6 +703,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 @@ -192,6 +192,7 @@ struct tmc_drvdata { struct coresight_csr *csr; const char *csr_name; struct byte_cntr *byte_cntr; bool force_reg_dump; }; /* Generic functions */ Loading drivers/hwtracing/coresight/coresight-tpdm.c +9 −4 Original line number Diff line number Diff line Loading @@ -3898,6 +3898,8 @@ static const struct attribute_group *tpdm_attr_grps[] = { static int tpdm_datasets_alloc(struct tpdm_drvdata *drvdata) { struct dump_vaddr_entry *dump_entry; if (test_bit(TPDM_DS_GPR, drvdata->datasets)) { drvdata->gpr = devm_kzalloc(drvdata->dev, sizeof(*drvdata->gpr), GFP_KERNEL); Loading Loading @@ -3939,10 +3941,13 @@ static int tpdm_datasets_alloc(struct tpdm_drvdata *drvdata) return -ENOMEM; if (of_property_read_bool(drvdata->dev->of_node, "qcom,dump-enable")) drvdata->cmb->mcmb->mcmb_msr_dump_ptr = (uint32_t *)get_msm_dump_ptr( "qcom,dump-enable")) { dump_entry = get_msm_dump_ptr( MSM_DUMP_DATA_TPDM_SWAO_MCMB); if (dump_entry) drvdata->cmb->mcmb->mcmb_msr_dump_ptr = (uint32_t *)(dump_entry->dump_vaddr); } } return 0; } Loading drivers/soc/qcom/memory_dump_v2.c +4 −12 Original line number Diff line number Diff line /* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 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 @@ -39,15 +39,6 @@ struct msm_memory_dump { struct msm_dump_table *table; }; struct dump_vaddr_entry { uint32_t id; void *dump_vaddr; }; struct msm_mem_dump_vaddr_tbl { uint8_t num_node; struct dump_vaddr_entry *entries; }; static struct msm_memory_dump memdump; static struct msm_mem_dump_vaddr_tbl vaddr_tbl; Loading Loading @@ -156,7 +147,7 @@ int msm_dump_data_register(enum msm_dump_table_ids id, } EXPORT_SYMBOL(msm_dump_data_register); void *get_msm_dump_ptr(enum msm_dump_data_ids id) struct dump_vaddr_entry *get_msm_dump_ptr(enum msm_dump_data_ids id) { int i; Loading @@ -174,7 +165,7 @@ void *get_msm_dump_ptr(enum msm_dump_data_ids id) if (i == vaddr_tbl.num_node) return NULL; return (void *)vaddr_tbl.entries[i].dump_vaddr; return &vaddr_tbl.entries[i]; } EXPORT_SYMBOL(get_msm_dump_ptr); Loading Loading @@ -333,6 +324,7 @@ static int mem_dump_probe(struct platform_device *pdev) } 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++; } } Loading include/soc/qcom/memory_dump.h +15 −3 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 @@ -87,7 +87,8 @@ enum msm_dump_data_ids { MSM_DUMP_DATA_POWER_REGS = 0xED, MSM_DUMP_DATA_TMC_ETF = 0xF0, MSM_DUMP_DATA_TPDM_SWAO_MCMB = 0xF2, 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 @@ -121,11 +122,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 void *get_msm_dump_ptr(enum msm_dump_data_ids id); 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 +79 −0 Original line number Diff line number Diff line Loading @@ -28,10 +28,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 @@ -61,11 +64,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 @@ -626,6 +703,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 @@ -192,6 +192,7 @@ struct tmc_drvdata { struct coresight_csr *csr; const char *csr_name; struct byte_cntr *byte_cntr; bool force_reg_dump; }; /* Generic functions */ Loading
drivers/hwtracing/coresight/coresight-tpdm.c +9 −4 Original line number Diff line number Diff line Loading @@ -3898,6 +3898,8 @@ static const struct attribute_group *tpdm_attr_grps[] = { static int tpdm_datasets_alloc(struct tpdm_drvdata *drvdata) { struct dump_vaddr_entry *dump_entry; if (test_bit(TPDM_DS_GPR, drvdata->datasets)) { drvdata->gpr = devm_kzalloc(drvdata->dev, sizeof(*drvdata->gpr), GFP_KERNEL); Loading Loading @@ -3939,10 +3941,13 @@ static int tpdm_datasets_alloc(struct tpdm_drvdata *drvdata) return -ENOMEM; if (of_property_read_bool(drvdata->dev->of_node, "qcom,dump-enable")) drvdata->cmb->mcmb->mcmb_msr_dump_ptr = (uint32_t *)get_msm_dump_ptr( "qcom,dump-enable")) { dump_entry = get_msm_dump_ptr( MSM_DUMP_DATA_TPDM_SWAO_MCMB); if (dump_entry) drvdata->cmb->mcmb->mcmb_msr_dump_ptr = (uint32_t *)(dump_entry->dump_vaddr); } } return 0; } Loading
drivers/soc/qcom/memory_dump_v2.c +4 −12 Original line number Diff line number Diff line /* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 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 @@ -39,15 +39,6 @@ struct msm_memory_dump { struct msm_dump_table *table; }; struct dump_vaddr_entry { uint32_t id; void *dump_vaddr; }; struct msm_mem_dump_vaddr_tbl { uint8_t num_node; struct dump_vaddr_entry *entries; }; static struct msm_memory_dump memdump; static struct msm_mem_dump_vaddr_tbl vaddr_tbl; Loading Loading @@ -156,7 +147,7 @@ int msm_dump_data_register(enum msm_dump_table_ids id, } EXPORT_SYMBOL(msm_dump_data_register); void *get_msm_dump_ptr(enum msm_dump_data_ids id) struct dump_vaddr_entry *get_msm_dump_ptr(enum msm_dump_data_ids id) { int i; Loading @@ -174,7 +165,7 @@ void *get_msm_dump_ptr(enum msm_dump_data_ids id) if (i == vaddr_tbl.num_node) return NULL; return (void *)vaddr_tbl.entries[i].dump_vaddr; return &vaddr_tbl.entries[i]; } EXPORT_SYMBOL(get_msm_dump_ptr); Loading Loading @@ -333,6 +324,7 @@ static int mem_dump_probe(struct platform_device *pdev) } 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++; } } Loading
include/soc/qcom/memory_dump.h +15 −3 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 @@ -87,7 +87,8 @@ enum msm_dump_data_ids { MSM_DUMP_DATA_POWER_REGS = 0xED, MSM_DUMP_DATA_TMC_ETF = 0xF0, MSM_DUMP_DATA_TPDM_SWAO_MCMB = 0xF2, 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 @@ -121,11 +122,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 void *get_msm_dump_ptr(enum msm_dump_data_ids id); 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