Unverified Commit 139aa37a authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!596 drivers/coresight: Add UltraSoc System Memory Buffer driver

Merge Pull Request from: @huangfangrun 
 
Add driver for UltraSoc SMB(System Memory Buffer) device. SMB provides a way to buffer messages from ETM, and store these "CPU instructions trace" in system memory. The SMB device is identifier as ACPI HID "HISI03A1". Device system memory address resources are allocated using the _CRS method and buffer modes is the circular buffer mode.

SMB is developed by UltraSoc technology, which is acquired by Siemens, and we still use "UltraSoc" to name driver. 
 
Link:https://gitee.com/openeuler/kernel/pulls/596

 

Reviewed-by: default avatarYang Shen <shenyang39@huawei.com>
Signed-off-by: default avatarJialin Zhang <zhangjialin11@huawei.com>
parents 5d1d1df9 a6511ea4
Loading
Loading
Loading
Loading
+10 −9
Original line number Diff line number Diff line
@@ -190,6 +190,7 @@ config CORESIGHT_TRBE

config ULTRASOC_SMB
       tristate "Ultrasoc system memory buffer drivers"
       depends on ACPI || COMPILE_TEST
       depends on ARM64 && CORESIGHT_LINKS_AND_SINKS
       help
         This driver provides support for the Ultrasoc system memory buffer (SMB).
+8 −19
Original line number Diff line number Diff line
@@ -365,26 +365,15 @@ static const struct etr_buf_operations etr_catu_buf_ops = {
	.get_data = catu_get_data_etr_buf,
};

coresight_simple_reg32(struct catu_drvdata, devid, CORESIGHT_DEVID);
coresight_simple_reg32(struct catu_drvdata, control, CATU_CONTROL);
coresight_simple_reg32(struct catu_drvdata, status, CATU_STATUS);
coresight_simple_reg32(struct catu_drvdata, mode, CATU_MODE);
coresight_simple_reg32(struct catu_drvdata, axictrl, CATU_AXICTRL);
coresight_simple_reg32(struct catu_drvdata, irqen, CATU_IRQEN);
coresight_simple_reg64(struct catu_drvdata, sladdr,
		       CATU_SLADDRLO, CATU_SLADDRHI);
coresight_simple_reg64(struct catu_drvdata, inaddr,
		       CATU_INADDRLO, CATU_INADDRHI);

static struct attribute *catu_mgmt_attrs[] = {
	&dev_attr_devid.attr,
	&dev_attr_control.attr,
	&dev_attr_status.attr,
	&dev_attr_mode.attr,
	&dev_attr_axictrl.attr,
	&dev_attr_irqen.attr,
	&dev_attr_sladdr.attr,
	&dev_attr_inaddr.attr,
	coresight_simple_reg32(devid, CORESIGHT_DEVID),
	coresight_simple_reg32(control, CATU_CONTROL),
	coresight_simple_reg32(status, CATU_STATUS),
	coresight_simple_reg32(mode, CATU_MODE),
	coresight_simple_reg32(axictrl, CATU_AXICTRL),
	coresight_simple_reg32(irqen, CATU_IRQEN),
	coresight_simple_reg64(sladdr, CATU_SLADDRLO, CATU_SLADDRHI),
	coresight_simple_reg64(inaddr, CATU_INADDRLO, CATU_INADDRHI),
	NULL,
};

+4 −4
Original line number Diff line number Diff line
@@ -70,24 +70,24 @@ struct catu_drvdata {
static inline u32							\
catu_read_##name(struct catu_drvdata *drvdata)				\
{									\
	return coresight_read_reg_pair(drvdata->base, offset, -1);	\
	return csdev_access_relaxed_read32(&drvdata->csdev->access, offset); \
}									\
static inline void							\
catu_write_##name(struct catu_drvdata *drvdata, u32 val)		\
{									\
	coresight_write_reg_pair(drvdata->base, val, offset, -1);	\
	csdev_access_relaxed_write32(&drvdata->csdev->access, val, offset); \
}

#define CATU_REG_PAIR(name, lo_off, hi_off)				\
static inline u64							\
catu_read_##name(struct catu_drvdata *drvdata)				\
{									\
	return coresight_read_reg_pair(drvdata->base, lo_off, hi_off);	\
	return csdev_access_relaxed_read_pair(&drvdata->csdev->access, lo_off, hi_off); \
}									\
static inline void							\
catu_write_##name(struct catu_drvdata *drvdata, u64 val)		\
{									\
	coresight_write_reg_pair(drvdata->base, val, lo_off, hi_off);	\
	csdev_access_relaxed_write_pair(&drvdata->csdev->access, val, lo_off, hi_off); \
}

CATU_REG32(control, CATU_CONTROL);
+28 −0
Original line number Diff line number Diff line
@@ -59,6 +59,34 @@ EXPORT_SYMBOL_GPL(coresight_barrier_pkt);

static const struct cti_assoc_op *cti_assoc_ops;

ssize_t coresight_simple_show_pair(struct device *_dev,
			      struct device_attribute *attr, char *buf)
{
	struct coresight_device *csdev = container_of(_dev, struct coresight_device, dev);
	struct cs_pair_attribute *cs_attr = container_of(attr, struct cs_pair_attribute, attr);
	u64 val;

	pm_runtime_get_sync(_dev->parent);
	val = csdev_access_relaxed_read_pair(&csdev->access, cs_attr->lo_off, cs_attr->hi_off);
	pm_runtime_put_sync(_dev->parent);
	return sysfs_emit(buf, "0x%llx\n", val);
}
EXPORT_SYMBOL_GPL(coresight_simple_show_pair);

ssize_t coresight_simple_show32(struct device *_dev,
			      struct device_attribute *attr, char *buf)
{
	struct coresight_device *csdev = container_of(_dev, struct coresight_device, dev);
	struct cs_off_attribute *cs_attr = container_of(attr, struct cs_off_attribute, attr);
	u64 val;

	pm_runtime_get_sync(_dev->parent);
	val = csdev_access_relaxed_read32(&csdev->access, cs_attr->off);
	pm_runtime_put_sync(_dev->parent);
	return sysfs_emit(buf, "0x%llx\n", val);
}
EXPORT_SYMBOL_GPL(coresight_simple_show32);

void coresight_set_cti_ops(const struct cti_assoc_op *cti_op)
{
	cti_assoc_ops = cti_op;
+86 −127
Original line number Diff line number Diff line
@@ -163,48 +163,82 @@ static struct attribute *coresight_cti_attrs[] = {

/* register based attributes */

/* macro to access RO registers with power check only (no enable check). */
/* Read registers with power check only (no enable check). */
static ssize_t coresight_cti_reg_show(struct device *dev,
			   struct device_attribute *attr, char *buf)
{
	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
	struct cs_off_attribute *cti_attr = container_of(attr, struct cs_off_attribute, attr);
	u32 val = 0;

	pm_runtime_get_sync(dev->parent);
	spin_lock(&drvdata->spinlock);
	if (drvdata->config.hw_powered)
		val = readl_relaxed(drvdata->base + cti_attr->off);
	spin_unlock(&drvdata->spinlock);
	pm_runtime_put_sync(dev->parent);
	return sysfs_emit(buf, "0x%x\n", val);
}

/* Write registers with power check only (no enable check). */
static __maybe_unused ssize_t coresight_cti_reg_store(struct device *dev,
						      struct device_attribute *attr,
						      const char *buf, size_t size)
{
	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
	struct cs_off_attribute *cti_attr = container_of(attr, struct cs_off_attribute, attr);
	unsigned long val = 0;

	if (kstrtoul(buf, 0, &val))
		return -EINVAL;

	pm_runtime_get_sync(dev->parent);
	spin_lock(&drvdata->spinlock);
	if (drvdata->config.hw_powered)
		cti_write_single_reg(drvdata, cti_attr->off, val);
	spin_unlock(&drvdata->spinlock);
	pm_runtime_put_sync(dev->parent);
	return size;
}

#define coresight_cti_reg(name, offset)					\
static ssize_t name##_show(struct device *dev,				\
			   struct device_attribute *attr, char *buf)	\
	(&((struct cs_off_attribute[]) {				\
	   {								\
	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);	\
	u32 val = 0;							\
	pm_runtime_get_sync(dev->parent);				\
	spin_lock(&drvdata->spinlock);					\
	if (drvdata->config.hw_powered)					\
		val = readl_relaxed(drvdata->base + offset);		\
	spin_unlock(&drvdata->spinlock);				\
	pm_runtime_put_sync(dev->parent);				\
	return sprintf(buf, "0x%x\n", val);				\
		__ATTR(name, 0444, coresight_cti_reg_show, NULL),	\
		offset							\
	   }								\
static DEVICE_ATTR_RO(name)
	})[0].attr.attr)

/* coresight management registers */
coresight_cti_reg(devaff0, CTIDEVAFF0);
coresight_cti_reg(devaff1, CTIDEVAFF1);
coresight_cti_reg(authstatus, CORESIGHT_AUTHSTATUS);
coresight_cti_reg(devarch, CORESIGHT_DEVARCH);
coresight_cti_reg(devid, CORESIGHT_DEVID);
coresight_cti_reg(devtype, CORESIGHT_DEVTYPE);
coresight_cti_reg(pidr0, CORESIGHT_PERIPHIDR0);
coresight_cti_reg(pidr1, CORESIGHT_PERIPHIDR1);
coresight_cti_reg(pidr2, CORESIGHT_PERIPHIDR2);
coresight_cti_reg(pidr3, CORESIGHT_PERIPHIDR3);
coresight_cti_reg(pidr4, CORESIGHT_PERIPHIDR4);
#define coresight_cti_reg_rw(name, offset)				\
	(&((struct cs_off_attribute[]) {				\
	   {								\
		__ATTR(name, 0644, coresight_cti_reg_show,		\
		       coresight_cti_reg_store),			\
		offset							\
	   }								\
	})[0].attr.attr)

#define coresight_cti_reg_wo(name, offset)				\
	(&((struct cs_off_attribute[]) {				\
	   {								\
		__ATTR(name, 0200, NULL, coresight_cti_reg_store),	\
		offset							\
	   }								\
	})[0].attr.attr)

/* coresight management registers */
static struct attribute *coresight_cti_mgmt_attrs[] = {
	&dev_attr_devaff0.attr,
	&dev_attr_devaff1.attr,
	&dev_attr_authstatus.attr,
	&dev_attr_devarch.attr,
	&dev_attr_devid.attr,
	&dev_attr_devtype.attr,
	&dev_attr_pidr0.attr,
	&dev_attr_pidr1.attr,
	&dev_attr_pidr2.attr,
	&dev_attr_pidr3.attr,
	&dev_attr_pidr4.attr,
	coresight_cti_reg(devaff0, CTIDEVAFF0),
	coresight_cti_reg(devaff1, CTIDEVAFF1),
	coresight_cti_reg(authstatus, CORESIGHT_AUTHSTATUS),
	coresight_cti_reg(devarch, CORESIGHT_DEVARCH),
	coresight_cti_reg(devid, CORESIGHT_DEVID),
	coresight_cti_reg(devtype, CORESIGHT_DEVTYPE),
	coresight_cti_reg(pidr0, CORESIGHT_PERIPHIDR0),
	coresight_cti_reg(pidr1, CORESIGHT_PERIPHIDR1),
	coresight_cti_reg(pidr2, CORESIGHT_PERIPHIDR2),
	coresight_cti_reg(pidr3, CORESIGHT_PERIPHIDR3),
	coresight_cti_reg(pidr4, CORESIGHT_PERIPHIDR4),
	NULL,
};

@@ -454,86 +488,11 @@ static ssize_t apppulse_store(struct device *dev,
}
static DEVICE_ATTR_WO(apppulse);

coresight_cti_reg(triginstatus, CTITRIGINSTATUS);
coresight_cti_reg(trigoutstatus, CTITRIGOUTSTATUS);
coresight_cti_reg(chinstatus, CTICHINSTATUS);
coresight_cti_reg(choutstatus, CTICHOUTSTATUS);

/*
 * Define CONFIG_CORESIGHT_CTI_INTEGRATION_REGS to enable the access to the
 * integration control registers. Normally only used to investigate connection
 * data.
 */
#ifdef CONFIG_CORESIGHT_CTI_INTEGRATION_REGS

/* macro to access RW registers with power check only (no enable check). */
#define coresight_cti_reg_rw(name, offset)				\
static ssize_t name##_show(struct device *dev,				\
			   struct device_attribute *attr, char *buf)	\
{									\
	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);	\
	u32 val = 0;							\
	pm_runtime_get_sync(dev->parent);				\
	spin_lock(&drvdata->spinlock);					\
	if (drvdata->config.hw_powered)					\
		val = readl_relaxed(drvdata->base + offset);		\
	spin_unlock(&drvdata->spinlock);				\
	pm_runtime_put_sync(dev->parent);				\
	return sprintf(buf, "0x%x\n", val);				\
}									\
									\
static ssize_t name##_store(struct device *dev,				\
			    struct device_attribute *attr,		\
			    const char *buf, size_t size)		\
{									\
	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);	\
	unsigned long val = 0;						\
	if (kstrtoul(buf, 0, &val))					\
		return -EINVAL;						\
									\
	pm_runtime_get_sync(dev->parent);				\
	spin_lock(&drvdata->spinlock);					\
	if (drvdata->config.hw_powered)					\
		cti_write_single_reg(drvdata, offset, val);		\
	spin_unlock(&drvdata->spinlock);				\
	pm_runtime_put_sync(dev->parent);				\
	return size;							\
}									\
static DEVICE_ATTR_RW(name)

/* macro to access WO registers with power check only (no enable check). */
#define coresight_cti_reg_wo(name, offset)				\
static ssize_t name##_store(struct device *dev,				\
			    struct device_attribute *attr,		\
			    const char *buf, size_t size)		\
{									\
	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);	\
	unsigned long val = 0;						\
	if (kstrtoul(buf, 0, &val))					\
		return -EINVAL;						\
									\
	pm_runtime_get_sync(dev->parent);				\
	spin_lock(&drvdata->spinlock);					\
	if (drvdata->config.hw_powered)					\
		cti_write_single_reg(drvdata, offset, val);		\
	spin_unlock(&drvdata->spinlock);				\
	pm_runtime_put_sync(dev->parent);				\
	return size;							\
}									\
static DEVICE_ATTR_WO(name)

coresight_cti_reg_rw(itchout, ITCHOUT);
coresight_cti_reg_rw(ittrigout, ITTRIGOUT);
coresight_cti_reg_rw(itctrl, CORESIGHT_ITCTRL);
coresight_cti_reg_wo(itchinack, ITCHINACK);
coresight_cti_reg_wo(ittriginack, ITTRIGINACK);
coresight_cti_reg(ittrigin, ITTRIGIN);
coresight_cti_reg(itchin, ITCHIN);
coresight_cti_reg(itchoutack, ITCHOUTACK);
coresight_cti_reg(ittrigoutack, ITTRIGOUTACK);

#endif /* CORESIGHT_CTI_INTEGRATION_REGS */

static struct attribute *coresight_cti_regs_attrs[] = {
	&dev_attr_inout_sel.attr,
	&dev_attr_inen.attr,
@@ -544,20 +503,20 @@ static struct attribute *coresight_cti_regs_attrs[] = {
	&dev_attr_appset.attr,
	&dev_attr_appclear.attr,
	&dev_attr_apppulse.attr,
	&dev_attr_triginstatus.attr,
	&dev_attr_trigoutstatus.attr,
	&dev_attr_chinstatus.attr,
	&dev_attr_choutstatus.attr,
	coresight_cti_reg(triginstatus, CTITRIGINSTATUS),
	coresight_cti_reg(trigoutstatus, CTITRIGOUTSTATUS),
	coresight_cti_reg(chinstatus, CTICHINSTATUS),
	coresight_cti_reg(choutstatus, CTICHOUTSTATUS),
#ifdef CONFIG_CORESIGHT_CTI_INTEGRATION_REGS
	&dev_attr_itctrl.attr,
	&dev_attr_ittrigin.attr,
	&dev_attr_itchin.attr,
	&dev_attr_ittrigout.attr,
	&dev_attr_itchout.attr,
	&dev_attr_itchoutack.attr,
	&dev_attr_ittrigoutack.attr,
	&dev_attr_ittriginack.attr,
	&dev_attr_itchinack.attr,
	coresight_cti_reg_rw(itctrl, CORESIGHT_ITCTRL),
	coresight_cti_reg(ittrigin, ITTRIGIN),
	coresight_cti_reg(itchin, ITCHIN),
	coresight_cti_reg_rw(ittrigout, ITTRIGOUT),
	coresight_cti_reg_rw(itchout, ITCHOUT),
	coresight_cti_reg(itchoutack, ITCHOUTACK),
	coresight_cti_reg(ittrigoutack, ITTRIGOUTACK),
	coresight_cti_reg_wo(ittriginack, ITTRIGINACK),
	coresight_cti_reg_wo(itchinack, ITCHINACK),
#endif
	NULL,
};
Loading