[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <62ba4735-37b5-e82-6180-54807f86dd@os.amperecomputing.com>
Date: Fri, 23 Aug 2024 16:38:40 -0700 (PDT)
From: Ilkka Koskinen <ilkka@...amperecomputing.com>
To: Robin Murphy <robin.murphy@....com>
cc: will@...nel.org, mark.rutland@....com,
linux-arm-kernel@...ts.infradead.org, linux-kernel@...r.kernel.org,
ilkka@...amperecomputing.com
Subject: Re: [PATCH 8/8] perf/arm-cmn: Support CMN S3
Hi Robin,
On Fri, 9 Aug 2024, Robin Murphy wrote:
> CMN S3 is the latest and greatest evolution for 2024, although most of
> the new features don't impact the PMU, so from our point of view it ends
> up looking a lot like CMN-700 r3 still. We have some new device types to
> ignore, a mildly irritating rearrangement of the register layouts, and a
> scary new configuration option that makes it potentially unsafe to even
> walk the full discovery tree, let alone attempt to use the PMU.
>
> Signed-off-by: Robin Murphy <robin.murphy@....com>
I didn't look at CMN S3 spec but the patch looks good to me.
Reviewed-by: Ilkka Koskinen <ilkka@...amperecomputing.com>
Cheers, Ilkka
> ---
> drivers/perf/arm-cmn.c | 117 ++++++++++++++++++++++++++---------------
> 1 file changed, 74 insertions(+), 43 deletions(-)
>
> diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
> index 12bbb689a1af..0d19163fba5a 100644
> --- a/drivers/perf/arm-cmn.c
> +++ b/drivers/perf/arm-cmn.c
> @@ -42,24 +42,28 @@
> #define CMN_CFGM_PERIPH_ID_23 0x0010
> #define CMN_CFGM_PID2_REVISION GENMASK_ULL(7, 4)
>
> -#define CMN_CFGM_INFO_GLOBAL 0x900
> +#define CMN_CFGM_INFO_GLOBAL 0x0900
> #define CMN_INFO_MULTIPLE_DTM_EN BIT_ULL(63)
> #define CMN_INFO_RSP_VC_NUM GENMASK_ULL(53, 52)
> #define CMN_INFO_DAT_VC_NUM GENMASK_ULL(51, 50)
> +#define CMN_INFO_DEVICE_ISO_ENABLE BIT_ULL(44)
>
> -#define CMN_CFGM_INFO_GLOBAL_1 0x908
> +#define CMN_CFGM_INFO_GLOBAL_1 0x0908
> #define CMN_INFO_SNP_VC_NUM GENMASK_ULL(3, 2)
> #define CMN_INFO_REQ_VC_NUM GENMASK_ULL(1, 0)
>
> /* XPs also have some local topology info which has uses too */
> #define CMN_MXP__CONNECT_INFO(p) (0x0008 + 8 * (p))
> -#define CMN__CONNECT_INFO_DEVICE_TYPE GENMASK_ULL(4, 0)
> +#define CMN__CONNECT_INFO_DEVICE_TYPE GENMASK_ULL(5, 0)
>
> #define CMN_MAX_PORTS 6
> #define CI700_CONNECT_INFO_P2_5_OFFSET 0x10
>
> /* PMU registers occupy the 3rd 4KB page of each node's region */
> #define CMN_PMU_OFFSET 0x2000
> +/* ...except when they don't :( */
> +#define CMN_S3_DTM_OFFSET 0xa000
> +#define CMN_S3_PMU_OFFSET 0xd900
>
> /* For most nodes, this is all there is */
> #define CMN_PMU_EVENT_SEL 0x000
> @@ -191,10 +195,11 @@ enum cmn_model {
> CMN650 = 2,
> CMN700 = 4,
> CI700 = 8,
> + CMNS3 = 16,
> /* ...and then we can use bitmap tricks for commonality */
> CMN_ANY = -1,
> NOT_CMN600 = -2,
> - CMN_650ON = CMN650 | CMN700,
> + CMN_650ON = CMN650 | CMN700 | CMNS3,
> };
>
> /* Actual part numbers and revision IDs defined by the hardware */
> @@ -203,6 +208,7 @@ enum cmn_part {
> PART_CMN650 = 0x436,
> PART_CMN700 = 0x43c,
> PART_CI700 = 0x43a,
> + PART_CMN_S3 = 0x43e,
> };
>
> /* CMN-600 r0px shouldn't exist in silicon, thankfully */
> @@ -254,6 +260,7 @@ enum cmn_node_type {
> CMN_TYPE_HNS = 0x200,
> CMN_TYPE_HNS_MPAM_S,
> CMN_TYPE_HNS_MPAM_NS,
> + CMN_TYPE_APB = 0x1000,
> /* Not a real node type */
> CMN_TYPE_WP = 0x7770
> };
> @@ -404,6 +411,8 @@ static enum cmn_model arm_cmn_model(const struct arm_cmn *cmn)
> return CMN700;
> case PART_CI700:
> return CI700;
> + case PART_CMN_S3:
> + return CMNS3;
> default:
> return 0;
> };
> @@ -411,6 +420,11 @@ static enum cmn_model arm_cmn_model(const struct arm_cmn *cmn)
>
> static int arm_cmn_pmu_offset(const struct arm_cmn *cmn, const struct arm_cmn_node *dn)
> {
> + if (cmn->part == PART_CMN_S3) {
> + if (dn->type == CMN_TYPE_XP)
> + return CMN_S3_DTM_OFFSET;
> + return CMN_S3_PMU_OFFSET;
> + }
> return CMN_PMU_OFFSET;
> }
>
> @@ -467,6 +481,9 @@ static const char *arm_cmn_device_type(u8 type)
> case 0x1c: return " MTSX |";
> case 0x1d: return " HN-V |";
> case 0x1e: return " CCG |";
> + case 0x20: return " RN-F_F |";
> + case 0x21: return "RN-F_F_E|";
> + case 0x22: return " SN-F_F |";
> default: return " ???? |";
> }
> }
> @@ -777,8 +794,8 @@ static umode_t arm_cmn_event_attr_is_visible(struct kobject *kobj,
> CMN_EVENT_ATTR(CMN_ANY, cxha_##_name, CMN_TYPE_CXHA, _event)
> #define CMN_EVENT_CCRA(_name, _event) \
> CMN_EVENT_ATTR(CMN_ANY, ccra_##_name, CMN_TYPE_CCRA, _event)
> -#define CMN_EVENT_CCHA(_name, _event) \
> - CMN_EVENT_ATTR(CMN_ANY, ccha_##_name, CMN_TYPE_CCHA, _event)
> +#define CMN_EVENT_CCHA(_model, _name, _event) \
> + CMN_EVENT_ATTR(_model, ccha_##_name, CMN_TYPE_CCHA, _event)
> #define CMN_EVENT_CCLA(_name, _event) \
> CMN_EVENT_ATTR(CMN_ANY, ccla_##_name, CMN_TYPE_CCLA, _event)
> #define CMN_EVENT_CCLA_RNI(_name, _event) \
> @@ -1136,42 +1153,43 @@ static struct attribute *arm_cmn_event_attrs[] = {
> CMN_EVENT_CCRA(wdb_alloc, 0x59),
> CMN_EVENT_CCRA(ssb_alloc, 0x5a),
>
> - CMN_EVENT_CCHA(rddatbyp, 0x61),
> - CMN_EVENT_CCHA(chirsp_up_stall, 0x62),
> - CMN_EVENT_CCHA(chidat_up_stall, 0x63),
> - CMN_EVENT_CCHA(snppcrd_link0_stall, 0x64),
> - CMN_EVENT_CCHA(snppcrd_link1_stall, 0x65),
> - CMN_EVENT_CCHA(snppcrd_link2_stall, 0x66),
> - CMN_EVENT_CCHA(reqtrk_occ, 0x67),
> - CMN_EVENT_CCHA(rdb_occ, 0x68),
> - CMN_EVENT_CCHA(rdbyp_occ, 0x69),
> - CMN_EVENT_CCHA(wdb_occ, 0x6a),
> - CMN_EVENT_CCHA(snptrk_occ, 0x6b),
> - CMN_EVENT_CCHA(sdb_occ, 0x6c),
> - CMN_EVENT_CCHA(snphaz_occ, 0x6d),
> - CMN_EVENT_CCHA(reqtrk_alloc, 0x6e),
> - CMN_EVENT_CCHA(rdb_alloc, 0x6f),
> - CMN_EVENT_CCHA(rdbyp_alloc, 0x70),
> - CMN_EVENT_CCHA(wdb_alloc, 0x71),
> - CMN_EVENT_CCHA(snptrk_alloc, 0x72),
> - CMN_EVENT_CCHA(sdb_alloc, 0x73),
> - CMN_EVENT_CCHA(snphaz_alloc, 0x74),
> - CMN_EVENT_CCHA(pb_rhu_req_occ, 0x75),
> - CMN_EVENT_CCHA(pb_rhu_req_alloc, 0x76),
> - CMN_EVENT_CCHA(pb_rhu_pcie_req_occ, 0x77),
> - CMN_EVENT_CCHA(pb_rhu_pcie_req_alloc, 0x78),
> - CMN_EVENT_CCHA(pb_pcie_wr_req_occ, 0x79),
> - CMN_EVENT_CCHA(pb_pcie_wr_req_alloc, 0x7a),
> - CMN_EVENT_CCHA(pb_pcie_reg_req_occ, 0x7b),
> - CMN_EVENT_CCHA(pb_pcie_reg_req_alloc, 0x7c),
> - CMN_EVENT_CCHA(pb_pcie_rsvd_req_occ, 0x7d),
> - CMN_EVENT_CCHA(pb_pcie_rsvd_req_alloc, 0x7e),
> - CMN_EVENT_CCHA(pb_rhu_dat_occ, 0x7f),
> - CMN_EVENT_CCHA(pb_rhu_dat_alloc, 0x80),
> - CMN_EVENT_CCHA(pb_rhu_pcie_dat_occ, 0x81),
> - CMN_EVENT_CCHA(pb_rhu_pcie_dat_alloc, 0x82),
> - CMN_EVENT_CCHA(pb_pcie_wr_dat_occ, 0x83),
> - CMN_EVENT_CCHA(pb_pcie_wr_dat_alloc, 0x84),
> + CMN_EVENT_CCHA(CMN_ANY, rddatbyp, 0x61),
> + CMN_EVENT_CCHA(CMN_ANY, chirsp_up_stall, 0x62),
> + CMN_EVENT_CCHA(CMN_ANY, chidat_up_stall, 0x63),
> + CMN_EVENT_CCHA(CMN_ANY, snppcrd_link0_stall, 0x64),
> + CMN_EVENT_CCHA(CMN_ANY, snppcrd_link1_stall, 0x65),
> + CMN_EVENT_CCHA(CMN_ANY, snppcrd_link2_stall, 0x66),
> + CMN_EVENT_CCHA(CMN_ANY, reqtrk_occ, 0x67),
> + CMN_EVENT_CCHA(CMN_ANY, rdb_occ, 0x68),
> + CMN_EVENT_CCHA(CMN_ANY, rdbyp_occ, 0x69),
> + CMN_EVENT_CCHA(CMN_ANY, wdb_occ, 0x6a),
> + CMN_EVENT_CCHA(CMN_ANY, snptrk_occ, 0x6b),
> + CMN_EVENT_CCHA(CMN_ANY, sdb_occ, 0x6c),
> + CMN_EVENT_CCHA(CMN_ANY, snphaz_occ, 0x6d),
> + CMN_EVENT_CCHA(CMN_ANY, reqtrk_alloc, 0x6e),
> + CMN_EVENT_CCHA(CMN_ANY, rdb_alloc, 0x6f),
> + CMN_EVENT_CCHA(CMN_ANY, rdbyp_alloc, 0x70),
> + CMN_EVENT_CCHA(CMN_ANY, wdb_alloc, 0x71),
> + CMN_EVENT_CCHA(CMN_ANY, snptrk_alloc, 0x72),
> + CMN_EVENT_CCHA(CMN_ANY, db_alloc, 0x73),
> + CMN_EVENT_CCHA(CMN_ANY, snphaz_alloc, 0x74),
> + CMN_EVENT_CCHA(CMN_ANY, pb_rhu_req_occ, 0x75),
> + CMN_EVENT_CCHA(CMN_ANY, pb_rhu_req_alloc, 0x76),
> + CMN_EVENT_CCHA(CMN_ANY, pb_rhu_pcie_req_occ, 0x77),
> + CMN_EVENT_CCHA(CMN_ANY, pb_rhu_pcie_req_alloc, 0x78),
> + CMN_EVENT_CCHA(CMN_ANY, pb_pcie_wr_req_occ, 0x79),
> + CMN_EVENT_CCHA(CMN_ANY, pb_pcie_wr_req_alloc, 0x7a),
> + CMN_EVENT_CCHA(CMN_ANY, pb_pcie_reg_req_occ, 0x7b),
> + CMN_EVENT_CCHA(CMN_ANY, pb_pcie_reg_req_alloc, 0x7c),
> + CMN_EVENT_CCHA(CMN_ANY, pb_pcie_rsvd_req_occ, 0x7d),
> + CMN_EVENT_CCHA(CMN_ANY, pb_pcie_rsvd_req_alloc, 0x7e),
> + CMN_EVENT_CCHA(CMN_ANY, pb_rhu_dat_occ, 0x7f),
> + CMN_EVENT_CCHA(CMN_ANY, pb_rhu_dat_alloc, 0x80),
> + CMN_EVENT_CCHA(CMN_ANY, pb_rhu_pcie_dat_occ, 0x81),
> + CMN_EVENT_CCHA(CMN_ANY, pb_rhu_pcie_dat_alloc, 0x82),
> + CMN_EVENT_CCHA(CMN_ANY, pb_pcie_wr_dat_occ, 0x83),
> + CMN_EVENT_CCHA(CMN_ANY, pb_pcie_wr_dat_alloc, 0x84),
> + CMN_EVENT_CCHA(CMNS3, chirsp1_up_stall, 0x85),
>
> CMN_EVENT_CCLA(rx_cxs, 0x21),
> CMN_EVENT_CCLA(tx_cxs, 0x22),
> @@ -1777,7 +1795,8 @@ static int arm_cmn_event_init(struct perf_event *event)
> /* ...but the DTM may depend on which port we're watching */
> if (cmn->multi_dtm)
> hw->dtm_offset = CMN_EVENT_WP_DEV_SEL(event) / 2;
> - } else if (type == CMN_TYPE_XP && cmn->part == PART_CMN700) {
> + } else if (type == CMN_TYPE_XP &&
> + (cmn->part == PART_CMN700 || cmn->part == PART_CMN_S3)) {
> hw->wide_sel = true;
> }
>
> @@ -2264,7 +2283,17 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
> reg = readl_relaxed(cfg_region + CMN_CFGM_PERIPH_ID_23);
> cmn->rev = FIELD_GET(CMN_CFGM_PID2_REVISION, reg);
>
> + /*
> + * With the device isolation feature, if firmware has neglected to enable
> + * an XP port then we risk locking up if we try to access anything behind
> + * it; however we also have no way to tell from Non-Secure whether any
> + * given port is disabled or not, so the only way to win is not to play...
> + */
> reg = readq_relaxed(cfg_region + CMN_CFGM_INFO_GLOBAL);
> + if (reg & CMN_INFO_DEVICE_ISO_ENABLE) {
> + dev_err(cmn->dev, "Device isolation enabled, not continuing due to risk of lockup\n");
> + return -ENODEV;
> + }
> cmn->multi_dtm = reg & CMN_INFO_MULTIPLE_DTM_EN;
> cmn->rsp_vc_num = FIELD_GET(CMN_INFO_RSP_VC_NUM, reg);
> cmn->dat_vc_num = FIELD_GET(CMN_INFO_DAT_VC_NUM, reg);
> @@ -2423,6 +2452,7 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
> case CMN_TYPE_CXLA:
> case CMN_TYPE_HNS_MPAM_S:
> case CMN_TYPE_HNS_MPAM_NS:
> + case CMN_TYPE_APB:
> break;
> /*
> * Split "optimised" combination nodes into separate
> @@ -2608,6 +2638,7 @@ static const struct of_device_id arm_cmn_of_match[] = {
> { .compatible = "arm,cmn-600", .data = (void *)PART_CMN600 },
> { .compatible = "arm,cmn-650" },
> { .compatible = "arm,cmn-700" },
> + { .compatible = "arm,cmn-s3" },
> { .compatible = "arm,ci-700" },
> {}
> };
> --
> 2.39.2.101.g768bb238c484.dirty
>
>
Powered by blists - more mailing lists