diff options
| -rw-r--r-- | drivers/hwtracing/coresight/coresight-tmc.c | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c index 27b6f1820223..08743533c568 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.c +++ b/drivers/hwtracing/coresight/coresight-tmc.c @@ -32,6 +32,7 @@ #include <linux/msm-sps.h> #include <linux/usb_bam.h> #include <linux/usb/usb_qdss.h> +#include <soc/qcom/memory_dump.h> #include "coresight-priv.h" @@ -162,6 +163,8 @@ struct tmc_etr_bam_data { * @enable: this TMC is being used. * @config_type: TMC variant, must be of type @tmc_config_type. * @trigger_cntr: amount of words to store after a trigger. + * @reg_data: MSM memory dump data to store TMC registers. + * @buf_data: MSM memory dump data to store ETF/ETB buffer. */ struct tmc_drvdata { void __iomem *base; @@ -188,6 +191,8 @@ struct tmc_drvdata { struct usb_qdss_ch *usbch; struct tmc_etr_bam_data *bamdata; bool enable_to_bam; + struct msm_dump_data reg_data; + struct msm_dump_data buf_data; }; static void tmc_wait_for_ready(struct tmc_drvdata *drvdata) @@ -1606,6 +1611,67 @@ static struct attribute *coresight_etf_attrs[] = { }; ATTRIBUTE_GROUPS(coresight_etf); +static int tmc_etf_set_buf_dump(struct tmc_drvdata *drvdata) +{ + int ret; + struct msm_dump_entry dump_entry; + static int count; + + drvdata->buf_data.addr = virt_to_phys(drvdata->buf); + drvdata->buf_data.len = drvdata->size; + dump_entry.id = MSM_DUMP_DATA_TMC_ETF + count; + dump_entry.addr = virt_to_phys(&drvdata->buf_data); + + ret = msm_dump_data_register(MSM_DUMP_TABLE_APPS, + &dump_entry); + if (ret) + return ret; + + count++; + + return 0; +} + +static int tmc_set_reg_dump(struct tmc_drvdata *drvdata) +{ + int ret; + void *baddr; + struct amba_device *adev; + struct resource *res; + struct device *dev = drvdata->dev; + struct msm_dump_entry dump_entry; + uint32_t size; + static int count; + + adev = to_amba_device(dev); + if (!adev) + return -EINVAL; + + res = &adev->res; + size = resource_size(res); + + baddr = devm_kzalloc(dev, size, GFP_KERNEL); + if (!baddr) + return -ENOMEM; + + drvdata->reg_data.addr = virt_to_phys(baddr); + drvdata->reg_data.len = size; + + dump_entry.id = MSM_DUMP_DATA_TMC_REG + count; + dump_entry.addr = virt_to_phys(&drvdata->reg_data); + + ret = msm_dump_data_register(MSM_DUMP_TABLE_APPS, + &dump_entry); + if (ret) { + devm_kfree(dev, baddr); + return ret; + } + + count++; + + return 0; +} + static int tmc_probe(struct amba_device *adev, const struct amba_id *id) { int ret = 0; @@ -1671,8 +1737,17 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) drvdata->buf = devm_kzalloc(dev, drvdata->size, GFP_KERNEL); if (!drvdata->buf) return -ENOMEM; + + ret = tmc_etf_set_buf_dump(drvdata); + if (ret) + dev_err(dev, "TMC ETF-ETB dump setup failed. ret: %d\n", + ret); } + ret = tmc_set_reg_dump(drvdata); + if (ret) + dev_err(dev, "TMC REG dump setup failed. ret: %d\n", ret); + pdata->default_sink = of_property_read_bool(np, "arm,default-sink"); desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL); |
