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

Commit a939fc5a authored by Pratik Patel's avatar Pratik Patel Committed by Greg Kroah-Hartman
Browse files

coresight-etm: add CoreSight ETM/PTM driver



This driver manages CoreSight ETM (Embedded Trace Macrocell) that
supports processor tracing. Currently supported version are ARM
ETMv3.x and PTM1.x.

Signed-off-by: default avatarPratik Patel <pratikp@codeaurora.org>
Signed-off-by: default avatarMathieu Poirier <mathieu.poirier@linaro.org>

coresight-etm3x: adding missing error checking
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent ceacc1d9
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -1376,5 +1376,14 @@ config CORESIGHT_SINK_ETBV10
	  This enables support for the Embedded Trace Buffer version 1.0 driver
	  that complies with the generic implementation of the component without
	  special enhancement or added features.

config CORESIGHT_SOURCE_ETM3X
	bool "CoreSight Embedded Trace Macrocell 3.x driver"
	select CORESIGHT_LINKS_AND_SINKS
	help
	  This driver provides support for processor ETM3.x and PTM1.x modules,
	  which allows tracing the instructions that a processor is executing
	  This is primarily useful for instruction level tracing.  Depending
	  the ETM version data tracing may also be available.
endif
endmenu
+542 −0

File added.

Preview size limit exceeded, changes collapsed.

+1 −0
Original line number Diff line number Diff line
@@ -8,3 +8,4 @@ obj-$(CONFIG_CORESIGHT_SINK_TPIU) += coresight-tpiu.o
obj-$(CONFIG_CORESIGHT_SINK_ETBV10) += coresight-etb10.o
obj-$(CONFIG_CORESIGHT_LINKS_AND_SINKS) += coresight-funnel.o \
					   coresight-replicator.o
obj-$(CONFIG_CORESIGHT_SOURCE_ETM3X) += coresight-etm3x.o coresight-etm-cp14.o
+591 −0
Original line number Diff line number Diff line
/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/bug.h>
#include <asm/hardware/cp14.h>

#include "coresight-etm.h"

int etm_readl_cp14(u32 reg, unsigned int *val)
{
	switch (reg) {
	case ETMCR:
		*val = etm_read(ETMCR);
		return 0;
	case ETMCCR:
		*val = etm_read(ETMCCR);
		return 0;
	case ETMTRIGGER:
		*val = etm_read(ETMTRIGGER);
		return 0;
	case ETMSR:
		*val = etm_read(ETMSR);
		return 0;
	case ETMSCR:
		*val = etm_read(ETMSCR);
		return 0;
	case ETMTSSCR:
		*val = etm_read(ETMTSSCR);
		return 0;
	case ETMTEEVR:
		*val = etm_read(ETMTEEVR);
		return 0;
	case ETMTECR1:
		*val = etm_read(ETMTECR1);
		return 0;
	case ETMFFLR:
		*val = etm_read(ETMFFLR);
		return 0;
	case ETMACVRn(0):
		*val = etm_read(ETMACVR0);
		return 0;
	case ETMACVRn(1):
		*val = etm_read(ETMACVR1);
		return 0;
	case ETMACVRn(2):
		*val = etm_read(ETMACVR2);
		return 0;
	case ETMACVRn(3):
		*val = etm_read(ETMACVR3);
		return 0;
	case ETMACVRn(4):
		*val = etm_read(ETMACVR4);
		return 0;
	case ETMACVRn(5):
		*val = etm_read(ETMACVR5);
		return 0;
	case ETMACVRn(6):
		*val = etm_read(ETMACVR6);
		return 0;
	case ETMACVRn(7):
		*val = etm_read(ETMACVR7);
		return 0;
	case ETMACVRn(8):
		*val = etm_read(ETMACVR8);
		return 0;
	case ETMACVRn(9):
		*val = etm_read(ETMACVR9);
		return 0;
	case ETMACVRn(10):
		*val = etm_read(ETMACVR10);
		return 0;
	case ETMACVRn(11):
		*val = etm_read(ETMACVR11);
		return 0;
	case ETMACVRn(12):
		*val = etm_read(ETMACVR12);
		return 0;
	case ETMACVRn(13):
		*val = etm_read(ETMACVR13);
		return 0;
	case ETMACVRn(14):
		*val = etm_read(ETMACVR14);
		return 0;
	case ETMACVRn(15):
		*val = etm_read(ETMACVR15);
		return 0;
	case ETMACTRn(0):
		*val = etm_read(ETMACTR0);
		return 0;
	case ETMACTRn(1):
		*val = etm_read(ETMACTR1);
		return 0;
	case ETMACTRn(2):
		*val = etm_read(ETMACTR2);
		return 0;
	case ETMACTRn(3):
		*val = etm_read(ETMACTR3);
		return 0;
	case ETMACTRn(4):
		*val = etm_read(ETMACTR4);
		return 0;
	case ETMACTRn(5):
		*val = etm_read(ETMACTR5);
		return 0;
	case ETMACTRn(6):
		*val = etm_read(ETMACTR6);
		return 0;
	case ETMACTRn(7):
		*val = etm_read(ETMACTR7);
		return 0;
	case ETMACTRn(8):
		*val = etm_read(ETMACTR8);
		return 0;
	case ETMACTRn(9):
		*val = etm_read(ETMACTR9);
		return 0;
	case ETMACTRn(10):
		*val = etm_read(ETMACTR10);
		return 0;
	case ETMACTRn(11):
		*val = etm_read(ETMACTR11);
		return 0;
	case ETMACTRn(12):
		*val = etm_read(ETMACTR12);
		return 0;
	case ETMACTRn(13):
		*val = etm_read(ETMACTR13);
		return 0;
	case ETMACTRn(14):
		*val = etm_read(ETMACTR14);
		return 0;
	case ETMACTRn(15):
		*val = etm_read(ETMACTR15);
		return 0;
	case ETMCNTRLDVRn(0):
		*val = etm_read(ETMCNTRLDVR0);
		return 0;
	case ETMCNTRLDVRn(1):
		*val = etm_read(ETMCNTRLDVR1);
		return 0;
	case ETMCNTRLDVRn(2):
		*val = etm_read(ETMCNTRLDVR2);
		return 0;
	case ETMCNTRLDVRn(3):
		*val = etm_read(ETMCNTRLDVR3);
		return 0;
	case ETMCNTENRn(0):
		*val = etm_read(ETMCNTENR0);
		return 0;
	case ETMCNTENRn(1):
		*val = etm_read(ETMCNTENR1);
		return 0;
	case ETMCNTENRn(2):
		*val = etm_read(ETMCNTENR2);
		return 0;
	case ETMCNTENRn(3):
		*val = etm_read(ETMCNTENR3);
		return 0;
	case ETMCNTRLDEVRn(0):
		*val = etm_read(ETMCNTRLDEVR0);
		return 0;
	case ETMCNTRLDEVRn(1):
		*val = etm_read(ETMCNTRLDEVR1);
		return 0;
	case ETMCNTRLDEVRn(2):
		*val = etm_read(ETMCNTRLDEVR2);
		return 0;
	case ETMCNTRLDEVRn(3):
		*val = etm_read(ETMCNTRLDEVR3);
		return 0;
	case ETMCNTVRn(0):
		*val = etm_read(ETMCNTVR0);
		return 0;
	case ETMCNTVRn(1):
		*val = etm_read(ETMCNTVR1);
		return 0;
	case ETMCNTVRn(2):
		*val = etm_read(ETMCNTVR2);
		return 0;
	case ETMCNTVRn(3):
		*val = etm_read(ETMCNTVR3);
		return 0;
	case ETMSQ12EVR:
		*val = etm_read(ETMSQ12EVR);
		return 0;
	case ETMSQ21EVR:
		*val = etm_read(ETMSQ21EVR);
		return 0;
	case ETMSQ23EVR:
		*val = etm_read(ETMSQ23EVR);
		return 0;
	case ETMSQ31EVR:
		*val = etm_read(ETMSQ31EVR);
		return 0;
	case ETMSQ32EVR:
		*val = etm_read(ETMSQ32EVR);
		return 0;
	case ETMSQ13EVR:
		*val = etm_read(ETMSQ13EVR);
		return 0;
	case ETMSQR:
		*val = etm_read(ETMSQR);
		return 0;
	case ETMEXTOUTEVRn(0):
		*val = etm_read(ETMEXTOUTEVR0);
		return 0;
	case ETMEXTOUTEVRn(1):
		*val = etm_read(ETMEXTOUTEVR1);
		return 0;
	case ETMEXTOUTEVRn(2):
		*val = etm_read(ETMEXTOUTEVR2);
		return 0;
	case ETMEXTOUTEVRn(3):
		*val = etm_read(ETMEXTOUTEVR3);
		return 0;
	case ETMCIDCVRn(0):
		*val = etm_read(ETMCIDCVR0);
		return 0;
	case ETMCIDCVRn(1):
		*val = etm_read(ETMCIDCVR1);
		return 0;
	case ETMCIDCVRn(2):
		*val = etm_read(ETMCIDCVR2);
		return 0;
	case ETMCIDCMR:
		*val = etm_read(ETMCIDCMR);
		return 0;
	case ETMIMPSPEC0:
		*val = etm_read(ETMIMPSPEC0);
		return 0;
	case ETMIMPSPEC1:
		*val = etm_read(ETMIMPSPEC1);
		return 0;
	case ETMIMPSPEC2:
		*val = etm_read(ETMIMPSPEC2);
		return 0;
	case ETMIMPSPEC3:
		*val = etm_read(ETMIMPSPEC3);
		return 0;
	case ETMIMPSPEC4:
		*val = etm_read(ETMIMPSPEC4);
		return 0;
	case ETMIMPSPEC5:
		*val = etm_read(ETMIMPSPEC5);
		return 0;
	case ETMIMPSPEC6:
		*val = etm_read(ETMIMPSPEC6);
		return 0;
	case ETMIMPSPEC7:
		*val = etm_read(ETMIMPSPEC7);
		return 0;
	case ETMSYNCFR:
		*val = etm_read(ETMSYNCFR);
		return 0;
	case ETMIDR:
		*val = etm_read(ETMIDR);
		return 0;
	case ETMCCER:
		*val = etm_read(ETMCCER);
		return 0;
	case ETMEXTINSELR:
		*val = etm_read(ETMEXTINSELR);
		return 0;
	case ETMTESSEICR:
		*val = etm_read(ETMTESSEICR);
		return 0;
	case ETMEIBCR:
		*val = etm_read(ETMEIBCR);
		return 0;
	case ETMTSEVR:
		*val = etm_read(ETMTSEVR);
		return 0;
	case ETMAUXCR:
		*val = etm_read(ETMAUXCR);
		return 0;
	case ETMTRACEIDR:
		*val = etm_read(ETMTRACEIDR);
		return 0;
	case ETMVMIDCVR:
		*val = etm_read(ETMVMIDCVR);
		return 0;
	case ETMOSLSR:
		*val = etm_read(ETMOSLSR);
		return 0;
	case ETMOSSRR:
		*val = etm_read(ETMOSSRR);
		return 0;
	case ETMPDCR:
		*val = etm_read(ETMPDCR);
		return 0;
	case ETMPDSR:
		*val = etm_read(ETMPDSR);
		return 0;
	default:
		*val = 0;
		return -EINVAL;
	}
}

int etm_writel_cp14(u32 reg, u32 val)
{
	switch (reg) {
	case ETMCR:
		etm_write(val, ETMCR);
		break;
	case ETMTRIGGER:
		etm_write(val, ETMTRIGGER);
		break;
	case ETMSR:
		etm_write(val, ETMSR);
		break;
	case ETMTSSCR:
		etm_write(val, ETMTSSCR);
		break;
	case ETMTEEVR:
		etm_write(val, ETMTEEVR);
		break;
	case ETMTECR1:
		etm_write(val, ETMTECR1);
		break;
	case ETMFFLR:
		etm_write(val, ETMFFLR);
		break;
	case ETMACVRn(0):
		etm_write(val, ETMACVR0);
		break;
	case ETMACVRn(1):
		etm_write(val, ETMACVR1);
		break;
	case ETMACVRn(2):
		etm_write(val, ETMACVR2);
		break;
	case ETMACVRn(3):
		etm_write(val, ETMACVR3);
		break;
	case ETMACVRn(4):
		etm_write(val, ETMACVR4);
		break;
	case ETMACVRn(5):
		etm_write(val, ETMACVR5);
		break;
	case ETMACVRn(6):
		etm_write(val, ETMACVR6);
		break;
	case ETMACVRn(7):
		etm_write(val, ETMACVR7);
		break;
	case ETMACVRn(8):
		etm_write(val, ETMACVR8);
		break;
	case ETMACVRn(9):
		etm_write(val, ETMACVR9);
		break;
	case ETMACVRn(10):
		etm_write(val, ETMACVR10);
		break;
	case ETMACVRn(11):
		etm_write(val, ETMACVR11);
		break;
	case ETMACVRn(12):
		etm_write(val, ETMACVR12);
		break;
	case ETMACVRn(13):
		etm_write(val, ETMACVR13);
		break;
	case ETMACVRn(14):
		etm_write(val, ETMACVR14);
		break;
	case ETMACVRn(15):
		etm_write(val, ETMACVR15);
		break;
	case ETMACTRn(0):
		etm_write(val, ETMACTR0);
		break;
	case ETMACTRn(1):
		etm_write(val, ETMACTR1);
		break;
	case ETMACTRn(2):
		etm_write(val, ETMACTR2);
		break;
	case ETMACTRn(3):
		etm_write(val, ETMACTR3);
		break;
	case ETMACTRn(4):
		etm_write(val, ETMACTR4);
		break;
	case ETMACTRn(5):
		etm_write(val, ETMACTR5);
		break;
	case ETMACTRn(6):
		etm_write(val, ETMACTR6);
		break;
	case ETMACTRn(7):
		etm_write(val, ETMACTR7);
		break;
	case ETMACTRn(8):
		etm_write(val, ETMACTR8);
		break;
	case ETMACTRn(9):
		etm_write(val, ETMACTR9);
		break;
	case ETMACTRn(10):
		etm_write(val, ETMACTR10);
		break;
	case ETMACTRn(11):
		etm_write(val, ETMACTR11);
		break;
	case ETMACTRn(12):
		etm_write(val, ETMACTR12);
		break;
	case ETMACTRn(13):
		etm_write(val, ETMACTR13);
		break;
	case ETMACTRn(14):
		etm_write(val, ETMACTR14);
		break;
	case ETMACTRn(15):
		etm_write(val, ETMACTR15);
		break;
	case ETMCNTRLDVRn(0):
		etm_write(val, ETMCNTRLDVR0);
		break;
	case ETMCNTRLDVRn(1):
		etm_write(val, ETMCNTRLDVR1);
		break;
	case ETMCNTRLDVRn(2):
		etm_write(val, ETMCNTRLDVR2);
		break;
	case ETMCNTRLDVRn(3):
		etm_write(val, ETMCNTRLDVR3);
		break;
	case ETMCNTENRn(0):
		etm_write(val, ETMCNTENR0);
		break;
	case ETMCNTENRn(1):
		etm_write(val, ETMCNTENR1);
		break;
	case ETMCNTENRn(2):
		etm_write(val, ETMCNTENR2);
		break;
	case ETMCNTENRn(3):
		etm_write(val, ETMCNTENR3);
		break;
	case ETMCNTRLDEVRn(0):
		etm_write(val, ETMCNTRLDEVR0);
		break;
	case ETMCNTRLDEVRn(1):
		etm_write(val, ETMCNTRLDEVR1);
		break;
	case ETMCNTRLDEVRn(2):
		etm_write(val, ETMCNTRLDEVR2);
		break;
	case ETMCNTRLDEVRn(3):
		etm_write(val, ETMCNTRLDEVR3);
		break;
	case ETMCNTVRn(0):
		etm_write(val, ETMCNTVR0);
		break;
	case ETMCNTVRn(1):
		etm_write(val, ETMCNTVR1);
		break;
	case ETMCNTVRn(2):
		etm_write(val, ETMCNTVR2);
		break;
	case ETMCNTVRn(3):
		etm_write(val, ETMCNTVR3);
		break;
	case ETMSQ12EVR:
		etm_write(val, ETMSQ12EVR);
		break;
	case ETMSQ21EVR:
		etm_write(val, ETMSQ21EVR);
		break;
	case ETMSQ23EVR:
		etm_write(val, ETMSQ23EVR);
		break;
	case ETMSQ31EVR:
		etm_write(val, ETMSQ31EVR);
		break;
	case ETMSQ32EVR:
		etm_write(val, ETMSQ32EVR);
		break;
	case ETMSQ13EVR:
		etm_write(val, ETMSQ13EVR);
		break;
	case ETMSQR:
		etm_write(val, ETMSQR);
		break;
	case ETMEXTOUTEVRn(0):
		etm_write(val, ETMEXTOUTEVR0);
		break;
	case ETMEXTOUTEVRn(1):
		etm_write(val, ETMEXTOUTEVR1);
		break;
	case ETMEXTOUTEVRn(2):
		etm_write(val, ETMEXTOUTEVR2);
		break;
	case ETMEXTOUTEVRn(3):
		etm_write(val, ETMEXTOUTEVR3);
		break;
	case ETMCIDCVRn(0):
		etm_write(val, ETMCIDCVR0);
		break;
	case ETMCIDCVRn(1):
		etm_write(val, ETMCIDCVR1);
		break;
	case ETMCIDCVRn(2):
		etm_write(val, ETMCIDCVR2);
		break;
	case ETMCIDCMR:
		etm_write(val, ETMCIDCMR);
		break;
	case ETMIMPSPEC0:
		etm_write(val, ETMIMPSPEC0);
		break;
	case ETMIMPSPEC1:
		etm_write(val, ETMIMPSPEC1);
		break;
	case ETMIMPSPEC2:
		etm_write(val, ETMIMPSPEC2);
		break;
	case ETMIMPSPEC3:
		etm_write(val, ETMIMPSPEC3);
		break;
	case ETMIMPSPEC4:
		etm_write(val, ETMIMPSPEC4);
		break;
	case ETMIMPSPEC5:
		etm_write(val, ETMIMPSPEC5);
		break;
	case ETMIMPSPEC6:
		etm_write(val, ETMIMPSPEC6);
		break;
	case ETMIMPSPEC7:
		etm_write(val, ETMIMPSPEC7);
		break;
	case ETMSYNCFR:
		etm_write(val, ETMSYNCFR);
		break;
	case ETMEXTINSELR:
		etm_write(val, ETMEXTINSELR);
		break;
	case ETMTESSEICR:
		etm_write(val, ETMTESSEICR);
		break;
	case ETMEIBCR:
		etm_write(val, ETMEIBCR);
		break;
	case ETMTSEVR:
		etm_write(val, ETMTSEVR);
		break;
	case ETMAUXCR:
		etm_write(val, ETMAUXCR);
		break;
	case ETMTRACEIDR:
		etm_write(val, ETMTRACEIDR);
		break;
	case ETMVMIDCVR:
		etm_write(val, ETMVMIDCVR);
		break;
	case ETMOSLAR:
		etm_write(val, ETMOSLAR);
		break;
	case ETMOSSRR:
		etm_write(val, ETMOSSRR);
		break;
	case ETMPDCR:
		etm_write(val, ETMPDCR);
		break;
	case ETMPDSR:
		etm_write(val, ETMPDSR);
		break;
	default:
		return -EINVAL;
	}

	return 0;
}
+251 −0
Original line number Diff line number Diff line
/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#ifndef _CORESIGHT_CORESIGHT_ETM_H
#define _CORESIGHT_CORESIGHT_ETM_H

#include <linux/spinlock.h>
#include "coresight-priv.h"

/*
 * Device registers:
 * 0x000 - 0x2FC: Trace         registers
 * 0x300 - 0x314: Management    registers
 * 0x318 - 0xEFC: Trace         registers
 *
 * Coresight registers
 * 0xF00 - 0xF9C: Management    registers
 * 0xFA0 - 0xFA4: Management    registers in PFTv1.0
 *                Trace         registers in PFTv1.1
 * 0xFA8 - 0xFFC: Management    registers
 */

/* Trace registers (0x000-0x2FC) */
#define ETMCR			0x000
#define ETMCCR			0x004
#define ETMTRIGGER		0x008
#define ETMSR			0x010
#define ETMSCR			0x014
#define ETMTSSCR		0x018
#define ETMTECR2		0x01c
#define ETMTEEVR		0x020
#define ETMTECR1		0x024
#define ETMFFLR			0x02c
#define ETMACVRn(n)		(0x040 + (n * 4))
#define ETMACTRn(n)		(0x080 + (n * 4))
#define ETMCNTRLDVRn(n)		(0x140 + (n * 4))
#define ETMCNTENRn(n)		(0x150 + (n * 4))
#define ETMCNTRLDEVRn(n)	(0x160 + (n * 4))
#define ETMCNTVRn(n)		(0x170 + (n * 4))
#define ETMSQ12EVR		0x180
#define ETMSQ21EVR		0x184
#define ETMSQ23EVR		0x188
#define ETMSQ31EVR		0x18c
#define ETMSQ32EVR		0x190
#define ETMSQ13EVR		0x194
#define ETMSQR			0x19c
#define ETMEXTOUTEVRn(n)	(0x1a0 + (n * 4))
#define ETMCIDCVRn(n)		(0x1b0 + (n * 4))
#define ETMCIDCMR		0x1bc
#define ETMIMPSPEC0		0x1c0
#define ETMIMPSPEC1		0x1c4
#define ETMIMPSPEC2		0x1c8
#define ETMIMPSPEC3		0x1cc
#define ETMIMPSPEC4		0x1d0
#define ETMIMPSPEC5		0x1d4
#define ETMIMPSPEC6		0x1d8
#define ETMIMPSPEC7		0x1dc
#define ETMSYNCFR		0x1e0
#define ETMIDR			0x1e4
#define ETMCCER			0x1e8
#define ETMEXTINSELR		0x1ec
#define ETMTESSEICR		0x1f0
#define ETMEIBCR		0x1f4
#define ETMTSEVR		0x1f8
#define ETMAUXCR		0x1fc
#define ETMTRACEIDR		0x200
#define ETMVMIDCVR		0x240
/* Management registers (0x300-0x314) */
#define ETMOSLAR		0x300
#define ETMOSLSR		0x304
#define ETMOSSRR		0x308
#define ETMPDCR			0x310
#define ETMPDSR			0x314
#define ETM_MAX_ADDR_CMP	16
#define ETM_MAX_CNTR		4
#define ETM_MAX_CTXID_CMP	3

/* Register definition */
/* ETMCR - 0x00 */
#define ETMCR_PWD_DWN		BIT(0)
#define ETMCR_STALL_MODE	BIT(7)
#define ETMCR_ETM_PRG		BIT(10)
#define ETMCR_ETM_EN		BIT(11)
#define ETMCR_CYC_ACC		BIT(12)
#define ETMCR_CTXID_SIZE	(BIT(14)|BIT(15))
#define ETMCR_TIMESTAMP_EN	BIT(28)
/* ETMCCR - 0x04 */
#define ETMCCR_FIFOFULL		BIT(23)
/* ETMPDCR - 0x310 */
#define ETMPDCR_PWD_UP		BIT(3)
/* ETMTECR1 - 0x024 */
#define ETMTECR1_ADDR_COMP_1	BIT(0)
#define ETMTECR1_INC_EXC	BIT(24)
#define ETMTECR1_START_STOP	BIT(25)
/* ETMCCER - 0x1E8 */
#define ETMCCER_TIMESTAMP	BIT(22)

#define ETM_MODE_EXCLUDE	BIT(0)
#define ETM_MODE_CYCACC		BIT(1)
#define ETM_MODE_STALL		BIT(2)
#define ETM_MODE_TIMESTAMP	BIT(3)
#define ETM_MODE_CTXID		BIT(4)
#define ETM_MODE_ALL		0x1f

#define ETM_SQR_MASK		0x3
#define ETM_TRACEID_MASK	0x3f
#define ETM_EVENT_MASK		0x1ffff
#define ETM_SYNC_MASK		0xfff
#define ETM_ALL_MASK		0xffffffff

#define ETMSR_PROG_BIT		1
#define ETM_SEQ_STATE_MAX_VAL	(0x2)
#define PORT_SIZE_MASK		(GENMASK(21, 21) | GENMASK(6, 4))

#define ETM_HARD_WIRE_RES_A	/* Hard wired, always true */	\
				((0x0f << 0)	|		\
				/* Resource index A */		\
				(0x06 << 4))

#define ETM_ADD_COMP_0		/* Single addr comparator 1 */	\
				((0x00 << 7)	|		\
				/* Resource index B */		\
				(0x00 << 11))

#define ETM_EVENT_NOT_A		BIT(14) /* NOT(A) */

#define ETM_DEFAULT_EVENT_VAL	(ETM_HARD_WIRE_RES_A	|	\
				 ETM_ADD_COMP_0		|	\
				 ETM_EVENT_NOT_A)
/**
 * struct etm_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.
 * @clk:	the clock this component is associated to.
 * @spinlock:	only one at a time pls.
 * @cpu:	the cpu this component is affined to.
 * @port_size:	port size as reported by ETMCR bit 4-6 and 21.
 * @arch:	ETM/PTM version number.
 * @use_cpu14:	true if management registers need to be accessed via CP14.
 * @enable:	is this ETM/PTM 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_addr_cmp:Number of pairs of address comparators as found in ETMCCR.
 * @nr_cntr:	Number of counters as found in ETMCCR bit 13-15.
 * @nr_ext_inp:	Number of external input as found in ETMCCR bit 17-19.
 * @nr_ext_out:	Number of external output as found in ETMCCR bit 20-22.
 * @nr_ctxid_cmp: Number of contextID comparators as found in ETMCCR bit 24-25.
 * @etmccr:	value of register ETMCCR.
 * @etmccer:	value of register ETMCCER.
 * @traceid:	value of the current ID for this component.
 * @mode:	controls various modes supported by this ETM/PTM.
 * @ctrl:	used in conjunction with @mode.
 * @trigger_event: setting for register ETMTRIGGER.
 * @startstop_ctrl: setting for register ETMTSSCR.
 * @enable_event: setting for register ETMTEEVR.
 * @enable_ctrl1: setting for register ETMTECR1.
 * @fifofull_level: setting for register ETMFFLR.
 * @addr_idx:	index for the address comparator selection.
 * @addr_val:	value for address comparator register.
 * @addr_acctype: access type for address comparator register.
 * @addr_type:	current status of the comparator register.
 * @cntr_idx:	index for the counter register selection.
 * @cntr_rld_val: reload value of a counter register.
 * @cntr_event:	control for counter enable register.
 * @cntr_rld_event: value for counter reload event register.
 * @cntr_val:	counter value register.
 * @seq_12_event: event causing the transition from 1 to 2.
 * @seq_21_event: event causing the transition from 2 to 1.
 * @seq_23_event: event causing the transition from 2 to 3.
 * @seq_31_event: event causing the transition from 3 to 1.
 * @seq_32_event: event causing the transition from 3 to 2.
 * @seq_13_event: event causing the transition from 1 to 3.
 * @seq_curr_state: current value of the sequencer register.
 * @ctxid_idx: index for the context ID registers.
 * @ctxid_val: value for the context ID to trigger on.
 * @ctxid_mask: mask applicable to all the context IDs.
 * @sync_freq:	Synchronisation frequency.
 * @timestamp_event: Defines an event that requests the insertion
		     of a timestamp into the trace stream.
 */
struct etm_drvdata {
	void __iomem			*base;
	struct device			*dev;
	struct coresight_device		*csdev;
	struct clk			*clk;
	spinlock_t			spinlock;
	int				cpu;
	int				port_size;
	u8				arch;
	bool				use_cp14;
	bool				enable;
	bool				sticky_enable;
	bool				boot_enable;
	bool				os_unlock;
	u8				nr_addr_cmp;
	u8				nr_cntr;
	u8				nr_ext_inp;
	u8				nr_ext_out;
	u8				nr_ctxid_cmp;
	u32				etmccr;
	u32				etmccer;
	u32				traceid;
	u32				mode;
	u32				ctrl;
	u32				trigger_event;
	u32				startstop_ctrl;
	u32				enable_event;
	u32				enable_ctrl1;
	u32				fifofull_level;
	u8				addr_idx;
	u32				addr_val[ETM_MAX_ADDR_CMP];
	u32				addr_acctype[ETM_MAX_ADDR_CMP];
	u32				addr_type[ETM_MAX_ADDR_CMP];
	u8				cntr_idx;
	u32				cntr_rld_val[ETM_MAX_CNTR];
	u32				cntr_event[ETM_MAX_CNTR];
	u32				cntr_rld_event[ETM_MAX_CNTR];
	u32				cntr_val[ETM_MAX_CNTR];
	u32				seq_12_event;
	u32				seq_21_event;
	u32				seq_23_event;
	u32				seq_31_event;
	u32				seq_32_event;
	u32				seq_13_event;
	u32				seq_curr_state;
	u8				ctxid_idx;
	u32				ctxid_val[ETM_MAX_CTXID_CMP];
	u32				ctxid_mask;
	u32				sync_freq;
	u32				timestamp_event;
};

enum etm_addr_type {
	ETM_ADDR_TYPE_NONE,
	ETM_ADDR_TYPE_SINGLE,
	ETM_ADDR_TYPE_RANGE,
	ETM_ADDR_TYPE_START,
	ETM_ADDR_TYPE_STOP,
};
#endif
Loading