coresight-tpdm: Add DSB dataset support

TPDM serves as data collection component for various dataset types.
DSB(Discrete Single Bit) is one of the dataset types. DSB subunit
can be enabled for data collection by writing 1 to the first bit of
DSB_CR register. This change is to add enable/disable function for
DSB dataset by writing DSB_CR register.

Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Tao Zhang <quic_taozha@quicinc.com>
Signed-off-by: Mao Jinlong <quic_jinlmao@quicinc.com>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Link: https://lore.kernel.org/r/20230117145708.16739-5-quic_jinlmao@quicinc.com
This commit is contained in:
Mao Jinlong 2023-01-17 06:57:03 -08:00 committed by Suzuki K Poulose
parent 6c781a3513
commit 1f00465d7f
2 changed files with 78 additions and 0 deletions

View File

@ -20,7 +20,28 @@
DEFINE_CORESIGHT_DEVLIST(tpdm_devs, "tpdm");
static void tpdm_enable_dsb(struct tpdm_drvdata *drvdata)
{
u32 val;
/* Set the enable bit of DSB control register to 1 */
val = readl_relaxed(drvdata->base + TPDM_DSB_CR);
val |= TPDM_DSB_CR_ENA;
writel_relaxed(val, drvdata->base + TPDM_DSB_CR);
}
/* TPDM enable operations */
static void __tpdm_enable(struct tpdm_drvdata *drvdata)
{
CS_UNLOCK(drvdata->base);
/* Check if DSB datasets is present for TPDM. */
if (drvdata->datasets & TPDM_PIDR0_DS_DSB)
tpdm_enable_dsb(drvdata);
CS_LOCK(drvdata->base);
}
static int tpdm_enable(struct coresight_device *csdev,
struct perf_event *event, u32 mode)
{
@ -32,6 +53,7 @@ static int tpdm_enable(struct coresight_device *csdev,
return -EBUSY;
}
__tpdm_enable(drvdata);
drvdata->enable = true;
spin_unlock(&drvdata->spinlock);
@ -39,7 +61,28 @@ static int tpdm_enable(struct coresight_device *csdev,
return 0;
}
static void tpdm_disable_dsb(struct tpdm_drvdata *drvdata)
{
u32 val;
/* Set the enable bit of DSB control register to 0 */
val = readl_relaxed(drvdata->base + TPDM_DSB_CR);
val &= ~TPDM_DSB_CR_ENA;
writel_relaxed(val, drvdata->base + TPDM_DSB_CR);
}
/* TPDM disable operations */
static void __tpdm_disable(struct tpdm_drvdata *drvdata)
{
CS_UNLOCK(drvdata->base);
/* Check if DSB datasets is present for TPDM. */
if (drvdata->datasets & TPDM_PIDR0_DS_DSB)
tpdm_disable_dsb(drvdata);
CS_LOCK(drvdata->base);
}
static void tpdm_disable(struct coresight_device *csdev,
struct perf_event *event)
{
@ -51,6 +94,7 @@ static void tpdm_disable(struct coresight_device *csdev,
return;
}
__tpdm_disable(drvdata);
drvdata->enable = false;
spin_unlock(&drvdata->spinlock);
@ -66,6 +110,17 @@ static const struct coresight_ops tpdm_cs_ops = {
.source_ops = &tpdm_source_ops,
};
static void tpdm_init_default_data(struct tpdm_drvdata *drvdata)
{
u32 pidr;
CS_UNLOCK(drvdata->base);
/* Get the datasets present on the TPDM. */
pidr = readl_relaxed(drvdata->base + CORESIGHT_PERIPHIDR0);
drvdata->datasets |= pidr & GENMASK(TPDM_DATASETS - 1, 0);
CS_LOCK(drvdata->base);
}
static int tpdm_probe(struct amba_device *adev, const struct amba_id *id)
{
void __iomem *base;
@ -107,6 +162,7 @@ static int tpdm_probe(struct amba_device *adev, const struct amba_id *id)
return PTR_ERR(drvdata->csdev);
spin_lock_init(&drvdata->spinlock);
tpdm_init_default_data(drvdata);
/* Decrease pm refcount when probe is done.*/
pm_runtime_put(&adev->dev);

View File

@ -6,6 +6,26 @@
#ifndef _CORESIGHT_CORESIGHT_TPDM_H
#define _CORESIGHT_CORESIGHT_TPDM_H
/* The max number of the datasets that TPDM supports */
#define TPDM_DATASETS 7
/* DSB Subunit Registers */
#define TPDM_DSB_CR (0x780)
/* Enable bit for DSB subunit */
#define TPDM_DSB_CR_ENA BIT(0)
/**
* The bits of PERIPHIDR0 register.
* The fields [6:0] of PERIPHIDR0 are used to determine what
* interfaces and subunits are present on a given TPDM.
*
* PERIPHIDR0[0] : Fix to 1 if ImplDef subunit present, else 0
* PERIPHIDR0[1] : Fix to 1 if DSB subunit present, else 0
*/
#define TPDM_PIDR0_DS_IMPDEF BIT(0)
#define TPDM_PIDR0_DS_DSB BIT(1)
/**
* struct tpdm_drvdata - specifics associated to an TPDM component
* @base: memory mapped base address for this component.
@ -13,6 +33,7 @@
* @csdev: component vitals needed by the framework.
* @spinlock: lock for the drvdata value.
* @enable: enable status of the component.
* @datasets: The datasets types present of the TPDM.
*/
struct tpdm_drvdata {
@ -21,6 +42,7 @@ struct tpdm_drvdata {
struct coresight_device *csdev;
spinlock_t spinlock;
bool enable;
unsigned long datasets;
};
#endif /* _CORESIGHT_CORESIGHT_TPDM_H */