mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
coresight: etm4x: Properly control filter in CPU idle with FEAT_TRF
If a CPU supports FEAT_TRF, as described in the section K5.5 "Context
switching", Arm ARM (ARM DDI 0487 L.a), it defines a flow to prohibit
program-flow trace, execute a TSB CSYNC instruction for flushing,
followed by clearing TRCPRGCTLR.EN bit.
To restore the state, the reverse sequence is required.
This differs from the procedure described in the section 3.4.1 "The
procedure when powering down the PE" of ARM IHI0064H.b, which involves
the OS Lock to prevent external debugger accesses and implicitly
disables trace.
To be compatible with different ETM versions, explicitly control trace
unit using etm4_disable_trace_unit() and etm4_enable_trace_unit()
during CPU idle to comply with FEAT_TRF.
As a result, the save states for TRFCR_ELx and trcprgctlr are redundant,
remove them.
Fixes: f188b5e76a ("coresight: etm4x: Save/restore state across CPU low power states")
Reviewed-by: Mike Leach <mike.leach@linaro.org>
Tested-by: James Clark <james.clark@linaro.org>
Reviewed-by: Yeoreum Yun <yeoreum.yun@arm.com>
Signed-off-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Link: https://lore.kernel.org/r/20251111-arm_coresight_power_management_fix-v6-6-f55553b6c8b3@arm.com
This commit is contained in:
committed by
Suzuki K Poulose
parent
64eb04ae54
commit
1fdc2cd347
@@ -1858,9 +1858,11 @@ static int __etm4_cpu_save(struct etmv4_drvdata *drvdata)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!drvdata->paused)
|
||||
etm4_disable_trace_unit(drvdata);
|
||||
|
||||
state = drvdata->save_state;
|
||||
|
||||
state->trcprgctlr = etm4x_read32(csa, TRCPRGCTLR);
|
||||
if (drvdata->nr_pe)
|
||||
state->trcprocselr = etm4x_read32(csa, TRCPROCSELR);
|
||||
state->trcconfigr = etm4x_read32(csa, TRCCONFIGR);
|
||||
@@ -1970,9 +1972,6 @@ static int etm4_cpu_save(struct etmv4_drvdata *drvdata)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
/* Save the TRFCR irrespective of whether the ETM is ON */
|
||||
if (drvdata->trfcr)
|
||||
drvdata->save_trfcr = read_trfcr();
|
||||
/*
|
||||
* Save and restore the ETM Trace registers only if
|
||||
* the ETM is active.
|
||||
@@ -1994,7 +1993,6 @@ static void __etm4_cpu_restore(struct etmv4_drvdata *drvdata)
|
||||
etm4_cs_unlock(drvdata, csa);
|
||||
etm4x_relaxed_write32(csa, state->trcclaimset, TRCCLAIMSET);
|
||||
|
||||
etm4x_relaxed_write32(csa, state->trcprgctlr, TRCPRGCTLR);
|
||||
if (drvdata->nr_pe)
|
||||
etm4x_relaxed_write32(csa, state->trcprocselr, TRCPROCSELR);
|
||||
etm4x_relaxed_write32(csa, state->trcconfigr, TRCCONFIGR);
|
||||
@@ -2079,13 +2077,15 @@ static void __etm4_cpu_restore(struct etmv4_drvdata *drvdata)
|
||||
|
||||
/* Unlock the OS lock to re-enable trace and external debug access */
|
||||
etm4_os_unlock(drvdata);
|
||||
|
||||
if (!drvdata->paused)
|
||||
etm4_enable_trace_unit(drvdata);
|
||||
|
||||
etm4_cs_lock(drvdata, csa);
|
||||
}
|
||||
|
||||
static void etm4_cpu_restore(struct etmv4_drvdata *drvdata)
|
||||
{
|
||||
if (drvdata->trfcr)
|
||||
write_trfcr(drvdata->save_trfcr);
|
||||
if (drvdata->state_needs_restore)
|
||||
__etm4_cpu_restore(drvdata);
|
||||
}
|
||||
|
||||
@@ -866,7 +866,6 @@ struct etmv4_config {
|
||||
* struct etm4_save_state - state to be preserved when ETM is without power
|
||||
*/
|
||||
struct etmv4_save_state {
|
||||
u32 trcprgctlr;
|
||||
u32 trcprocselr;
|
||||
u32 trcconfigr;
|
||||
u32 trcauxctlr;
|
||||
@@ -980,7 +979,6 @@ struct etmv4_save_state {
|
||||
* at runtime, due to the additional setting of TRFCR_CX when
|
||||
* in EL2. Otherwise, 0.
|
||||
* @config: structure holding configuration parameters.
|
||||
* @save_trfcr: Saved TRFCR_EL1 register during a CPU PM event.
|
||||
* @save_state: State to be preserved across power loss
|
||||
* @state_needs_restore: True when there is context to restore after PM exit
|
||||
* @skip_power_up: Indicates if an implementation can skip powering up
|
||||
@@ -1037,7 +1035,6 @@ struct etmv4_drvdata {
|
||||
bool lpoverride;
|
||||
u64 trfcr;
|
||||
struct etmv4_config config;
|
||||
u64 save_trfcr;
|
||||
struct etmv4_save_state *save_state;
|
||||
bool state_needs_restore;
|
||||
bool skip_power_up;
|
||||
|
||||
Reference in New Issue
Block a user