/* * Read the element size from the TPDM device. One TPDM must have at least one of the * element size property. * Returns * 0 - The element size property is read * Others - Cannot read the property of the element size
*/ staticint tpdm_read_element_size(struct tpda_drvdata *drvdata, struct coresight_device *csdev)
{ int rc = -EINVAL; struct tpdm_drvdata *tpdm_data = dev_get_drvdata(csdev->dev.parent);
if (tpdm_data->dsb) {
rc = fwnode_property_read_u32(dev_fwnode(csdev->dev.parent), "qcom,dsb-element-bits", &drvdata->dsb_esize); if (rc) goto out;
}
if (tpdm_data->cmb) {
rc = fwnode_property_read_u32(dev_fwnode(csdev->dev.parent), "qcom,cmb-element-bits", &drvdata->cmb_esize);
}
out: if (rc)
dev_warn_once(&csdev->dev, "Failed to read TPDM Element size: %d\n", rc);
return rc;
}
/* * Search and read element data size from the TPDM node in * the devicetree. Each input port of TPDA is connected to * a TPDM. Different TPDM supports different types of dataset, * and some may support more than one type of dataset. * Parameter "inport" is used to pass in the input port number * of TPDA, and it is set to -1 in the recursize call.
*/ staticint tpda_get_element_size(struct tpda_drvdata *drvdata, struct coresight_device *csdev, int inport)
{ int rc = 0; int i; struct coresight_device *in;
for (i = 0; i < csdev->pdata->nr_inconns; i++) {
in = csdev->pdata->in_conns[i]->src_dev; if (!in) continue;
/* Ignore the paths that do not match port */ if (inport >= 0 &&
csdev->pdata->in_conns[i]->dest_port != inport) continue;
/* * If this port has a hardcoded filter, use the source * device directly.
*/ if (csdev->pdata->in_conns[i]->filter_src_fwnode) {
in = csdev->pdata->in_conns[i]->filter_src_dev; if (!in) continue;
}
if (coresight_device_is_tpdm(in)) { if (drvdata->dsb_esize || drvdata->cmb_esize) return -EEXIST;
rc = tpdm_read_element_size(drvdata, in); if (rc) return rc;
} else { /* Recurse down the path */
rc = tpda_get_element_size(drvdata, in, -1); if (rc) return rc;
}
}
return rc;
}
/* Settings pre enabling port control register */ staticvoid tpda_enable_pre_port(struct tpda_drvdata *drvdata)
{
u32 val;
val = readl_relaxed(drvdata->base + TPDA_CR);
val &= ~TPDA_CR_ATID;
val |= FIELD_PREP(TPDA_CR_ATID, drvdata->atid);
writel_relaxed(val, drvdata->base + TPDA_CR);
}
staticint tpda_enable_port(struct tpda_drvdata *drvdata, int port)
{
u32 val; int rc;
val = readl_relaxed(drvdata->base + TPDA_Pn_CR(port));
tpda_clear_element_size(drvdata->csdev);
rc = tpda_get_element_size(drvdata, drvdata->csdev, port); if (!rc && (drvdata->dsb_esize || drvdata->cmb_esize)) {
tpda_set_element_size(drvdata, &val); /* Enable the port */
val |= TPDA_Pn_CR_ENA;
writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port));
} elseif (rc == -EEXIST)
dev_warn_once(&drvdata->csdev->dev, "Detected multiple TPDMs on port %d", port); else
dev_warn_once(&drvdata->csdev->dev, "Didn't find TPDM element size");
return rc;
}
staticint __tpda_enable(struct tpda_drvdata *drvdata, int port)
{ int ret;
CS_UNLOCK(drvdata->base);
/* * Only do pre-port enable for first port that calls enable when the * device's main refcount is still 0
*/
lockdep_assert_held(&drvdata->spinlock); if (!drvdata->csdev->refcnt)
tpda_enable_pre_port(drvdata);
ret = tpda_enable_port(drvdata, port);
CS_LOCK(drvdata->base);
return ret;
}
staticint tpda_enable(struct coresight_device *csdev, struct coresight_connection *in, struct coresight_connection *out)
{ struct tpda_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); int ret = 0;
spin_lock(&drvdata->spinlock); if (in->dest_refcnt == 0) {
ret = __tpda_enable(drvdata, in->dest_port); if (!ret) {
in->dest_refcnt++;
csdev->refcnt++;
dev_dbg(drvdata->dev, "TPDA inport %d enabled.\n", in->dest_port);
}
}
spin_unlock(&drvdata->spinlock); return ret;
}
staticvoid __tpda_disable(struct tpda_drvdata *drvdata, int port)
{
u32 val;
CS_UNLOCK(drvdata->base);
val = readl_relaxed(drvdata->base + TPDA_Pn_CR(port));
val &= ~TPDA_Pn_CR_ENA;
writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port));
staticint tpda_init_default_data(struct tpda_drvdata *drvdata)
{ int atid; /* * TPDA must has a unique atid. This atid can uniquely * identify the TPDM trace source connected to the TPDA. * The TPDMs which are connected to same TPDA share the * same trace-id. When TPDA does packetization, different * port will have unique channel number for decoding.
*/
atid = coresight_trace_id_get_system_id(); if (atid < 0) return atid;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.