Message ID | 1690269353-10829-10-git-send-email-quic_taozha@quicinc.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | Add support to configure TPDM DSB subunit | expand |
Hi Tao, kernel test robot noticed the following build warnings: [auto build test WARNING on robh/for-next] [also build test WARNING on linus/master v6.5-rc3 next-20230725] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Tao-Zhang/coresight-tpdm-Remove-the-unnecessary-lock/20230725-152235 base: https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next patch link: https://lore.kernel.org/r/1690269353-10829-10-git-send-email-quic_taozha%40quicinc.com patch subject: [PATCH v7 09/13] coresight-tpdm: Add nodes for dsb edge control config: arm-randconfig-r003-20230725 (https://download.01.org/0day-ci/archive/20230725/202307252010.fbqRILwZ-lkp@intel.com/config) compiler: arm-linux-gnueabi-gcc (GCC) 12.3.0 reproduce: (https://download.01.org/0day-ci/archive/20230725/202307252010.fbqRILwZ-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202307252010.fbqRILwZ-lkp@intel.com/ All warnings (new ones prefixed by >>): drivers/hwtracing/coresight/coresight-tpdm.c: In function 'dsb_edge_ctrl_val_store': >> drivers/hwtracing/coresight/coresight-tpdm.c:383:28: warning: variable 'mask' set but not used [-Wunused-but-set-variable] 383 | unsigned long val, mask, edge_ctrl; | ^~~~ drivers/hwtracing/coresight/coresight-tpdm.c: In function 'dsb_edge_ctrl_mask_store': >> drivers/hwtracing/coresight/coresight-tpdm.c:449:9: warning: this 'else' clause does not guard... [-Wmisleading-indentation] 449 | else | ^~~~ drivers/hwtracing/coresight/coresight-tpdm.c:451:17: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'else' 451 | drvdata->dsb->edge_ctrl_mask[reg] = set; | ^~~~~~~ vim +/mask +383 drivers/hwtracing/coresight/coresight-tpdm.c 368 369 /* 370 * This function is used to control the edge detection according 371 * to the index number that has been set. 372 * "edge_ctrl" should be one of the following values. 373 * 0 - Rising edge detection 374 * 1 - Falling edge detection 375 * 2 - Rising and falling edge detection (toggle detection) 376 */ 377 static ssize_t dsb_edge_ctrl_val_store(struct device *dev, 378 struct device_attribute *attr, 379 const char *buf, 380 size_t size) 381 { 382 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); > 383 unsigned long val, mask, edge_ctrl; 384 int reg; 385 386 if ((kstrtoul(buf, 0, &edge_ctrl)) || (edge_ctrl > 0x2)) 387 return -EINVAL; 388 389 spin_lock(&drvdata->spinlock); 390 /* 391 * There are 2 bit per DSB Edge Control line. 392 * Thus we have 16 lines in a 32bit word. 393 */ 394 reg = EDCR_TO_WORD_IDX(drvdata->dsb->edge_ctrl_idx); 395 mask = EDCR_TO_WORD_MASK(drvdata->dsb->edge_ctrl_idx); 396 val = drvdata->dsb->edge_ctrl[reg]; 397 val &= ~EDCR_TO_WORD_MASK(drvdata->dsb->edge_ctrl_idx); 398 val |= EDCR_TO_WORD_VAL(edge_ctrl, drvdata->dsb->edge_ctrl_idx); 399 drvdata->dsb->edge_ctrl[reg] = val; 400 spin_unlock(&drvdata->spinlock); 401 402 return size; 403 } 404 static DEVICE_ATTR_RW(dsb_edge_ctrl_val); 405 406 static ssize_t dsb_edge_ctrl_mask_show(struct device *dev, 407 struct device_attribute *attr, 408 char *buf) 409 { 410 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 411 ssize_t size = 0; 412 unsigned long bytes; 413 int i; 414 415 spin_lock(&drvdata->spinlock); 416 for (i = 0; i < TPDM_DSB_MAX_EDCMR; i++) { 417 bytes = sysfs_emit_at(buf, size, 418 "Val:0x%x\n", drvdata->dsb->edge_ctrl_mask[i]); 419 if (bytes <= 0) 420 break; 421 size += bytes; 422 } 423 spin_unlock(&drvdata->spinlock); 424 return size; 425 } 426 427 static ssize_t dsb_edge_ctrl_mask_store(struct device *dev, 428 struct device_attribute *attr, 429 const char *buf, 430 size_t size) 431 { 432 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 433 unsigned long val; 434 u32 set; 435 int reg; 436 437 if ((kstrtoul(buf, 0, &val)) || (val & ~1UL)) 438 return -EINVAL; 439 440 spin_lock(&drvdata->spinlock); 441 /* 442 * There is 1 bit per DSB Edge Control Mark line. 443 * Thus we have 32 lines in a 32bit word. 444 */ 445 reg = EDCMR_TO_WORD_IDX(drvdata->dsb->edge_ctrl_idx); 446 set = drvdata->dsb->edge_ctrl_mask[reg]; 447 if (val) 448 set |= BIT(EDCMR_TO_WORD_SHIFT(drvdata->dsb->edge_ctrl_idx)); > 449 else 450 set &= ~BIT(EDCMR_TO_WORD_SHIFT(drvdata->dsb->edge_ctrl_idx)); 451 drvdata->dsb->edge_ctrl_mask[reg] = set; 452 spin_unlock(&drvdata->spinlock); 453 454 return size; 455 } 456 static DEVICE_ATTR_RW(dsb_edge_ctrl_mask); 457
Hi Tao, kernel test robot noticed the following build warnings: [auto build test WARNING on robh/for-next] [also build test WARNING on linus/master v6.5-rc3 next-20230725] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Tao-Zhang/coresight-tpdm-Remove-the-unnecessary-lock/20230725-152235 base: https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next patch link: https://lore.kernel.org/r/1690269353-10829-10-git-send-email-quic_taozha%40quicinc.com patch subject: [PATCH v7 09/13] coresight-tpdm: Add nodes for dsb edge control config: arm-randconfig-r013-20230725 (https://download.01.org/0day-ci/archive/20230726/202307260533.MTqa5ObG-lkp@intel.com/config) compiler: clang version 17.0.0 (https://github.com/llvm/llvm-project.git 4a5ac14ee968ff0ad5d2cc1ffa0299048db4c88a) reproduce: (https://download.01.org/0day-ci/archive/20230726/202307260533.MTqa5ObG-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202307260533.MTqa5ObG-lkp@intel.com/ All warnings (new ones prefixed by >>): drivers/hwtracing/coresight/coresight-tpdm.c:383:21: warning: variable 'mask' set but not used [-Wunused-but-set-variable] 383 | unsigned long val, mask, edge_ctrl; | ^ >> drivers/hwtracing/coresight/coresight-tpdm.c:451:3: warning: misleading indentation; statement is not part of the previous 'else' [-Wmisleading-indentation] 451 | drvdata->dsb->edge_ctrl_mask[reg] = set; | ^ drivers/hwtracing/coresight/coresight-tpdm.c:449:2: note: previous statement is here 449 | else | ^ 2 warnings generated. vim +/else +451 drivers/hwtracing/coresight/coresight-tpdm.c 426 427 static ssize_t dsb_edge_ctrl_mask_store(struct device *dev, 428 struct device_attribute *attr, 429 const char *buf, 430 size_t size) 431 { 432 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 433 unsigned long val; 434 u32 set; 435 int reg; 436 437 if ((kstrtoul(buf, 0, &val)) || (val & ~1UL)) 438 return -EINVAL; 439 440 spin_lock(&drvdata->spinlock); 441 /* 442 * There is 1 bit per DSB Edge Control Mark line. 443 * Thus we have 32 lines in a 32bit word. 444 */ 445 reg = EDCMR_TO_WORD_IDX(drvdata->dsb->edge_ctrl_idx); 446 set = drvdata->dsb->edge_ctrl_mask[reg]; 447 if (val) 448 set |= BIT(EDCMR_TO_WORD_SHIFT(drvdata->dsb->edge_ctrl_idx)); 449 else 450 set &= ~BIT(EDCMR_TO_WORD_SHIFT(drvdata->dsb->edge_ctrl_idx)); > 451 drvdata->dsb->edge_ctrl_mask[reg] = set; 452 spin_unlock(&drvdata->spinlock); 453 454 return size; 455 } 456 static DEVICE_ATTR_RW(dsb_edge_ctrl_mask); 457
On 25/07/2023 08:15, Tao Zhang wrote: > Add the nodes to set value for DSB edge control and DSB edge > control mask. Each DSB subunit TPDM has maximum of n(n<16) EDCR > resgisters to configure edge control. DSB edge detection control > 00: Rising edge detection > 01: Falling edge detection > 10: Rising and falling edge detection (toggle detection) > And each DSB subunit TPDM has maximum of m(m<8) ECDMR registers to > configure mask. Eight 32 bit registers providing DSB interface > edge detection mask control. > > Add the nodes to configure DSB edge control and DSB edge control > mask. Each DSB subunit TPDM maximum of 256 edge detections can be > configured. The index and value sysfs files need to be paired and > written to order. The index sysfs file is to set the index number > of the edge detection which needs to be configured. And the value > sysfs file is to set the control or mask for the edge detection. > DSB edge detection control should be set as the following values. > 00: Rising edge detection > 01: Falling edge detection > 10: Rising and falling edge detection (toggle detection) > And DSB edge mask should be set as 0 or 1. > Each DSB subunit TPDM has maximum of n(n<16) EDCR resgisters to > configure edge control. And each DSB subunit TPDM has maximum of > m(m<8) ECDMR registers to configure mask. > > Signed-off-by: Tao Zhang <quic_taozha@quicinc.com> > --- > .../ABI/testing/sysfs-bus-coresight-devices-tpdm | 39 +++++ > drivers/hwtracing/coresight/coresight-tpdm.c | 158 ++++++++++++++++++++- > drivers/hwtracing/coresight/coresight-tpdm.h | 30 +++- > 3 files changed, 223 insertions(+), 4 deletions(-) > > diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm > index 2a82cd0..a4550c5 100644 > --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm > +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm > @@ -60,3 +60,42 @@ Description: > 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. > + > +What: /sys/bus/coresight/devices/<tpdm-name>/dsb_edge_ctrl_idx > +Date: March 2023 > +KernelVersion 6.5 > +Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com> > +Description: > + Read/Write the index number of the edge detection for the DSB > + subunit TPDM. Since there are at most 256 edge detections, this > + value ranges from 0 to 255. > + > +What: /sys/bus/coresight/devices/<tpdm-name>/dsb_edge_ctrl_val > +Date: March 2023 > +KernelVersion 6.5 > +Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com> > +Description: > + Read a set of the edge control registers of the DSB in TPDM. > + Write a data to control the edge detection corresponding to > + the index number. Before writing data to this sysfs file, > + "dsb_edge_ctrl_idx" should be written first to configure the > + index number of the edge detection which needs to be controlled. > + > + Accepts only one of the following values. > + 0 - Rising edge detection > + 1 - Falling edge detection > + 2 - Rising and falling edge detection (toggle detection) > + > + > +What: /sys/bus/coresight/devices/<tpdm-name>/dsb_edge_ctrl_mask > +Date: March 2023 > +KernelVersion 6.5 > +Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com> > +Description: > + Read a set of the edge control mask registers of the DSB in TPDM. > + Write a data to mask the edge detection corresponding to the index > + number. Before writing data to this sysfs file, "dsb_edge_ctrl_idx" > + should be written first to configure the index number of the edge > + detection which needs to be masked. > + > + Accepts only one of the 2 values - 0 or 1. > \ No newline at end of file > diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c > index c38760b..98fd6ab 100644 > --- a/drivers/hwtracing/coresight/coresight-tpdm.c > +++ b/drivers/hwtracing/coresight/coresight-tpdm.c > @@ -71,7 +71,14 @@ static void set_dsb_perf_mode(struct tpdm_drvdata *drvdata, u32 *val) > > static void tpdm_enable_dsb(struct tpdm_drvdata *drvdata) > { > - u32 val; > + u32 val, i; > + > + for (i = 0; i < TPDM_DSB_MAX_EDCR; i++) > + writel_relaxed(drvdata->dsb->edge_ctrl[i], > + drvdata->base + TPDM_DSB_EDCR(i)); > + for (i = 0; i < TPDM_DSB_MAX_EDCMR; i++) > + writel_relaxed(drvdata->dsb->edge_ctrl_mask[i], > + drvdata->base + TPDM_DSB_EDCMR(i)); > > val = readl_relaxed(drvdata->base + TPDM_DSB_TIER); > /* Set trigger timestamp */ > @@ -302,6 +309,152 @@ static ssize_t dsb_mode_store(struct device *dev, > } > static DEVICE_ATTR_RW(dsb_mode); > > +static ssize_t dsb_edge_ctrl_idx_show(struct device *dev, > + struct device_attribute *attr, > + char *buf) > +{ > + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); > + > + return sysfs_emit(buf, "%u\n", > + (unsigned int)drvdata->dsb->edge_ctrl_idx); > +} > + > +/* > + * The EDCR registers can include up to 16 32-bit registers, and each > + * one can be configured to control up to 16 edge detections(2 bits > + * control one edge detection). So a total 256 edge detections can be > + * configured. This function provides a way to set the index number of > + * the edge detection which needs to be configured. > + */ > +static ssize_t dsb_edge_ctrl_idx_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 >= TPDM_DSB_MAX_LINES)) > + return -EINVAL; > + > + spin_lock(&drvdata->spinlock); > + drvdata->dsb->edge_ctrl_idx = val; > + spin_unlock(&drvdata->spinlock); > + > + return size; > +} > +static DEVICE_ATTR_RW(dsb_edge_ctrl_idx); > + > +static ssize_t dsb_edge_ctrl_val_show(struct device *dev, > + struct device_attribute *attr, > + char *buf) > +{ > + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); > + ssize_t size = 0; > + unsigned long bytes; > + int i; > + > + spin_lock(&drvdata->spinlock); > + for (i = 0; i < TPDM_DSB_MAX_EDCR; i++) { > + bytes = sysfs_emit_at(buf, size, > + "Val:0x%x\n", drvdata->dsb->edge_ctrl[i]); > + if (bytes <= 0) > + break; > + size += bytes; > + } > + spin_unlock(&drvdata->spinlock); > + return size; > +} > + > +/* > + * This function is used to control the edge detection according > + * to the index number that has been set. > + * "edge_ctrl" should be one of the following values. > + * 0 - Rising edge detection > + * 1 - Falling edge detection > + * 2 - Rising and falling edge detection (toggle detection) > + */ > +static ssize_t dsb_edge_ctrl_val_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, mask, edge_ctrl; > + int reg; > + > + if ((kstrtoul(buf, 0, &edge_ctrl)) || (edge_ctrl > 0x2)) > + return -EINVAL; > + > + spin_lock(&drvdata->spinlock); > + /* > + * There are 2 bit per DSB Edge Control line. > + * Thus we have 16 lines in a 32bit word. > + */ > + reg = EDCR_TO_WORD_IDX(drvdata->dsb->edge_ctrl_idx); > + mask = EDCR_TO_WORD_MASK(drvdata->dsb->edge_ctrl_idx); > + val = drvdata->dsb->edge_ctrl[reg]; > + val &= ~EDCR_TO_WORD_MASK(drvdata->dsb->edge_ctrl_idx); > + val |= EDCR_TO_WORD_VAL(edge_ctrl, drvdata->dsb->edge_ctrl_idx); > + drvdata->dsb->edge_ctrl[reg] = val; > + spin_unlock(&drvdata->spinlock); > + > + return size; > +} > +static DEVICE_ATTR_RW(dsb_edge_ctrl_val); > + > +static ssize_t dsb_edge_ctrl_mask_show(struct device *dev, > + struct device_attribute *attr, > + char *buf) > +{ > + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); > + ssize_t size = 0; > + unsigned long bytes; > + int i; > + > + spin_lock(&drvdata->spinlock); > + for (i = 0; i < TPDM_DSB_MAX_EDCMR; i++) { > + bytes = sysfs_emit_at(buf, size, > + "Val:0x%x\n", drvdata->dsb->edge_ctrl_mask[i]); > + if (bytes <= 0) > + break; > + size += bytes; > + } > + spin_unlock(&drvdata->spinlock); > + return size; > +} > + > +static ssize_t dsb_edge_ctrl_mask_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; > + u32 set; > + int reg; > + > + if ((kstrtoul(buf, 0, &val)) || (val & ~1UL)) > + return -EINVAL; > + > + spin_lock(&drvdata->spinlock); > + /* > + * There is 1 bit per DSB Edge Control Mark line. > + * Thus we have 32 lines in a 32bit word. > + */ > + reg = EDCMR_TO_WORD_IDX(drvdata->dsb->edge_ctrl_idx); > + set = drvdata->dsb->edge_ctrl_mask[reg]; > + if (val) > + set |= BIT(EDCMR_TO_WORD_SHIFT(drvdata->dsb->edge_ctrl_idx)); > + else > + set &= ~BIT(EDCMR_TO_WORD_SHIFT(drvdata->dsb->edge_ctrl_idx)); > + drvdata->dsb->edge_ctrl_mask[reg] = set; drivers/hwtracing/coresight/coresight-tpdm.c: In function ‘dsb_edge_ctrl_mask_store’: drivers/hwtracing/coresight/coresight-tpdm.c:449:2: error: this ‘else’ clause does not guard... [-Werror=misleading-indentation] else ^~~~ drivers/hwtracing/coresight/coresight-tpdm.c:451:3: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the ‘else’ drvdata->dsb->edge_ctrl_mask[reg] = set; ^~~~~~~ cc1: all warnings being treated as errors make[4]: *** [scripts/Makefile.build:243: drivers/hwtracing/coresight/coresight-tpdm.o] Error 1 make[3]: *** [scripts/Makefile.build:480: drivers/hwtracing/coresight] Error 2 make[2]: *** [scripts/Makefile.build:480: drivers] Error 2 make[1]: *** [/ssd/src/LINUX-CORESIGHT/Makefile:2032: .] Error 2 make: *** [Makefile:234: __sub-make] Error 2 Suzuki
On 25/07/2023 08:15, Tao Zhang wrote: > Add the nodes to set value for DSB edge control and DSB edge > control mask. Each DSB subunit TPDM has maximum of n(n<16) EDCR > resgisters to configure edge control. DSB edge detection control > 00: Rising edge detection > 01: Falling edge detection > 10: Rising and falling edge detection (toggle detection) > And each DSB subunit TPDM has maximum of m(m<8) ECDMR registers to > configure mask. Eight 32 bit registers providing DSB interface > edge detection mask control. > > Add the nodes to configure DSB edge control and DSB edge control > mask. Each DSB subunit TPDM maximum of 256 edge detections can be > configured. The index and value sysfs files need to be paired and > written to order. The index sysfs file is to set the index number > of the edge detection which needs to be configured. And the value > sysfs file is to set the control or mask for the edge detection. > DSB edge detection control should be set as the following values. > 00: Rising edge detection > 01: Falling edge detection > 10: Rising and falling edge detection (toggle detection) > And DSB edge mask should be set as 0 or 1. > Each DSB subunit TPDM has maximum of n(n<16) EDCR resgisters to > configure edge control. And each DSB subunit TPDM has maximum of > m(m<8) ECDMR registers to configure mask. > > Signed-off-by: Tao Zhang <quic_taozha@quicinc.com> > --- > .../ABI/testing/sysfs-bus-coresight-devices-tpdm | 39 +++++ > drivers/hwtracing/coresight/coresight-tpdm.c | 158 ++++++++++++++++++++- > drivers/hwtracing/coresight/coresight-tpdm.h | 30 +++- > 3 files changed, 223 insertions(+), 4 deletions(-) > > diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm > index 2a82cd0..a4550c5 100644 > --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm > +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm > @@ -60,3 +60,42 @@ Description: > 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. > + > +What: /sys/bus/coresight/devices/<tpdm-name>/dsb_edge_ctrl_idx > +Date: March 2023 > +KernelVersion 6.5 > +Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com> > +Description: > + Read/Write the index number of the edge detection for the DSB > + subunit TPDM. Since there are at most 256 edge detections, this > + value ranges from 0 to 255. > + > +What: /sys/bus/coresight/devices/<tpdm-name>/dsb_edge_ctrl_val > +Date: March 2023 > +KernelVersion 6.5 > +Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com> > +Description: > + Read a set of the edge control registers of the DSB in TPDM. > + Write a data to control the edge detection corresponding to > + the index number. Before writing data to this sysfs file, > + "dsb_edge_ctrl_idx" should be written first to configure the > + index number of the edge detection which needs to be controlled. > + > + Accepts only one of the following values. > + 0 - Rising edge detection > + 1 - Falling edge detection > + 2 - Rising and falling edge detection (toggle detection) > + > + > +What: /sys/bus/coresight/devices/<tpdm-name>/dsb_edge_ctrl_mask > +Date: March 2023 > +KernelVersion 6.5 > +Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com> > +Description: > + Read a set of the edge control mask registers of the DSB in TPDM. > + Write a data to mask the edge detection corresponding to the index > + number. Before writing data to this sysfs file, "dsb_edge_ctrl_idx" > + should be written first to configure the index number of the edge > + detection which needs to be masked. > + > + Accepts only one of the 2 values - 0 or 1. > \ No newline at end of file > diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c > index c38760b..98fd6ab 100644 > --- a/drivers/hwtracing/coresight/coresight-tpdm.c > +++ b/drivers/hwtracing/coresight/coresight-tpdm.c > @@ -71,7 +71,14 @@ static void set_dsb_perf_mode(struct tpdm_drvdata *drvdata, u32 *val) > > static void tpdm_enable_dsb(struct tpdm_drvdata *drvdata) > { > - u32 val; > + u32 val, i; > + > + for (i = 0; i < TPDM_DSB_MAX_EDCR; i++) > + writel_relaxed(drvdata->dsb->edge_ctrl[i], > + drvdata->base + TPDM_DSB_EDCR(i)); > + for (i = 0; i < TPDM_DSB_MAX_EDCMR; i++) > + writel_relaxed(drvdata->dsb->edge_ctrl_mask[i], > + drvdata->base + TPDM_DSB_EDCMR(i)); > > val = readl_relaxed(drvdata->base + TPDM_DSB_TIER); > /* Set trigger timestamp */ > @@ -302,6 +309,152 @@ static ssize_t dsb_mode_store(struct device *dev, > } > static DEVICE_ATTR_RW(dsb_mode); > > +static ssize_t dsb_edge_ctrl_idx_show(struct device *dev, > + struct device_attribute *attr, > + char *buf) > +{ > + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); > + > + return sysfs_emit(buf, "%u\n", > + (unsigned int)drvdata->dsb->edge_ctrl_idx); > +} > + > +/* > + * The EDCR registers can include up to 16 32-bit registers, and each > + * one can be configured to control up to 16 edge detections(2 bits > + * control one edge detection). So a total 256 edge detections can be > + * configured. This function provides a way to set the index number of > + * the edge detection which needs to be configured. > + */ > +static ssize_t dsb_edge_ctrl_idx_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 >= TPDM_DSB_MAX_LINES)) > + return -EINVAL; > + > + spin_lock(&drvdata->spinlock); > + drvdata->dsb->edge_ctrl_idx = val; > + spin_unlock(&drvdata->spinlock); > + > + return size; > +} > +static DEVICE_ATTR_RW(dsb_edge_ctrl_idx); > + > +static ssize_t dsb_edge_ctrl_val_show(struct device *dev, > + struct device_attribute *attr, > + char *buf) > +{ > + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); > + ssize_t size = 0; > + unsigned long bytes; > + int i; > + > + spin_lock(&drvdata->spinlock); > + for (i = 0; i < TPDM_DSB_MAX_EDCR; i++) { > + bytes = sysfs_emit_at(buf, size, > + "Val:0x%x\n", drvdata->dsb->edge_ctrl[i]); This feels a bit odd. edget_ctrl_val allows storing one "edge ctrl" value, while "show"ing all EDCR values. We could split them to : Read only sysfs files: dsb_edcr0 ... dsb_edcr15 for each EDCR register (similarly for the mask) and may be show the specific edge_ctrl_line for with the above function for selected index. > + if (bytes <= 0) > + break; > + size += bytes; > + } > + spin_unlock(&drvdata->spinlock); > + return size; > +} > + > +/* > + * This function is used to control the edge detection according > + * to the index number that has been set. > + * "edge_ctrl" should be one of the following values. > + * 0 - Rising edge detection > + * 1 - Falling edge detection > + * 2 - Rising and falling edge detection (toggle detection) > + */ > +static ssize_t dsb_edge_ctrl_val_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, mask, edge_ctrl; > + int reg; > + > + if ((kstrtoul(buf, 0, &edge_ctrl)) || (edge_ctrl > 0x2)) > + return -EINVAL; > + > + spin_lock(&drvdata->spinlock); > + /* > + * There are 2 bit per DSB Edge Control line. > + * Thus we have 16 lines in a 32bit word. > + */ > + reg = EDCR_TO_WORD_IDX(drvdata->dsb->edge_ctrl_idx); > + mask = EDCR_TO_WORD_MASK(drvdata->dsb->edge_ctrl_idx); > + val = drvdata->dsb->edge_ctrl[reg]; > + val &= ~EDCR_TO_WORD_MASK(drvdata->dsb->edge_ctrl_idx); > + val |= EDCR_TO_WORD_VAL(edge_ctrl, drvdata->dsb->edge_ctrl_idx); > + drvdata->dsb->edge_ctrl[reg] = val; > + spin_unlock(&drvdata->spinlock); > + > + return size; > +} > +static DEVICE_ATTR_RW(dsb_edge_ctrl_val); This can be WO attribute to write to a given line. > + > +static ssize_t dsb_edge_ctrl_mask_show(struct device *dev, > + struct device_attribute *attr, > + char *buf) > +{ > + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); > + ssize_t size = 0; > + unsigned long bytes; > + int i; > + > + spin_lock(&drvdata->spinlock); > + for (i = 0; i < TPDM_DSB_MAX_EDCMR; i++) { > + bytes = sysfs_emit_at(buf, size, > + "Val:0x%x\n", drvdata->dsb->edge_ctrl_mask[i]); As mentioned above, please don't do this. One value per file. Add dsb_edcmr0..dsb_edcmr7 and print only the selected index mask for this function. > + if (bytes <= 0) > + break; > + size += bytes; > + } > + spin_unlock(&drvdata->spinlock); > + return size; > +} > + > +static ssize_t dsb_edge_ctrl_mask_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; > + u32 set; > + int reg; > + > + if ((kstrtoul(buf, 0, &val)) || (val & ~1UL)) > + return -EINVAL; > + > + spin_lock(&drvdata->spinlock); > + /* > + * There is 1 bit per DSB Edge Control Mark line. > + * Thus we have 32 lines in a 32bit word. > + */ > + reg = EDCMR_TO_WORD_IDX(drvdata->dsb->edge_ctrl_idx); > + set = drvdata->dsb->edge_ctrl_mask[reg]; > + if (val) > + set |= BIT(EDCMR_TO_WORD_SHIFT(drvdata->dsb->edge_ctrl_idx)); > + else > + set &= ~BIT(EDCMR_TO_WORD_SHIFT(drvdata->dsb->edge_ctrl_idx)); > + drvdata->dsb->edge_ctrl_mask[reg] = set; > + spin_unlock(&drvdata->spinlock); > + > + return size; > +} > +static DEVICE_ATTR_RW(dsb_edge_ctrl_mask); > + > static ssize_t dsb_trig_type_show(struct device *dev, > struct device_attribute *attr, char *buf) > { > @@ -374,6 +527,9 @@ static DEVICE_ATTR_RW(dsb_trig_ts); > > static struct attribute *tpdm_dsb_attrs[] = { > &dev_attr_dsb_mode.attr, > + &dev_attr_dsb_edge_ctrl_idx.attr, > + &dev_attr_dsb_edge_ctrl_val.attr, > + &dev_attr_dsb_edge_ctrl_mask.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 49fffb1..4afdb29 100644 > --- a/drivers/hwtracing/coresight/coresight-tpdm.h > +++ b/drivers/hwtracing/coresight/coresight-tpdm.h > @@ -12,6 +12,8 @@ > /* DSB Subunit Registers */ > #define TPDM_DSB_CR (0x780) > #define TPDM_DSB_TIER (0x784) > +#define TPDM_DSB_EDCR(n) (0x808 + (n * 4)) > +#define TPDM_DSB_EDCMR(n) (0x848 + (n * 4)) > > /* Enable bit for DSB subunit */ > #define TPDM_DSB_CR_ENA BIT(0) > @@ -34,6 +36,16 @@ > #define TPDM_DSB_TEST_MODE GENMASK(10, 9) > #define TPDM_DSB_HPSEL GENMASK(6, 2) > > +#define EDCRS_PER_WORD 16 > +#define EDCR_TO_WORD_IDX(r) ((r) / EDCRS_PER_WORD) > +#define EDCR_TO_WORD_SHIFT(r) ((r % EDCRS_PER_WORD) * 2) > +#define EDCR_TO_WORD_VAL(val, r) (val << EDCR_TO_WORD_SHIFT(r)) > +#define EDCR_TO_WORD_MASK(r) EDCR_TO_WORD_VAL(0x3, r) > + > +#define EDCMRS_PER_WORD 32 > +#define EDCMR_TO_WORD_IDX(r) ((r) / EDCMRS_PER_WORD) > +#define EDCMR_TO_WORD_SHIFT(r) ((r) % EDCMRS_PER_WORD) > + > /* TPDM integration test registers */ > #define TPDM_ITATBCNTRL (0xEF0) > #define TPDM_ITCNTRL (0xF00) > @@ -60,14 +72,26 @@ > #define TPDM_PIDR0_DS_IMPDEF BIT(0) > #define TPDM_PIDR0_DS_DSB BIT(1) > > +#define TPDM_DSB_MAX_LINES 256 > +/* MAX number of EDCR registers */ > +#define TPDM_DSB_MAX_EDCR 16 > +/* MAX number of EDCMR registers */ > +#define TPDM_DSB_MAX_EDCMR 8 > + > /** > * struct dsb_dataset - specifics associated to dsb dataset > - * @mode: DSB programming mode > - * @trig_ts: Enable/Disable trigger timestamp. > - * @trig_type: Enable/Disable trigger type. > + * @mode: DSB programming mode > + * @edge_ctrl_idx Index number of the edge control > + * @edge_ctrl: Save value for edge control > + * @edge_ctrl_mask: Save value for edge control mask > + * @trig_ts: Enable/Disable trigger timestamp. > + * @trig_type: Enable/Disable trigger type. > */ > struct dsb_dataset { > u32 mode; > + u32 edge_ctrl_idx; > + u32 edge_ctrl[TPDM_DSB_MAX_EDCR]; > + u32 edge_ctrl_mask[TPDM_DSB_MAX_EDCMR]; Please keep them aligned with the rest of the fields. > bool trig_ts; > bool trig_type; Suzuki > };
On 8/7/2023 5:24 PM, Suzuki K Poulose wrote: > On 25/07/2023 08:15, Tao Zhang wrote: >> Add the nodes to set value for DSB edge control and DSB edge >> control mask. Each DSB subunit TPDM has maximum of n(n<16) EDCR >> resgisters to configure edge control. DSB edge detection control >> 00: Rising edge detection >> 01: Falling edge detection >> 10: Rising and falling edge detection (toggle detection) >> And each DSB subunit TPDM has maximum of m(m<8) ECDMR registers to >> configure mask. Eight 32 bit registers providing DSB interface >> edge detection mask control. >> >> Add the nodes to configure DSB edge control and DSB edge control >> mask. Each DSB subunit TPDM maximum of 256 edge detections can be >> configured. The index and value sysfs files need to be paired and >> written to order. The index sysfs file is to set the index number >> of the edge detection which needs to be configured. And the value >> sysfs file is to set the control or mask for the edge detection. >> DSB edge detection control should be set as the following values. >> 00: Rising edge detection >> 01: Falling edge detection >> 10: Rising and falling edge detection (toggle detection) >> And DSB edge mask should be set as 0 or 1. >> Each DSB subunit TPDM has maximum of n(n<16) EDCR resgisters to >> configure edge control. And each DSB subunit TPDM has maximum of >> m(m<8) ECDMR registers to configure mask. >> >> Signed-off-by: Tao Zhang <quic_taozha@quicinc.com> >> --- >> .../ABI/testing/sysfs-bus-coresight-devices-tpdm | 39 +++++ >> drivers/hwtracing/coresight/coresight-tpdm.c | 158 >> ++++++++++++++++++++- >> drivers/hwtracing/coresight/coresight-tpdm.h | 30 +++- >> 3 files changed, 223 insertions(+), 4 deletions(-) >> >> diff --git >> a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm >> b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm >> index 2a82cd0..a4550c5 100644 >> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm >> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm >> @@ -60,3 +60,42 @@ Description: >> 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. >> + >> +What: /sys/bus/coresight/devices/<tpdm-name>/dsb_edge_ctrl_idx >> +Date: March 2023 >> +KernelVersion 6.5 >> +Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang >> (QUIC) <quic_taozha@quicinc.com> >> +Description: >> + Read/Write the index number of the edge detection for the DSB >> + subunit TPDM. Since there are at most 256 edge detections, this >> + value ranges from 0 to 255. >> + >> +What: /sys/bus/coresight/devices/<tpdm-name>/dsb_edge_ctrl_val >> +Date: March 2023 >> +KernelVersion 6.5 >> +Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang >> (QUIC) <quic_taozha@quicinc.com> >> +Description: >> + Read a set of the edge control registers of the DSB in TPDM. >> + Write a data to control the edge detection corresponding to >> + the index number. Before writing data to this sysfs file, >> + "dsb_edge_ctrl_idx" should be written first to configure the >> + index number of the edge detection which needs to be >> controlled. >> + >> + Accepts only one of the following values. >> + 0 - Rising edge detection >> + 1 - Falling edge detection >> + 2 - Rising and falling edge detection (toggle detection) >> + >> + >> +What: /sys/bus/coresight/devices/<tpdm-name>/dsb_edge_ctrl_mask >> +Date: March 2023 >> +KernelVersion 6.5 >> +Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang >> (QUIC) <quic_taozha@quicinc.com> >> +Description: >> + Read a set of the edge control mask registers of the DSB in >> TPDM. >> + Write a data to mask the edge detection corresponding to the >> index >> + number. Before writing data to this sysfs file, >> "dsb_edge_ctrl_idx" >> + should be written first to configure the index number of the >> edge >> + detection which needs to be masked. >> + >> + Accepts only one of the 2 values - 0 or 1. >> \ No newline at end of file >> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c >> b/drivers/hwtracing/coresight/coresight-tpdm.c >> index c38760b..98fd6ab 100644 >> --- a/drivers/hwtracing/coresight/coresight-tpdm.c >> +++ b/drivers/hwtracing/coresight/coresight-tpdm.c >> @@ -71,7 +71,14 @@ static void set_dsb_perf_mode(struct tpdm_drvdata >> *drvdata, u32 *val) >> static void tpdm_enable_dsb(struct tpdm_drvdata *drvdata) >> { >> - u32 val; >> + u32 val, i; >> + >> + for (i = 0; i < TPDM_DSB_MAX_EDCR; i++) >> + writel_relaxed(drvdata->dsb->edge_ctrl[i], >> + drvdata->base + TPDM_DSB_EDCR(i)); >> + for (i = 0; i < TPDM_DSB_MAX_EDCMR; i++) >> + writel_relaxed(drvdata->dsb->edge_ctrl_mask[i], >> + drvdata->base + TPDM_DSB_EDCMR(i)); >> val = readl_relaxed(drvdata->base + TPDM_DSB_TIER); >> /* Set trigger timestamp */ >> @@ -302,6 +309,152 @@ static ssize_t dsb_mode_store(struct device *dev, >> } >> static DEVICE_ATTR_RW(dsb_mode); >> +static ssize_t dsb_edge_ctrl_idx_show(struct device *dev, >> + struct device_attribute *attr, >> + char *buf) >> +{ >> + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); >> + >> + return sysfs_emit(buf, "%u\n", >> + (unsigned int)drvdata->dsb->edge_ctrl_idx); >> +} >> + >> +/* >> + * The EDCR registers can include up to 16 32-bit registers, and each >> + * one can be configured to control up to 16 edge detections(2 bits >> + * control one edge detection). So a total 256 edge detections can be >> + * configured. This function provides a way to set the index number of >> + * the edge detection which needs to be configured. >> + */ >> +static ssize_t dsb_edge_ctrl_idx_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 >= TPDM_DSB_MAX_LINES)) >> + return -EINVAL; >> + >> + spin_lock(&drvdata->spinlock); >> + drvdata->dsb->edge_ctrl_idx = val; >> + spin_unlock(&drvdata->spinlock); >> + >> + return size; >> +} >> +static DEVICE_ATTR_RW(dsb_edge_ctrl_idx); >> + >> +static ssize_t dsb_edge_ctrl_val_show(struct device *dev, >> + struct device_attribute *attr, >> + char *buf) >> +{ >> + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); >> + ssize_t size = 0; >> + unsigned long bytes; >> + int i; >> + >> + spin_lock(&drvdata->spinlock); >> + for (i = 0; i < TPDM_DSB_MAX_EDCR; i++) { >> + bytes = sysfs_emit_at(buf, size, >> + "Val:0x%x\n", drvdata->dsb->edge_ctrl[i]); >> + if (bytes <= 0) >> + break; >> + size += bytes; >> + } >> + spin_unlock(&drvdata->spinlock); >> + return size; >> +} >> + >> +/* >> + * This function is used to control the edge detection according >> + * to the index number that has been set. >> + * "edge_ctrl" should be one of the following values. >> + * 0 - Rising edge detection >> + * 1 - Falling edge detection >> + * 2 - Rising and falling edge detection (toggle detection) >> + */ >> +static ssize_t dsb_edge_ctrl_val_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, mask, edge_ctrl; >> + int reg; >> + >> + if ((kstrtoul(buf, 0, &edge_ctrl)) || (edge_ctrl > 0x2)) >> + return -EINVAL; >> + >> + spin_lock(&drvdata->spinlock); >> + /* >> + * There are 2 bit per DSB Edge Control line. >> + * Thus we have 16 lines in a 32bit word. >> + */ >> + reg = EDCR_TO_WORD_IDX(drvdata->dsb->edge_ctrl_idx); >> + mask = EDCR_TO_WORD_MASK(drvdata->dsb->edge_ctrl_idx); >> + val = drvdata->dsb->edge_ctrl[reg]; >> + val &= ~EDCR_TO_WORD_MASK(drvdata->dsb->edge_ctrl_idx); >> + val |= EDCR_TO_WORD_VAL(edge_ctrl, drvdata->dsb->edge_ctrl_idx); >> + drvdata->dsb->edge_ctrl[reg] = val; >> + spin_unlock(&drvdata->spinlock); >> + >> + return size; >> +} >> +static DEVICE_ATTR_RW(dsb_edge_ctrl_val); >> + >> +static ssize_t dsb_edge_ctrl_mask_show(struct device *dev, >> + struct device_attribute *attr, >> + char *buf) >> +{ >> + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); >> + ssize_t size = 0; >> + unsigned long bytes; >> + int i; >> + >> + spin_lock(&drvdata->spinlock); >> + for (i = 0; i < TPDM_DSB_MAX_EDCMR; i++) { >> + bytes = sysfs_emit_at(buf, size, >> + "Val:0x%x\n", drvdata->dsb->edge_ctrl_mask[i]); >> + if (bytes <= 0) >> + break; >> + size += bytes; >> + } >> + spin_unlock(&drvdata->spinlock); >> + return size; >> +} >> + >> +static ssize_t dsb_edge_ctrl_mask_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; >> + u32 set; >> + int reg; >> + >> + if ((kstrtoul(buf, 0, &val)) || (val & ~1UL)) >> + return -EINVAL; >> + >> + spin_lock(&drvdata->spinlock); >> + /* >> + * There is 1 bit per DSB Edge Control Mark line. >> + * Thus we have 32 lines in a 32bit word. >> + */ >> + reg = EDCMR_TO_WORD_IDX(drvdata->dsb->edge_ctrl_idx); >> + set = drvdata->dsb->edge_ctrl_mask[reg]; >> + if (val) >> + set |= BIT(EDCMR_TO_WORD_SHIFT(drvdata->dsb->edge_ctrl_idx)); >> + else >> + set &= ~BIT(EDCMR_TO_WORD_SHIFT(drvdata->dsb->edge_ctrl_idx)); >> + drvdata->dsb->edge_ctrl_mask[reg] = set; > > > drivers/hwtracing/coresight/coresight-tpdm.c: In function > ‘dsb_edge_ctrl_mask_store’: > drivers/hwtracing/coresight/coresight-tpdm.c:449:2: error: this ‘else’ > clause does not guard... [-Werror=misleading-indentation] > else > ^~~~ > drivers/hwtracing/coresight/coresight-tpdm.c:451:3: note: ...this > statement, but the latter is misleadingly indented as if it were > guarded by the ‘else’ > drvdata->dsb->edge_ctrl_mask[reg] = set; > ^~~~~~~ > cc1: all warnings being treated as errors > make[4]: *** [scripts/Makefile.build:243: > drivers/hwtracing/coresight/coresight-tpdm.o] Error 1 > make[3]: *** [scripts/Makefile.build:480: drivers/hwtracing/coresight] > Error 2 > make[2]: *** [scripts/Makefile.build:480: drivers] Error 2 > make[1]: *** [/ssd/src/LINUX-CORESIGHT/Makefile:2032: .] Error 2 > make: *** [Makefile:234: __sub-make] Error 2 > I will update this in the next patch series. Best, Tao > Suzuki
On 8/7/2023 6:58 PM, Suzuki K Poulose wrote: > On 25/07/2023 08:15, Tao Zhang wrote: >> Add the nodes to set value for DSB edge control and DSB edge >> control mask. Each DSB subunit TPDM has maximum of n(n<16) EDCR >> resgisters to configure edge control. DSB edge detection control >> 00: Rising edge detection >> 01: Falling edge detection >> 10: Rising and falling edge detection (toggle detection) >> And each DSB subunit TPDM has maximum of m(m<8) ECDMR registers to >> configure mask. Eight 32 bit registers providing DSB interface >> edge detection mask control. >> >> Add the nodes to configure DSB edge control and DSB edge control >> mask. Each DSB subunit TPDM maximum of 256 edge detections can be >> configured. The index and value sysfs files need to be paired and >> written to order. The index sysfs file is to set the index number >> of the edge detection which needs to be configured. And the value >> sysfs file is to set the control or mask for the edge detection. >> DSB edge detection control should be set as the following values. >> 00: Rising edge detection >> 01: Falling edge detection >> 10: Rising and falling edge detection (toggle detection) >> And DSB edge mask should be set as 0 or 1. >> Each DSB subunit TPDM has maximum of n(n<16) EDCR resgisters to >> configure edge control. And each DSB subunit TPDM has maximum of >> m(m<8) ECDMR registers to configure mask. >> >> Signed-off-by: Tao Zhang <quic_taozha@quicinc.com> >> --- >> .../ABI/testing/sysfs-bus-coresight-devices-tpdm | 39 +++++ >> drivers/hwtracing/coresight/coresight-tpdm.c | 158 >> ++++++++++++++++++++- >> drivers/hwtracing/coresight/coresight-tpdm.h | 30 +++- >> 3 files changed, 223 insertions(+), 4 deletions(-) >> >> diff --git >> a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm >> b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm >> index 2a82cd0..a4550c5 100644 >> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm >> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm >> @@ -60,3 +60,42 @@ Description: >> 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. >> + >> +What: /sys/bus/coresight/devices/<tpdm-name>/dsb_edge_ctrl_idx >> +Date: March 2023 >> +KernelVersion 6.5 >> +Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang >> (QUIC) <quic_taozha@quicinc.com> >> +Description: >> + Read/Write the index number of the edge detection for the DSB >> + subunit TPDM. Since there are at most 256 edge detections, this >> + value ranges from 0 to 255. >> + >> +What: /sys/bus/coresight/devices/<tpdm-name>/dsb_edge_ctrl_val >> +Date: March 2023 >> +KernelVersion 6.5 >> +Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang >> (QUIC) <quic_taozha@quicinc.com> >> +Description: >> + Read a set of the edge control registers of the DSB in TPDM. >> + Write a data to control the edge detection corresponding to >> + the index number. Before writing data to this sysfs file, >> + "dsb_edge_ctrl_idx" should be written first to configure the >> + index number of the edge detection which needs to be >> controlled. >> + >> + Accepts only one of the following values. >> + 0 - Rising edge detection >> + 1 - Falling edge detection >> + 2 - Rising and falling edge detection (toggle detection) >> + >> + >> +What: /sys/bus/coresight/devices/<tpdm-name>/dsb_edge_ctrl_mask >> +Date: March 2023 >> +KernelVersion 6.5 >> +Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang >> (QUIC) <quic_taozha@quicinc.com> >> +Description: >> + Read a set of the edge control mask registers of the DSB in >> TPDM. >> + Write a data to mask the edge detection corresponding to the >> index >> + number. Before writing data to this sysfs file, >> "dsb_edge_ctrl_idx" >> + should be written first to configure the index number of the >> edge >> + detection which needs to be masked. >> + >> + Accepts only one of the 2 values - 0 or 1. >> \ No newline at end of file >> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c >> b/drivers/hwtracing/coresight/coresight-tpdm.c >> index c38760b..98fd6ab 100644 >> --- a/drivers/hwtracing/coresight/coresight-tpdm.c >> +++ b/drivers/hwtracing/coresight/coresight-tpdm.c >> @@ -71,7 +71,14 @@ static void set_dsb_perf_mode(struct tpdm_drvdata >> *drvdata, u32 *val) >> static void tpdm_enable_dsb(struct tpdm_drvdata *drvdata) >> { >> - u32 val; >> + u32 val, i; >> + >> + for (i = 0; i < TPDM_DSB_MAX_EDCR; i++) >> + writel_relaxed(drvdata->dsb->edge_ctrl[i], >> + drvdata->base + TPDM_DSB_EDCR(i)); >> + for (i = 0; i < TPDM_DSB_MAX_EDCMR; i++) >> + writel_relaxed(drvdata->dsb->edge_ctrl_mask[i], >> + drvdata->base + TPDM_DSB_EDCMR(i)); >> val = readl_relaxed(drvdata->base + TPDM_DSB_TIER); >> /* Set trigger timestamp */ >> @@ -302,6 +309,152 @@ static ssize_t dsb_mode_store(struct device *dev, >> } >> static DEVICE_ATTR_RW(dsb_mode); >> +static ssize_t dsb_edge_ctrl_idx_show(struct device *dev, >> + struct device_attribute *attr, >> + char *buf) >> +{ >> + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); >> + >> + return sysfs_emit(buf, "%u\n", >> + (unsigned int)drvdata->dsb->edge_ctrl_idx); >> +} >> + >> +/* >> + * The EDCR registers can include up to 16 32-bit registers, and each >> + * one can be configured to control up to 16 edge detections(2 bits >> + * control one edge detection). So a total 256 edge detections can be >> + * configured. This function provides a way to set the index number of >> + * the edge detection which needs to be configured. >> + */ >> +static ssize_t dsb_edge_ctrl_idx_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 >= TPDM_DSB_MAX_LINES)) >> + return -EINVAL; >> + >> + spin_lock(&drvdata->spinlock); >> + drvdata->dsb->edge_ctrl_idx = val; >> + spin_unlock(&drvdata->spinlock); >> + >> + return size; >> +} >> +static DEVICE_ATTR_RW(dsb_edge_ctrl_idx); >> + >> +static ssize_t dsb_edge_ctrl_val_show(struct device *dev, >> + struct device_attribute *attr, >> + char *buf) >> +{ >> + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); >> + ssize_t size = 0; >> + unsigned long bytes; >> + int i; >> + >> + spin_lock(&drvdata->spinlock); >> + for (i = 0; i < TPDM_DSB_MAX_EDCR; i++) { >> + bytes = sysfs_emit_at(buf, size, >> + "Val:0x%x\n", drvdata->dsb->edge_ctrl[i]); > > This feels a bit odd. edget_ctrl_val allows storing one "edge ctrl" > value, while "show"ing all EDCR values. We could split them to : > > Read only sysfs files: > > dsb_edcr0 ... dsb_edcr15 > > for each EDCR register (similarly for the mask) > > and may be show the specific edge_ctrl_line for with the above > function for selected index. Sure, I will update this in the next patch series. > >> + if (bytes <= 0) >> + break; >> + size += bytes; >> + } >> + spin_unlock(&drvdata->spinlock); >> + return size; >> +} >> + >> +/* >> + * This function is used to control the edge detection according >> + * to the index number that has been set. >> + * "edge_ctrl" should be one of the following values. >> + * 0 - Rising edge detection >> + * 1 - Falling edge detection >> + * 2 - Rising and falling edge detection (toggle detection) >> + */ >> +static ssize_t dsb_edge_ctrl_val_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, mask, edge_ctrl; >> + int reg; >> + >> + if ((kstrtoul(buf, 0, &edge_ctrl)) || (edge_ctrl > 0x2)) >> + return -EINVAL; >> + >> + spin_lock(&drvdata->spinlock); >> + /* >> + * There are 2 bit per DSB Edge Control line. >> + * Thus we have 16 lines in a 32bit word. >> + */ >> + reg = EDCR_TO_WORD_IDX(drvdata->dsb->edge_ctrl_idx); >> + mask = EDCR_TO_WORD_MASK(drvdata->dsb->edge_ctrl_idx); >> + val = drvdata->dsb->edge_ctrl[reg]; >> + val &= ~EDCR_TO_WORD_MASK(drvdata->dsb->edge_ctrl_idx); >> + val |= EDCR_TO_WORD_VAL(edge_ctrl, drvdata->dsb->edge_ctrl_idx); >> + drvdata->dsb->edge_ctrl[reg] = val; >> + spin_unlock(&drvdata->spinlock); >> + >> + return size; >> +} >> +static DEVICE_ATTR_RW(dsb_edge_ctrl_val); > > This can be WO attribute to write to a given line. I will update this in the next patch series. > >> + >> +static ssize_t dsb_edge_ctrl_mask_show(struct device *dev, >> + struct device_attribute *attr, >> + char *buf) >> +{ >> + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); >> + ssize_t size = 0; >> + unsigned long bytes; >> + int i; >> + >> + spin_lock(&drvdata->spinlock); >> + for (i = 0; i < TPDM_DSB_MAX_EDCMR; i++) { >> + bytes = sysfs_emit_at(buf, size, >> + "Val:0x%x\n", drvdata->dsb->edge_ctrl_mask[i]); > > As mentioned above, please don't do this. One value per file. Add > > dsb_edcmr0..dsb_edcmr7 > > and print only the selected index mask for this function. I will update this in the next patch series. > >> + if (bytes <= 0) >> + break; >> + size += bytes; >> + } >> + spin_unlock(&drvdata->spinlock); >> + return size; >> +} >> + >> +static ssize_t dsb_edge_ctrl_mask_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; >> + u32 set; >> + int reg; >> + >> + if ((kstrtoul(buf, 0, &val)) || (val & ~1UL)) >> + return -EINVAL; >> + >> + spin_lock(&drvdata->spinlock); >> + /* >> + * There is 1 bit per DSB Edge Control Mark line. >> + * Thus we have 32 lines in a 32bit word. >> + */ >> + reg = EDCMR_TO_WORD_IDX(drvdata->dsb->edge_ctrl_idx); >> + set = drvdata->dsb->edge_ctrl_mask[reg]; >> + if (val) >> + set |= BIT(EDCMR_TO_WORD_SHIFT(drvdata->dsb->edge_ctrl_idx)); >> + else >> + set &= ~BIT(EDCMR_TO_WORD_SHIFT(drvdata->dsb->edge_ctrl_idx)); >> + drvdata->dsb->edge_ctrl_mask[reg] = set; >> + spin_unlock(&drvdata->spinlock); >> + >> + return size; >> +} >> +static DEVICE_ATTR_RW(dsb_edge_ctrl_mask); >> + >> static ssize_t dsb_trig_type_show(struct device *dev, >> struct device_attribute *attr, char *buf) >> { >> @@ -374,6 +527,9 @@ static DEVICE_ATTR_RW(dsb_trig_ts); >> static struct attribute *tpdm_dsb_attrs[] = { >> &dev_attr_dsb_mode.attr, >> + &dev_attr_dsb_edge_ctrl_idx.attr, >> + &dev_attr_dsb_edge_ctrl_val.attr, >> + &dev_attr_dsb_edge_ctrl_mask.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 49fffb1..4afdb29 100644 >> --- a/drivers/hwtracing/coresight/coresight-tpdm.h >> +++ b/drivers/hwtracing/coresight/coresight-tpdm.h >> @@ -12,6 +12,8 @@ >> /* DSB Subunit Registers */ >> #define TPDM_DSB_CR (0x780) >> #define TPDM_DSB_TIER (0x784) >> +#define TPDM_DSB_EDCR(n) (0x808 + (n * 4)) >> +#define TPDM_DSB_EDCMR(n) (0x848 + (n * 4)) >> /* Enable bit for DSB subunit */ >> #define TPDM_DSB_CR_ENA BIT(0) >> @@ -34,6 +36,16 @@ >> #define TPDM_DSB_TEST_MODE GENMASK(10, 9) >> #define TPDM_DSB_HPSEL GENMASK(6, 2) >> +#define EDCRS_PER_WORD 16 >> +#define EDCR_TO_WORD_IDX(r) ((r) / EDCRS_PER_WORD) >> +#define EDCR_TO_WORD_SHIFT(r) ((r % EDCRS_PER_WORD) * 2) >> +#define EDCR_TO_WORD_VAL(val, r) (val << EDCR_TO_WORD_SHIFT(r)) >> +#define EDCR_TO_WORD_MASK(r) EDCR_TO_WORD_VAL(0x3, r) >> + >> +#define EDCMRS_PER_WORD 32 >> +#define EDCMR_TO_WORD_IDX(r) ((r) / EDCMRS_PER_WORD) >> +#define EDCMR_TO_WORD_SHIFT(r) ((r) % EDCMRS_PER_WORD) >> + >> /* TPDM integration test registers */ >> #define TPDM_ITATBCNTRL (0xEF0) >> #define TPDM_ITCNTRL (0xF00) >> @@ -60,14 +72,26 @@ >> #define TPDM_PIDR0_DS_IMPDEF BIT(0) >> #define TPDM_PIDR0_DS_DSB BIT(1) >> +#define TPDM_DSB_MAX_LINES 256 >> +/* MAX number of EDCR registers */ >> +#define TPDM_DSB_MAX_EDCR 16 >> +/* MAX number of EDCMR registers */ >> +#define TPDM_DSB_MAX_EDCMR 8 >> + >> /** >> * struct dsb_dataset - specifics associated to dsb dataset >> - * @mode: DSB programming mode >> - * @trig_ts: Enable/Disable trigger timestamp. >> - * @trig_type: Enable/Disable trigger type. >> + * @mode: DSB programming mode >> + * @edge_ctrl_idx Index number of the edge control >> + * @edge_ctrl: Save value for edge control >> + * @edge_ctrl_mask: Save value for edge control mask >> + * @trig_ts: Enable/Disable trigger timestamp. >> + * @trig_type: Enable/Disable trigger type. >> */ >> struct dsb_dataset { >> u32 mode; >> + u32 edge_ctrl_idx; >> + u32 edge_ctrl[TPDM_DSB_MAX_EDCR]; >> + u32 edge_ctrl_mask[TPDM_DSB_MAX_EDCMR]; > > Please keep them aligned with the rest of the fields. I will update this in the next patch series. Best, Tao > >> bool trig_ts; >> bool trig_type; > > Suzuki > > >> }; >
diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm index 2a82cd0..a4550c5 100644 --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm @@ -60,3 +60,42 @@ Description: 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. + +What: /sys/bus/coresight/devices/<tpdm-name>/dsb_edge_ctrl_idx +Date: March 2023 +KernelVersion 6.5 +Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com> +Description: + Read/Write the index number of the edge detection for the DSB + subunit TPDM. Since there are at most 256 edge detections, this + value ranges from 0 to 255. + +What: /sys/bus/coresight/devices/<tpdm-name>/dsb_edge_ctrl_val +Date: March 2023 +KernelVersion 6.5 +Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com> +Description: + Read a set of the edge control registers of the DSB in TPDM. + Write a data to control the edge detection corresponding to + the index number. Before writing data to this sysfs file, + "dsb_edge_ctrl_idx" should be written first to configure the + index number of the edge detection which needs to be controlled. + + Accepts only one of the following values. + 0 - Rising edge detection + 1 - Falling edge detection + 2 - Rising and falling edge detection (toggle detection) + + +What: /sys/bus/coresight/devices/<tpdm-name>/dsb_edge_ctrl_mask +Date: March 2023 +KernelVersion 6.5 +Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com> +Description: + Read a set of the edge control mask registers of the DSB in TPDM. + Write a data to mask the edge detection corresponding to the index + number. Before writing data to this sysfs file, "dsb_edge_ctrl_idx" + should be written first to configure the index number of the edge + detection which needs to be masked. + + Accepts only one of the 2 values - 0 or 1. \ No newline at end of file diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c index c38760b..98fd6ab 100644 --- a/drivers/hwtracing/coresight/coresight-tpdm.c +++ b/drivers/hwtracing/coresight/coresight-tpdm.c @@ -71,7 +71,14 @@ static void set_dsb_perf_mode(struct tpdm_drvdata *drvdata, u32 *val) static void tpdm_enable_dsb(struct tpdm_drvdata *drvdata) { - u32 val; + u32 val, i; + + for (i = 0; i < TPDM_DSB_MAX_EDCR; i++) + writel_relaxed(drvdata->dsb->edge_ctrl[i], + drvdata->base + TPDM_DSB_EDCR(i)); + for (i = 0; i < TPDM_DSB_MAX_EDCMR; i++) + writel_relaxed(drvdata->dsb->edge_ctrl_mask[i], + drvdata->base + TPDM_DSB_EDCMR(i)); val = readl_relaxed(drvdata->base + TPDM_DSB_TIER); /* Set trigger timestamp */ @@ -302,6 +309,152 @@ static ssize_t dsb_mode_store(struct device *dev, } static DEVICE_ATTR_RW(dsb_mode); +static ssize_t dsb_edge_ctrl_idx_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + return sysfs_emit(buf, "%u\n", + (unsigned int)drvdata->dsb->edge_ctrl_idx); +} + +/* + * The EDCR registers can include up to 16 32-bit registers, and each + * one can be configured to control up to 16 edge detections(2 bits + * control one edge detection). So a total 256 edge detections can be + * configured. This function provides a way to set the index number of + * the edge detection which needs to be configured. + */ +static ssize_t dsb_edge_ctrl_idx_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 >= TPDM_DSB_MAX_LINES)) + return -EINVAL; + + spin_lock(&drvdata->spinlock); + drvdata->dsb->edge_ctrl_idx = val; + spin_unlock(&drvdata->spinlock); + + return size; +} +static DEVICE_ATTR_RW(dsb_edge_ctrl_idx); + +static ssize_t dsb_edge_ctrl_val_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); + ssize_t size = 0; + unsigned long bytes; + int i; + + spin_lock(&drvdata->spinlock); + for (i = 0; i < TPDM_DSB_MAX_EDCR; i++) { + bytes = sysfs_emit_at(buf, size, + "Val:0x%x\n", drvdata->dsb->edge_ctrl[i]); + if (bytes <= 0) + break; + size += bytes; + } + spin_unlock(&drvdata->spinlock); + return size; +} + +/* + * This function is used to control the edge detection according + * to the index number that has been set. + * "edge_ctrl" should be one of the following values. + * 0 - Rising edge detection + * 1 - Falling edge detection + * 2 - Rising and falling edge detection (toggle detection) + */ +static ssize_t dsb_edge_ctrl_val_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, mask, edge_ctrl; + int reg; + + if ((kstrtoul(buf, 0, &edge_ctrl)) || (edge_ctrl > 0x2)) + return -EINVAL; + + spin_lock(&drvdata->spinlock); + /* + * There are 2 bit per DSB Edge Control line. + * Thus we have 16 lines in a 32bit word. + */ + reg = EDCR_TO_WORD_IDX(drvdata->dsb->edge_ctrl_idx); + mask = EDCR_TO_WORD_MASK(drvdata->dsb->edge_ctrl_idx); + val = drvdata->dsb->edge_ctrl[reg]; + val &= ~EDCR_TO_WORD_MASK(drvdata->dsb->edge_ctrl_idx); + val |= EDCR_TO_WORD_VAL(edge_ctrl, drvdata->dsb->edge_ctrl_idx); + drvdata->dsb->edge_ctrl[reg] = val; + spin_unlock(&drvdata->spinlock); + + return size; +} +static DEVICE_ATTR_RW(dsb_edge_ctrl_val); + +static ssize_t dsb_edge_ctrl_mask_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); + ssize_t size = 0; + unsigned long bytes; + int i; + + spin_lock(&drvdata->spinlock); + for (i = 0; i < TPDM_DSB_MAX_EDCMR; i++) { + bytes = sysfs_emit_at(buf, size, + "Val:0x%x\n", drvdata->dsb->edge_ctrl_mask[i]); + if (bytes <= 0) + break; + size += bytes; + } + spin_unlock(&drvdata->spinlock); + return size; +} + +static ssize_t dsb_edge_ctrl_mask_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; + u32 set; + int reg; + + if ((kstrtoul(buf, 0, &val)) || (val & ~1UL)) + return -EINVAL; + + spin_lock(&drvdata->spinlock); + /* + * There is 1 bit per DSB Edge Control Mark line. + * Thus we have 32 lines in a 32bit word. + */ + reg = EDCMR_TO_WORD_IDX(drvdata->dsb->edge_ctrl_idx); + set = drvdata->dsb->edge_ctrl_mask[reg]; + if (val) + set |= BIT(EDCMR_TO_WORD_SHIFT(drvdata->dsb->edge_ctrl_idx)); + else + set &= ~BIT(EDCMR_TO_WORD_SHIFT(drvdata->dsb->edge_ctrl_idx)); + drvdata->dsb->edge_ctrl_mask[reg] = set; + spin_unlock(&drvdata->spinlock); + + return size; +} +static DEVICE_ATTR_RW(dsb_edge_ctrl_mask); + static ssize_t dsb_trig_type_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -374,6 +527,9 @@ static DEVICE_ATTR_RW(dsb_trig_ts); static struct attribute *tpdm_dsb_attrs[] = { &dev_attr_dsb_mode.attr, + &dev_attr_dsb_edge_ctrl_idx.attr, + &dev_attr_dsb_edge_ctrl_val.attr, + &dev_attr_dsb_edge_ctrl_mask.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 49fffb1..4afdb29 100644 --- a/drivers/hwtracing/coresight/coresight-tpdm.h +++ b/drivers/hwtracing/coresight/coresight-tpdm.h @@ -12,6 +12,8 @@ /* DSB Subunit Registers */ #define TPDM_DSB_CR (0x780) #define TPDM_DSB_TIER (0x784) +#define TPDM_DSB_EDCR(n) (0x808 + (n * 4)) +#define TPDM_DSB_EDCMR(n) (0x848 + (n * 4)) /* Enable bit for DSB subunit */ #define TPDM_DSB_CR_ENA BIT(0) @@ -34,6 +36,16 @@ #define TPDM_DSB_TEST_MODE GENMASK(10, 9) #define TPDM_DSB_HPSEL GENMASK(6, 2) +#define EDCRS_PER_WORD 16 +#define EDCR_TO_WORD_IDX(r) ((r) / EDCRS_PER_WORD) +#define EDCR_TO_WORD_SHIFT(r) ((r % EDCRS_PER_WORD) * 2) +#define EDCR_TO_WORD_VAL(val, r) (val << EDCR_TO_WORD_SHIFT(r)) +#define EDCR_TO_WORD_MASK(r) EDCR_TO_WORD_VAL(0x3, r) + +#define EDCMRS_PER_WORD 32 +#define EDCMR_TO_WORD_IDX(r) ((r) / EDCMRS_PER_WORD) +#define EDCMR_TO_WORD_SHIFT(r) ((r) % EDCMRS_PER_WORD) + /* TPDM integration test registers */ #define TPDM_ITATBCNTRL (0xEF0) #define TPDM_ITCNTRL (0xF00) @@ -60,14 +72,26 @@ #define TPDM_PIDR0_DS_IMPDEF BIT(0) #define TPDM_PIDR0_DS_DSB BIT(1) +#define TPDM_DSB_MAX_LINES 256 +/* MAX number of EDCR registers */ +#define TPDM_DSB_MAX_EDCR 16 +/* MAX number of EDCMR registers */ +#define TPDM_DSB_MAX_EDCMR 8 + /** * struct dsb_dataset - specifics associated to dsb dataset - * @mode: DSB programming mode - * @trig_ts: Enable/Disable trigger timestamp. - * @trig_type: Enable/Disable trigger type. + * @mode: DSB programming mode + * @edge_ctrl_idx Index number of the edge control + * @edge_ctrl: Save value for edge control + * @edge_ctrl_mask: Save value for edge control mask + * @trig_ts: Enable/Disable trigger timestamp. + * @trig_type: Enable/Disable trigger type. */ struct dsb_dataset { u32 mode; + u32 edge_ctrl_idx; + u32 edge_ctrl[TPDM_DSB_MAX_EDCR]; + u32 edge_ctrl_mask[TPDM_DSB_MAX_EDCMR]; bool trig_ts; bool trig_type; };
Add the nodes to set value for DSB edge control and DSB edge control mask. Each DSB subunit TPDM has maximum of n(n<16) EDCR resgisters to configure edge control. DSB edge detection control 00: Rising edge detection 01: Falling edge detection 10: Rising and falling edge detection (toggle detection) And each DSB subunit TPDM has maximum of m(m<8) ECDMR registers to configure mask. Eight 32 bit registers providing DSB interface edge detection mask control. Add the nodes to configure DSB edge control and DSB edge control mask. Each DSB subunit TPDM maximum of 256 edge detections can be configured. The index and value sysfs files need to be paired and written to order. The index sysfs file is to set the index number of the edge detection which needs to be configured. And the value sysfs file is to set the control or mask for the edge detection. DSB edge detection control should be set as the following values. 00: Rising edge detection 01: Falling edge detection 10: Rising and falling edge detection (toggle detection) And DSB edge mask should be set as 0 or 1. Each DSB subunit TPDM has maximum of n(n<16) EDCR resgisters to configure edge control. And each DSB subunit TPDM has maximum of m(m<8) ECDMR registers to configure mask. Signed-off-by: Tao Zhang <quic_taozha@quicinc.com> --- .../ABI/testing/sysfs-bus-coresight-devices-tpdm | 39 +++++ drivers/hwtracing/coresight/coresight-tpdm.c | 158 ++++++++++++++++++++- drivers/hwtracing/coresight/coresight-tpdm.h | 30 +++- 3 files changed, 223 insertions(+), 4 deletions(-)