mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 05:02:12 +00:00
intel_th: Add switch triggering support
Add support for asserting window switch trigger when tracing to MSU output ports. This allows for software controlled switching between windows of the MSU buffer, which can be used for double buffering while exporting the trace data further from the MSU. Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
9958e02523
commit
8116db57cf
@ -430,9 +430,9 @@ static const struct intel_th_subdevice {
|
||||
.nres = 1,
|
||||
.res = {
|
||||
{
|
||||
/* Handle TSCU from GTH driver */
|
||||
/* Handle TSCU and CTS from GTH driver */
|
||||
.start = REG_GTH_OFFSET,
|
||||
.end = REG_TSCU_OFFSET + REG_TSCU_LENGTH - 1,
|
||||
.end = REG_CTS_OFFSET + REG_CTS_LENGTH - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
},
|
||||
@ -987,6 +987,27 @@ int intel_th_trace_enable(struct intel_th_device *thdev)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(intel_th_trace_enable);
|
||||
|
||||
/**
|
||||
* intel_th_trace_switch() - execute a switch sequence
|
||||
* @thdev: output device that requests tracing switch
|
||||
*/
|
||||
int intel_th_trace_switch(struct intel_th_device *thdev)
|
||||
{
|
||||
struct intel_th_device *hub = to_intel_th_device(thdev->dev.parent);
|
||||
struct intel_th_driver *hubdrv = to_intel_th_driver(hub->dev.driver);
|
||||
|
||||
if (WARN_ON_ONCE(hub->type != INTEL_TH_SWITCH))
|
||||
return -EINVAL;
|
||||
|
||||
if (WARN_ON_ONCE(thdev->type != INTEL_TH_OUTPUT))
|
||||
return -EINVAL;
|
||||
|
||||
hubdrv->trig_switch(hub, &thdev->output);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(intel_th_trace_switch);
|
||||
|
||||
/**
|
||||
* intel_th_trace_disable() - disable tracing for an output device
|
||||
* @thdev: output device that requests tracing be disabled
|
||||
|
@ -308,6 +308,11 @@ static int intel_th_gth_reset(struct gth_device *gth)
|
||||
iowrite32(0, gth->base + REG_GTH_SCR);
|
||||
iowrite32(0xfc, gth->base + REG_GTH_SCR2);
|
||||
|
||||
/* setup CTS for single trigger */
|
||||
iowrite32(CTS_EVENT_ENABLE_IF_ANYTHING, gth->base + REG_CTS_C0S0_EN);
|
||||
iowrite32(CTS_ACTION_CONTROL_SET_STATE(CTS_STATE_IDLE) |
|
||||
CTS_ACTION_CONTROL_TRIGGER, gth->base + REG_CTS_C0S0_ACT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -594,6 +599,37 @@ static void intel_th_gth_enable(struct intel_th_device *thdev,
|
||||
intel_th_gth_start(gth, output);
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_th_gth_switch() - execute a switch sequence
|
||||
* @thdev: GTH device
|
||||
* @output: output device's descriptor
|
||||
*
|
||||
* This will execute a switch sequence that will trigger a switch window
|
||||
* when tracing to MSC in multi-block mode.
|
||||
*/
|
||||
static void intel_th_gth_switch(struct intel_th_device *thdev,
|
||||
struct intel_th_output *output)
|
||||
{
|
||||
struct gth_device *gth = dev_get_drvdata(&thdev->dev);
|
||||
unsigned long count;
|
||||
u32 reg;
|
||||
|
||||
/* trigger */
|
||||
iowrite32(0, gth->base + REG_CTS_CTL);
|
||||
iowrite32(CTS_CTL_SEQUENCER_ENABLE, gth->base + REG_CTS_CTL);
|
||||
/* wait on trigger status */
|
||||
for (reg = 0, count = CTS_TRIG_WAITLOOP_DEPTH;
|
||||
count && !(reg & BIT(4)); count--) {
|
||||
reg = ioread32(gth->base + REG_CTS_STAT);
|
||||
cpu_relax();
|
||||
}
|
||||
if (!count)
|
||||
dev_dbg(&thdev->dev, "timeout waiting for CTS Trigger\n");
|
||||
|
||||
intel_th_gth_stop(gth, output, false);
|
||||
intel_th_gth_start(gth, output);
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_th_gth_assign() - assign output device to a GTH output port
|
||||
* @thdev: GTH device
|
||||
@ -777,6 +813,7 @@ static struct intel_th_driver intel_th_gth_driver = {
|
||||
.unassign = intel_th_gth_unassign,
|
||||
.set_output = intel_th_gth_set_output,
|
||||
.enable = intel_th_gth_enable,
|
||||
.trig_switch = intel_th_gth_switch,
|
||||
.disable = intel_th_gth_disable,
|
||||
.driver = {
|
||||
.name = "gth",
|
||||
|
@ -49,6 +49,12 @@ enum {
|
||||
REG_GTH_SCRPD3 = 0xec, /* ScratchPad[3] */
|
||||
REG_TSCU_TSUCTRL = 0x2000, /* TSCU control register */
|
||||
REG_TSCU_TSCUSTAT = 0x2004, /* TSCU status register */
|
||||
|
||||
/* Common Capture Sequencer (CTS) registers */
|
||||
REG_CTS_C0S0_EN = 0x30c0, /* clause_event_enable_c0s0 */
|
||||
REG_CTS_C0S0_ACT = 0x3180, /* clause_action_control_c0s0 */
|
||||
REG_CTS_STAT = 0x32a0, /* cts_status */
|
||||
REG_CTS_CTL = 0x32a4, /* cts_control */
|
||||
};
|
||||
|
||||
/* waiting for Pipeline Empty bit(s) to assert for GTH */
|
||||
@ -57,4 +63,17 @@ enum {
|
||||
#define TSUCTRL_CTCRESYNC BIT(0)
|
||||
#define TSCUSTAT_CTCSYNCING BIT(1)
|
||||
|
||||
/* waiting for Trigger status to assert for CTS */
|
||||
#define CTS_TRIG_WAITLOOP_DEPTH 10000
|
||||
|
||||
#define CTS_EVENT_ENABLE_IF_ANYTHING BIT(31)
|
||||
#define CTS_ACTION_CONTROL_STATE_OFF 27
|
||||
#define CTS_ACTION_CONTROL_SET_STATE(x) \
|
||||
(((x) & 0x1f) << CTS_ACTION_CONTROL_STATE_OFF)
|
||||
#define CTS_ACTION_CONTROL_TRIGGER BIT(4)
|
||||
|
||||
#define CTS_STATE_IDLE 0x10u
|
||||
|
||||
#define CTS_CTL_SEQUENCER_ENABLE BIT(0)
|
||||
|
||||
#endif /* __INTEL_TH_GTH_H__ */
|
||||
|
@ -164,6 +164,8 @@ struct intel_th_driver {
|
||||
struct intel_th_device *othdev);
|
||||
void (*enable)(struct intel_th_device *thdev,
|
||||
struct intel_th_output *output);
|
||||
void (*trig_switch)(struct intel_th_device *thdev,
|
||||
struct intel_th_output *output);
|
||||
void (*disable)(struct intel_th_device *thdev,
|
||||
struct intel_th_output *output);
|
||||
/* output ops */
|
||||
@ -228,6 +230,7 @@ int intel_th_driver_register(struct intel_th_driver *thdrv);
|
||||
void intel_th_driver_unregister(struct intel_th_driver *thdrv);
|
||||
|
||||
int intel_th_trace_enable(struct intel_th_device *thdev);
|
||||
int intel_th_trace_switch(struct intel_th_device *thdev);
|
||||
int intel_th_trace_disable(struct intel_th_device *thdev);
|
||||
int intel_th_set_output(struct intel_th_device *thdev,
|
||||
unsigned int master);
|
||||
@ -308,6 +311,9 @@ enum {
|
||||
REG_TSCU_OFFSET = 0x2000,
|
||||
REG_TSCU_LENGTH = 0x1000,
|
||||
|
||||
REG_CTS_OFFSET = 0x3000,
|
||||
REG_CTS_LENGTH = 0x1000,
|
||||
|
||||
/* Software Trace Hub (STH) [0x4000..0x4fff] */
|
||||
REG_STH_OFFSET = 0x4000,
|
||||
REG_STH_LENGTH = 0x2000,
|
||||
|
Loading…
Reference in New Issue
Block a user