Message ID | 1682586037-25973-7-git-send-email-quic_taozha@quicinc.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Add support to configure TPDM DSB subunit | expand |
On 27/04/2023 10:00, Tao Zhang wrote: > Add node to set and show programming mode for TPDM DSB subunit. > Once the DSB programming mode is set, it will be written to the > register DSB_CR. > > Signed-off-by: Tao Zhang <quic_taozha@quicinc.com> > --- > .../ABI/testing/sysfs-bus-coresight-devices-tpdm | 15 ++++++ > drivers/hwtracing/coresight/coresight-tpdm.c | 62 ++++++++++++++++++++++ > drivers/hwtracing/coresight/coresight-tpdm.h | 16 ++++++ > 3 files changed, 93 insertions(+) > > diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm > index 77e67f2..348e167 100644 > --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm > +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm > @@ -45,3 +45,18 @@ Description: > Accepts only one of the 2 values - 0 or 1. > 0 : Set the DSB trigger type to false > 1 : Set the DSB trigger type to true > + > +What: /sys/bus/coresight/devices/<tpdm-name>/dsb_mode > +Date: March 2023 > +KernelVersion 6.3 > +Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com> > +Description: > + (Write) Set the mode of DSB tpdm. Read the mode of DSB > + tpdm. > + > + Accepts the value needs to be greater than 0. What data > + bits do is listed below. > + Bit[0:1] : Test mode control bit for choosing the inputs. > + Bit[3] : Set to 0 for low performance mode. > + Set to 1 for high performance mode. > + Bit[4:8] : Select byte lane for high performance mode. > diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c > index 14f4352..1bacaa5 100644 > --- a/drivers/hwtracing/coresight/coresight-tpdm.c > +++ b/drivers/hwtracing/coresight/coresight-tpdm.c > @@ -4,6 +4,7 @@ > */ > > #include <linux/amba/bus.h> > +#include <linux/bitfield.h> > #include <linux/bitmap.h> > #include <linux/coresight.h> > #include <linux/coresight-pmu.h> > @@ -43,6 +44,32 @@ static void tpdm_reset_datasets(struct tpdm_drvdata *drvdata) > } > } > > +static void set_dsb_test_mode(struct tpdm_drvdata *drvdata, u32 *val) > +{ > + u32 mode; > + > + mode = TPDM_DSB_MODE_TEST(drvdata->dsb->mode); > + *val &= ~TPDM_DSB_TEST_MODE; > + *val |= FIELD_PREP(TPDM_DSB_TEST_MODE, mode); > +} > + > +static void set_dsb_hpsel_mode(struct tpdm_drvdata *drvdata, u32 *val) > +{ > + u32 mode; > + > + mode = TPDM_DSB_MODE_HPBYTESEL(drvdata->dsb->mode); > + *val &= ~TPDM_DSB_HPSEL; > + *val |= FIELD_PREP(TPDM_DSB_HPSEL, mode); > +} > + > +static void set_dsb_perf_mode(struct tpdm_drvdata *drvdata, u32 *val) > +{ > + if (drvdata->dsb->mode & TPDM_DSB_MODE_PERF) > + *val |= TPDM_DSB_CR_MODE; > + else > + *val &= ~TPDM_DSB_CR_MODE; > +} > + > static void set_trigger_type(struct tpdm_drvdata *drvdata, u32 *val) > { > if (drvdata->dsb->trig_type) > @@ -64,6 +91,12 @@ static void tpdm_enable_dsb(struct tpdm_drvdata *drvdata) > writel_relaxed(val, drvdata->base + TPDM_DSB_TIER); > > val = readl_relaxed(drvdata->base + TPDM_DSB_CR); > + /* Set the test accurate mode */ > + set_dsb_test_mode(drvdata, &val); > + /* Set the byte lane for high-performance mode */ > + set_dsb_hpsel_mode(drvdata, &val); > + /* Set the performance mode */ > + set_dsb_perf_mode(drvdata, &val); > /* Set trigger type */ > set_trigger_type(drvdata, &val); > /* Set the enable bit of DSB control register to 1 */ > @@ -252,6 +285,34 @@ static struct attribute_group tpdm_attr_grp = { > .attrs = tpdm_attrs, > }; > > +static ssize_t dsb_mode_show(struct device *dev, > + struct device_attribute *attr, > + char *buf) > +{ > + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); > + > + return sysfs_emit(buf, "%lx\n", > + (unsigned long)drvdata->dsb->mode); > +} > + > +static ssize_t dsb_mode_store(struct device *dev, > + struct device_attribute *attr, > + const char *buf, > + size_t size) > +{ > + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); > + unsigned long val; > + > + if ((kstrtoul(buf, 0, &val)) || val < 0) > + return -EINVAL; > + > + spin_lock(&drvdata->spinlock); > + drvdata->dsb->mode = val & TPDM_MODE_ALL; > + spin_unlock(&drvdata->spinlock); > + return size; > +} > +static DEVICE_ATTR_RW(dsb_mode); > + > static ssize_t dsb_trig_type_show(struct device *dev, > struct device_attribute *attr, char *buf) > { > @@ -323,6 +384,7 @@ static ssize_t dsb_trig_ts_store(struct device *dev, > static DEVICE_ATTR_RW(dsb_trig_ts); > > static struct attribute *tpdm_dsb_attrs[] = { > + &dev_attr_dsb_mode.attr, > &dev_attr_dsb_trig_ts.attr, > &dev_attr_dsb_trig_type.attr, > NULL, > diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h > index 68f33bd..79df07e 100644 > --- a/drivers/hwtracing/coresight/coresight-tpdm.h > +++ b/drivers/hwtracing/coresight/coresight-tpdm.h > @@ -15,11 +15,25 @@ > > /* Enable bit for DSB subunit */ > #define TPDM_DSB_CR_ENA BIT(0) > +/* Enable bit for DSB subunit perfmance mode */ > +#define TPDM_DSB_CR_MODE BIT(1) > /* Enable bit for DSB subunit trigger type */ > #define TPDM_DSB_CR_TRIG_TYPE BIT(12) > + > /* Enable bit for DSB subunit trigger timestamp */ > #define TPDM_DSB_TIER_XTRIG_TSENAB BIT(1) > > +/* DSB programming modes */ > +/* Test mode control bit*/ > +#define TPDM_DSB_MODE_TEST(val) (val & GENMASK(1, 0)) > +/* Perforceman mode */ minor nit: typo ^^ > +#define TPDM_DSB_MODE_PERF BIT(3) > +/* High performance mode */ > +#define TPDM_DSB_MODE_HPBYTESEL(val) (val & GENMASK(8, 4)) > +#define TPDM_MODE_ALL (0xFFFFFFF) GENMASK(27, 0) ? Also, why do we cover bits 27-0 ? Suzuki
On 6/1/2023 5:23 PM, Suzuki K Poulose wrote: > On 27/04/2023 10:00, Tao Zhang wrote: >> Add node to set and show programming mode for TPDM DSB subunit. >> Once the DSB programming mode is set, it will be written to the >> register DSB_CR. >> >> Signed-off-by: Tao Zhang <quic_taozha@quicinc.com> >> --- >> .../ABI/testing/sysfs-bus-coresight-devices-tpdm | 15 ++++++ >> drivers/hwtracing/coresight/coresight-tpdm.c | 62 >> ++++++++++++++++++++++ >> drivers/hwtracing/coresight/coresight-tpdm.h | 16 ++++++ >> 3 files changed, 93 insertions(+) >> >> diff --git >> a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm >> b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm >> index 77e67f2..348e167 100644 >> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm >> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm >> @@ -45,3 +45,18 @@ Description: >> Accepts only one of the 2 values - 0 or 1. >> 0 : Set the DSB trigger type to false >> 1 : Set the DSB trigger type to true >> + >> +What: /sys/bus/coresight/devices/<tpdm-name>/dsb_mode >> +Date: March 2023 >> +KernelVersion 6.3 >> +Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang >> (QUIC) <quic_taozha@quicinc.com> >> +Description: >> + (Write) Set the mode of DSB tpdm. Read the mode of DSB >> + tpdm. >> + >> + Accepts the value needs to be greater than 0. What data >> + bits do is listed below. >> + Bit[0:1] : Test mode control bit for choosing the inputs. >> + Bit[3] : Set to 0 for low performance mode. >> + Set to 1 for high performance mode. >> + Bit[4:8] : Select byte lane for high performance mode. >> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c >> b/drivers/hwtracing/coresight/coresight-tpdm.c >> index 14f4352..1bacaa5 100644 >> --- a/drivers/hwtracing/coresight/coresight-tpdm.c >> +++ b/drivers/hwtracing/coresight/coresight-tpdm.c >> @@ -4,6 +4,7 @@ >> */ >> #include <linux/amba/bus.h> >> +#include <linux/bitfield.h> >> #include <linux/bitmap.h> >> #include <linux/coresight.h> >> #include <linux/coresight-pmu.h> >> @@ -43,6 +44,32 @@ static void tpdm_reset_datasets(struct >> tpdm_drvdata *drvdata) >> } >> } >> +static void set_dsb_test_mode(struct tpdm_drvdata *drvdata, u32 *val) >> +{ >> + u32 mode; >> + >> + mode = TPDM_DSB_MODE_TEST(drvdata->dsb->mode); >> + *val &= ~TPDM_DSB_TEST_MODE; >> + *val |= FIELD_PREP(TPDM_DSB_TEST_MODE, mode); >> +} >> + >> +static void set_dsb_hpsel_mode(struct tpdm_drvdata *drvdata, u32 *val) >> +{ >> + u32 mode; >> + >> + mode = TPDM_DSB_MODE_HPBYTESEL(drvdata->dsb->mode); >> + *val &= ~TPDM_DSB_HPSEL; >> + *val |= FIELD_PREP(TPDM_DSB_HPSEL, mode); >> +} >> + >> +static void set_dsb_perf_mode(struct tpdm_drvdata *drvdata, u32 *val) >> +{ >> + if (drvdata->dsb->mode & TPDM_DSB_MODE_PERF) >> + *val |= TPDM_DSB_CR_MODE; >> + else >> + *val &= ~TPDM_DSB_CR_MODE; >> +} >> + >> static void set_trigger_type(struct tpdm_drvdata *drvdata, u32 *val) >> { >> if (drvdata->dsb->trig_type) >> @@ -64,6 +91,12 @@ static void tpdm_enable_dsb(struct tpdm_drvdata >> *drvdata) >> writel_relaxed(val, drvdata->base + TPDM_DSB_TIER); >> val = readl_relaxed(drvdata->base + TPDM_DSB_CR); >> + /* Set the test accurate mode */ >> + set_dsb_test_mode(drvdata, &val); >> + /* Set the byte lane for high-performance mode */ >> + set_dsb_hpsel_mode(drvdata, &val); >> + /* Set the performance mode */ >> + set_dsb_perf_mode(drvdata, &val); >> /* Set trigger type */ >> set_trigger_type(drvdata, &val); >> /* Set the enable bit of DSB control register to 1 */ >> @@ -252,6 +285,34 @@ static struct attribute_group tpdm_attr_grp = { >> .attrs = tpdm_attrs, >> }; >> +static ssize_t dsb_mode_show(struct device *dev, >> + struct device_attribute *attr, >> + char *buf) >> +{ >> + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); >> + >> + return sysfs_emit(buf, "%lx\n", >> + (unsigned long)drvdata->dsb->mode); >> +} >> + >> +static ssize_t dsb_mode_store(struct device *dev, >> + struct device_attribute *attr, >> + const char *buf, >> + size_t size) >> +{ >> + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); >> + unsigned long val; >> + >> + if ((kstrtoul(buf, 0, &val)) || val < 0) >> + return -EINVAL; >> + >> + spin_lock(&drvdata->spinlock); >> + drvdata->dsb->mode = val & TPDM_MODE_ALL; >> + spin_unlock(&drvdata->spinlock); >> + return size; >> +} >> +static DEVICE_ATTR_RW(dsb_mode); >> + >> static ssize_t dsb_trig_type_show(struct device *dev, >> struct device_attribute *attr, char *buf) >> { >> @@ -323,6 +384,7 @@ static ssize_t dsb_trig_ts_store(struct device *dev, >> static DEVICE_ATTR_RW(dsb_trig_ts); >> static struct attribute *tpdm_dsb_attrs[] = { >> + &dev_attr_dsb_mode.attr, >> &dev_attr_dsb_trig_ts.attr, >> &dev_attr_dsb_trig_type.attr, >> NULL, >> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h >> b/drivers/hwtracing/coresight/coresight-tpdm.h >> index 68f33bd..79df07e 100644 >> --- a/drivers/hwtracing/coresight/coresight-tpdm.h >> +++ b/drivers/hwtracing/coresight/coresight-tpdm.h >> @@ -15,11 +15,25 @@ >> /* Enable bit for DSB subunit */ >> #define TPDM_DSB_CR_ENA BIT(0) >> +/* Enable bit for DSB subunit perfmance mode */ >> +#define TPDM_DSB_CR_MODE BIT(1) >> /* Enable bit for DSB subunit trigger type */ >> #define TPDM_DSB_CR_TRIG_TYPE BIT(12) >> + >> /* Enable bit for DSB subunit trigger timestamp */ >> #define TPDM_DSB_TIER_XTRIG_TSENAB BIT(1) >> +/* DSB programming modes */ >> +/* Test mode control bit*/ >> +#define TPDM_DSB_MODE_TEST(val) (val & GENMASK(1, 0)) >> +/* Perforceman mode */ > > minor nit: typo ^^ I will update this in the next patch series. > >> +#define TPDM_DSB_MODE_PERF BIT(3) >> +/* High performance mode */ >> +#define TPDM_DSB_MODE_HPBYTESEL(val) (val & GENMASK(8, 4)) >> +#define TPDM_MODE_ALL (0xFFFFFFF) > > GENMASK(27, 0) ? > > Also, why do we cover bits 27-0 ? The TPDM mode is only represented by [0:8]bits. Can I replace it with "#define TPDM_DSB_MODE(val) (VAL & GENMASK(8, 0))"? Best, Tao > > Suzuki
On 02/06/2023 03:58, Tao Zhang wrote: > > On 6/1/2023 5:23 PM, Suzuki K Poulose wrote: >> On 27/04/2023 10:00, Tao Zhang wrote: >>> Add node to set and show programming mode for TPDM DSB subunit. >>> Once the DSB programming mode is set, it will be written to the >>> register DSB_CR. >>> >>> Signed-off-by: Tao Zhang <quic_taozha@quicinc.com> >>> --- >>> .../ABI/testing/sysfs-bus-coresight-devices-tpdm | 15 ++++++ >>> drivers/hwtracing/coresight/coresight-tpdm.c | 62 >>> ++++++++++++++++++++++ >>> drivers/hwtracing/coresight/coresight-tpdm.h | 16 ++++++ >>> 3 files changed, 93 insertions(+) >>> >>> diff --git >>> a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm >>> b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm >>> index 77e67f2..348e167 100644 >>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm >>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm >>> @@ -45,3 +45,18 @@ Description: >>> Accepts only one of the 2 values - 0 or 1. >>> 0 : Set the DSB trigger type to false >>> 1 : Set the DSB trigger type to true >>> + >>> +What: /sys/bus/coresight/devices/<tpdm-name>/dsb_mode >>> +Date: March 2023 >>> +KernelVersion 6.3 >>> +Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang >>> (QUIC) <quic_taozha@quicinc.com> >>> +Description: >>> + (Write) Set the mode of DSB tpdm. Read the mode of DSB >>> + tpdm. >>> + >>> + Accepts the value needs to be greater than 0. What data >>> + bits do is listed below. >>> + Bit[0:1] : Test mode control bit for choosing the inputs. >>> + Bit[3] : Set to 0 for low performance mode. >>> + Set to 1 for high performance mode. >>> + Bit[4:8] : Select byte lane for high performance mode. >>> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c >>> b/drivers/hwtracing/coresight/coresight-tpdm.c >>> index 14f4352..1bacaa5 100644 >>> --- a/drivers/hwtracing/coresight/coresight-tpdm.c >>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.c >>> @@ -4,6 +4,7 @@ >>> */ >>> #include <linux/amba/bus.h> >>> +#include <linux/bitfield.h> >>> #include <linux/bitmap.h> >>> #include <linux/coresight.h> >>> #include <linux/coresight-pmu.h> >>> @@ -43,6 +44,32 @@ static void tpdm_reset_datasets(struct >>> tpdm_drvdata *drvdata) >>> } >>> } >>> +static void set_dsb_test_mode(struct tpdm_drvdata *drvdata, u32 *val) >>> +{ >>> + u32 mode; >>> + >>> + mode = TPDM_DSB_MODE_TEST(drvdata->dsb->mode); >>> + *val &= ~TPDM_DSB_TEST_MODE; >>> + *val |= FIELD_PREP(TPDM_DSB_TEST_MODE, mode); >>> +} >>> + >>> +static void set_dsb_hpsel_mode(struct tpdm_drvdata *drvdata, u32 *val) >>> +{ >>> + u32 mode; >>> + >>> + mode = TPDM_DSB_MODE_HPBYTESEL(drvdata->dsb->mode); >>> + *val &= ~TPDM_DSB_HPSEL; >>> + *val |= FIELD_PREP(TPDM_DSB_HPSEL, mode); >>> +} >>> + >>> +static void set_dsb_perf_mode(struct tpdm_drvdata *drvdata, u32 *val) >>> +{ >>> + if (drvdata->dsb->mode & TPDM_DSB_MODE_PERF) >>> + *val |= TPDM_DSB_CR_MODE; >>> + else >>> + *val &= ~TPDM_DSB_CR_MODE; >>> +} >>> + >>> static void set_trigger_type(struct tpdm_drvdata *drvdata, u32 *val) >>> { >>> if (drvdata->dsb->trig_type) >>> @@ -64,6 +91,12 @@ static void tpdm_enable_dsb(struct tpdm_drvdata >>> *drvdata) >>> writel_relaxed(val, drvdata->base + TPDM_DSB_TIER); >>> val = readl_relaxed(drvdata->base + TPDM_DSB_CR); >>> + /* Set the test accurate mode */ >>> + set_dsb_test_mode(drvdata, &val); >>> + /* Set the byte lane for high-performance mode */ >>> + set_dsb_hpsel_mode(drvdata, &val); >>> + /* Set the performance mode */ >>> + set_dsb_perf_mode(drvdata, &val); >>> /* Set trigger type */ >>> set_trigger_type(drvdata, &val); >>> /* Set the enable bit of DSB control register to 1 */ >>> @@ -252,6 +285,34 @@ static struct attribute_group tpdm_attr_grp = { >>> .attrs = tpdm_attrs, >>> }; >>> +static ssize_t dsb_mode_show(struct device *dev, >>> + struct device_attribute *attr, >>> + char *buf) >>> +{ >>> + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); >>> + >>> + return sysfs_emit(buf, "%lx\n", >>> + (unsigned long)drvdata->dsb->mode); >>> +} >>> + >>> +static ssize_t dsb_mode_store(struct device *dev, >>> + struct device_attribute *attr, >>> + const char *buf, >>> + size_t size) >>> +{ >>> + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); >>> + unsigned long val; >>> + >>> + if ((kstrtoul(buf, 0, &val)) || val < 0) >>> + return -EINVAL; >>> + >>> + spin_lock(&drvdata->spinlock); >>> + drvdata->dsb->mode = val & TPDM_MODE_ALL; >>> + spin_unlock(&drvdata->spinlock); >>> + return size; >>> +} >>> +static DEVICE_ATTR_RW(dsb_mode); >>> + >>> static ssize_t dsb_trig_type_show(struct device *dev, >>> struct device_attribute *attr, char *buf) >>> { >>> @@ -323,6 +384,7 @@ static ssize_t dsb_trig_ts_store(struct device *dev, >>> static DEVICE_ATTR_RW(dsb_trig_ts); >>> static struct attribute *tpdm_dsb_attrs[] = { >>> + &dev_attr_dsb_mode.attr, >>> &dev_attr_dsb_trig_ts.attr, >>> &dev_attr_dsb_trig_type.attr, >>> NULL, >>> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h >>> b/drivers/hwtracing/coresight/coresight-tpdm.h >>> index 68f33bd..79df07e 100644 >>> --- a/drivers/hwtracing/coresight/coresight-tpdm.h >>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.h >>> @@ -15,11 +15,25 @@ >>> /* Enable bit for DSB subunit */ >>> #define TPDM_DSB_CR_ENA BIT(0) >>> +/* Enable bit for DSB subunit perfmance mode */ >>> +#define TPDM_DSB_CR_MODE BIT(1) >>> /* Enable bit for DSB subunit trigger type */ >>> #define TPDM_DSB_CR_TRIG_TYPE BIT(12) >>> + >>> /* Enable bit for DSB subunit trigger timestamp */ >>> #define TPDM_DSB_TIER_XTRIG_TSENAB BIT(1) >>> +/* DSB programming modes */ >>> +/* Test mode control bit*/ >>> +#define TPDM_DSB_MODE_TEST(val) (val & GENMASK(1, 0)) >>> +/* Perforceman mode */ >> >> minor nit: typo ^^ > I will update this in the next patch series. >> >>> +#define TPDM_DSB_MODE_PERF BIT(3) >>> +/* High performance mode */ >>> +#define TPDM_DSB_MODE_HPBYTESEL(val) (val & GENMASK(8, 4)) >>> +#define TPDM_MODE_ALL (0xFFFFFFF) >> >> GENMASK(27, 0) ? >> >> Also, why do we cover bits 27-0 ? > > The TPDM mode is only represented by [0:8]bits. > > Can I replace it with "#define TPDM_DSB_MODE(val) (VAL & GENMASK(8, > 0))"? #define TPDM_DSB_MODE_MASK GENMASK(8, 0) ? Suzuki
On 6/2/2023 4:25 PM, Suzuki K Poulose wrote: > On 02/06/2023 03:58, Tao Zhang wrote: >> >> On 6/1/2023 5:23 PM, Suzuki K Poulose wrote: >>> On 27/04/2023 10:00, Tao Zhang wrote: >>>> Add node to set and show programming mode for TPDM DSB subunit. >>>> Once the DSB programming mode is set, it will be written to the >>>> register DSB_CR. >>>> >>>> Signed-off-by: Tao Zhang <quic_taozha@quicinc.com> >>>> --- >>>> .../ABI/testing/sysfs-bus-coresight-devices-tpdm | 15 ++++++ >>>> drivers/hwtracing/coresight/coresight-tpdm.c | 62 >>>> ++++++++++++++++++++++ >>>> drivers/hwtracing/coresight/coresight-tpdm.h | 16 ++++++ >>>> 3 files changed, 93 insertions(+) >>>> >>>> diff --git >>>> a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm >>>> b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm >>>> index 77e67f2..348e167 100644 >>>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm >>>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm >>>> @@ -45,3 +45,18 @@ Description: >>>> Accepts only one of the 2 values - 0 or 1. >>>> 0 : Set the DSB trigger type to false >>>> 1 : Set the DSB trigger type to true >>>> + >>>> +What: /sys/bus/coresight/devices/<tpdm-name>/dsb_mode >>>> +Date: March 2023 >>>> +KernelVersion 6.3 >>>> +Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao >>>> Zhang (QUIC) <quic_taozha@quicinc.com> >>>> +Description: >>>> + (Write) Set the mode of DSB tpdm. Read the mode of DSB >>>> + tpdm. >>>> + >>>> + Accepts the value needs to be greater than 0. What data >>>> + bits do is listed below. >>>> + Bit[0:1] : Test mode control bit for choosing the inputs. >>>> + Bit[3] : Set to 0 for low performance mode. >>>> + Set to 1 for high performance mode. >>>> + Bit[4:8] : Select byte lane for high performance mode. >>>> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c >>>> b/drivers/hwtracing/coresight/coresight-tpdm.c >>>> index 14f4352..1bacaa5 100644 >>>> --- a/drivers/hwtracing/coresight/coresight-tpdm.c >>>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.c >>>> @@ -4,6 +4,7 @@ >>>> */ >>>> #include <linux/amba/bus.h> >>>> +#include <linux/bitfield.h> >>>> #include <linux/bitmap.h> >>>> #include <linux/coresight.h> >>>> #include <linux/coresight-pmu.h> >>>> @@ -43,6 +44,32 @@ static void tpdm_reset_datasets(struct >>>> tpdm_drvdata *drvdata) >>>> } >>>> } >>>> +static void set_dsb_test_mode(struct tpdm_drvdata *drvdata, u32 >>>> *val) >>>> +{ >>>> + u32 mode; >>>> + >>>> + mode = TPDM_DSB_MODE_TEST(drvdata->dsb->mode); >>>> + *val &= ~TPDM_DSB_TEST_MODE; >>>> + *val |= FIELD_PREP(TPDM_DSB_TEST_MODE, mode); >>>> +} >>>> + >>>> +static void set_dsb_hpsel_mode(struct tpdm_drvdata *drvdata, u32 >>>> *val) >>>> +{ >>>> + u32 mode; >>>> + >>>> + mode = TPDM_DSB_MODE_HPBYTESEL(drvdata->dsb->mode); >>>> + *val &= ~TPDM_DSB_HPSEL; >>>> + *val |= FIELD_PREP(TPDM_DSB_HPSEL, mode); >>>> +} >>>> + >>>> +static void set_dsb_perf_mode(struct tpdm_drvdata *drvdata, u32 *val) >>>> +{ >>>> + if (drvdata->dsb->mode & TPDM_DSB_MODE_PERF) >>>> + *val |= TPDM_DSB_CR_MODE; >>>> + else >>>> + *val &= ~TPDM_DSB_CR_MODE; >>>> +} >>>> + >>>> static void set_trigger_type(struct tpdm_drvdata *drvdata, u32 *val) >>>> { >>>> if (drvdata->dsb->trig_type) >>>> @@ -64,6 +91,12 @@ static void tpdm_enable_dsb(struct tpdm_drvdata >>>> *drvdata) >>>> writel_relaxed(val, drvdata->base + TPDM_DSB_TIER); >>>> val = readl_relaxed(drvdata->base + TPDM_DSB_CR); >>>> + /* Set the test accurate mode */ >>>> + set_dsb_test_mode(drvdata, &val); >>>> + /* Set the byte lane for high-performance mode */ >>>> + set_dsb_hpsel_mode(drvdata, &val); >>>> + /* Set the performance mode */ >>>> + set_dsb_perf_mode(drvdata, &val); >>>> /* Set trigger type */ >>>> set_trigger_type(drvdata, &val); >>>> /* Set the enable bit of DSB control register to 1 */ >>>> @@ -252,6 +285,34 @@ static struct attribute_group tpdm_attr_grp = { >>>> .attrs = tpdm_attrs, >>>> }; >>>> +static ssize_t dsb_mode_show(struct device *dev, >>>> + struct device_attribute *attr, >>>> + char *buf) >>>> +{ >>>> + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); >>>> + >>>> + return sysfs_emit(buf, "%lx\n", >>>> + (unsigned long)drvdata->dsb->mode); >>>> +} >>>> + >>>> +static ssize_t dsb_mode_store(struct device *dev, >>>> + struct device_attribute *attr, >>>> + const char *buf, >>>> + size_t size) >>>> +{ >>>> + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); >>>> + unsigned long val; >>>> + >>>> + if ((kstrtoul(buf, 0, &val)) || val < 0) >>>> + return -EINVAL; >>>> + >>>> + spin_lock(&drvdata->spinlock); >>>> + drvdata->dsb->mode = val & TPDM_MODE_ALL; >>>> + spin_unlock(&drvdata->spinlock); >>>> + return size; >>>> +} >>>> +static DEVICE_ATTR_RW(dsb_mode); >>>> + >>>> static ssize_t dsb_trig_type_show(struct device *dev, >>>> struct device_attribute *attr, char *buf) >>>> { >>>> @@ -323,6 +384,7 @@ static ssize_t dsb_trig_ts_store(struct device >>>> *dev, >>>> static DEVICE_ATTR_RW(dsb_trig_ts); >>>> static struct attribute *tpdm_dsb_attrs[] = { >>>> + &dev_attr_dsb_mode.attr, >>>> &dev_attr_dsb_trig_ts.attr, >>>> &dev_attr_dsb_trig_type.attr, >>>> NULL, >>>> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h >>>> b/drivers/hwtracing/coresight/coresight-tpdm.h >>>> index 68f33bd..79df07e 100644 >>>> --- a/drivers/hwtracing/coresight/coresight-tpdm.h >>>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.h >>>> @@ -15,11 +15,25 @@ >>>> /* Enable bit for DSB subunit */ >>>> #define TPDM_DSB_CR_ENA BIT(0) >>>> +/* Enable bit for DSB subunit perfmance mode */ >>>> +#define TPDM_DSB_CR_MODE BIT(1) >>>> /* Enable bit for DSB subunit trigger type */ >>>> #define TPDM_DSB_CR_TRIG_TYPE BIT(12) >>>> + >>>> /* Enable bit for DSB subunit trigger timestamp */ >>>> #define TPDM_DSB_TIER_XTRIG_TSENAB BIT(1) >>>> +/* DSB programming modes */ >>>> +/* Test mode control bit*/ >>>> +#define TPDM_DSB_MODE_TEST(val) (val & GENMASK(1, 0)) >>>> +/* Perforceman mode */ >>> >>> minor nit: typo ^^ >> I will update this in the next patch series. >>> >>>> +#define TPDM_DSB_MODE_PERF BIT(3) >>>> +/* High performance mode */ >>>> +#define TPDM_DSB_MODE_HPBYTESEL(val) (val & GENMASK(8, 4)) >>>> +#define TPDM_MODE_ALL (0xFFFFFFF) >>> >>> GENMASK(27, 0) ? >>> >>> Also, why do we cover bits 27-0 ? >> >> The TPDM mode is only represented by [0:8]bits. >> >> Can I replace it with "#define TPDM_DSB_MODE(val) (VAL & >> GENMASK(8, 0))"? > > #define TPDM_DSB_MODE_MASK GENMASK(8, 0) ? Sure, I will change it in the next patch series. Best, Tao > > Suzuki > _______________________________________________ > CoreSight mailing list -- coresight@lists.linaro.org > To unsubscribe send an email to coresight-leave@lists.linaro.org
diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm index 77e67f2..348e167 100644 --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm @@ -45,3 +45,18 @@ Description: Accepts only one of the 2 values - 0 or 1. 0 : Set the DSB trigger type to false 1 : Set the DSB trigger type to true + +What: /sys/bus/coresight/devices/<tpdm-name>/dsb_mode +Date: March 2023 +KernelVersion 6.3 +Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com> +Description: + (Write) Set the mode of DSB tpdm. Read the mode of DSB + tpdm. + + Accepts the value needs to be greater than 0. What data + bits do is listed below. + Bit[0:1] : Test mode control bit for choosing the inputs. + Bit[3] : Set to 0 for low performance mode. + Set to 1 for high performance mode. + Bit[4:8] : Select byte lane for high performance mode. diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c index 14f4352..1bacaa5 100644 --- a/drivers/hwtracing/coresight/coresight-tpdm.c +++ b/drivers/hwtracing/coresight/coresight-tpdm.c @@ -4,6 +4,7 @@ */ #include <linux/amba/bus.h> +#include <linux/bitfield.h> #include <linux/bitmap.h> #include <linux/coresight.h> #include <linux/coresight-pmu.h> @@ -43,6 +44,32 @@ static void tpdm_reset_datasets(struct tpdm_drvdata *drvdata) } } +static void set_dsb_test_mode(struct tpdm_drvdata *drvdata, u32 *val) +{ + u32 mode; + + mode = TPDM_DSB_MODE_TEST(drvdata->dsb->mode); + *val &= ~TPDM_DSB_TEST_MODE; + *val |= FIELD_PREP(TPDM_DSB_TEST_MODE, mode); +} + +static void set_dsb_hpsel_mode(struct tpdm_drvdata *drvdata, u32 *val) +{ + u32 mode; + + mode = TPDM_DSB_MODE_HPBYTESEL(drvdata->dsb->mode); + *val &= ~TPDM_DSB_HPSEL; + *val |= FIELD_PREP(TPDM_DSB_HPSEL, mode); +} + +static void set_dsb_perf_mode(struct tpdm_drvdata *drvdata, u32 *val) +{ + if (drvdata->dsb->mode & TPDM_DSB_MODE_PERF) + *val |= TPDM_DSB_CR_MODE; + else + *val &= ~TPDM_DSB_CR_MODE; +} + static void set_trigger_type(struct tpdm_drvdata *drvdata, u32 *val) { if (drvdata->dsb->trig_type) @@ -64,6 +91,12 @@ static void tpdm_enable_dsb(struct tpdm_drvdata *drvdata) writel_relaxed(val, drvdata->base + TPDM_DSB_TIER); val = readl_relaxed(drvdata->base + TPDM_DSB_CR); + /* Set the test accurate mode */ + set_dsb_test_mode(drvdata, &val); + /* Set the byte lane for high-performance mode */ + set_dsb_hpsel_mode(drvdata, &val); + /* Set the performance mode */ + set_dsb_perf_mode(drvdata, &val); /* Set trigger type */ set_trigger_type(drvdata, &val); /* Set the enable bit of DSB control register to 1 */ @@ -252,6 +285,34 @@ static struct attribute_group tpdm_attr_grp = { .attrs = tpdm_attrs, }; +static ssize_t dsb_mode_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + return sysfs_emit(buf, "%lx\n", + (unsigned long)drvdata->dsb->mode); +} + +static ssize_t dsb_mode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t size) +{ + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); + unsigned long val; + + if ((kstrtoul(buf, 0, &val)) || val < 0) + return -EINVAL; + + spin_lock(&drvdata->spinlock); + drvdata->dsb->mode = val & TPDM_MODE_ALL; + spin_unlock(&drvdata->spinlock); + return size; +} +static DEVICE_ATTR_RW(dsb_mode); + static ssize_t dsb_trig_type_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -323,6 +384,7 @@ static ssize_t dsb_trig_ts_store(struct device *dev, static DEVICE_ATTR_RW(dsb_trig_ts); static struct attribute *tpdm_dsb_attrs[] = { + &dev_attr_dsb_mode.attr, &dev_attr_dsb_trig_ts.attr, &dev_attr_dsb_trig_type.attr, NULL, diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h index 68f33bd..79df07e 100644 --- a/drivers/hwtracing/coresight/coresight-tpdm.h +++ b/drivers/hwtracing/coresight/coresight-tpdm.h @@ -15,11 +15,25 @@ /* Enable bit for DSB subunit */ #define TPDM_DSB_CR_ENA BIT(0) +/* Enable bit for DSB subunit perfmance mode */ +#define TPDM_DSB_CR_MODE BIT(1) /* Enable bit for DSB subunit trigger type */ #define TPDM_DSB_CR_TRIG_TYPE BIT(12) + /* Enable bit for DSB subunit trigger timestamp */ #define TPDM_DSB_TIER_XTRIG_TSENAB BIT(1) +/* DSB programming modes */ +/* Test mode control bit*/ +#define TPDM_DSB_MODE_TEST(val) (val & GENMASK(1, 0)) +/* Perforceman mode */ +#define TPDM_DSB_MODE_PERF BIT(3) +/* High performance mode */ +#define TPDM_DSB_MODE_HPBYTESEL(val) (val & GENMASK(8, 4)) +#define TPDM_MODE_ALL (0xFFFFFFF) +#define TPDM_DSB_TEST_MODE GENMASK(10, 9) +#define TPDM_DSB_HPSEL GENMASK(6, 2) + /* TPDM integration test registers */ #define TPDM_ITATBCNTRL (0xEF0) #define TPDM_ITCNTRL (0xF00) @@ -48,10 +62,12 @@ /** * struct dsb_dataset - specifics associated to dsb dataset + * @mode: DSB programming mode * @trig_ts: Enable/Disable trigger timestamp. * @trig_type: Enable/Disable trigger type. */ struct dsb_dataset { + u32 mode; bool trig_ts; bool trig_type; };
Add node to set and show programming mode for TPDM DSB subunit. Once the DSB programming mode is set, it will be written to the register DSB_CR. Signed-off-by: Tao Zhang <quic_taozha@quicinc.com> --- .../ABI/testing/sysfs-bus-coresight-devices-tpdm | 15 ++++++ drivers/hwtracing/coresight/coresight-tpdm.c | 62 ++++++++++++++++++++++ drivers/hwtracing/coresight/coresight-tpdm.h | 16 ++++++ 3 files changed, 93 insertions(+)