From 2ed59bfb7c4a3f7a6ba93ab90a8a5bf28b4d017b Mon Sep 17 00:00:00 2001 From: Yuanfang Zhang Date: Fri, 11 Dec 2020 16:58:04 +0800 Subject: [PATCH] coresight-tmc-etr: Add QDSS IPA bam connection support Add QDSS IPA bam connection support for pcie hw transfer path. And add support to switch between pcie sw and hw path. Change-Id: Idbd6f9e2a869fabfa0a23a834b1cbd7945cf93f4 Signed-off-by: Mao Jinlong Signed-off-by: Yuanfang Zhang --- .../hwtracing/coresight/coresight-tmc-etr.c | 320 ++++++++++++++---- drivers/hwtracing/coresight/coresight-tmc.c | 49 +++ drivers/hwtracing/coresight/coresight-tmc.h | 20 +- 3 files changed, 319 insertions(+), 70 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c index dce2333ac654..74555e8e0528 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c @@ -1087,16 +1087,37 @@ ssize_t tmc_etr_get_sysfs_trace(struct tmc_drvdata *drvdata, static struct etr_buf * tmc_etr_setup_sysfs_buf(struct tmc_drvdata *drvdata) { - if (drvdata->out_mode == TMC_ETR_OUT_MODE_USB - && drvdata->byte_cntr->sw_usb) - return tmc_alloc_etr_buf(drvdata, TMC_ETR_SW_USB_BUF_SIZE, - 0, cpu_to_node(0), NULL); - else if (drvdata->out_mode == TMC_ETR_OUT_MODE_PCIE) - return tmc_alloc_etr_buf(drvdata, TMC_ETR_PCIE_MEM_SIZE, - 0, cpu_to_node(0), NULL); - else - return tmc_alloc_etr_buf(drvdata, drvdata->size, - 0, cpu_to_node(0), NULL); + struct etr_buf *sysfs_buf = NULL; + + /* + * If we are enabling the ETR from disabled state, we need to make + * sure we have a buffer with the right size. The etr_buf is not reset + * immediately after we stop the tracing in SYSFS mode as we wait for + * the user to collect the data. We may be able to reuse the existing + * buffer, provided the size matches. Any allocation has to be done + * with the lock released. + */ + sysfs_buf = READ_ONCE(drvdata->sysfs_buf); + if (!sysfs_buf || (drvdata->out_mode == TMC_ETR_OUT_MODE_MEM + && sysfs_buf->size != drvdata->size) + || (drvdata->out_mode == TMC_ETR_OUT_MODE_USB + && drvdata->byte_cntr->sw_usb + && sysfs_buf->size != TMC_ETR_SW_USB_BUF_SIZE) + || (drvdata->out_mode == TMC_ETR_OUT_MODE_PCIE + && sysfs_buf->size != TMC_ETR_PCIE_MEM_SIZE)) { + + if (drvdata->out_mode == TMC_ETR_OUT_MODE_USB + && drvdata->byte_cntr->sw_usb) + sysfs_buf = tmc_alloc_etr_buf(drvdata, TMC_ETR_SW_USB_BUF_SIZE, + 0, cpu_to_node(0), NULL); + else if (drvdata->out_mode == TMC_ETR_OUT_MODE_PCIE) + sysfs_buf = tmc_alloc_etr_buf(drvdata, TMC_ETR_PCIE_MEM_SIZE, + 0, cpu_to_node(0), NULL); + else + sysfs_buf = tmc_alloc_etr_buf(drvdata, drvdata->size, + 0, cpu_to_node(0), NULL); + } + return sysfs_buf; } static void @@ -1190,13 +1211,13 @@ static int tmc_etr_fill_usb_bam_data(struct tmc_drvdata *drvdata) return 0; } -static void __tmc_etr_enable_to_bam(struct tmc_drvdata *drvdata) +static int __tmc_etr_enable_to_bam(struct tmc_drvdata *drvdata) { struct tmc_etr_bam_data *bamdata = drvdata->bamdata; uint32_t axictl; if (drvdata->enable_to_bam) - return; + return 0; /* Configure and enable required CSR registers */ msm_qdss_csr_enable_bam_to_usb(drvdata->csr); @@ -1205,7 +1226,13 @@ static void __tmc_etr_enable_to_bam(struct tmc_drvdata *drvdata) CS_UNLOCK(drvdata->base); - writel_relaxed(bamdata->data_fifo.size / 4, drvdata->base + TMC_RSZ); + if (drvdata->out_mode == TMC_ETR_OUT_MODE_USB) + writel_relaxed(bamdata->data_fifo.size / 4, + drvdata->base + TMC_RSZ); + else if (drvdata->out_mode == TMC_ETR_OUT_MODE_PCIE) + writel_relaxed(bamdata->connect.data.size / 4, + drvdata->base + TMC_RSZ); + writel_relaxed(TMC_MODE_CIRCULAR_BUFFER, drvdata->base + TMC_MODE); axictl = readl_relaxed(drvdata->base + TMC_AXICTL); @@ -1216,15 +1243,34 @@ static void __tmc_etr_enable_to_bam(struct tmc_drvdata *drvdata) axictl = (axictl & ~0x3) | 0x2; writel_relaxed(axictl, drvdata->base + TMC_AXICTL); - if (bamdata->props.options & SPS_BAM_SMMU_EN) { - writel_relaxed((uint32_t)bamdata->data_fifo.iova, - drvdata->base + TMC_DBALO); - writel_relaxed((((uint64_t)bamdata->data_fifo.iova) >> 32) - & 0xFF, drvdata->base + TMC_DBAHI); - } else { - writel_relaxed((uint32_t)bamdata->data_fifo.phys_base, - drvdata->base + TMC_DBALO); - writel_relaxed((((uint64_t)bamdata->data_fifo.phys_base) >> 32) + if (drvdata->out_mode == TMC_ETR_OUT_MODE_USB) { + if (bamdata->props.options & SPS_BAM_SMMU_EN) { + writel_relaxed((uint32_t)bamdata->data_fifo.iova, + drvdata->base + TMC_DBALO); + writel_relaxed( + (((uint64_t)bamdata->data_fifo.iova) >> 32) + & 0xFF, drvdata->base + TMC_DBAHI); + } else { + writel_relaxed((uint32_t)bamdata->data_fifo.phys_base, + drvdata->base + TMC_DBALO); + writel_relaxed( + (((uint64_t)bamdata->data_fifo.phys_base) >> 32) + & 0xFF, drvdata->base + TMC_DBAHI); + } + } + + if (drvdata->out_mode == TMC_ETR_OUT_MODE_PCIE) { + if (bamdata->props.options & SPS_BAM_SMMU_EN) { + CS_LOCK(drvdata->base); + dev_err(&drvdata->csdev->dev, + "PCIE mode doesn't support smmu.\n"); + return -EINVAL; + } + + writel_relaxed((uint32_t)bamdata->connect.data.phys_base, + drvdata->base + TMC_DBALO); + writel_relaxed( + (((uint64_t)bamdata->connect.data.phys_base) >> 32) & 0xFF, drvdata->base + TMC_DBAHI); } /* Set FOnFlIn for periodic flush */ @@ -1236,6 +1282,7 @@ static void __tmc_etr_enable_to_bam(struct tmc_drvdata *drvdata) msm_qdss_csr_enable_flush(drvdata->csr); drvdata->enable_to_bam = true; + return 0; } static int get_usb_bam_iova(struct device *dev, unsigned long usb_bam_handle, @@ -1285,20 +1332,59 @@ static int tmc_etr_bam_enable(struct tmc_drvdata *drvdata) bamdata->connect.source = bamdata->handle; bamdata->connect.event_thresh = 0x4; bamdata->connect.src_pipe_index = TMC_ETR_BAM_PIPE_INDEX; - bamdata->connect.options = SPS_O_AUTO_ENABLE; - bamdata->connect.destination = bamdata->dest; - bamdata->connect.dest_pipe_index = bamdata->dest_pipe_idx; - bamdata->connect.desc = bamdata->desc_fifo; - bamdata->connect.data = bamdata->data_fifo; + if (drvdata->out_mode == TMC_ETR_OUT_MODE_USB) { + bamdata->connect.options = SPS_O_AUTO_ENABLE; - if (bamdata->props.options & SPS_BAM_SMMU_EN) { - ret = get_usb_bam_iova(drvdata->csdev->dev.parent, + bamdata->connect.destination = bamdata->dest; + bamdata->connect.dest_pipe_index = bamdata->dest_pipe_idx; + bamdata->connect.desc = bamdata->desc_fifo; + bamdata->connect.data = bamdata->data_fifo; + if (bamdata->props.options & SPS_BAM_SMMU_EN) { + ret = get_usb_bam_iova(drvdata->csdev->dev.parent, bamdata->dest, &iova); - if (ret) + if (ret) + goto err1; + bamdata->connect.dest_iova = iova; + } + } else if (drvdata->out_mode == TMC_ETR_OUT_MODE_PCIE) { + if (bamdata->props.options & SPS_BAM_SMMU_EN) { + dev_err(&drvdata->csdev->dev, + "PCIE mode doesn't support smmu.\n"); + ret = -EINVAL; goto err1; - bamdata->connect.dest_iova = iova; + } + + bamdata->connect.options = SPS_O_AUTO_ENABLE | SPS_O_DUMMY_PEER; + + bamdata->connect.destination = + drvdata->ipa_data->ipa_qdss_out.ipa_rx_db_pa; + bamdata->connect.dest_pipe_index = 0; + bamdata->connect.desc.phys_base = + drvdata->ipa_data->ipa_qdss_in.desc_fifo_base_addr; + bamdata->connect.desc.size = + drvdata->ipa_data->ipa_qdss_in.desc_fifo_size; + bamdata->connect.desc.base = + ioremap(bamdata->connect.desc.phys_base, + bamdata->connect.desc.size); + if (!bamdata->connect.desc.base) { + ret = -ENOMEM; + goto err1; + } + + bamdata->connect.data.phys_base = + drvdata->ipa_data->ipa_qdss_in.data_fifo_base_addr; + bamdata->connect.data.size = + drvdata->ipa_data->ipa_qdss_in.data_fifo_size; + bamdata->connect.data.base = + ioremap(bamdata->connect.data.phys_base, + bamdata->connect.data.size); + if (!bamdata->connect.data.base) { + ret = -ENOMEM; + goto err1; + } } + ret = sps_connect(bamdata->pipe, &bamdata->connect); if (ret) goto err1; @@ -1439,6 +1525,77 @@ int tmc_etr_bam_init(struct amba_device *adev, return sps_register_bam_device(&bamdata->props, &bamdata->handle); } +int tmc_etr_ipa_init(struct amba_device *adev, + struct tmc_drvdata *drvdata) +{ + int ret; + struct device *dev = &adev->dev; + struct device_node *node = adev->dev.of_node; + struct tmc_etr_ipa_data *ipa_data; + u32 value = 0; + + ipa_data = devm_kzalloc(dev, sizeof(*ipa_data), GFP_KERNEL); + if (!ipa_data) + return -ENOMEM; + + drvdata->ipa_data = ipa_data; + + ret = of_property_read_u32(node, "ipa-conn-data-base-pa", &value); + if (ret) { + pr_err("%s: Invalid ipa data base address property\n", + __func__); + return -EINVAL; + } + ipa_data->ipa_qdss_in.data_fifo_base_addr = value; + + ret = of_property_read_u32(node, "ipa-conn-data-size", &value); + if (ret) { + pr_err("%s: Invalid ipa data base size\n", __func__); + return -EINVAL; + } + ipa_data->ipa_qdss_in.data_fifo_size = value; + + ret = of_property_read_u32(node, "ipa-conn-desc-base-pa", &value); + if (ret) { + pr_err("%s: Invalid ipa desc base address property\n", + __func__); + return -EINVAL; + } + ipa_data->ipa_qdss_in.desc_fifo_base_addr = value; + + ret = of_property_read_u32(node, "ipa-conn-desc-size", &value); + if (ret) { + pr_err("%s: Invalid ipa desc size property\n", __func__); + return -EINVAL; + } + ipa_data->ipa_qdss_in.desc_fifo_size = value; + + ret = of_property_read_u32(node, "ipa-peer-evt-reg-pa", &value); + if (ret) { + pr_err("%s: Invalid ipa peer reg pa property\n", __func__); + return -EINVAL; + } + ipa_data->ipa_qdss_in.bam_p_evt_dest_addr = value; + + ipa_data->ipa_qdss_in.bam_p_evt_threshold = 0x4; + ipa_data->ipa_qdss_in.override_eot = 0x1; + return 0; +} + +static int tmc_etr_ipa_conn(struct tmc_drvdata *drvdata) +{ + if (!drvdata->ipa_data) + return -ENOMEM; + + return ipa_qdss_conn_pipes(&drvdata->ipa_data->ipa_qdss_in, + &drvdata->ipa_data->ipa_qdss_out); +} + +static int tmc_etr_ipa_disconn(void) +{ + return ipa_qdss_disconn_pipes(); +} + static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev) { int ret = 0; @@ -1465,39 +1622,23 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev) if (drvdata->out_mode == TMC_ETR_OUT_MODE_MEM || (drvdata->out_mode == TMC_ETR_OUT_MODE_USB && drvdata->byte_cntr->sw_usb) - || drvdata->out_mode == TMC_ETR_OUT_MODE_PCIE) { - /* - * If we are enabling the ETR from disabled state, we need to make - * sure we have a buffer with the right size. The etr_buf is not reset - * immediately after we stop the tracing in SYSFS mode as we wait for - * the user to collect the data. We may be able to reuse the existing - * buffer, provided the size matches. Any allocation has to be done - * with the lock released. - */ - sysfs_buf = READ_ONCE(drvdata->sysfs_buf); - if (!sysfs_buf || (drvdata->out_mode == TMC_ETR_OUT_MODE_MEM - && sysfs_buf->size != drvdata->size) - || (drvdata->out_mode == TMC_ETR_OUT_MODE_USB - && drvdata->byte_cntr->sw_usb - && sysfs_buf->size != TMC_ETR_SW_USB_BUF_SIZE) - || (drvdata->out_mode == TMC_ETR_OUT_MODE_PCIE - && sysfs_buf->size != TMC_ETR_PCIE_MEM_SIZE)) { + || (drvdata->out_mode == TMC_ETR_OUT_MODE_PCIE && + drvdata->pcie_path == TMC_ETR_PCIE_SW_PATH)) { - spin_unlock_irqrestore(&drvdata->spinlock, flags); - /* - * ETR DDR memory is not allocated until user enables - * tmc at least once. If user specifies different ETR - * DDR size than the default size or switches between - * contiguous or scatter-gather memory type after - * enabling tmc; the new selection will be honored from - * next tmc enable session. - */ - /* Allocate memory with the locks released */ - new_buf = tmc_etr_setup_sysfs_buf(drvdata); - if (IS_ERR(new_buf)) - return -ENOMEM; - spin_lock_irqsave(&drvdata->spinlock, flags); - } + /* + * ETR DDR memory is not allocated until user enables + * tmc at least once. If user specifies different ETR + * DDR size than the default size or switches between + * contiguous or scatter-gather memory type after + * enabling tmc; the new selection will be honored from + * next tmc enable session. + */ + /* Allocate memory with the locks released */ + spin_unlock_irqrestore(&drvdata->spinlock, flags); + new_buf = tmc_etr_setup_sysfs_buf(drvdata); + if (IS_ERR(new_buf)) + return -ENOMEM; + spin_lock_irqsave(&drvdata->spinlock, flags); /* * If we don't have a buffer or it doesn't match the requested size, @@ -1512,6 +1653,29 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev) goto unlock_out; } + if (drvdata->out_mode == TMC_ETR_OUT_MODE_PCIE && + drvdata->pcie_path == TMC_ETR_PCIE_HW_PATH) { + spin_unlock_irqrestore(&drvdata->spinlock, flags); + ret = tmc_etr_ipa_conn(drvdata); + if (ret) + return ret; + + ret = tmc_etr_bam_enable(drvdata); + if (ret) { + tmc_etr_ipa_disconn(); + return ret; + } + + spin_lock_irqsave(&drvdata->spinlock, flags); + ret = __tmc_etr_enable_to_bam(drvdata); + if (ret) { + spin_unlock_irqrestore(&drvdata->spinlock, + flags); + tmc_etr_ipa_disconn(); + return ret; + } + } + drvdata->mode = CS_MODE_SYSFS; drvdata->enable = true; @@ -1543,6 +1707,10 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev) if (drvdata->out_mode == TMC_ETR_OUT_MODE_PCIE) etr_pcie_start(drvdata->byte_cntr); + if (drvdata->out_mode == TMC_ETR_OUT_MODE_PCIE + && drvdata->pcie_path == TMC_ETR_PCIE_SW_PATH) + etr_pcie_start(drvdata->byte_cntr); + if (drvdata->out_mode == TMC_ETR_OUT_MODE_MEM || (drvdata->byte_cntr->sw_usb && drvdata->out_mode == TMC_ETR_OUT_MODE_USB)) { @@ -2043,6 +2211,13 @@ static int _tmc_disable_etr_sink(struct coresight_device *csdev, spin_lock_irqsave(&drvdata->spinlock, flags); tmc_etr_disable_hw(drvdata); } + } else if (drvdata->out_mode == TMC_ETR_OUT_MODE_PCIE + && drvdata->pcie_path == TMC_ETR_PCIE_HW_PATH) { + __tmc_etr_disable_to_bam(drvdata); + spin_unlock_irqrestore(&drvdata->spinlock, flags); + tmc_etr_bam_disable(drvdata); + tmc_etr_ipa_disconn(); + goto out; } else { tmc_etr_disable_hw(drvdata); } @@ -2057,18 +2232,19 @@ static int _tmc_disable_etr_sink(struct coresight_device *csdev, if ((drvdata->out_mode == TMC_ETR_OUT_MODE_USB && drvdata->byte_cntr->sw_usb) || drvdata->out_mode == TMC_ETR_OUT_MODE_MEM - || drvdata->out_mode == TMC_ETR_OUT_MODE_PCIE) { + || (drvdata->out_mode == TMC_ETR_OUT_MODE_PCIE + && drvdata->pcie_path == TMC_ETR_PCIE_SW_PATH)) { - if (drvdata->out_mode == TMC_ETR_OUT_MODE_MEM) - tmc_etr_byte_cntr_stop(drvdata->byte_cntr); - else if (drvdata->out_mode == TMC_ETR_OUT_MODE_PCIE) { + if (drvdata->out_mode == TMC_ETR_OUT_MODE_PCIE) { etr_pcie_stop(drvdata->byte_cntr); flush_workqueue(drvdata->byte_cntr->pcie_wq); - } else { + } else if (drvdata->out_mode == TMC_ETR_OUT_MODE_USB) { usb_bypass_stop(drvdata->byte_cntr); flush_workqueue(drvdata->byte_cntr->usb_wq); drvdata->usbch = NULL; - } + } else + tmc_etr_byte_cntr_stop(drvdata->byte_cntr); + coresight_cti_unmap_trigin(drvdata->cti_reset, drvdata->cti_reset_trig_num, 0); coresight_cti_unmap_trigout(drvdata->cti_flush, @@ -2167,6 +2343,12 @@ int tmc_read_prepare_etr(struct tmc_drvdata *drvdata) goto out; } + if (drvdata->out_mode == TMC_ETR_OUT_MODE_USB || + drvdata->out_mode == TMC_ETR_OUT_MODE_PCIE) { + ret = -EINVAL; + goto out; + } + if (drvdata->out_mode == TMC_ETR_OUT_MODE_USB) { ret = -EINVAL; goto out; diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c index e01a824f894b..ef29709b2903 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.c +++ b/drivers/hwtracing/coresight/coresight-tmc.c @@ -443,6 +443,47 @@ static ssize_t available_out_modes_show(struct device *dev, } static DEVICE_ATTR_RO(available_out_modes); +static ssize_t pcie_path_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tmc_drvdata *drvdata = dev_get_drvdata(dev->parent); + + return scnprintf(buf, PAGE_SIZE, "%s\n", + str_tmc_etr_pcie_path[drvdata->pcie_path]); +} + +static ssize_t pcie_path_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + struct tmc_drvdata *drvdata = dev_get_drvdata(dev->parent); + char str[10] = ""; + + if (strlen(buf) >= 10) + return -EINVAL; + if (sscanf(buf, "%10s", str) != 1) + return -EINVAL; + + mutex_lock(&drvdata->mem_lock); + if (drvdata->enable) { + mutex_unlock(&drvdata->mem_lock); + pr_err("ETR is in use, disable it to switch the pcie path\n"); + return -EINVAL; + } + + if (!strcmp(str, str_tmc_etr_pcie_path[TMC_ETR_PCIE_SW_PATH])) + drvdata->pcie_path = TMC_ETR_PCIE_SW_PATH; + else if (!strcmp(str, str_tmc_etr_pcie_path[TMC_ETR_PCIE_HW_PATH])) + drvdata->pcie_path = TMC_ETR_PCIE_HW_PATH; + else + size = -EINVAL; + + mutex_unlock(&drvdata->mem_lock); + return size; +} +static DEVICE_ATTR_RW(pcie_path); + + static struct attribute *coresight_tmc_etf_attrs[] = { &dev_attr_trigger_cntr.attr, NULL, @@ -454,6 +495,7 @@ static struct attribute *coresight_tmc_etr_attrs[] = { &dev_attr_block_size.attr, &dev_attr_out_mode.attr, &dev_attr_available_out_modes.attr, + &dev_attr_pcie_path.attr, NULL, }; @@ -586,6 +628,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) { drvdata->out_mode = TMC_ETR_OUT_MODE_MEM; + drvdata->pcie_path = TMC_ETR_PCIE_HW_PATH; drvdata->size = tmc_etr_get_default_buffer_size(dev); } else { drvdata->size = readl_relaxed(drvdata->base + TMC_RSZ) * 4; @@ -655,6 +698,12 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) goto out; idr_init(&drvdata->idr); mutex_init(&drvdata->idr_mutex); + if (of_property_read_bool(dev->of_node, + "qcom,qdss-ipa-support")) { + ret = tmc_etr_ipa_init(adev, drvdata); + if (ret) + goto out; + } dev_list = &etr_devs; break; case TMC_CONFIG_TYPE_ETF: diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h index 4bbae28641f6..0c70b54863bb 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.h +++ b/drivers/hwtracing/coresight/coresight-tmc.h @@ -20,6 +20,7 @@ #include #include #include +#include #include "coresight-byte-cntr.h" @@ -150,6 +151,16 @@ enum etr_mode { ETR_MODE_CATU, /* Use SG mechanism in CATU */ }; +enum tmc_etr_pcie_path { + TMC_ETR_PCIE_SW_PATH, + TMC_ETR_PCIE_HW_PATH, +}; + +static const char * const str_tmc_etr_pcie_path[] = { + [TMC_ETR_PCIE_SW_PATH] = "sw", + [TMC_ETR_PCIE_HW_PATH] = "hw", +}; + enum tmc_etr_out_mode { TMC_ETR_OUT_MODE_NONE, TMC_ETR_OUT_MODE_MEM, @@ -163,7 +174,10 @@ static const char * const str_tmc_etr_out_mode[] = { [TMC_ETR_OUT_MODE_USB] = "usb", [TMC_ETR_OUT_MODE_PCIE] = "pcie", }; - +struct tmc_etr_ipa_data { + struct ipa_qdss_conn_out_params ipa_qdss_out; + struct ipa_qdss_conn_in_params ipa_qdss_in; +}; struct tmc_etr_bam_data { struct sps_bam_props props; unsigned long handle; @@ -267,6 +281,8 @@ struct tmc_drvdata { u32 cti_flush_trig_num; u32 cti_reset_trig_num; enum tmc_etr_out_mode out_mode; + enum tmc_etr_pcie_path pcie_path; + struct tmc_etr_ipa_data *ipa_data; }; struct etr_buf_operations { @@ -335,6 +351,8 @@ void usb_notifier(void *priv, unsigned int event, struct qdss_request *d_req, struct usb_qdss_ch *ch); int tmc_etr_bam_init(struct amba_device *adev, struct tmc_drvdata *drvdata); +int tmc_etr_ipa_init(struct amba_device *adev, + struct tmc_drvdata *drvdata); extern struct byte_cntr *byte_cntr_init(struct amba_device *adev, struct tmc_drvdata *drvdata); int tmc_etr_enable_hw(struct tmc_drvdata *drvdata, struct etr_buf *etr_buf);