diff options
Diffstat (limited to 'drivers/platform/mellanox/mlxbf-pmc.c')
| -rw-r--r-- | drivers/platform/mellanox/mlxbf-pmc.c | 741 | 
1 files changed, 682 insertions, 59 deletions
| diff --git a/drivers/platform/mellanox/mlxbf-pmc.c b/drivers/platform/mellanox/mlxbf-pmc.c index be967d797c28..1dd84c7a79de 100644 --- a/drivers/platform/mellanox/mlxbf-pmc.c +++ b/drivers/platform/mellanox/mlxbf-pmc.c @@ -30,14 +30,16 @@  #define MLXBF_PMC_EVENT_SET_BF1 0  #define MLXBF_PMC_EVENT_SET_BF2 1 +#define MLXBF_PMC_EVENT_SET_BF3 2  #define MLXBF_PMC_EVENT_INFO_LEN 100  #define MLXBF_PMC_MAX_BLOCKS 30 -#define MLXBF_PMC_MAX_ATTRS 30 +#define MLXBF_PMC_MAX_ATTRS 70  #define MLXBF_PMC_INFO_SZ 4  #define MLXBF_PMC_REG_SIZE 8  #define MLXBF_PMC_L3C_REG_SIZE 4 +#define MLXBF_PMC_TYPE_CRSPACE 2  #define MLXBF_PMC_TYPE_COUNTER 1  #define MLXBF_PMC_TYPE_REGISTER 0 @@ -78,6 +80,16 @@  #define MLXBF_PMC_L3C_PERF_CNT_LOW_VAL GENMASK(31, 0)  #define MLXBF_PMC_L3C_PERF_CNT_HIGH_VAL GENMASK(24, 0) +#define MLXBF_PMC_CRSPACE_PERFMON_REG0 0x0 +#define MLXBF_PMC_CRSPACE_PERFSEL_SZ 4 +#define MLXBF_PMC_CRSPACE_PERFSEL0 GENMASK(23, 16) +#define MLXBF_PMC_CRSPACE_PERFSEL1 GENMASK(7, 0) +#define MLXBF_PMC_CRSPACE_PERFMON_REG0_SZ 0x2 +#define MLXBF_PMC_CRSPACE_PERFMON_CTL(n) (n * MLXBF_PMC_CRSPACE_PERFMON_REG0_SZ) +#define MLXBF_PMC_CRSPACE_PERFMON_EN BIT(30) +#define MLXBF_PMC_CRSPACE_PERFMON_CLR BIT(28) +#define MLXBF_PMC_CRSPACE_PERFMON_VAL0(n) (MLXBF_PMC_CRSPACE_PERFMON_CTL(n) + 0xc) +  /**   * struct mlxbf_pmc_attribute - Structure to hold attribute and block info   * for each sysfs entry @@ -124,6 +136,9 @@ struct mlxbf_pmc_block_info {   * @pdev: The kernel structure representing the device   * @total_blocks: Total number of blocks   * @tile_count: Number of tiles in the system + * @llt_enable: Info on enabled LLTs + * @mss_enable: Info on enabled MSSs + * @group_num: Group number assigned to each valid block   * @hwmon_dev: Hwmon device for bfperf   * @block_name: Block name   * @block:  Block info @@ -136,6 +151,9 @@ struct mlxbf_pmc_context {  	struct platform_device *pdev;  	uint32_t total_blocks;  	uint32_t tile_count; +	uint8_t llt_enable; +	uint8_t mss_enable; +	uint32_t group_num;  	struct device *hwmon_dev;  	const char *block_name[MLXBF_PMC_MAX_BLOCKS];  	struct mlxbf_pmc_block_info block[MLXBF_PMC_MAX_BLOCKS]; @@ -191,6 +209,7 @@ static const struct mlxbf_pmc_events mlxbf_pmc_smgen_events[] = {  };  static const struct mlxbf_pmc_events mlxbf_pmc_trio_events_1[] = { +	{ 0x0, "DISABLE" },  	{ 0xa0, "TPIO_DATA_BEAT" },  	{ 0xa1, "TDMA_DATA_BEAT" },  	{ 0xa2, "MAP_DATA_BEAT" }, @@ -214,6 +233,7 @@ static const struct mlxbf_pmc_events mlxbf_pmc_trio_events_1[] = {  };  static const struct mlxbf_pmc_events mlxbf_pmc_trio_events_2[] = { +	{ 0x0, "DISABLE" },  	{ 0xa0, "TPIO_DATA_BEAT" },  	{ 0xa1, "TDMA_DATA_BEAT" },  	{ 0xa2, "MAP_DATA_BEAT" }, @@ -246,6 +266,7 @@ static const struct mlxbf_pmc_events mlxbf_pmc_trio_events_2[] = {  };  static const struct mlxbf_pmc_events mlxbf_pmc_ecc_events[] = { +	{ 0x0, "DISABLE" },  	{ 0x100, "ECC_SINGLE_ERROR_CNT" },  	{ 0x104, "ECC_DOUBLE_ERROR_CNT" },  	{ 0x114, "SERR_INJ" }, @@ -257,14 +278,174 @@ static const struct mlxbf_pmc_events mlxbf_pmc_ecc_events[] = {  	{ 0x348, "DRAM_ECC_ERROR" },  }; -static const struct mlxbf_pmc_events mlxbf_pmc_mss_events[] = { +static const struct mlxbf_pmc_events mlxbf_pmc_mss_events_1[] = { +	{ 0x0, "DISABLE" },  	{ 0xc0, "RXREQ_MSS" },  	{ 0xc1, "RXDAT_MSS" },  	{ 0xc2, "TXRSP_MSS" },  	{ 0xc3, "TXDAT_MSS" },  }; +static const struct mlxbf_pmc_events mlxbf_pmc_mss_events_3[] = { +	{0, "SKYLIB_CDN_TX_FLITS"}, +	{1, "SKYLIB_DDN_TX_FLITS"}, +	{2, "SKYLIB_NDN_TX_FLITS"}, +	{3, "SKYLIB_SDN_TX_FLITS"}, +	{4, "SKYLIB_UDN_TX_FLITS"}, +	{5, "SKYLIB_CDN_RX_FLITS"}, +	{6, "SKYLIB_DDN_RX_FLITS"}, +	{7, "SKYLIB_NDN_RX_FLITS"}, +	{8, "SKYLIB_SDN_RX_FLITS"}, +	{9, "SKYLIB_UDN_RX_FLITS"}, +	{10, "SKYLIB_CDN_TX_STALL"}, +	{11, "SKYLIB_DDN_TX_STALL"}, +	{12, "SKYLIB_NDN_TX_STALL"}, +	{13, "SKYLIB_SDN_TX_STALL"}, +	{14, "SKYLIB_UDN_TX_STALL"}, +	{15, "SKYLIB_CDN_RX_STALL"}, +	{16, "SKYLIB_DDN_RX_STALL"}, +	{17, "SKYLIB_NDN_RX_STALL"}, +	{18, "SKYLIB_SDN_RX_STALL"}, +	{19, "SKYLIB_UDN_RX_STALL"}, +	{20, "SKYLIB_CHI_REQ0_TX_FLITS"}, +	{21, "SKYLIB_CHI_DATA0_TX_FLITS"}, +	{22, "SKYLIB_CHI_RESP0_TX_FLITS"}, +	{23, "SKYLIB_CHI_SNP0_TX_FLITS"}, +	{24, "SKYLIB_CHI_REQ1_TX_FLITS"}, +	{25, "SKYLIB_CHI_DATA1_TX_FLITS"}, +	{26, "SKYLIB_CHI_RESP1_TX_FLITS"}, +	{27, "SKYLIB_CHI_SNP1_TX_FLITS"}, +	{28, "SKYLIB_CHI_REQ2_TX_FLITS"}, +	{29, "SKYLIB_CHI_DATA2_TX_FLITS"}, +	{30, "SKYLIB_CHI_RESP2_TX_FLITS"}, +	{31, "SKYLIB_CHI_SNP2_TX_FLITS"}, +	{32, "SKYLIB_CHI_REQ3_TX_FLITS"}, +	{33, "SKYLIB_CHI_DATA3_TX_FLITS"}, +	{34, "SKYLIB_CHI_RESP3_TX_FLITS"}, +	{35, "SKYLIB_CHI_SNP3_TX_FLITS"}, +	{36, "SKYLIB_TLP_REQ_TX_FLITS"}, +	{37, "SKYLIB_TLP_RESP_TX_FLITS"}, +	{38, "SKYLIB_TLP_META_TX_FLITS"}, +	{39, "SKYLIB_AXIS_DATA_TX_FLITS"}, +	{40, "SKYLIB_AXIS_CRED_TX_FLITS"}, +	{41, "SKYLIB_APB_TX_FLITS"}, +	{42, "SKYLIB_VW_TX_FLITS"}, +	{43, "SKYLIB_GGA_MSN_W_TX_FLITS"}, +	{44, "SKYLIB_GGA_MSN_N_TX_FLITS"}, +	{45, "SKYLIB_CR_REQ_TX_FLITS"}, +	{46, "SKYLIB_CR_RESP_TX_FLITS"}, +	{47, "SKYLIB_MSN_PRNF_TX_FLITS"}, +	{48, "SKYLIB_DBG_DATA_TX_FLITS"}, +	{49, "SKYLIB_DBG_CRED_TX_FLITS"}, +	{50, "SKYLIB_CHI_REQ0_RX_FLITS"}, +	{51, "SKYLIB_CHI_DATA0_RX_FLITS"}, +	{52, "SKYLIB_CHI_RESP0_RX_FLITS"}, +	{53, "SKYLIB_CHI_SNP0_RX_FLITS"}, +	{54, "SKYLIB_CHI_REQ1_RX_FLITS"}, +	{55, "SKYLIB_CHI_DATA1_RX_FLITS"}, +	{56, "SKYLIB_CHI_RESP1_RX_FLITS"}, +	{57, "SKYLIB_CHI_SNP1_RX_FLITS"}, +	{58, "SKYLIB_CHI_REQ2_RX_FLITS"}, +	{59, "SKYLIB_CHI_DATA2_RX_FLITS"}, +	{60, "SKYLIB_CHI_RESP2_RX_FLITS"}, +	{61, "SKYLIB_CHI_SNP2_RX_FLITS"}, +	{62, "SKYLIB_CHI_REQ3_RX_FLITS"}, +	{63, "SKYLIB_CHI_DATA3_RX_FLITS"}, +	{64, "SKYLIB_CHI_RESP3_RX_FLITS"}, +	{65, "SKYLIB_CHI_SNP3_RX_FLITS"}, +	{66, "SKYLIB_TLP_REQ_RX_FLITS"}, +	{67, "SKYLIB_TLP_RESP_RX_FLITS"}, +	{68, "SKYLIB_TLP_META_RX_FLITS"}, +	{69, "SKYLIB_AXIS_DATA_RX_FLITS"}, +	{70, "SKYLIB_AXIS_CRED_RX_FLITS"}, +	{71, "SKYLIB_APB_RX_FLITS"}, +	{72, "SKYLIB_VW_RX_FLITS"}, +	{73, "SKYLIB_GGA_MSN_W_RX_FLITS"}, +	{74, "SKYLIB_GGA_MSN_N_RX_FLITS"}, +	{75, "SKYLIB_CR_REQ_RX_FLITS"}, +	{76, "SKYLIB_CR_RESP_RX_FLITS"}, +	{77, "SKYLIB_MSN_PRNF_RX_FLITS"}, +	{78, "SKYLIB_DBG_DATA_RX_FLITS"}, +	{79, "SKYLIB_DBG_CRED_RX_FLITS"}, +	{80, "SKYLIB_CHI_REQ0_TX_STALL"}, +	{81, "SKYLIB_CHI_DATA0_TX_STALL"}, +	{82, "SKYLIB_CHI_RESP0_TX_STALL"}, +	{83, "SKYLIB_CHI_SNP0_TX_STALL"}, +	{84, "SKYLIB_CHI_REQ1_TX_STALL"}, +	{85, "SKYLIB_CHI_DATA1_TX_STALL"}, +	{86, "SKYLIB_CHI_RESP1_TX_STALL"}, +	{87, "SKYLIB_CHI_SNP1_TX_STALL"}, +	{88, "SKYLIB_CHI_REQ2_TX_STALL"}, +	{89, "SKYLIB_CHI_DATA2_TX_STALL"}, +	{90, "SKYLIB_CHI_RESP2_TX_STALL"}, +	{91, "SKYLIB_CHI_SNP2_TX_STALL"}, +	{92, "SKYLIB_CHI_REQ3_TX_STALL"}, +	{93, "SKYLIB_CHI_DATA3_TX_STALL"}, +	{94, "SKYLIB_CHI_RESP3_TX_STALL"}, +	{95, "SKYLIB_CHI_SNP3_TX_STALL"}, +	{96, "SKYLIB_TLP_REQ_TX_STALL"}, +	{97, "SKYLIB_TLP_RESP_TX_STALL"}, +	{98, "SKYLIB_TLP_META_TX_STALL"}, +	{99, "SKYLIB_AXIS_DATA_TX_STALL"}, +	{100, "SKYLIB_AXIS_CRED_TX_STALL"}, +	{101, "SKYLIB_APB_TX_STALL"}, +	{102, "SKYLIB_VW_TX_STALL"}, +	{103, "SKYLIB_GGA_MSN_W_TX_STALL"}, +	{104, "SKYLIB_GGA_MSN_N_TX_STALL"}, +	{105, "SKYLIB_CR_REQ_TX_STALL"}, +	{106, "SKYLIB_CR_RESP_TX_STALL"}, +	{107, "SKYLIB_MSN_PRNF_TX_STALL"}, +	{108, "SKYLIB_DBG_DATA_TX_STALL"}, +	{109, "SKYLIB_DBG_CRED_TX_STALL"}, +	{110, "SKYLIB_CHI_REQ0_RX_STALL"}, +	{111, "SKYLIB_CHI_DATA0_RX_STALL"}, +	{112, "SKYLIB_CHI_RESP0_RX_STALL"}, +	{113, "SKYLIB_CHI_SNP0_RX_STALL"}, +	{114, "SKYLIB_CHI_REQ1_RX_STALL"}, +	{115, "SKYLIB_CHI_DATA1_RX_STALL"}, +	{116, "SKYLIB_CHI_RESP1_RX_STALL"}, +	{117, "SKYLIB_CHI_SNP1_RX_STALL"}, +	{118, "SKYLIB_CHI_REQ2_RX_STALL"}, +	{119, "SKYLIB_CHI_DATA2_RX_STALL"}, +	{120, "SKYLIB_CHI_RESP2_RX_STALL"}, +	{121, "SKYLIB_CHI_SNP2_RX_STALL"}, +	{122, "SKYLIB_CHI_REQ3_RX_STALL"}, +	{123, "SKYLIB_CHI_DATA3_RX_STALL"}, +	{124, "SKYLIB_CHI_RESP3_RX_STALL"}, +	{125, "SKYLIB_CHI_SNP3_RX_STALL"}, +	{126, "SKYLIB_TLP_REQ_RX_STALL"}, +	{127, "SKYLIB_TLP_RESP_RX_STALL"}, +	{128, "SKYLIB_TLP_META_RX_STALL"}, +	{129, "SKYLIB_AXIS_DATA_RX_STALL"}, +	{130, "SKYLIB_AXIS_CRED_RX_STALL"}, +	{131, "SKYLIB_APB_RX_STALL"}, +	{132, "SKYLIB_VW_RX_STALL"}, +	{133, "SKYLIB_GGA_MSN_W_RX_STALL"}, +	{134, "SKYLIB_GGA_MSN_N_RX_STALL"}, +	{135, "SKYLIB_CR_REQ_RX_STALL"}, +	{136, "SKYLIB_CR_RESP_RX_STALL"}, +	{137, "SKYLIB_MSN_PRNF_RX_STALL"}, +	{138, "SKYLIB_DBG_DATA_RX_STALL"}, +	{139, "SKYLIB_DBG_CRED_RX_STALL"}, +	{140, "SKYLIB_CDN_LOOPBACK_FLITS"}, +	{141, "SKYLIB_DDN_LOOPBACK_FLITS"}, +	{142, "SKYLIB_NDN_LOOPBACK_FLITS"}, +	{143, "SKYLIB_SDN_LOOPBACK_FLITS"}, +	{144, "SKYLIB_UDN_LOOPBACK_FLITS"}, +	{145, "HISTOGRAM_HISTOGRAM_BIN0"}, +	{146, "HISTOGRAM_HISTOGRAM_BIN1"}, +	{147, "HISTOGRAM_HISTOGRAM_BIN2"}, +	{148, "HISTOGRAM_HISTOGRAM_BIN3"}, +	{149, "HISTOGRAM_HISTOGRAM_BIN4"}, +	{150, "HISTOGRAM_HISTOGRAM_BIN5"}, +	{151, "HISTOGRAM_HISTOGRAM_BIN6"}, +	{152, "HISTOGRAM_HISTOGRAM_BIN7"}, +	{153, "HISTOGRAM_HISTOGRAM_BIN8"}, +	{154, "HISTOGRAM_HISTOGRAM_BIN9"}, +}; +  static const struct mlxbf_pmc_events mlxbf_pmc_hnf_events[] = { +	{ 0x0, "DISABLE" },  	{ 0x45, "HNF_REQUESTS" },  	{ 0x46, "HNF_REJECTS" },  	{ 0x47, "ALL_BUSY" }, @@ -323,6 +504,7 @@ static const struct mlxbf_pmc_events mlxbf_pmc_hnf_events[] = {  };  static const struct mlxbf_pmc_events mlxbf_pmc_hnfnet_events[] = { +	{ 0x0, "DISABLE" },  	{ 0x12, "CDN_REQ" },  	{ 0x13, "DDN_REQ" },  	{ 0x14, "NDN_REQ" }, @@ -423,6 +605,260 @@ static const struct mlxbf_pmc_events mlxbf_pmc_l3c_events[] = {  	{ 0x2b, "ANY_REJECT_BANK1" },  }; +static const struct mlxbf_pmc_events mlxbf_pmc_llt_events[] = { +	{0, "HNF0_CYCLES"}, +	{1, "HNF0_REQS_RECEIVED"}, +	{2, "HNF0_REQS_PROCESSED"}, +	{3, "HNF0_DIR_HIT"}, +	{4, "HNF0_DIR_MISS"}, +	{5, "HNF0_DIR_RD_ALLOC"}, +	{6, "HNF0_DIR_WR_ALLOC"}, +	{7, "HNF0_DIR_VICTIM"}, +	{8, "HNF0_CL_HAZARD"}, +	{9, "HNF0_ALL_HAZARD"}, +	{10, "HNF0_PIPE_STALLS"}, +	{11, "HNF0_MEM_READS"}, +	{12, "HNF0_MEM_WRITES"}, +	{13, "HNF0_MEM_ACCESS"}, +	{14, "HNF0_DCL_READ"}, +	{15, "HNF0_DCL_INVAL"}, +	{16, "HNF0_CHI_RXDAT"}, +	{17, "HNF0_CHI_RXRSP"}, +	{18, "HNF0_CHI_TXDAT"}, +	{19, "HNF0_CHI_TXRSP"}, +	{20, "HNF0_CHI_TXSNP"}, +	{21, "HNF0_DCT_SNP"}, +	{22, "HNF0_SNP_FWD_DATA"}, +	{23, "HNF0_SNP_FWD_RSP"}, +	{24, "HNF0_SNP_RSP"}, +	{25, "HNF0_EXCL_FULL"}, +	{26, "HNF0_EXCL_WRITE_F"}, +	{27, "HNF0_EXCL_WRITE_S"}, +	{28, "HNF0_EXCL_WRITE"}, +	{29, "HNF0_EXCL_READ"}, +	{30, "HNF0_REQ_BUF_EMPTY"}, +	{31, "HNF0_ALL_MAFS_BUSY"}, +	{32, "HNF0_TXDAT_NO_LCRD"}, +	{33, "HNF0_TXSNP_NO_LCRD"}, +	{34, "HNF0_TXRSP_NO_LCRD"}, +	{35, "HNF0_TXREQ_NO_LCRD"}, +	{36, "HNF0_WRITE"}, +	{37, "HNF0_READ"}, +	{38, "HNF0_ACCESS"}, +	{39, "HNF0_MAF_N_BUSY"}, +	{40, "HNF0_MAF_N_REQS"}, +	{41, "HNF0_SEL_OPCODE"}, +	{42, "HNF1_CYCLES"}, +	{43, "HNF1_REQS_RECEIVED"}, +	{44, "HNF1_REQS_PROCESSED"}, +	{45, "HNF1_DIR_HIT"}, +	{46, "HNF1_DIR_MISS"}, +	{47, "HNF1_DIR_RD_ALLOC"}, +	{48, "HNF1_DIR_WR_ALLOC"}, +	{49, "HNF1_DIR_VICTIM"}, +	{50, "HNF1_CL_HAZARD"}, +	{51, "HNF1_ALL_HAZARD"}, +	{52, "HNF1_PIPE_STALLS"}, +	{53, "HNF1_MEM_READS"}, +	{54, "HNF1_MEM_WRITES"}, +	{55, "HNF1_MEM_ACCESS"}, +	{56, "HNF1_DCL_READ"}, +	{57, "HNF1_DCL_INVAL"}, +	{58, "HNF1_CHI_RXDAT"}, +	{59, "HNF1_CHI_RXRSP"}, +	{60, "HNF1_CHI_TXDAT"}, +	{61, "HNF1_CHI_TXRSP"}, +	{62, "HNF1_CHI_TXSNP"}, +	{63, "HNF1_DCT_SNP"}, +	{64, "HNF1_SNP_FWD_DATA"}, +	{65, "HNF1_SNP_FWD_RSP"}, +	{66, "HNF1_SNP_RSP"}, +	{67, "HNF1_EXCL_FULL"}, +	{68, "HNF1_EXCL_WRITE_F"}, +	{69, "HNF1_EXCL_WRITE_S"}, +	{70, "HNF1_EXCL_WRITE"}, +	{71, "HNF1_EXCL_READ"}, +	{72, "HNF1_REQ_BUF_EMPTY"}, +	{73, "HNF1_ALL_MAFS_BUSY"}, +	{74, "HNF1_TXDAT_NO_LCRD"}, +	{75, "HNF1_TXSNP_NO_LCRD"}, +	{76, "HNF1_TXRSP_NO_LCRD"}, +	{77, "HNF1_TXREQ_NO_LCRD"}, +	{78, "HNF1_WRITE"}, +	{79, "HNF1_READ"}, +	{80, "HNF1_ACCESS"}, +	{81, "HNF1_MAF_N_BUSY"}, +	{82, "HNF1_MAF_N_REQS"}, +	{83, "HNF1_SEL_OPCODE"}, +	{84, "GDC_BANK0_RD_REQ"}, +	{85, "GDC_BANK0_WR_REQ"}, +	{86, "GDC_BANK0_ALLOCATE"}, +	{87, "GDC_BANK0_HIT"}, +	{88, "GDC_BANK0_MISS"}, +	{89, "GDC_BANK0_INVALIDATE"}, +	{90, "GDC_BANK0_EVICT"}, +	{91, "GDC_BANK0_RD_RESP"}, +	{92, "GDC_BANK0_WR_ACK"}, +	{93, "GDC_BANK0_SNOOP"}, +	{94, "GDC_BANK0_SNOOP_NORMAL"}, +	{95, "GDC_BANK0_SNOOP_FWD"}, +	{96, "GDC_BANK0_SNOOP_STASH"}, +	{97, "GDC_BANK0_SNOOP_STASH_INDPND_RD"}, +	{98, "GDC_BANK0_FOLLOWER"}, +	{99, "GDC_BANK0_FW"}, +	{100, "GDC_BANK0_HIT_DCL_BOTH"}, +	{101, "GDC_BANK0_HIT_DCL_PARTIAL"}, +	{102, "GDC_BANK0_EVICT_DCL"}, +	{103, "GDC_BANK0_G_RSE_PIPE_CACHE_DATA0"}, +	{103, "GDC_BANK0_G_RSE_PIPE_CACHE_DATA1"}, +	{105, "GDC_BANK0_ARB_STRB"}, +	{106, "GDC_BANK0_ARB_WAIT"}, +	{107, "GDC_BANK0_GGA_STRB"}, +	{108, "GDC_BANK0_GGA_WAIT"}, +	{109, "GDC_BANK0_FW_STRB"}, +	{110, "GDC_BANK0_FW_WAIT"}, +	{111, "GDC_BANK0_SNP_STRB"}, +	{112, "GDC_BANK0_SNP_WAIT"}, +	{113, "GDC_BANK0_MISS_INARB_STRB"}, +	{114, "GDC_BANK0_MISS_INARB_WAIT"}, +	{115, "GDC_BANK0_G_FIFO_FF_GGA_RSP_RD0"}, +	{116, "GDC_BANK0_G_FIFO_FF_GGA_RSP_RD1"}, +	{117, "GDC_BANK0_G_FIFO_FF_GGA_RSP_RD2"}, +	{118, "GDC_BANK0_G_FIFO_FF_GGA_RSP_RD3"}, +	{119, "GDC_BANK0_G_FIFO_FF_GGA_RSP_WR0"}, +	{120, "GDC_BANK0_G_FIFO_FF_GGA_RSP_WR1"}, +	{121, "GDC_BANK0_G_FIFO_FF_GGA_RSP_WR2"}, +	{122, "GDC_BANK0_G_FIFO_FF_GGA_RSP_WR3"}, +	{123, "GDC_BANK1_RD_REQ"}, +	{124, "GDC_BANK1_WR_REQ"}, +	{125, "GDC_BANK1_ALLOCATE"}, +	{126, "GDC_BANK1_HIT"}, +	{127, "GDC_BANK1_MISS"}, +	{128, "GDC_BANK1_INVALIDATE"}, +	{129, "GDC_BANK1_EVICT"}, +	{130, "GDC_BANK1_RD_RESP"}, +	{131, "GDC_BANK1_WR_ACK"}, +	{132, "GDC_BANK1_SNOOP"}, +	{133, "GDC_BANK1_SNOOP_NORMAL"}, +	{134, "GDC_BANK1_SNOOP_FWD"}, +	{135, "GDC_BANK1_SNOOP_STASH"}, +	{136, "GDC_BANK1_SNOOP_STASH_INDPND_RD"}, +	{137, "GDC_BANK1_FOLLOWER"}, +	{138, "GDC_BANK1_FW"}, +	{139, "GDC_BANK1_HIT_DCL_BOTH"}, +	{140, "GDC_BANK1_HIT_DCL_PARTIAL"}, +	{141, "GDC_BANK1_EVICT_DCL"}, +	{142, "GDC_BANK1_G_RSE_PIPE_CACHE_DATA0"}, +	{143, "GDC_BANK1_G_RSE_PIPE_CACHE_DATA1"}, +	{144, "GDC_BANK1_ARB_STRB"}, +	{145, "GDC_BANK1_ARB_WAIT"}, +	{146, "GDC_BANK1_GGA_STRB"}, +	{147, "GDC_BANK1_GGA_WAIT"}, +	{148, "GDC_BANK1_FW_STRB"}, +	{149, "GDC_BANK1_FW_WAIT"}, +	{150, "GDC_BANK1_SNP_STRB"}, +	{151, "GDC_BANK1_SNP_WAIT"}, +	{152, "GDC_BANK1_MISS_INARB_STRB"}, +	{153, "GDC_BANK1_MISS_INARB_WAIT"}, +	{154, "GDC_BANK1_G_FIFO_FF_GGA_RSP_RD0"}, +	{155, "GDC_BANK1_G_FIFO_FF_GGA_RSP_RD1"}, +	{156, "GDC_BANK1_G_FIFO_FF_GGA_RSP_RD2"}, +	{157, "GDC_BANK1_G_FIFO_FF_GGA_RSP_RD3"}, +	{158, "GDC_BANK1_G_FIFO_FF_GGA_RSP_WR0"}, +	{159, "GDC_BANK1_G_FIFO_FF_GGA_RSP_WR1"}, +	{160, "GDC_BANK1_G_FIFO_FF_GGA_RSP_WR2"}, +	{161, "GDC_BANK1_G_FIFO_FF_GGA_RSP_WR3"}, +	{162, "HISTOGRAM_HISTOGRAM_BIN0"}, +	{163, "HISTOGRAM_HISTOGRAM_BIN1"}, +	{164, "HISTOGRAM_HISTOGRAM_BIN2"}, +	{165, "HISTOGRAM_HISTOGRAM_BIN3"}, +	{166, "HISTOGRAM_HISTOGRAM_BIN4"}, +	{167, "HISTOGRAM_HISTOGRAM_BIN5"}, +	{168, "HISTOGRAM_HISTOGRAM_BIN6"}, +	{169, "HISTOGRAM_HISTOGRAM_BIN7"}, +	{170, "HISTOGRAM_HISTOGRAM_BIN8"}, +	{171, "HISTOGRAM_HISTOGRAM_BIN9"}, +}; + +static const struct mlxbf_pmc_events mlxbf_pmc_llt_miss_events[] = { +	{0, "GDC_MISS_MACHINE_RD_REQ"}, +	{1, "GDC_MISS_MACHINE_WR_REQ"}, +	{2, "GDC_MISS_MACHINE_SNP_REQ"}, +	{3, "GDC_MISS_MACHINE_EVICT_REQ"}, +	{4, "GDC_MISS_MACHINE_FW_REQ"}, +	{5, "GDC_MISS_MACHINE_RD_RESP"}, +	{6, "GDC_MISS_MACHINE_WR_RESP"}, +	{7, "GDC_MISS_MACHINE_SNP_STASH_DATAPULL_DROP"}, +	{8, "GDC_MISS_MACHINE_SNP_STASH_DATAPULL_DROP_TXDAT"}, +	{9, "GDC_MISS_MACHINE_CHI_TXREQ"}, +	{10, "GDC_MISS_MACHINE_CHI_RXRSP"}, +	{11, "GDC_MISS_MACHINE_CHI_TXDAT"}, +	{12, "GDC_MISS_MACHINE_CHI_RXDAT"}, +	{13, "GDC_MISS_MACHINE_G_FIFO_FF_EXEC0_0"}, +	{14, "GDC_MISS_MACHINE_G_FIFO_FF_EXEC0_1 "}, +	{15, "GDC_MISS_MACHINE_G_FIFO_FF_EXEC0_2"}, +	{16, "GDC_MISS_MACHINE_G_FIFO_FF_EXEC0_3 "}, +	{17, "GDC_MISS_MACHINE_G_FIFO_FF_EXEC1_0 "}, +	{18, "GDC_MISS_MACHINE_G_FIFO_FF_EXEC1_1 "}, +	{19, "GDC_MISS_MACHINE_G_FIFO_FF_EXEC1_2 "}, +	{20, "GDC_MISS_MACHINE_G_FIFO_FF_EXEC1_3 "}, +	{21, "GDC_MISS_MACHINE_G_FIFO_FF_EXEC_DONE0_0"}, +	{22, "GDC_MISS_MACHINE_G_FIFO_FF_EXEC_DONE0_1"}, +	{23, "GDC_MISS_MACHINE_G_FIFO_FF_EXEC_DONE0_2"}, +	{24, "GDC_MISS_MACHINE_G_FIFO_FF_EXEC_DONE0_3"}, +	{25, "GDC_MISS_MACHINE_G_FIFO_FF_EXEC_DONE1_0 "}, +	{26, "GDC_MISS_MACHINE_G_FIFO_FF_EXEC_DONE1_1"}, +	{27, "GDC_MISS_MACHINE_G_FIFO_FF_EXEC_DONE1_2"}, +	{28, "GDC_MISS_MACHINE_G_FIFO_FF_EXEC_DONE1_3"}, +	{29, "GDC_MISS_MACHINE_GDC_LINK_LIST_FF_0"}, +	{30, "GDC_MISS_MACHINE_GDC_LINK_LIST_FF_1"}, +	{31, "GDC_MISS_MACHINE_GDC_LINK_LIST_FF_2"}, +	{32, "GDC_MISS_MACHINE_GDC_LINK_LIST_FF_3"}, +	{33, "GDC_MISS_MACHINE_GDC_LINK_LIST_FF_4"}, +	{34, "GDC_MISS_MACHINE_GDC_LINK_LIST_FF_5"}, +	{35, "GDC_MISS_MACHINE_GDC_LINK_LIST_FF_6"}, +	{36, "GDC_MISS_MACHINE_G_RSE_PIPE_TXREQ_0"}, +	{37, "GDC_MISS_MACHINE_G_RSE_PIPE_TXREQ_1"}, +	{38, "GDC_MISS_MACHINE_G_CREDIT_TXREQ_0"}, +	{39, "GDC_MISS_MACHINE_G_CREDIT_TXREQ_1"}, +	{40, "GDC_MISS_MACHINE_G_RSE_PIPE_TXDAT_0"}, +	{41, "GDC_MISS_MACHINE_G_RSE_PIPE_TXDAT_1"}, +	{42, "GDC_MISS_MACHINE_G_CREDIT_TXDAT_0"}, +	{43, "GDC_MISS_MACHINE_G_CREDIT_TXDAT_1"}, +	{44, "GDC_MISS_MACHINE_G_FIFO_FF_COMPACK_0"}, +	{45, "GDC_MISS_MACHINE_G_FIFO_FF_COMPACK_1"}, +	{46, "GDC_MISS_MACHINE_G_FIFO_FF_COMPACK_2"}, +	{47, "GDC_MISS_MACHINE_G_FIFO_FF_COMPACK_3"}, +	{48, "GDC_MISS_MACHINE_G_RSE_PIPE_TXRSP_0"}, +	{49, "GDC_MISS_MACHINE_G_RSE_PIPE_TXRSP_1"}, +	{50, "GDC_MISS_MACHINE_G_CREDIT_TXRSP_0"}, +	{51, "GDC_MISS_MACHINE_G_CREDIT_TXRSP_1"}, +	{52, "GDC_MISS_MACHINE_G_RSE_PIPE_INARB_0"}, +	{53, "GDC_MISS_MACHINE_G_RSE_PIPE_INARB_1"}, +	{54, "GDC_MISS_MACHINE_G_FIFO_FF_SNOOP_IN_0"}, +	{55, "GDC_MISS_MACHINE_G_FIFO_FF_SNOOP_IN_1"}, +	{56, "GDC_MISS_MACHINE_G_FIFO_FF_SNOOP_IN_2"}, +	{57, "GDC_MISS_MACHINE_G_FIFO_FF_SNOOP_IN_3"}, +	{58, "GDC_MISS_MACHINE_G_FIFO_FF_TXRSP_SNOOP_DATAPULL_0"}, +	{59, "GDC_MISS_MACHINE_G_FIFO_FF_TXRSP_SNOOP_DATAPULL_1"}, +	{60, "GDC_MISS_MACHINE_G_FIFO_FF_TXRSP_SNOOP_DATAPULL_2"}, +	{61, "GDC_MISS_MACHINE_G_FIFO_FF_TXRSP_SNOOP_DATAPULL_3"}, +	{62, "GDC_MISS_MACHINE_G_FIFO_FF_TXDAT_SNOOP_DATAPULL_4"}, +	{63, "GDC_MISS_MACHINE_G_FIFO_FF_TXDAT_SNOOP_DATAPULL_5"}, +	{64, "GDC_MISS_MACHINE_G_FIFO_FF_TXDAT_SNOOP_DATAPULL_6"}, +	{65, "GDC_MISS_MACHINE_G_FIFO_FF_TXDAT_SNOOP_DATAPULL_7"}, +	{66, "HISTOGRAM_HISTOGRAM_BIN0"}, +	{67, "HISTOGRAM_HISTOGRAM_BIN1"}, +	{68, "HISTOGRAM_HISTOGRAM_BIN2"}, +	{69, "HISTOGRAM_HISTOGRAM_BIN3"}, +	{70, "HISTOGRAM_HISTOGRAM_BIN4"}, +	{71, "HISTOGRAM_HISTOGRAM_BIN5"}, +	{72, "HISTOGRAM_HISTOGRAM_BIN6"}, +	{73, "HISTOGRAM_HISTOGRAM_BIN7"}, +	{74, "HISTOGRAM_HISTOGRAM_BIN8"}, +	{75, "HISTOGRAM_HISTOGRAM_BIN9"}, +}; +  static struct mlxbf_pmc_context *pmc;  /* UUID used to probe ATF service. */ @@ -563,8 +999,21 @@ static const struct mlxbf_pmc_events *mlxbf_pmc_event_list(const char *blk,  			break;  		}  	} else if (strstr(blk, "mss")) { -		events = mlxbf_pmc_mss_events; -		*size = ARRAY_SIZE(mlxbf_pmc_mss_events); +		switch (pmc->event_set) { +		case MLXBF_PMC_EVENT_SET_BF1: +		case MLXBF_PMC_EVENT_SET_BF2: +			events = mlxbf_pmc_mss_events_1; +			*size = ARRAY_SIZE(mlxbf_pmc_mss_events_1); +			break; +		case MLXBF_PMC_EVENT_SET_BF3: +			events = mlxbf_pmc_mss_events_3; +			*size = ARRAY_SIZE(mlxbf_pmc_mss_events_3); +			break; +		default: +			events = NULL; +			*size = 0; +			break; +		}  	} else if (strstr(blk, "ecc")) {  		events = mlxbf_pmc_ecc_events;  		*size = ARRAY_SIZE(mlxbf_pmc_ecc_events); @@ -580,6 +1029,12 @@ static const struct mlxbf_pmc_events *mlxbf_pmc_event_list(const char *blk,  	} else if (strstr(blk, "smmu")) {  		events = mlxbf_pmc_smgen_events;  		*size = ARRAY_SIZE(mlxbf_pmc_smgen_events); +	} else if (strstr(blk, "llt_miss")) { +		events = mlxbf_pmc_llt_miss_events; +		*size = ARRAY_SIZE(mlxbf_pmc_llt_miss_events); +	} else if (strstr(blk, "llt")) { +		events = mlxbf_pmc_llt_events; +		*size = ARRAY_SIZE(mlxbf_pmc_llt_events);  	} else {  		events = NULL;  		*size = 0; @@ -706,6 +1161,43 @@ static int mlxbf_pmc_program_l3_counter(int blk_num, uint32_t cnt_num,  	return mlxbf_pmc_write(pmcaddr, MLXBF_PMC_WRITE_REG_32, *wordaddr);  } +/* Method to handle crspace counter programming */ +static int mlxbf_pmc_program_crspace_counter(int blk_num, uint32_t cnt_num, +					     uint32_t evt) +{ +	uint32_t word; +	void *addr; +	int ret; + +	addr = pmc->block[blk_num].mmio_base + +		(rounddown(cnt_num, 2) * MLXBF_PMC_CRSPACE_PERFSEL_SZ); +	ret = mlxbf_pmc_readl(addr, &word); +	if (ret) +		return ret; + +	if (cnt_num % 2) { +		word &= ~MLXBF_PMC_CRSPACE_PERFSEL1; +		word |= FIELD_PREP(MLXBF_PMC_CRSPACE_PERFSEL1, evt); +	} else { +		word &= ~MLXBF_PMC_CRSPACE_PERFSEL0; +		word |= FIELD_PREP(MLXBF_PMC_CRSPACE_PERFSEL0, evt); +	} + +	return mlxbf_pmc_write(addr, MLXBF_PMC_WRITE_REG_32, word); +} + +/* Method to clear crspace counter value */ +static int mlxbf_pmc_clear_crspace_counter(int blk_num, uint32_t cnt_num) +{ +	void *addr; + +	addr = pmc->block[blk_num].mmio_base + +		MLXBF_PMC_CRSPACE_PERFMON_VAL0(pmc->block[blk_num].counters) + +		(cnt_num * 4); + +	return mlxbf_pmc_write(addr, MLXBF_PMC_WRITE_REG_32, 0x0); +} +  /* Method to program a counter to monitor an event */  static int mlxbf_pmc_program_counter(int blk_num, uint32_t cnt_num,  				     uint32_t evt, bool is_l3) @@ -718,6 +1210,10 @@ static int mlxbf_pmc_program_counter(int blk_num, uint32_t cnt_num,  	if (is_l3)  		return mlxbf_pmc_program_l3_counter(blk_num, cnt_num, evt); +	if (pmc->block[blk_num].type == MLXBF_PMC_TYPE_CRSPACE) +		return mlxbf_pmc_program_crspace_counter(blk_num, cnt_num, +							 evt); +  	/* Configure the counter */  	perfctl = FIELD_PREP(MLXBF_PMC_PERFCTL_EN0, 1);  	perfctl |= FIELD_PREP(MLXBF_PMC_PERFCTL_EB0, 0); @@ -772,7 +1268,7 @@ static int mlxbf_pmc_read_l3_counter(int blk_num, uint32_t cnt_num,  {  	uint32_t perfcnt_low = 0, perfcnt_high = 0;  	uint64_t value; -	int status = 0; +	int status;  	status = mlxbf_pmc_readl(pmc->block[blk_num].mmio_base +  					 MLXBF_PMC_L3C_PERF_CNT_LOW + @@ -798,6 +1294,24 @@ static int mlxbf_pmc_read_l3_counter(int blk_num, uint32_t cnt_num,  	return 0;  } +/* Method to handle crspace counter reads */ +static int mlxbf_pmc_read_crspace_counter(int blk_num, uint32_t cnt_num, +					  uint64_t *result) +{ +	uint32_t value; +	int status = 0; + +	status = mlxbf_pmc_readl(pmc->block[blk_num].mmio_base + +		MLXBF_PMC_CRSPACE_PERFMON_VAL0(pmc->block[blk_num].counters) + +		(cnt_num * 4), &value); +	if (status) +		return status; + +	*result = value; + +	return 0; +} +  /* Method to read the counter value */  static int mlxbf_pmc_read_counter(int blk_num, uint32_t cnt_num, bool is_l3,  				  uint64_t *result) @@ -812,6 +1326,9 @@ static int mlxbf_pmc_read_counter(int blk_num, uint32_t cnt_num, bool is_l3,  	if (is_l3)  		return mlxbf_pmc_read_l3_counter(blk_num, cnt_num, result); +	if (pmc->block[blk_num].type == MLXBF_PMC_TYPE_CRSPACE) +		return mlxbf_pmc_read_crspace_counter(blk_num, cnt_num, result); +  	perfcfg_offset = cnt_num * MLXBF_PMC_REG_SIZE;  	perfval_offset = perfcfg_offset +  			 pmc->block[blk_num].counters * MLXBF_PMC_REG_SIZE; @@ -887,12 +1404,36 @@ static int mlxbf_pmc_read_l3_event(int blk_num, uint32_t cnt_num,  	return 0;  } +/* Method to read crspace block event */ +static int mlxbf_pmc_read_crspace_event(int blk_num, uint32_t cnt_num, +					uint64_t *result) +{ +	uint32_t word, evt; +	void *addr; +	int ret; + +	addr = pmc->block[blk_num].mmio_base + +		(rounddown(cnt_num, 2) * MLXBF_PMC_CRSPACE_PERFSEL_SZ); +	ret = mlxbf_pmc_readl(addr, &word); +	if (ret) +		return ret; + +	if (cnt_num % 2) +		evt = FIELD_GET(MLXBF_PMC_CRSPACE_PERFSEL1, word); +	else +		evt = FIELD_GET(MLXBF_PMC_CRSPACE_PERFSEL0, word); + +	*result = evt; + +	return 0; +} +  /* Method to find the event currently being monitored by a counter */  static int mlxbf_pmc_read_event(int blk_num, uint32_t cnt_num, bool is_l3,  				uint64_t *result)  {  	uint32_t perfcfg_offset, perfval_offset; -	uint64_t perfmon_cfg, perfevt, perfctl; +	uint64_t perfmon_cfg, perfevt;  	if (cnt_num >= pmc->block[blk_num].counters)  		return -EINVAL; @@ -900,31 +1441,15 @@ static int mlxbf_pmc_read_event(int blk_num, uint32_t cnt_num, bool is_l3,  	if (is_l3)  		return mlxbf_pmc_read_l3_event(blk_num, cnt_num, result); +	if (pmc->block[blk_num].type == MLXBF_PMC_TYPE_CRSPACE) +		return mlxbf_pmc_read_crspace_event(blk_num, cnt_num, result); +  	perfcfg_offset = cnt_num * MLXBF_PMC_REG_SIZE;  	perfval_offset = perfcfg_offset +  			 pmc->block[blk_num].counters * MLXBF_PMC_REG_SIZE;  	/* Set counter in "read" mode */  	perfmon_cfg = FIELD_PREP(MLXBF_PMC_PERFMON_CONFIG_ADDR, -				 MLXBF_PMC_PERFCTL); -	perfmon_cfg |= FIELD_PREP(MLXBF_PMC_PERFMON_CONFIG_STROBE, 1); -	perfmon_cfg |= FIELD_PREP(MLXBF_PMC_PERFMON_CONFIG_WR_R_B, 0); - -	if (mlxbf_pmc_write(pmc->block[blk_num].mmio_base + perfcfg_offset, -			    MLXBF_PMC_WRITE_REG_64, perfmon_cfg)) -		return -EFAULT; - -	/* Check if the counter is enabled */ - -	if (mlxbf_pmc_read(pmc->block[blk_num].mmio_base + perfval_offset, -			   MLXBF_PMC_READ_REG_64, &perfctl)) -		return -EFAULT; - -	if (!FIELD_GET(MLXBF_PMC_PERFCTL_EN0, perfctl)) -		return -EINVAL; - -	/* Set counter in "read" mode */ -	perfmon_cfg = FIELD_PREP(MLXBF_PMC_PERFMON_CONFIG_ADDR,  				 MLXBF_PMC_PERFEVT);  	perfmon_cfg |= FIELD_PREP(MLXBF_PMC_PERFMON_CONFIG_STROBE, 1);  	perfmon_cfg |= FIELD_PREP(MLXBF_PMC_PERFMON_CONFIG_WR_R_B, 0); @@ -995,7 +1520,8 @@ static ssize_t mlxbf_pmc_counter_show(struct device *dev,  	if (strstr(pmc->block_name[blk_num], "l3cache"))  		is_l3 = true; -	if (pmc->block[blk_num].type == MLXBF_PMC_TYPE_COUNTER) { +	if ((pmc->block[blk_num].type == MLXBF_PMC_TYPE_COUNTER) || +	    (pmc->block[blk_num].type == MLXBF_PMC_TYPE_CRSPACE)) {  		if (mlxbf_pmc_read_counter(blk_num, cnt_num, is_l3, &value))  			return -EINVAL;  	} else if (pmc->block[blk_num].type == MLXBF_PMC_TYPE_REGISTER) { @@ -1008,7 +1534,7 @@ static ssize_t mlxbf_pmc_counter_show(struct device *dev,  	} else  		return -EINVAL; -	return sprintf(buf, "0x%llx\n", value); +	return sysfs_emit(buf, "0x%llx\n", value);  }  /* Store function for "counter" sysfs files */ @@ -1053,6 +1579,10 @@ static ssize_t mlxbf_pmc_counter_store(struct device *dev,  		err = mlxbf_pmc_write_reg(blk_num, offset, data);  		if (err)  			return err; +	} else if (pmc->block[blk_num].type == MLXBF_PMC_TYPE_CRSPACE) { +		if (sscanf(attr->attr.name, "counter%d", &cnt_num) != 1) +			return -EINVAL; +		err = mlxbf_pmc_clear_crspace_counter(blk_num, cnt_num);  	} else  		return -EINVAL; @@ -1078,13 +1608,13 @@ static ssize_t mlxbf_pmc_event_show(struct device *dev,  	err = mlxbf_pmc_read_event(blk_num, cnt_num, is_l3, &evt_num);  	if (err) -		return sprintf(buf, "No event being monitored\n"); +		return sysfs_emit(buf, "No event being monitored\n");  	evt_name = mlxbf_pmc_get_event_name(pmc->block_name[blk_num], evt_num);  	if (!evt_name)  		return -EINVAL; -	return sprintf(buf, "0x%llx: %s\n", evt_num, evt_name); +	return sysfs_emit(buf, "0x%llx: %s\n", evt_num, evt_name);  }  /* Store function for "event" sysfs files */ @@ -1139,9 +1669,9 @@ static ssize_t mlxbf_pmc_event_list_show(struct device *dev,  		return -EINVAL;  	for (i = 0, buf[0] = '\0'; i < size; ++i) { -		len += sprintf(e_info, "0x%x: %s\n", events[i].evt_num, -			       events[i].evt_name); -		if (len > PAGE_SIZE) +		len += snprintf(e_info, sizeof(e_info), "0x%x: %s\n", +				events[i].evt_num, events[i].evt_name); +		if (len >= PAGE_SIZE)  			break;  		strcat(buf, e_info);  		ret = len; @@ -1150,28 +1680,37 @@ static ssize_t mlxbf_pmc_event_list_show(struct device *dev,  	return ret;  } -/* Show function for "enable" sysfs files - only for l3cache */ +/* Show function for "enable" sysfs files - only for l3cache & crspace */  static ssize_t mlxbf_pmc_enable_show(struct device *dev,  				     struct device_attribute *attr, char *buf)  {  	struct mlxbf_pmc_attribute *attr_enable = container_of(  		attr, struct mlxbf_pmc_attribute, dev_attr); -	uint32_t perfcnt_cfg; +	uint32_t perfcnt_cfg, word;  	int blk_num, value;  	blk_num = attr_enable->nr; -	if (mlxbf_pmc_readl(pmc->block[blk_num].mmio_base + -				    MLXBF_PMC_L3C_PERF_CNT_CFG, -			    &perfcnt_cfg)) -		return -EINVAL; +	if (pmc->block[blk_num].type == MLXBF_PMC_TYPE_CRSPACE) { +		if (mlxbf_pmc_readl(pmc->block[blk_num].mmio_base + +				MLXBF_PMC_CRSPACE_PERFMON_CTL(pmc->block[blk_num].counters), +				&word)) +			return -EINVAL; + +		value = FIELD_GET(MLXBF_PMC_CRSPACE_PERFMON_EN, word); +	} else { +		if (mlxbf_pmc_readl(pmc->block[blk_num].mmio_base + +					    MLXBF_PMC_L3C_PERF_CNT_CFG, +				    &perfcnt_cfg)) +			return -EINVAL; -	value = FIELD_GET(MLXBF_PMC_L3C_PERF_CNT_CFG_EN, perfcnt_cfg); +		value = FIELD_GET(MLXBF_PMC_L3C_PERF_CNT_CFG_EN, perfcnt_cfg); +	} -	return sprintf(buf, "%d\n", value); +	return sysfs_emit(buf, "%d\n", value);  } -/* Store function for "enable" sysfs files - only for l3cache */ +/* Store function for "enable" sysfs files - only for l3cache & crspace */  static ssize_t mlxbf_pmc_enable_store(struct device *dev,  				      struct device_attribute *attr,  				      const char *buf, size_t count) @@ -1179,6 +1718,7 @@ static ssize_t mlxbf_pmc_enable_store(struct device *dev,  	struct mlxbf_pmc_attribute *attr_enable = container_of(  		attr, struct mlxbf_pmc_attribute, dev_attr);  	int err, en, blk_num; +	uint32_t word;  	blk_num = attr_enable->nr; @@ -1186,19 +1726,35 @@ static ssize_t mlxbf_pmc_enable_store(struct device *dev,  	if (err < 0)  		return err; -	if (!en) { -		err = mlxbf_pmc_config_l3_counters(blk_num, false, false); -		if (err) -			return err; -	} else if (en == 1) { -		err = mlxbf_pmc_config_l3_counters(blk_num, false, true); +	if (pmc->block[blk_num].type == MLXBF_PMC_TYPE_CRSPACE) { +		err = mlxbf_pmc_readl(pmc->block[blk_num].mmio_base + +			MLXBF_PMC_CRSPACE_PERFMON_CTL(pmc->block[blk_num].counters), +			&word);  		if (err) -			return err; -		err = mlxbf_pmc_config_l3_counters(blk_num, true, false); +			return -EINVAL; + +		word &= ~MLXBF_PMC_CRSPACE_PERFMON_EN; +		word |= FIELD_PREP(MLXBF_PMC_CRSPACE_PERFMON_EN, en); +		if (en) +			word |= FIELD_PREP(MLXBF_PMC_CRSPACE_PERFMON_CLR, 1); + +		mlxbf_pmc_write(pmc->block[blk_num].mmio_base + +			MLXBF_PMC_CRSPACE_PERFMON_CTL(pmc->block[blk_num].counters), +			MLXBF_PMC_WRITE_REG_32, word); +	} else { +		if (en && en != 1) +			return -EINVAL; + +		err = mlxbf_pmc_config_l3_counters(blk_num, false, !!en);  		if (err)  			return err; -	} else -		return -EINVAL; + +		if (en == 1) { +			err = mlxbf_pmc_config_l3_counters(blk_num, true, false); +			if (err) +				return err; +		} +	}  	return count;  } @@ -1215,11 +1771,14 @@ static int mlxbf_pmc_init_perftype_counter(struct device *dev, int blk_num)  	attr->dev_attr.show = mlxbf_pmc_event_list_show;  	attr->nr = blk_num;  	attr->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL, "event_list"); +	if (!attr->dev_attr.attr.name) +		return -ENOMEM;  	pmc->block[blk_num].block_attr[i] = &attr->dev_attr.attr;  	attr = NULL;  	/* "enable" sysfs to start/stop the counters. Only in L3C blocks */ -	if (strstr(pmc->block_name[blk_num], "l3cache")) { +	if (strstr(pmc->block_name[blk_num], "l3cache") || +	    ((pmc->block[blk_num].type == MLXBF_PMC_TYPE_CRSPACE))) {  		attr = &pmc->block[blk_num].attr_enable;  		attr->dev_attr.attr.mode = 0644;  		attr->dev_attr.show = mlxbf_pmc_enable_show; @@ -1227,6 +1786,8 @@ static int mlxbf_pmc_init_perftype_counter(struct device *dev, int blk_num)  		attr->nr = blk_num;  		attr->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL,  							  "enable"); +		if (!attr->dev_attr.attr.name) +			return -ENOMEM;  		pmc->block[blk_num].block_attr[++i] = &attr->dev_attr.attr;  		attr = NULL;  	} @@ -1253,6 +1814,8 @@ static int mlxbf_pmc_init_perftype_counter(struct device *dev, int blk_num)  		attr->nr = blk_num;  		attr->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL,  							  "counter%d", j); +		if (!attr->dev_attr.attr.name) +			return -ENOMEM;  		pmc->block[blk_num].block_attr[++i] = &attr->dev_attr.attr;  		attr = NULL; @@ -1264,6 +1827,8 @@ static int mlxbf_pmc_init_perftype_counter(struct device *dev, int blk_num)  		attr->nr = blk_num;  		attr->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL,  							  "event%d", j); +		if (!attr->dev_attr.attr.name) +			return -ENOMEM;  		pmc->block[blk_num].block_attr[++i] = &attr->dev_attr.attr;  		attr = NULL;  	} @@ -1296,6 +1861,8 @@ static int mlxbf_pmc_init_perftype_reg(struct device *dev, int blk_num)  		attr->nr = blk_num;  		attr->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL,  							  events[j].evt_name); +		if (!attr->dev_attr.attr.name) +			return -ENOMEM;  		pmc->block[blk_num].block_attr[i] = &attr->dev_attr.attr;  		attr = NULL;  		i++; @@ -1310,7 +1877,8 @@ static int mlxbf_pmc_create_groups(struct device *dev, int blk_num)  	int err;  	/* Populate attributes based on counter type */ -	if (pmc->block[blk_num].type == MLXBF_PMC_TYPE_COUNTER) +	if ((pmc->block[blk_num].type == MLXBF_PMC_TYPE_COUNTER) || +	    (pmc->block[blk_num].type == MLXBF_PMC_TYPE_CRSPACE))  		err = mlxbf_pmc_init_perftype_counter(dev, blk_num);  	else if (pmc->block[blk_num].type == MLXBF_PMC_TYPE_REGISTER)  		err = mlxbf_pmc_init_perftype_reg(dev, blk_num); @@ -1324,7 +1892,10 @@ static int mlxbf_pmc_create_groups(struct device *dev, int blk_num)  	pmc->block[blk_num].block_attr_grp.attrs = pmc->block[blk_num].block_attr;  	pmc->block[blk_num].block_attr_grp.name = devm_kasprintf(  		dev, GFP_KERNEL, pmc->block_name[blk_num]); -	pmc->groups[blk_num] = &pmc->block[blk_num].block_attr_grp; +	if (!pmc->block[blk_num].block_attr_grp.name) +		return -ENOMEM; +	pmc->groups[pmc->group_num] = &pmc->block[blk_num].block_attr_grp; +	pmc->group_num++;  	return 0;  } @@ -1347,13 +1918,52 @@ static int mlxbf_pmc_map_counters(struct device *dev)  	int i, tile_num, ret;  	for (i = 0; i < pmc->total_blocks; ++i) { -		if (strstr(pmc->block_name[i], "tile")) { +		/* Create sysfs for tiles only if block number <  tile_count */ +		if (strstr(pmc->block_name[i], "tilenet")) { +			if (sscanf(pmc->block_name[i], "tilenet%d", &tile_num) != 1) +				continue; + +			if (tile_num >= pmc->tile_count) +				continue; +		} else if (strstr(pmc->block_name[i], "tile")) {  			if (sscanf(pmc->block_name[i], "tile%d", &tile_num) != 1) -				return -EINVAL; +				continue;  			if (tile_num >= pmc->tile_count)  				continue;  		} + +		/* Create sysfs only for enabled MSS blocks */ +		if (strstr(pmc->block_name[i], "mss") && +		    pmc->event_set == MLXBF_PMC_EVENT_SET_BF3) { +			int mss_num; + +			if (sscanf(pmc->block_name[i], "mss%d", &mss_num) != 1) +				continue; + +			if (!((pmc->mss_enable >> mss_num) & 0x1)) +				continue; +		} + +		/* Create sysfs only for enabled LLT blocks */ +		if (strstr(pmc->block_name[i], "llt_miss")) { +			int llt_num; + +			if (sscanf(pmc->block_name[i], "llt_miss%d", &llt_num) != 1) +				continue; + +			if (!((pmc->llt_enable >> llt_num) & 0x1)) +				continue; +		} else if (strstr(pmc->block_name[i], "llt")) { +			int llt_num; + +			if (sscanf(pmc->block_name[i], "llt%d", &llt_num) != 1) +				continue; + +			if (!((pmc->llt_enable >> llt_num) & 0x1)) +				continue; +		} +  		ret = device_property_read_u64_array(dev, pmc->block_name[i],  						     info, MLXBF_PMC_INFO_SZ);  		if (ret) @@ -1430,6 +2040,8 @@ static int mlxbf_pmc_probe(struct platform_device *pdev)  		pmc->event_set = MLXBF_PMC_EVENT_SET_BF1;  	else if (!strcmp(hid, "MLNXBFD1"))  		pmc->event_set = MLXBF_PMC_EVENT_SET_BF2; +	else if (!strcmp(hid, "MLNXBFD2")) +		pmc->event_set = MLXBF_PMC_EVENT_SET_BF3;  	else  		return -ENODEV; @@ -1443,11 +2055,19 @@ static int mlxbf_pmc_probe(struct platform_device *pdev)  	if (ret != pmc->total_blocks)  		return -EFAULT; -	ret = device_property_read_u32(dev, "tile_num", &pmc->tile_count); -	if (ret) -		return ret; +	if (device_property_read_u32(dev, "tile_num", &pmc->tile_count)) { +		if (device_property_read_u8(dev, "llt_enable", &pmc->llt_enable)) { +			dev_err(dev, "Number of tiles/LLTs undefined\n"); +			return -EINVAL; +		} +		if (device_property_read_u8(dev, "mss_enable", &pmc->mss_enable)) { +			dev_err(dev, "Number of tiles/MSSs undefined\n"); +			return -EINVAL; +		} +	}  	pmc->pdev = pdev; +	pmc->group_num = 0;  	ret = mlxbf_pmc_map_counters(dev);  	if (ret) @@ -1455,6 +2075,8 @@ static int mlxbf_pmc_probe(struct platform_device *pdev)  	pmc->hwmon_dev = devm_hwmon_device_register_with_groups(  		dev, "bfperf", pmc, pmc->groups); +	if (IS_ERR(pmc->hwmon_dev)) +		return PTR_ERR(pmc->hwmon_dev);  	platform_set_drvdata(pdev, pmc);  	return 0; @@ -1462,6 +2084,7 @@ static int mlxbf_pmc_probe(struct platform_device *pdev)  static const struct acpi_device_id mlxbf_pmc_acpi_ids[] = { { "MLNXBFD0", 0 },  							    { "MLNXBFD1", 0 }, +							    { "MLNXBFD2", 0 },  							    {}, };  MODULE_DEVICE_TABLE(acpi, mlxbf_pmc_acpi_ids); |