The current TRBE driver operates only in fill mode, where tracing stops
at the top of buffer and a maintenance interrupt is raised. Due to
interrupt latency, tracing is halted while the program continues to run,
resulting in trace data lose.
This series enhances the driver for the trigger mode to mitigate trace
discontinuity. The circle buffer mode is introduced to avoid any
maintenance interrupts during the snapshot session.
It can be divided into three parts for easier review:
Patches 01~05: Minor refactoring for disabling operations and
clearing status.
Patches 06~12: Refactor fault action and trace size calculation.
Patches 13~19: Support trigger and circle modes. To better utilize the
new buffer modes, perf sets the watermark to
one-quarter of the buffer size.
This series is applied on coresight-next branch and has been validated
on Orion O6 board:
1) The trigger count and wrap mode are verified using Ftrace logs.
2) A new kunit test module verifies limit and count calculations.
3) Basic perf record / script commands and module load/unload have
been tested successfully.
Signed-off-by: Leo Yan <leo.yan(a)arm.com>
---
Leo Yan (19):
coresight: trbe: Use helpers for checking errata
coresight: trbe: Remove redundant disable operation
coresight: trbe: Remove buffer disabling in trbe_handle_overflow()
coresight: trbe: Remove set_trbe_disabled() from the enable flow
coresight: trbe: Refactor status clearing
coresight: trbe: Refactor syndrome decoding
coresight: trbe: Refactor AUX flag setting
coresight: trbe: Use PERF_AUX_FLAG_PARTIAL instead of PERF_AUX_FLAG_COLLISION
coresight: trbe: Add fault action argument to trbe_handle_overflow()
coresight: trbe: Always check fault action when updating buffer
coresight: trbe: Apply overwrite erratum for only wrap event
coresight: trbe: Calculate size for buffer wrapping
coresight: trbe: Remove misleading comment
coresight: trbe: Refactor compute_trbe_buffer_limit()
coresight: trbe: Add static key for bypassing trigger mode
coresight: trbe: Support trigger mode
coresight: trbe: Enable circle mode for snapshot
coresight: trbe: Add kunit tests
perf: cs-etm: Set watermark for AUX trace
drivers/hwtracing/coresight/Kconfig | 9 +
drivers/hwtracing/coresight/Makefile | 1 +
.../coresight/coresight-trbe-kunit-tests.c | 536 +++++++++++++++++++++
drivers/hwtracing/coresight/coresight-trbe.c | 440 +++++++++--------
drivers/hwtracing/coresight/coresight-trbe.h | 111 ++++-
tools/perf/arch/arm/util/cs-etm.c | 7 +
6 files changed, 896 insertions(+), 208 deletions(-)
---
base-commit: 9e9182cab5ebc3ee7544e60ef08ba19fdf216920
change-id: 20251120-trbe_buffer_refactor_v1-1-8f8023105469
Best regards,
--
Leo Yan <leo.yan(a)arm.com>
On Tue, Dec 09, 2025 at 08:51:38PM +0800, Yingchao Deng (Consultant) wrote:
[...]
> > void cti_write_single_reg(struct cti_drvdata *drvdata,
> > int offset, u32 value)
> > {
> > CS_UNLOCK(drvdata->base);
> > writel_relaxed(value, cti_reg_addr(drvdata, offset));
> > CS_LOCK(drvdata->base);
> > }
>
> However, since we also need to handle cti_reg_addr_with_nr, it will be
> necessary to add an additional parameter "nr" to cti_write_single_reg?
I expect the argument "offset" has already containted the nr in
bits[31..28], so don't need to pass "nr" parameter to
cti_write_single_reg().
You will change inen_store() / outen_store(), e.g.,:
cti_write_single_reg(drvdata, CTI_REG_SET_NR(CTIINEN, index),
value);
Just remind, this might be a separate refactor for common code and you
need to write a patch for this, then is followed by QCOM CTI support
patch.
Thanks,
Leo
The specific config field that an event format attribute is in is
consistently hard coded, even though the API is supposed to be that the
driver publishes the config field name. To stop this pattern from being
copy pasted and causing problems in the future, replace them all with
calls to a new helper that returns the value that a user set.
This reveals some issues in evsel__set_config_if_unset(). It doesn't
work with sparse bitfields, which are an unused but documented feature.
And it also only writes to the attr.config field. To fix it we need to
start tracking user changes for all config fields and then use existing
helper functions that support sparse bitfields. Some other refactoring
was also required and a test was added.
Signed-off-by: James Clark <james.clark(a)linaro.org>
---
Changes in v2:
- Remove macros in get_config_chgs() and some other refactoring.
- Support sparse bitfields in evsel__set_config_if_unset().
- Always track user changes instead of only when
'pmu->perf_event_attr_init_default' is set.
- Add a test.
- Don't bail out in cs-etm.c if any format fields are missing (Leo).
- Rename 'guess' to 'synth' (Mike).
- Link to v1: https://lore.kernel.org/r/20251201-james-perf-config-bits-v1-0-22ecbbf8007c…
---
James Clark (12):
perf parse-events: Refactor get_config_terms() to remove macros
perf evsel: Support sparse fields in evsel__set_config_if_unset()
perf parse-events: Track all user changed config bits
perf evsel: apply evsel__set_config_if_unset() to all config fields
perf evsel: Add a helper to get the value of a config field
perf parse-events: Always track user config changes
perf tests: Test evsel__set_config_if_unset() and config change tracking
perf cs-etm: Make a helper to find the Coresight evsel
perf cs-etm: Don't use hard coded config bits when setting up ETMCR
perf cs-etm: Don't use hard coded config bits when setting up TRCCONFIGR
perf cs-etm: Don't hard code config attribute when configuring the event
perf arm-spe: Don't hard code config attribute
tools/perf/arch/arm/util/cs-etm.c | 193 +++++++++++++++------------
tools/perf/arch/arm64/util/arm-spe.c | 15 ++-
tools/perf/tests/pmu.c | 90 +++++++++++++
tools/perf/util/evsel.c | 6 +-
tools/perf/util/evsel.h | 2 +
tools/perf/util/evsel_config.h | 7 +-
tools/perf/util/parse-events.c | 248 ++++++++++++++++++++---------------
tools/perf/util/pmu.c | 112 ++++++++++++++--
8 files changed, 459 insertions(+), 214 deletions(-)
---
base-commit: 2eeb09fe1c5173b659929f92fee4461796ca8c14
change-id: 20251112-james-perf-config-bits-bee7106f0f00
Best regards,
--
James Clark <james.clark(a)linaro.org>
Hi Yingchao,
On Tue, Dec 09, 2025 at 04:16:28PM +0800, Yingchao Deng wrote:
> Hi Leo & Mike
>
> Based on Leo’s suggestions, I created a new patch, but there are three points that do not fully align with his recommendations:
>
> 1. The helper function for returning the register address now returns only the offset, because returning the full address would conflict with cti_write_single_reg.
No need to change each callsite for cti_write_single_reg(). You could
update cti_write_single_reg() instead:
void cti_write_single_reg(struct cti_drvdata *drvdata,
int offset, u32 value)
{
CS_UNLOCK(drvdata->base);
writel_relaxed(value, cti_reg_addr(drvdata, offset));
CS_LOCK(drvdata->base);
}
> 2. For registers such as triginstatus1...3, I defined additional macros CTITRIGINSTATUS1...3. This is because CTITRIGINSTATUS + 0x4 equals CTITRIGOUTSTATUS, and to avoid conflicts with existing macros, I chose numbers starting from 0x1000 for the new definitions.
To avoid the register naming pollution, please don't define the common
names but only used for Qcom registers.
AFAIK, you even don't need to define these registers. These registers
are only used for sysfs knobs, we can define an extra "nr" field (e.g.,
bits[31..28] for indexing these registers, something like:
#define CIT_REG_NR_SHIFT 28
#define CIT_REG_NR_MASK GENMASK(31, 28)
#define CTI_REG_GET_NR(reg) FIELD_GET(CIT_REG_NR_MASK, (reg))
#define CTI_REG_SET_NR(reg, nr) ((reg) | FIELD_PREP(CIT_REG_NR_MASK, (nr))
static struct attribute *coresight_cti_regs_attrs[] = {
...
coresight_cti_reg(triginstatus, CTITRIGINSTATUS),
coresight_cti_reg(triginstatus1, CTI_REG_SET_NR(CTITRIGINSTATUS, 1)),
coresight_cti_reg(triginstatus2, CTI_REG_SET_NR(CTITRIGINSTATUS, 2)),
coresight_cti_reg(triginstatus3, CTI_REG_SET_NR(CTITRIGINSTATUS, 3)),
...
Then, you just need to decode "nr" fields in cti_qcom_reg_off().
> 3. Regarding the visibility of attributes for triginstatus1...3, since coresight_cti_reg produces an anonymous variable that cannot be directly referenced, I used coresight_cti_regs_attrs[i] to obtain the attribute corresponding to triginstatus1.
Okay, I get the meaning for "an anonymous variable" - there have no
field naming when define attr with the macro coresight_cti_reg().
but you could comparing the attr string?
if (!strcmp(attr->name, "triginstatus1") ||
!strcmp(attr->name, "triginstatus2") ||
!strcmp(attr->name, "triginstatus3"))
...
Thanks,
Leo
On 05/12/2025 01:13, Songwei Chai wrote:
>
>
> On 12/3/2025 11:48 PM, Suzuki K Poulose wrote:
>> Cc: Greg
>>
>> On 03/12/2025 09:00, Songwei Chai wrote:
>>> We propose creating a new qcom directory under drivers/hwtracing
>>> to host this TGU driver, as well as additional Qualcomm-specific
>>> hwtracing drivers that we plan to submit in the coming months.
>>> This structure will help organize vendor-specific implementations
>>> and facilitate future development and maintenance.
>>>
>>> Feedback from the community on this proposal is highly appreciated.
>>>
>>> - Why we are proposing this:
>>>
>>> TGU has the ability to monitor signal conditions and trigger debug-
>>> related
>>> actions, serving as a programmable hardware component that enhances
>>> system
>>> trace and debug capabilities. Placing it under drivers/hwtracing
>>> aligns with
>>> its function as a trace generation utility.
>>>
>>> We previously attempted to push this driver to drivers/hwtracing/
>>> coresight,
>>> but did not receive support from the maintainers of the CoreSight
>>> subsystem.
>>> The reason provided was: “This component is primarily a part of the
>>> Qualcomm proprietary QPMDA subsystem, and is capable of operating
>>> independently from the CoreSight hardware trace generation system.”
>>>
>>> Chat history : https://lore.kernel.org/all/
>>> CAJ9a7ViKxHThyZfFFDV_FkNRimk4uo1NrMtQ-kcaj1qO4ZcGnA(a)mail.gmail.com/
>>>
>>> Given this, we have been considering whether it would be appropriate
>>> to create a dedicated drivers/hwtracing/qcom directory for
>>> Qualcomm-related hwtracing drivers. This would follow the precedent set
>>> by Intel, which maintains its own directory at drivers/hwtracing/
>>> intel_th.
>>> We believe this structure would significantly facilitate
>>> future submissions of related Qualcomm drivers.
>>>
>>> - Maintenance of drivers/hwtracing/qcom:
>>>
>>
>> Fine by, me.
>>
>>
>>> Bjorn, who maintains linux-arm-msm, will be the maintainer of this
>>> directory — we’ve discussed this with him and he’s aware that his task
>>> list may grow accordingly. Additionally, Qualcomm engineers familiar
>>> with
>>> the debug hardware — such as [Tingwei Zhang, Jinlong Mao, Songwei Chai],
>>> will be available to review incoming patches and support ongoing
>>> development.
>>>
>>> - Detail for TGU:
>>>
>>> This component can be utilized to sense a plurality of signals and
>>> create a trigger into the CTI or generate interrupts to processors
>>> once the input signal meets the conditions. We can treat the TGU’s
>>> workflow as a flowsheet, it has some “steps” regions for customization.
>>> In each step region, we can set the signals that we want with priority
>>> in priority_group, set the conditions in each step via condition_decode,
>>> and set the resultant action by condition_select. Meanwhile,
>>> some TGUs (not all) also provide timer/counter functionality.
>>> Based on the characteristics described above, we consider the TGU as a
>>> helper in the CoreSight subsystem. Its master device is the TPDM, which
>>> can transmit signals from other subsystems, and we reuse the existing
>>> ports mechanism to link the TPDM to the connected TGU.
>>
>> Please remove the coresight_device and other dependencies. You may use
>> generic bits, CS_LOCK/UNLOCK etc. But including coresight-priv.h is
>> not something I would prefer. It brings in unnecessary dependencies
>> between two subsystems and I don't see any reason for using -priv.h.
>> It is named as it is, for a reason, coresight private definitions.
>>
>>
>>>
>>> Here is a detailed example to explain how to use the TGU:
>>>
>>> In this example, the TGU is configured to use 2 conditions, 2 steps, and
>>> the timer. The goal is to look for one of two patterns which are
>>> generated
>>> from TPDM, giving priority to one, and then generate a trigger once the
>>> timer reaches a certain value. In other words, two conditions are used
>>> for the first step to look for the two patterns, where the one with the
>>> highest priority is used in the first condition. Then, in the second
>>> step,
>>> the timer is enabled and set to be compared to the given value at each
>>> clock cycle. These steps are better shown below.
>>> |-----------------|
>>> | |
>>> | TPDM |
>>> | |
>>> |-----------------|
>>> |
>>> |
>>> --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
>>> ------
>>> | |
>>> |
>>> | | |--------------------| |
>>> | |---- ---> | | Go to next
>>> steps | |
>>> | | | |--- ---> | Enable
>>> timer | |
>>> | | v | |
>>> | |
>>> | | |-----------------| | |--------------------| |
>>> | | | | Yes | |
>>> |
>>> | | | inputs==0xB | ----->| |
>>> <-------- |
>>> | | | | | | No | |
>>> | No | |-----------------| | v | |
>>> | | | | |-----------------| | |
>>> | | | | | | | |
>>> | | | | | timer>=3
>>> |-- |
>>> | | v | | | |
>>> | | |-----------------| | |-----------------| |
>>> | | | | Yes | |
>>> |
>>> | |--- | inputs==0xA | ----->| |
>>> Yes |
>>> | | | |
>>> |
>>> | |-----------------| v |
>>> | |-----------------| |
>>> | | | |
>>> | | Trigger | |
>>> | | | |
>>> | |-----------------| |
>>> | TGU |
>>> |
>>> |--- --- --- --- --- --- --- --- --- --- --- --- --- --- |---
>>> --- -- |
>>> |
>>> v
>>> |-----------------|
>>> |The controllers |
>>> |which will use |
>>> |triggers further |
>>> |-----------------|
>>>
>>> steps:
>>> 1. Reset TGU /*it will disable tgu and reset dataset*/
>>> - echo 1 > /sys/bus/coresight/devices/<tgu-name>/reset_tgu
>>>
>>> 2. Set the pattern match for priority0 to 0xA = 0b1010 and for
>>> priority 1 to 0xB = 0b1011.
>>> - echo 0x11113232 > /sys/bus/coresight/devices/<tgu-name>/
>>> step0_priority0/reg0
>>> - echo 0x11113233 > /sys/bus/coresight/devices/<tgu-name>/
>>> step0_priority1/reg0
>>
>> Why do they need to be coresight devices and appear on the coresight
>> bus if they are not coresight devices ? As I understand they are simply
>> devices with some sysfs knobs.
>>
>> Otherwise, happy with the proposal
>>
>>
>> Suzuki
>
> Hi Suzuki,
>
> Would it be a good idea to register the TGU device as a platform device
> so that it will appear under "/sys/devices/platform/" and the code could
> also be decoupled from coresight-priv.h
It is already an AMBA device, why do you need this as a platform device
? You are welcome to add a sysfs group "tgu" under the device.
Suzuki
>
> BRs,
> Songwei>
>>
>>
>>
>>>
>>> Note:
>>> Bit distribution diagram for each priority register
>>> |-------------------------------------------------------------------|
>>> | Bits | Field Nam | Description |
>>> |-------------------------------------------------------------------|
>>> | | | 00 = bypass for OR
>>> output |
>>> | 29:28 | SEL_BIT7_TYPE2 | 01 = bypass for AND
>>> output |
>>> | | | 10 = sense input '0' is
>>> true|
>>> | | | 11 = sense input '1' is
>>> true|
>>> |-------------------------------------------------------------------|
>>> | | | 00 = bypass for OR
>>> output |
>>> | 25:24 | SEL_BIT6_TYPE2 | 01 = bypass for AND
>>> output |
>>> | | | 10 = sense input '0' is
>>> true|
>>> | | | 11 = sense input '1' is
>>> true|
>>> |-------------------------------------------------------------------|
>>> | | | 00 = bypass for OR
>>> output |
>>> | 21:20 | SEL_BIT5_TYPE2 | 01 = bypass for AND
>>> output |
>>> | | | 10 = sense input '0' is
>>> true|
>>> | | | 11 = sense input '1' is
>>> true|
>>> |-------------------------------------------------------------------|
>>> | | | 00 = bypass for OR
>>> output |
>>> | 17:16 | SEL_BIT4_TYPE2 | 01 = bypass for AND
>>> output |
>>> | | | 10 = sense input '0' is
>>> true|
>>> | | | 11 = sense input '1' is
>>> true|
>>> |-------------------------------------------------------------------|
>>> | | | 00 = bypass for OR
>>> output |
>>> | 13:12 | SEL_BIT3_TYPE2 | 01 = bypass for AND
>>> output |
>>> | | | 10 = sense input '0' is
>>> true|
>>> | | | 11 = sense input '1' is
>>> true|
>>> |-------------------------------------------------------------------|
>>> | | | 00 = bypass for OR
>>> output |
>>> | 9:8 | SEL_BIT2_TYPE2 | 01 = bypass for AND
>>> output |
>>> | | | 10 = sense input '0' is
>>> true|
>>> | | | 11 = sense input '1' is
>>> true|
>>> |-------------------------------------------------------------------|
>>> | | | 00 = bypass for OR
>>> output |
>>> | 5:4 | SEL_BIT1_TYPE2 | 01 = bypass for AND
>>> output |
>>> | | | 10 = sense input '0' is
>>> true|
>>> | | | 11 = sense input '1' is
>>> true|
>>> |-------------------------------------------------------------------|
>>> | | | 00 = bypass for OR
>>> output |
>>> | 1:0 | SEL_BIT0_TYPE2 | 01 = bypass for AND
>>> output |
>>> | | | 10 = sense input '0' is
>>> true|
>>> | | | 11 = sense input '1' is
>>> true|
>>> |-------------------------------------------------------------------|
>>> These bits are used to identify the signals we want to sense, with
>>> a maximum signal number of 140. For example, to sense the signal
>>> 0xA (binary 1010), we set the value of bits 0 to 13 to 3232, which
>>> represents 1010. The remaining bits are set to 1, as we want to use
>>> AND gate to summarize all the signals we want to sense here. For
>>> rising or falling edge detection of any input to the priority, set
>>> the remaining bits to 0 to use an OR gate.
>>>
>>> 3. look for the pattern for priority_i i=0,1.
>>> - echo 0x3 > /sys/bus/coresight/devices/<tgu-name>/
>>> step0_condition_decode/reg0
>>> - echo 0x30 > /sys/bus/coresight/devices/<tgu-name>/
>>> step0_condition_decode/reg1
>>>
>>> |-------------------------------------------------------------------------------|
>>> | Bits | Field Nam |
>>> Description |
>>> |-------------------------------------------------------------------------------|
>>> | | |For each decoded
>>> condition, this |
>>> | 24 | NOT |inverts the output. If
>>> the condition |
>>> | | |decodes to true, and
>>> the NOT field |
>>> | | |is '1', then the output
>>> is NOT true. |
>>> |-------------------------------------------------------------------------------|
>>> | | |When '1' the output
>>> from the associated|
>>> | 21 | BC0_COMP_ACTIVE |comparator will be
>>> actively included in|
>>> | | |the decoding of this
>>> particular |
>>> | | |
>>> condition. |
>>> |-------------------------------------------------------------------------------|
>>> | | |When '1' the output
>>> from the associated|
>>> | | |comparator will need to
>>> be 1 to affect |
>>> | 20 | BC0_COMP_HIGH |the decoding of this
>>> condition. |
>>> | | |Conversely, a '0' here
>>> requires a '0' |
>>> | | |from the
>>> comparator |
>>> |-------------------------------------------------------------------------------|
>>> | | |When '1' the output
>>> from the associated|
>>> | 17 | |comparator will be
>>> actively included in|
>>> | | TC0_COMP_ACTIVE |the decoding of this
>>> particular |
>>> | | |
>>> condition. |
>>> |-------------------------------------------------------------------------------|
>>> | | |When '1' the output
>>> from the associated|
>>> | | |comparator will need to
>>> be 1 to affect |
>>> | 16 | TC0_COMP_HIGH |the decoding of this
>>> particular |
>>> | | |condition.Conversely, a
>>> 0 here |
>>> | | |requires a '0' from the
>>> comparator |
>>> |-------------------------------------------------------------------------------|
>>> | | |When '1' the output
>>> from Priority_n |
>>> | | |OR logic will be
>>> actively |
>>> | 4n+3 | Priority_n_OR_ACTIVE|included in the
>>> decoding of |
>>> | | (n=0,1,2,3) |this particular
>>> condition. |
>>> | | |
>>> |
>>> |-------------------------------------------------------------------------------|
>>> | | |When '1' the output
>>> from Priority_n |
>>> | | |will need to be '1' to
>>> affect the |
>>> | 4n+2 | Priority_n_OR_HIGH |decoding of this
>>> particular |
>>> | | (n=0,1,2,3) |condition. Conversely,
>>> a '0' here |
>>> | | |requires a '0' from
>>> Priority_n OR logic|
>>> |-------------------------------------------------------------------------------|
>>> | | |When '1' the output
>>> from Priority_n |
>>> | | |AND logic will be
>>> actively |
>>> | 4n+1 |Priority_n_AND_ACTIVE|included in the
>>> decoding of this |
>>> | | (n=0,1,2,3) |particular
>>> condition. |
>>> | | |
>>> |
>>> |-------------------------------------------------------------------------------|
>>> | | |When '1' the output
>>> from Priority_n |
>>> | | |AND logic will need to
>>> be '1' to |
>>> | 4n | Priority_n_AND_HIGH |affect the decoding of
>>> this |
>>> | | (n=0,1,2,3) |particular condition.
>>> Conversely, |
>>> | | |a '0' here requires a
>>> '0' from |
>>> | | |Priority_n AND
>>> logic. |
>>> |-------------------------------------------------------------------------------|
>>> Since we use `priority_0` and `priority_1` with an AND output in
>>> step 2, we set `0x3`
>>> and `0x30` here to activate them.
>>>
>>> 4. Set NEXT_STEP = 1 and TC0_ENABLE = 1 so that when the conditions
>>> are met then the next step will be step 1 and the timer will
>>> be enabled.
>>> - echo 0x20008 > /sys/bus/coresight/devices/<tgu-name>/
>>> step0_condition_select/reg0
>>> - echo 0x20008 > /sys/bus/coresight/devices/<tgu-name>/
>>> step0_condition_select/reg1
>>>
>>> |-----------------------------------------------------------------------------|
>>> | Bits | Field Nam |
>>> Description |
>>> |-----------------------------------------------------------------------------|
>>> | | |This field defines the
>>> next step the |
>>> | 18:17 | NEXT_STEP |TGU will 'goto' for the
>>> associated |
>>> | | |Condition and
>>> Step. |
>>> |-----------------------------------------------------------------------------|
>>> | | |For each possible output
>>> trigger |
>>> | 13 | TRIGGER |available, set a '1' if
>>> you want |
>>> | | |the trigger to go active
>>> for the |
>>> | | |associated condition and
>>> Step. |
>>> |-----------------------------------------------------------------------------|
>>> | | |This will cause BC0 to
>>> increment if the|
>>> | 9 | BC0_INC |associated Condition is
>>> decoded for |
>>> | | |this
>>> step. |
>>> |-----------------------------------------------------------------------------|
>>> | | |This will cause BC0 to
>>> decrement if the|
>>> | 8 | BC0_DEC |associated Condition is
>>> decoded for |
>>> | | |this
>>> step. |
>>> |-----------------------------------------------------------------------------|
>>> | | |This will clear BC0 count
>>> value to 0 if|
>>> | 7 | BC0_CLEAR |the associated Condition
>>> is decoded |
>>> | | |for this
>>> step. |
>>> |-----------------------------------------------------------------------------|
>>> | | |This will cause TC0 to
>>> increment until |
>>> | 3 | TC0_ENABLE |paused or cleared if the
>>> associated |
>>> | | |Condition is decoded for
>>> this step. |
>>> |-----------------------------------------------------------------------------|
>>> | | |This will cause TC0 to
>>> pause until |
>>> | 2 | TC0_PAUSE |enabled if the associated
>>> Condition |
>>> | | |is decoded for this
>>> step. |
>>> |-----------------------------------------------------------------------------|
>>> | | |This will clear TC0 count
>>> value to 0 |
>>> | 1 | TC0_CLEAR |if the associated
>>> Condition is |
>>> | | |decoded for this
>>> step. |
>>> |-----------------------------------------------------------------------------|
>>> | | |This will set the done
>>> signal to the |
>>> | 0 | DONE |TGU FSM if the associated
>>> Condition |
>>> | | |is decoded for this
>>> step. |
>>> |-----------------------------------------------------------------------------|
>>> Based on the distribution diagram, we set `0x20008` for
>>> `priority0` and `priority1` to
>>> achieve "jump to step 1 and enable TC0" once the signal is sensed.
>>>
>>> 5. activate the timer comparison for this step.
>>> - echo 0x30000 > /sys/bus/coresight/devices/<tgu-name>/
>>> step1_condition_decode/reg0
>>>
>>> |-------------------------------------------------------------------------------|
>>> | | |When '1' the output
>>> from the associated|
>>> | 17 | |comparator will be
>>> actively included in|
>>> | | TC0_COMP_ACTIVE |the decoding of this
>>> particular |
>>> | | |
>>> condition. |
>>> |-------------------------------------------------------------------------------|
>>> | | |When '1' the output
>>> from the associated|
>>> | | |comparator will need to
>>> be 1 to affect |
>>> | 16 | TC0_COMP_HIGH |the decoding of this
>>> particular |
>>> | | |condition.Conversely, a
>>> 0 here |
>>> | | |requires a '0' from the
>>> comparator |
>>> |-------------------------------------------------------------------------------|
>>> Accroding to the decode distribution diagram , we give 0x30000
>>> here to set 16th&17th bit
>>> to enable timer comparison.
>>>
>>> 6. Set the NEXT_STEP = 0 and TC0_PAUSE = 1 and TC0_CLEAR = 1
>>> once the timer
>>> has reached the given value.
>>> - echo 0x6 > /sys/bus/coresight/devices/<tgu-name>/
>>> step1_condition_select/reg0
>>>
>>> 7. Enable Trigger 0 for TGU when the condition 0 is met in step1,
>>> i.e. when the timer reaches 3.
>>> - echo 0x2000 > /sys/bus/coresight/devices/<tgu-name>/
>>> step1_condition_select/default
>>>
>>> Note:
>>> 1. 'default' register allows for establishing the resultant
>>> action for
>>> the default condition
>>>
>>> 2. Trigger:For each possible output trigger available from
>>> the Design document, there are three triggers: interrupts, CTI,
>>> and Cross-TGU mapping.All three triggers can occur, but
>>> the choice of which trigger to use depends on the user's
>>> needs.
>>>
>>> 8. Compare the timer to 3 in step 1.
>>> - echo 0x3 > /sys/bus/coresight/devices/<tgu-name>/step1_timer/reg0
>>>
>>> 9. enale tgu
>>> - echo 1 > /sys/bus/coresight/devices/<tgu-name>/enable_tgu
>>> ---
>>> Link to V7: https://lore.kernel.org/all/20251104064043.88972-1-
>>> songwei.chai(a)oss.qualcomm.com/
>>>
>>> Changes in V8:
>>> - Add "select" section in bindings.
>>> - Update publish date in "sysfs-bus-coresight-devices-tgu".
>>> ---
>>> Link to V6: https://lore.kernel.org/all/20250709104114.22240-1-
>>> songchai(a)qti.qualcomm.com/
>>>
>>> Changes in V7:
>>> - Move the TGU code location from 'drivers/hwtracing/coresight/' to
>>> 'drivers/hwtracing/qcom/'.
>>> - Rename the spinlock used in the code from 'spinlock' to 'lock'.
>>> - Perform the 'calculate_array_location' separately, instead of doing
>>> it within the function.
>>> - Update the sender email address.
>>> ---
>>> Link to V5: https://lore.kernel.org/all/20250529081949.26493-1-
>>> quic_songchai(a)quicinc.com/
>>>
>>> Changes in V6:
>>> - Replace spinlock with guard(spinlock) in tgu_enable.
>>> - Remove redundant blank line.
>>> - Update publish date and contact member's name in "sysfs-bus-
>>> coresight-devices-tgu".
>>> ---
>>> Link to V4: https://patchwork.kernel.org/project/linux-arm-msm/
>>> cover/20250423101054.954066-1-quic_songchai(a)quicinc.com/
>>>
>>> Changes in V5:
>>> - Update publish date and kernel_version in "sysfs-bus-coresight-
>>> devices-tgu"
>>> ---
>>> Link to V3: https://lore.kernel.org/all/20250227092640.2666894-1-
>>> quic_songchai(a)quicinc.com/
>>>
>>> Changes in V4:
>>> - Add changlog in coverletter.
>>> - Correct 'year' in Copyright in patch1.
>>> - Correct port mechansim description in patch1.
>>> - Remove 'tgu-steps','tgu-regs','tgu-conditions','tgu-timer-counters'
>>> from dt-binding
>>> and set them through reading DEVID register as per Mike's suggestion.
>>> - Modify tgu_disable func to make it have single return point in
>>> patch2 as per
>>> Mike's suggestion.
>>> - Use sysfs_emit in enable_tgu_show func in ptach2.
>>> - Remove redundant judgement in enable_tgu_store in patch2.
>>> - Correct typo in description in patch3.
>>> - Set default ret as SYSFS_GROUP_INVISIBLE, and returnret at end in
>>> pacth3 as
>>> per Mike's suggestion.
>>> - Remove tgu_dataset_ro definition in patch3
>>> - Use #define constants with explanations of what they are rather than
>>> arbitrary magic numbers in patch3 and patch4.
>>> - Check -EINVAL before using 'calculate_array_location()' in array in
>>> patch4.
>>> - Add 'default' in 'tgu_dataset_show''s switch part in patch4.
>>> - Document the value needed to initiate the reset in pacth7.
>>> - Check "value" in 'reset_tgu_store' and bail out with an error code
>>> if 0 in patch7.
>>> - Remove dev_dbg in 'reset_tgu_store' in patch7.
>>> ---
>>> Link to V2: https://lore.kernel.org/all/20241010073917.16023-1-
>>> quic_songchai(a)quicinc.com/
>>>
>>> Changes in V3:
>>> - Correct typo and format in dt-binding in patch1
>>> - Rebase to the latest kernel version
>>> ---
>>> Link to V1: https://lore.kernel.org/all/20240830092311.14400-1-
>>> quic_songchai(a)quicinc.com/
>>>
>>> Changes in V2:
>>> - Use real name instead of login name,
>>> - Correct typo and format in dt-binding and code.
>>> - Bring order in tgu_prob(declarations with and without
>>> assignments) as per
>>> Krzysztof's suggestion.
>>> - Add module device table in patch2.
>>> - Set const for tgu_common_grp and tgu_ids in patch2.
>>> - Initialize 'data' in tgu_ids to fix the warning in pacth2.
>>> ---
>>>
>>> Songwei Chai (7):
>>> dt-bindings: arm: Add support for Qualcomm TGU trace
>>> qcom-tgu: Add TGU driver
>>> qcom-tgu: Add signal priority support
>>> qcom-tgu: Add TGU decode support
>>> qcom-tgu: Add support to configure next action
>>> qcom-tgu: Add timer/counter functionality for TGU
>>> qcom-tgu: Add reset node to initialize
>>>
>>> .../testing/sysfs-bus-coresight-devices-tgu | 51 ++
>>> .../devicetree/bindings/arm/qcom,tgu.yaml | 92 +++
>>> drivers/Makefile | 1 +
>>> drivers/hwtracing/Kconfig | 2 +
>>> drivers/hwtracing/qcom/Kconfig | 18 +
>>> drivers/hwtracing/qcom/Makefile | 3 +
>>> drivers/hwtracing/qcom/tgu.c | 737 ++++++++++++++++++
>>> drivers/hwtracing/qcom/tgu.h | 252 ++++++
>>> 8 files changed, 1156 insertions(+)
>>> create mode 100644 Documentation/ABI/testing/sysfs-bus-coresight-
>>> devices-tgu
>>> create mode 100644 Documentation/devicetree/bindings/arm/qcom,tgu.yaml
>>> create mode 100644 drivers/hwtracing/qcom/Kconfig
>>> create mode 100644 drivers/hwtracing/qcom/Makefile
>>> create mode 100644 drivers/hwtracing/qcom/tgu.c
>>> create mode 100644 drivers/hwtracing/qcom/tgu.h
>>>
>>
>
The specific config field that an event format attribute is in is
consistently hard coded, even though the API is supposed to be that the
driver publishes the config field name. To stop this pattern from being
copy pasted and causing problems in the future, replace them all with
calls to a new helper that returns the value that a user set.
The existing evsel__set_config_if_unset() also has a similar problem
that it hard codes attr.config, so fix that too.
There are no functional changes here because all the fields touched are
in attr.config and not config1 or config2 etc. Although this may not be
the case for new fields.
Signed-off-by: James Clark <james.clark(a)linaro.org>
---
James Clark (7):
perf tools: Track all user changed config bits
perf tools: apply evsel__set_config_if_unset() to all config fields
perf cs-etm: Make a helper to find the Coresight evsel
perf cs-etm: Don't use hard coded config bits when setting up ETMCR
perf cs-etm: Don't use hard coded config bits when setting up TRCCONFIGR
perf cs-etm: Don't hard code config attribute when configuring the event
perf arm-spe: Don't hard code config attribute
tools/perf/arch/arm/util/cs-etm.c | 202 ++++++++++++++++++++---------------
tools/perf/arch/arm64/util/arm-spe.c | 15 +--
tools/perf/util/evsel.c | 6 +-
tools/perf/util/evsel.h | 2 +
tools/perf/util/evsel_config.h | 6 +-
tools/perf/util/parse-events.c | 89 +++++++--------
tools/perf/util/pmu.c | 93 +++++++++++++---
7 files changed, 251 insertions(+), 162 deletions(-)
---
base-commit: 834ebb5678d75d844f5d4f44ede78724d8c96630
change-id: 20251112-james-perf-config-bits-bee7106f0f00
Best regards,
--
James Clark <james.clark(a)linaro.org>
On 04/12/2025 02:53, Jie Gan wrote:
>
>
> On 12/4/2025 2:14 AM, Suzuki K Poulose wrote:
>> On 08/09/2025 03:01, Jie Gan wrote:
>>> Add an interrupt property to CTCU device. The interrupt will be
>>> triggered
>>> when the data size in the ETR buffer exceeds the threshold of the
>>> BYTECNTRVAL register. Programming a threshold in the BYTECNTRVAL
>>> register
>>> of CTCU device will enable the interrupt.
>>>
>>> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski(a)linaro.org>
>>> Signed-off-by: Jie Gan <jie.gan(a)oss.qualcomm.com>
>>> ---
>>> .../devicetree/bindings/arm/qcom,coresight-ctcu.yaml | 17 ++++++
>>> + ++++++++++
>>> 1 file changed, 17 insertions(+)
>>>
>>> diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-
>>> ctcu.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-
>>> ctcu.yaml
>>> index 843b52eaf872..ea05ad8f3dd3 100644
>>> --- a/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml
>>> +++ b/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml
>>> @@ -39,6 +39,16 @@ properties:
>>> items:
>>> - const: apb
>>> + interrupts:
>>> + items:
>>> + - description: Byte cntr interrupt for etr0
>>> + - description: Byte cntr interrupt for etr1
>>> +
>>> + interrupt-names:
>>> + items:
>>> + - const: etr0
>>> + - const: etr1
>>
>
> Hi Suzuki,
>
>> Why are they named "etr0" "etr1" ? That would be confusing, isn't it,
>> especially with the Linux driver naming things randomly for the TMC-ETRs.
>>
>
> Yes, it will cause misunderstandings since the "etr0" here may not the
> right device we are expecting.
>
>>
>> What we want is the "port" number corresponding to the "TMC-ETR" being
>> monitored ?
>>
>> Have you explored other options, "port-0", "port-1" ?
>>
>
> I think it's much better. Will update in next version.
I am not sure if there exists a better scheme for identifying or
numbering the interrupts. Happy to listen to the DT experts.
Rob, Krzysztof, thoughts ?
Suzuki
>
> Thanks,
> Jie
>
>> Suzuki
>>
>>> +
>>> in-ports:
>>> $ref: /schemas/graph.yaml#/properties/ports
>>> @@ -56,6 +66,8 @@ additionalProperties: false
>>> examples:
>>> - |
>>> + #include <dt-bindings/interrupt-controller/arm-gic.h>
>>> +
>>> ctcu@1001000 {
>>> compatible = "qcom,sa8775p-ctcu";
>>> reg = <0x1001000 0x1000>;
>>> @@ -63,6 +75,11 @@ examples:
>>> clocks = <&aoss_qmp>;
>>> clock-names = "apb";
>>> + interrupts = <GIC_SPI 270 IRQ_TYPE_EDGE_RISING>,
>>> + <GIC_SPI 262 IRQ_TYPE_EDGE_RISING>;
>>> + interrupt-names = "etr0",
>>> + "etr1";
>>> +
>>> in-ports {
>>> #address-cells = <1>;
>>> #size-cells = <0>;
>>>
>>
>>
>