/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _CORESIGHT_CORESIGHT_TPDM_H #define _CORESIGHT_CORESIGHT_TPDM_H /* The max number of the datasets that TPDM supports */ #define TPDM_DATASETS 7 /* CMB Subunit Registers */ #define TPDM_CMB_CR (0xA00) /* CMB subunit timestamp insertion enable register */ #define TPDM_CMB_TIER (0xA04) /* CMB subunit timestamp pattern registers */ #define TPDM_CMB_TPR(n) (0xA08 + (n * 4)) /* CMB subunit timestamp pattern mask registers */ #define TPDM_CMB_TPMR(n) (0xA10 + (n * 4)) /* CMB subunit trigger pattern registers */ #define TPDM_CMB_XPR(n) (0xA18 + (n * 4)) /* CMB subunit trigger pattern mask registers */ #define TPDM_CMB_XPMR(n) (0xA20 + (n * 4)) /* CMB MSR register */ #define TPDM_CMB_MSR(n) (0xA80 + (n * 4)) /* Enable bit for CMB subunit */ #define TPDM_CMB_CR_ENA BIT(0) /* Trace collection mode for CMB subunit */ #define TPDM_CMB_CR_MODE BIT(1) /* Timestamp control for pattern match */ #define TPDM_CMB_TIER_PATT_TSENAB BIT(0) /* CMB CTI timestamp request */ #define TPDM_CMB_TIER_XTRIG_TSENAB BIT(1) /* For timestamp fo all trace */ #define TPDM_CMB_TIER_TS_ALL BIT(2) /* Patten register number */ #define TPDM_CMB_MAX_PATT 2 /* MAX number of DSB MSR */ #define TPDM_CMB_MAX_MSR 32 /* DSB Subunit Registers */ #define TPDM_DSB_CR (0x780) #define TPDM_DSB_TIER (0x784) #define TPDM_DSB_TPR(n) (0x788 + (n * 4)) #define TPDM_DSB_TPMR(n) (0x7A8 + (n * 4)) #define TPDM_DSB_XPR(n) (0x7C8 + (n * 4)) #define TPDM_DSB_XPMR(n) (0x7E8 + (n * 4)) #define TPDM_DSB_EDCR(n) (0x808 + (n * 4)) #define TPDM_DSB_EDCMR(n) (0x848 + (n * 4)) #define TPDM_DSB_MSR(n) (0x980 + (n * 4)) /* Enable bit for DSB subunit */ #define TPDM_DSB_CR_ENA BIT(0) /* Enable bit for DSB subunit perfmance mode */ #define TPDM_DSB_CR_MODE BIT(1) /* Enable bit for DSB subunit trigger type */ #define TPDM_DSB_CR_TRIG_TYPE BIT(12) /* Data bits for DSB high performace mode */ #define TPDM_DSB_CR_HPSEL GENMASK(6, 2) /* Data bits for DSB test mode */ #define TPDM_DSB_CR_TEST_MODE GENMASK(10, 9) /* Enable bit for DSB subunit pattern timestamp */ #define TPDM_DSB_TIER_PATT_TSENAB BIT(0) /* Enable bit for DSB subunit trigger timestamp */ #define TPDM_DSB_TIER_XTRIG_TSENAB BIT(1) /* Bit for DSB subunit pattern type */ #define TPDM_DSB_TIER_PATT_TYPE BIT(2) /* DSB programming modes */ /* DSB mode bits mask */ #define TPDM_DSB_MODE_MASK GENMASK(8, 0) /* Test mode control bit*/ #define TPDM_DSB_MODE_TEST(val) (val & GENMASK(1, 0)) /* Performance mode */ #define TPDM_DSB_MODE_PERF BIT(3) /* High performance mode */ #define TPDM_DSB_MODE_HPBYTESEL(val) (val & GENMASK(8, 4)) #define EDCRS_PER_WORD 16 #define EDCR_TO_WORD_IDX(r) ((r) / EDCRS_PER_WORD) #define EDCR_TO_WORD_SHIFT(r) ((r % EDCRS_PER_WORD) * 2) #define EDCR_TO_WORD_VAL(val, r) (val << EDCR_TO_WORD_SHIFT(r)) #define EDCR_TO_WORD_MASK(r) EDCR_TO_WORD_VAL(0x3, r) #define EDCMRS_PER_WORD 32 #define EDCMR_TO_WORD_IDX(r) ((r) / EDCMRS_PER_WORD) #define EDCMR_TO_WORD_SHIFT(r) ((r) % EDCMRS_PER_WORD) /* TPDM integration test registers */ #define TPDM_ITATBCNTRL (0xEF0) #define TPDM_ITCNTRL (0xF00) /* Register value for integration test */ #define ATBCNTRL_VAL_32 0xC00F1409 #define ATBCNTRL_VAL_64 0xC01F1409 /* * Number of cycles to write value when * integration test. */ #define INTEGRATION_TEST_CYCLE 10 /** * The bits of PERIPHIDR0 register. * The fields [6:0] of PERIPHIDR0 are used to determine what * interfaces and subunits are present on a given TPDM. * * PERIPHIDR0[0] : Fix to 1 if ImplDef subunit present, else 0 * PERIPHIDR0[1] : Fix to 1 if DSB subunit present, else 0 * PERIPHIDR0[2] : Fix to 1 if CMB subunit present, else 0 */ #define TPDM_PIDR0_DS_IMPDEF BIT(0) #define TPDM_PIDR0_DS_DSB BIT(1) #define TPDM_PIDR0_DS_CMB BIT(2) #define TPDM_DSB_MAX_LINES 256 /* MAX number of EDCR registers */ #define TPDM_DSB_MAX_EDCR 16 /* MAX number of EDCMR registers */ #define TPDM_DSB_MAX_EDCMR 8 /* MAX number of DSB pattern */ #define TPDM_DSB_MAX_PATT 8 /* MAX number of DSB MSR */ #define TPDM_DSB_MAX_MSR 32 #define tpdm_simple_dataset_ro(name, mem, idx) \ (&((struct tpdm_dataset_attribute[]) { \ { \ __ATTR(name, 0444, tpdm_simple_dataset_show, NULL), \ mem, \ idx, \ } \ })[0].attr.attr) #define tpdm_simple_dataset_rw(name, mem, idx) \ (&((struct tpdm_dataset_attribute[]) { \ { \ __ATTR(name, 0644, tpdm_simple_dataset_show, \ tpdm_simple_dataset_store), \ mem, \ idx, \ } \ })[0].attr.attr) #define tpdm_patt_enable_ts(name, mem) \ (&((struct tpdm_dataset_attribute[]) { \ { \ __ATTR(name, 0644, enable_ts_show, \ enable_ts_store), \ mem, \ 0, \ } \ })[0].attr.attr) #define DSB_EDGE_CTRL_ATTR(nr) \ tpdm_simple_dataset_ro(edcr##nr, \ DSB_EDGE_CTRL, nr) #define DSB_EDGE_CTRL_MASK_ATTR(nr) \ tpdm_simple_dataset_ro(edcmr##nr, \ DSB_EDGE_CTRL_MASK, nr) #define DSB_TRIG_PATT_ATTR(nr) \ tpdm_simple_dataset_rw(xpr##nr, \ DSB_TRIG_PATT, nr) #define DSB_TRIG_PATT_MASK_ATTR(nr) \ tpdm_simple_dataset_rw(xpmr##nr, \ DSB_TRIG_PATT_MASK, nr) #define DSB_PATT_ATTR(nr) \ tpdm_simple_dataset_rw(tpr##nr, \ DSB_PATT, nr) #define DSB_PATT_MASK_ATTR(nr) \ tpdm_simple_dataset_rw(tpmr##nr, \ DSB_PATT_MASK, nr) #define DSB_PATT_ENABLE_TS \ tpdm_patt_enable_ts(enable_ts, \ DSB_PATT) #define DSB_MSR_ATTR(nr) \ tpdm_simple_dataset_rw(msr##nr, \ DSB_MSR, nr) #define CMB_TRIG_PATT_ATTR(nr) \ tpdm_simple_dataset_rw(xpr##nr, \ CMB_TRIG_PATT, nr) #define CMB_TRIG_PATT_MASK_ATTR(nr) \ tpdm_simple_dataset_rw(xpmr##nr, \ CMB_TRIG_PATT_MASK, nr) #define CMB_PATT_ATTR(nr) \ tpdm_simple_dataset_rw(tpr##nr, \ CMB_PATT, nr) #define CMB_PATT_MASK_ATTR(nr) \ tpdm_simple_dataset_rw(tpmr##nr, \ CMB_PATT_MASK, nr) #define CMB_PATT_ENABLE_TS \ tpdm_patt_enable_ts(enable_ts, \ CMB_PATT) #define CMB_MSR_ATTR(nr) \ tpdm_simple_dataset_rw(msr##nr, \ CMB_MSR, nr) /** * struct dsb_dataset - specifics associated to dsb dataset * @mode: DSB programming mode * @edge_ctrl_idx Index number of the edge control * @edge_ctrl: Save value for edge control * @edge_ctrl_mask: Save value for edge control mask * @patt_val: Save value for pattern * @patt_mask: Save value for pattern mask * @trig_patt: Save value for trigger pattern * @trig_patt_mask: Save value for trigger pattern mask * @msr Save value for MSR * @patt_ts: Enable/Disable pattern timestamp * @patt_type: Set pattern type * @trig_ts: Enable/Disable trigger timestamp. * @trig_type: Enable/Disable trigger type. */ struct dsb_dataset { u32 mode; u32 edge_ctrl_idx; u32 edge_ctrl[TPDM_DSB_MAX_EDCR]; u32 edge_ctrl_mask[TPDM_DSB_MAX_EDCMR]; u32 patt_val[TPDM_DSB_MAX_PATT]; u32 patt_mask[TPDM_DSB_MAX_PATT]; u32 trig_patt[TPDM_DSB_MAX_PATT]; u32 trig_patt_mask[TPDM_DSB_MAX_PATT]; u32 msr[TPDM_DSB_MAX_MSR]; bool patt_ts; bool patt_type; bool trig_ts; bool trig_type; }; /** * struct cmb_dataset * @trace_mode: Dataset collection mode * @patt_val: Save value for pattern * @patt_mask: Save value for pattern mask * @trig_patt: Save value for trigger pattern * @trig_patt_mask: Save value for trigger pattern mask * @msr Save value for MSR * @patt_ts: Indicates if pattern match for timestamp is enabled. * @trig_ts: Indicates if CTI trigger for timestamp is enabled. * @ts_all: Indicates if timestamp is enabled for all packets. */ struct cmb_dataset { u32 trace_mode; u32 patt_val[TPDM_CMB_MAX_PATT]; u32 patt_mask[TPDM_CMB_MAX_PATT]; u32 trig_patt[TPDM_CMB_MAX_PATT]; u32 trig_patt_mask[TPDM_CMB_MAX_PATT]; u32 msr[TPDM_CMB_MAX_MSR]; bool patt_ts; bool trig_ts; bool ts_all; }; /** * struct tpdm_drvdata - specifics associated to an TPDM 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: lock for the drvdata value. * @enable: enable status of the component. * @datasets: The datasets types present of the TPDM. * @dsb Specifics associated to TPDM DSB. * @cmb Specifics associated to TPDM CMB. * @dsb_msr_num Number of MSR supported by DSB TPDM * @cmb_msr_num Number of MSR supported by CMB TPDM */ struct tpdm_drvdata { void __iomem *base; struct device *dev; struct coresight_device *csdev; spinlock_t spinlock; bool enable; unsigned long datasets; struct dsb_dataset *dsb; struct cmb_dataset *cmb; u32 dsb_msr_num; u32 cmb_msr_num; }; /* Enumerate members of various datasets */ enum dataset_mem { DSB_EDGE_CTRL, DSB_EDGE_CTRL_MASK, DSB_TRIG_PATT, DSB_TRIG_PATT_MASK, DSB_PATT, DSB_PATT_MASK, DSB_MSR, CMB_TRIG_PATT, CMB_TRIG_PATT_MASK, CMB_PATT, CMB_PATT_MASK, CMB_MSR }; /** * struct tpdm_dataset_attribute - Record the member variables and * index number of datasets that need to be operated by sysfs file * @attr: The device attribute * @mem: The member in the dataset data structure * @idx: The index number of the array data */ struct tpdm_dataset_attribute { struct device_attribute attr; enum dataset_mem mem; u32 idx; }; static bool tpdm_has_dsb_dataset(struct tpdm_drvdata *drvdata) { return (drvdata->datasets & TPDM_PIDR0_DS_DSB); } static bool tpdm_has_cmb_dataset(struct tpdm_drvdata *drvdata) { return (drvdata->datasets & TPDM_PIDR0_DS_CMB); } #endif /* _CORESIGHT_CORESIGHT_TPDM_H */