Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 54ff892b authored by Mathieu Poirier's avatar Mathieu Poirier Committed by Greg Kroah-Hartman
Browse files

coresight: etm4x: splitting struct etmv4_drvdata



Similar to what was done on etm3x, splitting driver structure
etmv4_drvdata in two.  One half is concerned with the HW
characteristics that are generally static in nature.  The other
half deals with user configuration and will change from one
trace session to another.

No gain/loss of functionality is incurred from this patch.

Signed-off-by: default avatarMathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 7c38aa4b
Loading
Loading
Loading
Loading
+360 −282

File changed.

Preview size limit exceeded, changes collapsed.

+68 −66
Original line number Diff line number Diff line
@@ -95,6 +95,7 @@ static void etm4_enable_hw(void *info)
{
	int i;
	struct etmv4_drvdata *drvdata = info;
	struct etmv4_config *config = &drvdata->config;

	CS_UNLOCK(drvdata->base);

@@ -109,69 +110,69 @@ static void etm4_enable_hw(void *info)
			"timeout observed when probing at offset %#x\n",
			TRCSTATR);

	writel_relaxed(drvdata->pe_sel, drvdata->base + TRCPROCSELR);
	writel_relaxed(drvdata->cfg, drvdata->base + TRCCONFIGR);
	writel_relaxed(config->pe_sel, drvdata->base + TRCPROCSELR);
	writel_relaxed(config->cfg, drvdata->base + TRCCONFIGR);
	/* nothing specific implemented */
	writel_relaxed(0x0, drvdata->base + TRCAUXCTLR);
	writel_relaxed(drvdata->eventctrl0, drvdata->base + TRCEVENTCTL0R);
	writel_relaxed(drvdata->eventctrl1, drvdata->base + TRCEVENTCTL1R);
	writel_relaxed(drvdata->stall_ctrl, drvdata->base + TRCSTALLCTLR);
	writel_relaxed(drvdata->ts_ctrl, drvdata->base + TRCTSCTLR);
	writel_relaxed(drvdata->syncfreq, drvdata->base + TRCSYNCPR);
	writel_relaxed(drvdata->ccctlr, drvdata->base + TRCCCCTLR);
	writel_relaxed(drvdata->bb_ctrl, drvdata->base + TRCBBCTLR);
	writel_relaxed(config->eventctrl0, drvdata->base + TRCEVENTCTL0R);
	writel_relaxed(config->eventctrl1, drvdata->base + TRCEVENTCTL1R);
	writel_relaxed(config->stall_ctrl, drvdata->base + TRCSTALLCTLR);
	writel_relaxed(config->ts_ctrl, drvdata->base + TRCTSCTLR);
	writel_relaxed(config->syncfreq, drvdata->base + TRCSYNCPR);
	writel_relaxed(config->ccctlr, drvdata->base + TRCCCCTLR);
	writel_relaxed(config->bb_ctrl, drvdata->base + TRCBBCTLR);
	writel_relaxed(drvdata->trcid, drvdata->base + TRCTRACEIDR);
	writel_relaxed(drvdata->vinst_ctrl, drvdata->base + TRCVICTLR);
	writel_relaxed(drvdata->viiectlr, drvdata->base + TRCVIIECTLR);
	writel_relaxed(drvdata->vissctlr,
	writel_relaxed(config->vinst_ctrl, drvdata->base + TRCVICTLR);
	writel_relaxed(config->viiectlr, drvdata->base + TRCVIIECTLR);
	writel_relaxed(config->vissctlr,
		       drvdata->base + TRCVISSCTLR);
	writel_relaxed(drvdata->vipcssctlr,
	writel_relaxed(config->vipcssctlr,
		       drvdata->base + TRCVIPCSSCTLR);
	for (i = 0; i < drvdata->nrseqstate - 1; i++)
		writel_relaxed(drvdata->seq_ctrl[i],
		writel_relaxed(config->seq_ctrl[i],
			       drvdata->base + TRCSEQEVRn(i));
	writel_relaxed(drvdata->seq_rst, drvdata->base + TRCSEQRSTEVR);
	writel_relaxed(drvdata->seq_state, drvdata->base + TRCSEQSTR);
	writel_relaxed(drvdata->ext_inp, drvdata->base + TRCEXTINSELR);
	writel_relaxed(config->seq_rst, drvdata->base + TRCSEQRSTEVR);
	writel_relaxed(config->seq_state, drvdata->base + TRCSEQSTR);
	writel_relaxed(config->ext_inp, drvdata->base + TRCEXTINSELR);
	for (i = 0; i < drvdata->nr_cntr; i++) {
		writel_relaxed(drvdata->cntrldvr[i],
		writel_relaxed(config->cntrldvr[i],
			       drvdata->base + TRCCNTRLDVRn(i));
		writel_relaxed(drvdata->cntr_ctrl[i],
		writel_relaxed(config->cntr_ctrl[i],
			       drvdata->base + TRCCNTCTLRn(i));
		writel_relaxed(drvdata->cntr_val[i],
		writel_relaxed(config->cntr_val[i],
			       drvdata->base + TRCCNTVRn(i));
	}

	/* Resource selector pair 0 is always implemented and reserved */
	for (i = 2; i < drvdata->nr_resource * 2; i++)
		writel_relaxed(drvdata->res_ctrl[i],
	for (i = 0; i < drvdata->nr_resource * 2; i++)
		writel_relaxed(config->res_ctrl[i],
			       drvdata->base + TRCRSCTLRn(i));

	for (i = 0; i < drvdata->nr_ss_cmp; i++) {
		writel_relaxed(drvdata->ss_ctrl[i],
		writel_relaxed(config->ss_ctrl[i],
			       drvdata->base + TRCSSCCRn(i));
		writel_relaxed(drvdata->ss_status[i],
		writel_relaxed(config->ss_status[i],
			       drvdata->base + TRCSSCSRn(i));
		writel_relaxed(drvdata->ss_pe_cmp[i],
		writel_relaxed(config->ss_pe_cmp[i],
			       drvdata->base + TRCSSPCICRn(i));
	}
	for (i = 0; i < drvdata->nr_addr_cmp; i++) {
		writeq_relaxed(drvdata->addr_val[i],
		writeq_relaxed(config->addr_val[i],
			       drvdata->base + TRCACVRn(i));
		writeq_relaxed(drvdata->addr_acc[i],
		writeq_relaxed(config->addr_acc[i],
			       drvdata->base + TRCACATRn(i));
	}
	for (i = 0; i < drvdata->numcidc; i++)
		writeq_relaxed(drvdata->ctxid_pid[i],
		writeq_relaxed(config->ctxid_pid[i],
			       drvdata->base + TRCCIDCVRn(i));
	writel_relaxed(drvdata->ctxid_mask0, drvdata->base + TRCCIDCCTLR0);
	writel_relaxed(drvdata->ctxid_mask1, drvdata->base + TRCCIDCCTLR1);
	writel_relaxed(config->ctxid_mask0, drvdata->base + TRCCIDCCTLR0);
	writel_relaxed(config->ctxid_mask1, drvdata->base + TRCCIDCCTLR1);

	for (i = 0; i < drvdata->numvmidc; i++)
		writeq_relaxed(drvdata->vmid_val[i],
		writeq_relaxed(config->vmid_val[i],
			       drvdata->base + TRCVMIDCVRn(i));
	writel_relaxed(drvdata->vmid_mask0, drvdata->base + TRCVMIDCCTLR0);
	writel_relaxed(drvdata->vmid_mask1, drvdata->base + TRCVMIDCCTLR1);
	writel_relaxed(config->vmid_mask0, drvdata->base + TRCVMIDCCTLR0);
	writel_relaxed(config->vmid_mask1, drvdata->base + TRCVMIDCCTLR1);

	/* Enable the trace unit */
	writel_relaxed(1, drvdata->base + TRCPRGCTLR);
@@ -438,83 +439,84 @@ static void etm4_init_arch_data(void *info)
static void etm4_init_default_data(struct etmv4_drvdata *drvdata)
{
	int i;
	struct etmv4_config *config = &drvdata->config;

	drvdata->pe_sel = 0x0;
	drvdata->cfg = (ETMv4_MODE_CTXID | ETM_MODE_VMID |
	config->pe_sel = 0x0;
	config->cfg = (ETMv4_MODE_CTXID | ETM_MODE_VMID |
			ETMv4_MODE_TIMESTAMP | ETM_MODE_RETURNSTACK);

	/* disable all events tracing */
	drvdata->eventctrl0 = 0x0;
	drvdata->eventctrl1 = 0x0;
	config->eventctrl0 = 0x0;
	config->eventctrl1 = 0x0;

	/* disable stalling */
	drvdata->stall_ctrl = 0x0;
	config->stall_ctrl = 0x0;

	/* disable timestamp event */
	drvdata->ts_ctrl = 0x0;
	config->ts_ctrl = 0x0;

	/* enable trace synchronization every 4096 bytes for trace */
	if (drvdata->syncpr == false)
		drvdata->syncfreq = 0xC;
		config->syncfreq = 0xC;

	/*
	 *  enable viewInst to trace everything with start-stop logic in
	 *  started state
	 */
	drvdata->vinst_ctrl |= BIT(0);
	config->vinst_ctrl |= BIT(0);
	/* set initial state of start-stop logic */
	if (drvdata->nr_addr_cmp)
		drvdata->vinst_ctrl |= BIT(9);
		config->vinst_ctrl |= BIT(9);

	/* no address range filtering for ViewInst */
	drvdata->viiectlr = 0x0;
	config->viiectlr = 0x0;
	/* no start-stop filtering for ViewInst */
	drvdata->vissctlr = 0x0;
	config->vissctlr = 0x0;

	/* disable seq events */
	for (i = 0; i < drvdata->nrseqstate-1; i++)
		drvdata->seq_ctrl[i] = 0x0;
	drvdata->seq_rst = 0x0;
	drvdata->seq_state = 0x0;
		config->seq_ctrl[i] = 0x0;
	config->seq_rst = 0x0;
	config->seq_state = 0x0;

	/* disable external input events */
	drvdata->ext_inp = 0x0;
	config->ext_inp = 0x0;

	for (i = 0; i < drvdata->nr_cntr; i++) {
		drvdata->cntrldvr[i] = 0x0;
		drvdata->cntr_ctrl[i] = 0x0;
		drvdata->cntr_val[i] = 0x0;
		config->cntrldvr[i] = 0x0;
		config->cntr_ctrl[i] = 0x0;
		config->cntr_val[i] = 0x0;
	}

	/* Resource selector pair 0 is always implemented and reserved */
	drvdata->res_idx = 0x2;
	config->res_idx = 0x2;
	for (i = 2; i < drvdata->nr_resource * 2; i++)
		drvdata->res_ctrl[i] = 0x0;
		config->res_ctrl[i] = 0x0;

	for (i = 0; i < drvdata->nr_ss_cmp; i++) {
		drvdata->ss_ctrl[i] = 0x0;
		drvdata->ss_pe_cmp[i] = 0x0;
		config->ss_ctrl[i] = 0x0;
		config->ss_pe_cmp[i] = 0x0;
	}

	if (drvdata->nr_addr_cmp >= 1) {
		drvdata->addr_val[0] = (unsigned long)_stext;
		drvdata->addr_val[1] = (unsigned long)_etext;
		drvdata->addr_type[0] = ETM_ADDR_TYPE_RANGE;
		drvdata->addr_type[1] = ETM_ADDR_TYPE_RANGE;
		config->addr_val[0] = (unsigned long)_stext;
		config->addr_val[1] = (unsigned long)_etext;
		config->addr_type[0] = ETM_ADDR_TYPE_RANGE;
		config->addr_type[1] = ETM_ADDR_TYPE_RANGE;
	}

	for (i = 0; i < drvdata->numcidc; i++) {
		drvdata->ctxid_pid[i] = 0x0;
		drvdata->ctxid_vpid[i] = 0x0;
		config->ctxid_pid[i] = 0x0;
		config->ctxid_vpid[i] = 0x0;
	}

	drvdata->ctxid_mask0 = 0x0;
	drvdata->ctxid_mask1 = 0x0;
	config->ctxid_mask0 = 0x0;
	config->ctxid_mask1 = 0x0;

	for (i = 0; i < drvdata->numvmidc; i++)
		drvdata->vmid_val[i] = 0x0;
	drvdata->vmid_mask0 = 0x0;
	drvdata->vmid_mask1 = 0x0;
		config->vmid_val[i] = 0x0;
	config->vmid_mask0 = 0x0;
	config->vmid_mask1 = 0x0;

	/*
	 * A trace ID value of 0 is invalid, so let's start at some
+105 −97
Original line number Diff line number Diff line
@@ -180,66 +180,19 @@
#define TRCSTATR_IDLE_BIT		0

/**
 * struct etm4_drvdata - specifics associated to an ETM component
 * @base:       Memory mapped base address for this component.
 * @dev:        The device entity associated to this component.
 * @csdev:      Component vitals needed by the framework.
 * @spinlock:   Only one at a time pls.
 * @cpu:        The cpu this component is affined to.
 * @arch:       ETM version number.
 * @enable:	Is this ETM currently tracing.
 * @sticky_enable: true if ETM base configuration has been done.
 * @boot_enable:True if we should start tracing at boot time.
 * @os_unlock:  True if access to management registers is allowed.
 * @nr_pe:	The number of processing entity available for tracing.
 * @nr_pe_cmp:	The number of processing entity comparator inputs that are
 *		available for tracing.
 * @nr_addr_cmp:Number of pairs of address comparators available
 *		as found in ETMIDR4 0-3.
 * @nr_cntr:    Number of counters as found in ETMIDR5 bit 28-30.
 * @nr_ext_inp: Number of external input.
 * @numcidc:	Number of contextID comparators.
 * @numvmidc:	Number of VMID comparators.
 * @nrseqstate: The number of sequencer states that are implemented.
 * @nr_event:	Indicates how many events the trace unit support.
 * @nr_resource:The number of resource selection pairs available for tracing.
 * @nr_ss_cmp:	Number of single-shot comparator controls that are available.
 * struct etmv4_config - configuration information related to an ETMv4
 * @mode:	Controls various modes supported by this ETM.
 * @trcid:	value of the current ID for this component.
 * @trcid_size: Indicates the trace ID width.
 * @instrp0:	Tracing of load and store instructions
 *		as P0 elements is supported.
 * @trccond:	If the trace unit supports conditional
 *		instruction tracing.
 * @retstack:	Indicates if the implementation supports a return stack.
 * @trc_error:	Whether a trace unit can trace a system
 *		error exception.
 * @atbtrig:	If the implementation can support ATB triggers
 * @lpoverride:	If the implementation can support low-power state over.
 * @pe_sel:	Controls which PE to trace.
 * @cfg:	Controls the tracing options.
 * @eventctrl0: Controls the tracing of arbitrary events.
 * @eventctrl1: Controls the behavior of the events that @event_ctrl0 selects.
 * @stallctl:	If functionality that prevents trace unit buffer overflows
 *		is available.
 * @sysstall:	Does the system support stall control of the PE?
 * @nooverflow:	Indicate if overflow prevention is supported.
 * @stall_ctrl:	Enables trace unit functionality that prevents trace
 *		unit buffer overflows.
 * @ts_size:	Global timestamp size field.
 * @ts_ctrl:	Controls the insertion of global timestamps in the
 *		trace streams.
 * @syncpr:	Indicates if an implementation has a fixed
 *		synchronization period.
 * @syncfreq:	Controls how often trace synchronization requests occur.
 * @trccci:	Indicates if the trace unit supports cycle counting
 *		for instruction.
 * @ccsize:	Indicates the size of the cycle counter in bits.
 * @ccitmin:	minimum value that can be programmed in
 *		the TRCCCCTLR register.
 * @ccctlr:	Sets the threshold value for cycle counting.
 * @trcbb:	Indicates if the trace unit supports branch broadcast tracing.
 * @q_support:	Q element support characteristics.
 * @vinst_ctrl:	Controls instruction trace filtering.
 * @viiectlr:	Set or read, the address range comparators.
 * @vissctlr:	Set, or read, the single address comparators that control the
@@ -264,73 +217,28 @@
 * @addr_acc:	Address comparator access type.
 * @addr_type:	Current status of the comparator register.
 * @ctxid_idx:	Context ID index selector.
 * @ctxid_size:	Size of the context ID field to consider.
 * @ctxid_pid:	Value of the context ID comparator.
 * @ctxid_vpid:	Virtual PID seen by users if PID namespace is enabled, otherwise
 *		the same value of ctxid_pid.
 * @ctxid_mask0:Context ID comparator mask for comparator 0-3.
 * @ctxid_mask1:Context ID comparator mask for comparator 4-7.
 * @vmid_idx:	VM ID index selector.
 * @vmid_size:	Size of the VM ID comparator to consider.
 * @vmid_val:	Value of the VM ID comparator.
 * @vmid_mask0:	VM ID comparator mask for comparator 0-3.
 * @vmid_mask1:	VM ID comparator mask for comparator 4-7.
 * @s_ex_level:	In secure state, indicates whether instruction tracing is
 *		supported for the corresponding Exception level.
 * @ns_ex_level:In non-secure state, indicates whether instruction tracing is
 *		supported for the corresponding Exception level.
 * @ext_inp:	External input selection.
 */
struct etmv4_drvdata {
	void __iomem			*base;
	struct device			*dev;
	struct coresight_device		*csdev;
	spinlock_t			spinlock;
	int				cpu;
	u8				arch;
	bool				enable;
	bool				sticky_enable;
	bool				boot_enable;
	bool				os_unlock;
	u8				nr_pe;
	u8				nr_pe_cmp;
	u8				nr_addr_cmp;
	u8				nr_cntr;
	u8				nr_ext_inp;
	u8				numcidc;
	u8				numvmidc;
	u8				nrseqstate;
	u8				nr_event;
	u8				nr_resource;
	u8				nr_ss_cmp;
struct etmv4_config {
	u32				mode;
	u8				trcid;
	u8				trcid_size;
	bool				instrp0;
	bool				trccond;
	bool				retstack;
	bool				trc_error;
	bool				atbtrig;
	bool				lpoverride;
	u32				pe_sel;
	u32				cfg;
	u32				eventctrl0;
	u32				eventctrl1;
	bool				stallctl;
	bool				sysstall;
	bool				nooverflow;
	u32				stall_ctrl;
	u8				ts_size;
	u32				ts_ctrl;
	bool				syncpr;
	u32				syncfreq;
	bool				trccci;
	u8				ccsize;
	u8				ccitmin;
	u32				ccctlr;
	bool				trcbb;
	u32				bb_ctrl;
	bool				q_support;
	u32				vinst_ctrl;
	u32				viiectlr;
	u32				vissctlr;
@@ -353,19 +261,119 @@ struct etmv4_drvdata {
	u64				addr_acc[ETM_MAX_SINGLE_ADDR_CMP];
	u8				addr_type[ETM_MAX_SINGLE_ADDR_CMP];
	u8				ctxid_idx;
	u8				ctxid_size;
	u64				ctxid_pid[ETMv4_MAX_CTXID_CMP];
	u64				ctxid_vpid[ETMv4_MAX_CTXID_CMP];
	u32				ctxid_mask0;
	u32				ctxid_mask1;
	u8				vmid_idx;
	u8				vmid_size;
	u64				vmid_val[ETM_MAX_VMID_CMP];
	u32				vmid_mask0;
	u32				vmid_mask1;
	u32				ext_inp;
};

/**
 * struct etm4_drvdata - specifics associated to an ETM component
 * @base:       Memory mapped base address for this component.
 * @dev:        The device entity associated to this component.
 * @csdev:      Component vitals needed by the framework.
 * @spinlock:   Only one at a time pls.
 * @cpu:        The cpu this component is affined to.
 * @arch:       ETM version number.
 * @nr_pe:	The number of processing entity available for tracing.
 * @nr_pe_cmp:	The number of processing entity comparator inputs that are
 *		available for tracing.
 * @nr_addr_cmp:Number of pairs of address comparators available
 *		as found in ETMIDR4 0-3.
 * @nr_cntr:    Number of counters as found in ETMIDR5 bit 28-30.
 * @nr_ext_inp: Number of external input.
 * @numcidc:	Number of contextID comparators.
 * @numvmidc:	Number of VMID comparators.
 * @nrseqstate: The number of sequencer states that are implemented.
 * @nr_event:	Indicates how many events the trace unit support.
 * @nr_resource:The number of resource selection pairs available for tracing.
 * @nr_ss_cmp:	Number of single-shot comparator controls that are available.
 * @trcid:	value of the current ID for this component.
 * @trcid_size: Indicates the trace ID width.
 * @ts_size:	Global timestamp size field.
 * @ctxid_size:	Size of the context ID field to consider.
 * @vmid_size:	Size of the VM ID comparator to consider.
 * @ccsize:	Indicates the size of the cycle counter in bits.
 * @ccitmin:	minimum value that can be programmed in
 * @s_ex_level:	In secure state, indicates whether instruction tracing is
 *		supported for the corresponding Exception level.
 * @ns_ex_level:In non-secure state, indicates whether instruction tracing is
 *		supported for the corresponding Exception level.
 * @enable:	Is this ETM currently tracing.
 * @sticky_enable: true if ETM base configuration has been done.
 * @boot_enable:True if we should start tracing at boot time.
 * @os_unlock:  True if access to management registers is allowed.
 * @instrp0:	Tracing of load and store instructions
 *		as P0 elements is supported.
 * @trcbb:	Indicates if the trace unit supports branch broadcast tracing.
 * @trccond:	If the trace unit supports conditional
 *		instruction tracing.
 * @retstack:	Indicates if the implementation supports a return stack.
 * @trccci:	Indicates if the trace unit supports cycle counting
 *		for instruction.
 * @q_support:	Q element support characteristics.
 * @trc_error:	Whether a trace unit can trace a system
 *		error exception.
 * @syncpr:	Indicates if an implementation has a fixed
 *		synchronization period.
 * @stall_ctrl:	Enables trace unit functionality that prevents trace
 *		unit buffer overflows.
 * @sysstall:	Does the system support stall control of the PE?
 * @nooverflow:	Indicate if overflow prevention is supported.
 * @atbtrig:	If the implementation can support ATB triggers
 * @lpoverride:	If the implementation can support low-power state over.
 * @config:	structure holding configuration parameters.
 */
struct etmv4_drvdata {
	void __iomem			*base;
	struct device			*dev;
	struct coresight_device		*csdev;
	spinlock_t			spinlock;
	int				cpu;
	u8				arch;
	u8				nr_pe;
	u8				nr_pe_cmp;
	u8				nr_addr_cmp;
	u8				nr_cntr;
	u8				nr_ext_inp;
	u8				numcidc;
	u8				numvmidc;
	u8				nrseqstate;
	u8				nr_event;
	u8				nr_resource;
	u8				nr_ss_cmp;
	u8				trcid;
	u8				trcid_size;
	u8				ts_size;
	u8				ctxid_size;
	u8				vmid_size;
	u8				ccsize;
	u8				ccitmin;
	u8				s_ex_level;
	u8				ns_ex_level;
	u32				ext_inp;
	bool				enable;
	bool				sticky_enable;
	bool				boot_enable;
	bool				os_unlock;
	bool				instrp0;
	bool				trcbb;
	bool				trccond;
	bool				retstack;
	bool				trccci;
	bool				q_support;
	bool				trc_error;
	bool				syncpr;
	bool				stallctl;
	bool				sysstall;
	bool				nooverflow;
	bool				atbtrig;
	bool				lpoverride;
	struct etmv4_config		config;
};

/* Address comparator access types */