Hi Levi,
On 19/05/2026 16:48, Yeoreum Yun wrote:
The purpose of TRCSSCSRn register is to show status of the corresponding Single-shot Comparator Control and input supports. That means writable field's purpose for reset or restore from idle status not for configuration.
Therefore, exclude ss_status from drvdata->config and move it to drvdata.
TRCSSCSRn has two different types of fields.
1. Capability 2. Status
Moving the entire register from "config" to a common dangling place looks like shifting the problem to me.
Could we do something like :
1. Split the fields to two. a. Store only the capability information in etmv4_caps. Bits[4:0] b. Store the Status bit in drvdata->config , as it is really matters to the session ? Bits[31:30]
Add a helper to write/read the TRCSSSRn which would apply/mask the bits from drvdata->etmv4_caps->fields to the Status/Pending
Suzuki
Signed-off-by: Yeoreum Yun yeoreum.yun@arm.com
.../hwtracing/coresight/coresight-etm4x-cfg.c | 1 - .../hwtracing/coresight/coresight-etm4x-core.c | 16 +++++++++------- .../hwtracing/coresight/coresight-etm4x-sysfs.c | 10 +++++----- drivers/hwtracing/coresight/coresight-etm4x.h | 7 ++++++- 4 files changed, 20 insertions(+), 14 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-cfg.c b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c index e1a59b434505..9b4947d75fde 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-cfg.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c @@ -86,7 +86,6 @@ static int etm4_cfg_map_reg_offset(struct etmv4_drvdata *drvdata, off_mask = (offset & GENMASK(11, 5)); do { CHECKREGIDX(TRCSSCCRn(0), ss_ctrl, idx, off_mask);
} while (0); } else if ((offset >= TRCCIDCVRn(0)) && (offset <= TRCVMIDCVRn(7))) {CHECKREGIDX(TRCSSCSRn(0), ss_status, idx, off_mask); CHECKREGIDX(TRCSSPCICRn(0), ss_pe_cmp, idx, off_mask);diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c index 53fbc4826628..7783c97b53e8 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c @@ -95,7 +95,7 @@ static bool etm4x_sspcicrn_present(struct etmv4_drvdata *drvdata, int n) const struct etmv4_caps *caps = &drvdata->caps; return (n < caps->nr_ss_cmp) && caps->nr_pe_cmp &&
(drvdata->config.ss_status[n] & TRCSSCSRn_PC);
}(drvdata->ss_status[n] & TRCSSCSRn_PC);u64 etm4x_sysreg_read(u32 offset, bool _relaxed, bool _64bit) @@ -571,11 +571,11 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata) etm4x_relaxed_write32(csa, config->res_ctrl[i], TRCRSCTLRn(i)); for (i = 0; i < caps->nr_ss_cmp; i++) {
/* always clear status bit on restart if using single-shot */
if (config->ss_ctrl[i] || config->ss_pe_cmp[i])/* always clear status and pending bits on restart if using single-shot */
config->ss_status[i] &= ~TRCSSCSRn_STATUS;
etm4x_relaxed_write32(csa, config->ss_ctrl[i], TRCSSCCRn(i));drvdata->ss_status[i] &= ~(TRCSSCSRn_STATUS | TRCSSCSRn_PENDING);
etm4x_relaxed_write32(csa, config->ss_status[i], TRCSSCSRn(i));
if (etm4x_sspcicrn_present(drvdata, i)) etm4x_relaxed_write32(csa, config->ss_pe_cmp[i], TRCSSPCICRn(i)); }etm4x_relaxed_write32(csa, drvdata->ss_status[i], TRCSSCSRn(i));@@ -772,6 +772,7 @@ static int etm4_parse_event_config(struct coresight_device *csdev, /* Clear configuration from previous run */ memset(config, 0, sizeof(struct etmv4_config));
- if (attr->exclude_kernel) config->mode = ETM_MODE_EXCL_KERN;
@@ -1064,7 +1065,7 @@ static void etm4_disable_hw(struct etmv4_drvdata *drvdata) /* read the status of the single shot comparators */ for (i = 0; i < caps->nr_ss_cmp; i++) {
config->ss_status[i] =
}drvdata->ss_status[i] = etm4x_relaxed_read32(csa, TRCSSCSRn(i));@@ -1497,8 +1498,9 @@ static void etm4_init_arch_data(void *info) */ caps->nr_ss_cmp = FIELD_GET(TRCIDR4_NUMSSCC_MASK, etmidr4); for (i = 0; i < caps->nr_ss_cmp; i++) {
drvdata->config.ss_status[i] =etm4x_relaxed_read32(csa, TRCSSCSRn(i));
drvdata->ss_status[i] = etm4x_relaxed_read32(csa, TRCSSCSRn(i));drvdata->ss_status[i] &= (TRCSSCSRn_PC | TRCSSCSRn_DV | } /* NUMCIDC, bits[27:24] number of Context ID comparators for tracing */ caps->numcidc = FIELD_GET(TRCIDR4_NUMCIDC_MASK, etmidr4);TRCSSCSRn_DA | TRCSSCSRn_INST);diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c index 7de3c58a47b4..71e95d152ee6 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c @@ -1829,8 +1829,8 @@ static ssize_t sshot_ctrl_store(struct device *dev, raw_spin_lock(&drvdata->spinlock); idx = config->ss_idx; config->ss_ctrl[idx] = FIELD_PREP(TRCSSCCRn_SAC_ARC_RST_MASK, val);
- /* must clear bit 31 in related status register on programming */
- config->ss_status[idx] &= ~TRCSSCSRn_STATUS;
- /* must clear bit 31 and 30 in related status register on programming */
- drvdata->ss_status[idx] &= ~(TRCSSCSRn_STATUS | TRCSSCSRn_PENDING); raw_spin_unlock(&drvdata->spinlock); return size; }
@@ -1844,7 +1844,7 @@ static ssize_t sshot_status_show(struct device *dev, struct etmv4_config *config = &drvdata->config; raw_spin_lock(&drvdata->spinlock);
- val = config->ss_status[config->ss_idx];
- val = drvdata->ss_status[config->ss_idx]; raw_spin_unlock(&drvdata->spinlock); return scnprintf(buf, PAGE_SIZE, "%#lx\n", val); }
@@ -1879,8 +1879,8 @@ static ssize_t sshot_pe_ctrl_store(struct device *dev, raw_spin_lock(&drvdata->spinlock); idx = config->ss_idx; config->ss_pe_cmp[idx] = FIELD_PREP(TRCSSPCICRn_PC_MASK, val);
- /* must clear bit 31 in related status register on programming */
- config->ss_status[idx] &= ~TRCSSCSRn_STATUS;
- /* must clear bit 31 and 30 in related status register on programming */
- drvdata->ss_status[idx] &= ~(TRCSSCSRn_STATUS | TRCSSCSRn_PENDING); raw_spin_unlock(&drvdata->spinlock); return size; }
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h index 6d4fbae78448..43db1eb6f8cd 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.h +++ b/drivers/hwtracing/coresight/coresight-etm4x.h @@ -213,6 +213,7 @@ #define TRCACATRn_EXLEVEL_MASK GENMASK(14, 8) #define TRCSSCSRn_STATUS BIT(31) +#define TRCSSCSRn_PENDING BIT(30) #define TRCSSCCRn_SAC_ARC_RST_MASK GENMASK(24, 0) #define TRCSSPCICRn_PC_MASK GENMASK(7, 0) @@ -730,6 +731,9 @@ static inline u32 etm4_res_sel_pair(u8 res_sel_idx) #define ETM_DEFAULT_ADDR_COMP 0 #define TRCSSCSRn_PC BIT(3) +#define TRCSSCSRn_DV BIT(2) +#define TRCSSCSRn_DA BIT(1) +#define TRCSSCSRn_INST BIT(0) /* PowerDown Control Register bits */ #define TRCPDCR_PU BIT(3) @@ -978,7 +982,6 @@ struct etmv4_config { u32 res_ctrl[ETM_MAX_RES_SEL]; /* TRCRSCTLRn */ u8 ss_idx; u32 ss_ctrl[ETM_MAX_SS_CMP];
- u32 ss_status[ETM_MAX_SS_CMP]; u32 ss_pe_cmp[ETM_MAX_SS_CMP]; u8 addr_idx; u64 addr_val[ETM_MAX_SINGLE_ADDR_CMP];
@@ -1073,6 +1076,7 @@ struct etmv4_save_state {
- @config: structure holding configuration parameters.
- @save_state: State to be preserved across power loss
- @paused: Indicates if the trace unit is paused.
*/ struct etmv4_drvdata {
- @ss_status: The status of the corresponding single-shot comparator.
- @arch_features: Bitmap of arch features of etmv4 devices.
@@ -1092,6 +1096,7 @@ struct etmv4_drvdata { u64 trfcr; struct etmv4_config config; struct etmv4_save_state *save_state;
- u32 ss_status[ETM_MAX_SS_CMP]; DECLARE_BITMAP(arch_features, ETM4_IMPDEF_FEATURE_MAX); };