diff mbox series

[RFC,2/2] arm_mpam: add support for MSMON_MBWU_L/CAPTURE

Message ID 20230308134539.3071034-3-amitsinght@marvell.com (mailing list archive)
State New, archived
Headers show
Series Add support for DDR MPAM monitoring | expand

Commit Message

Amit Singh Tomar March 8, 2023, 1:45 p.m. UTC
In MPAM v0.1 and from MPAM v1.1, There is an optional long monitor
register, MSMON_MBWU_L/CAPTURE, that contains a count of 44 bits
or 63 bits

Capture register MSMON_MBWU_CAPTURE that is loaded from the monitor
register each time the selected capture event occurs. When a capture
event occurs, the monitor register is copied to the capture register

Signed-off-by: Amit Singh Tomar <amitsinght@marvell.com>
Change-Id: I0c7bb8d57a2f77e45b06df0529a5bf1624f66f77
---
 drivers/platform/mpam/mpam_devices.c  | 54 +++++++++++++++++++++++----
 drivers/platform/mpam/mpam_internal.h | 15 ++++++--
 2 files changed, 59 insertions(+), 10 deletions(-)
diff mbox series

Patch

diff --git a/drivers/platform/mpam/mpam_devices.c b/drivers/platform/mpam/mpam_devices.c
index 130e5997d336..22318730ef60 100644
--- a/drivers/platform/mpam/mpam_devices.c
+++ b/drivers/platform/mpam/mpam_devices.c
@@ -649,6 +649,10 @@  static void mpam_ris_hw_probe(struct mpam_msc_ris *ris)
 			props->num_mbwu_mon = FIELD_GET(MPAMF_MBWUMON_IDR_NUM_MON, mbwumonidr);
 			if (props->num_mbwu_mon)
 				mpam_set_feature(mpam_feat_msmon_mbwu, props);
+
+			msc->mbwu_has_capture =	FIELD_GET(MPAMF_MBWUMON_IDR_HAS_CAPTURE, mbwumonidr);
+			msc->mbwu_has_long = FIELD_GET(MPAMF_MBWUMON_IDR_HAS_LONG, mbwumonidr);
+			msc->mbwu_lwd = FIELD_GET(MPAMF_MBWUMON_IDR_HAS_LWD, mbwumonidr);
 		}
 	}
 
@@ -811,7 +815,8 @@  static void write_msmon_ctl_flt_vals(struct mon_read *m, u32 ctl_val,
 		mpam_write_monsel_reg(msc, CFG_MBWU_FLT, flt_val);
 		mpam_write_monsel_reg(msc, CFG_MBWU_CTL, ctl_val);
 		mpam_write_monsel_reg(msc, MBWU, 0);
-		mpam_write_monsel_reg(msc, CFG_MBWU_CTL, ctl_val|MSMON_CFG_x_CTL_EN);
+		mpam_write_monsel_reg(msc, CFG_MBWU_CTL, ctl_val|MSMON_CFG_x_CTL_EN|
+					MSMON_CFG_x_CTL_CAPT_EVNT);
 
 		mbwu_state = &m->ris->mbwu_state[m->ctx->mon];
 		if (mbwu_state)
@@ -841,7 +846,7 @@  static void __ris_msmon_read(void *arg)
 	struct mpam_msc_ris *ris = m->ris;
 	struct mpam_msc *msc = m->ris->msc;
 	struct msmon_mbwu_state *mbwu_state;
-	u32 mon_sel, ctl_val, flt_val, cur_ctl, cur_flt;
+	u32 mon_sel, ctl_val, flt_val, cur_ctl, cur_flt, now_low;
 
 	spin_lock_irqsave(&msc->mon_sel_lock, flags);
 	mon_sel = FIELD_PREP(MSMON_CFG_MON_SEL_MON_SEL, ctx->mon) |
@@ -875,12 +880,47 @@  static void __ris_msmon_read(void *arg)
 		now = FIELD_GET(MSMON___VALUE, now);
 		break;
 	case mpam_feat_msmon_mbwu:
-		now = mpam_read_monsel_reg(msc, MBWU);
-		nrdy = now & MSMON___NRDY;
-		now = FIELD_GET(MSMON___VALUE, now);
+		/* If the monitor is a counter monitor such as MBWU,
+		 * implementation should clear the nrdy bit, either
+		 * doing explicit software write to clear NRDY bit or
+		 * a capture event that automatically clear the nrdy
+		 * bit, let's use the latter one.
+		 * MSMON_MBWU_CAPTURE/L_CAPTURE is written atomically by
+		 * copying all bits from MSMON_MBWU_L when the capture
+		 * event that is programmed into the configuration of this
+		 * monitor instance occurs.
+		 */
+		mpam_write_monsel_reg(msc, CAPT_EVNT, 0x1);
 
-		if (nrdy)
-			break;
+		if (msc->mbwu_has_long && msc->mbwu_has_capture &&
+			msc->mbwu_lwd) {
+			now = mpam_read_monsel_reg(msc, MBWU_L + 4);
+			nrdy = now & MSMON___NRDY;
+			if (nrdy)
+				break;
+
+			now =  mpam_read_monsel_reg(msc, MBWU_CAPTURE_L + 4);
+			now_low = mpam_read_monsel_reg(msc, MBWU_CAPTURE_L);
+			now = MSMON_MBWU_L_VALUE & (now << 32 | now_low);
+		} else if (msc->mbwu_has_long && msc->mbwu_has_capture &&
+				!msc->mbwu_lwd) {
+			now = mpam_read_monsel_reg(msc, MBWU_L + 4);
+			nrdy = now & MSMON___NRDY;
+			if (nrdy)
+				break;
+
+			now =  mpam_read_monsel_reg(msc, MBWU_CAPTURE_L + 4);
+			now_low = mpam_read_monsel_reg(msc, MBWU_CAPTURE_L);
+			now = MSMON_MBWU_L_VALUE_LWD & (now << 32 | now_low);
+		} else {
+			now = mpam_read_monsel_reg(msc, MBWU);
+			nrdy = now & MSMON___NRDY;
+			if (nrdy)
+				break;
+
+			now =  mpam_read_monsel_reg(msc, MBWU_CAPTURE);
+			now = FIELD_GET(MSMON___VALUE, now);
+		}
 
 		if (!mbwu_state)
 			break;
diff --git a/drivers/platform/mpam/mpam_internal.h b/drivers/platform/mpam/mpam_internal.h
index d4bf14601db7..f75020eb318b 100644
--- a/drivers/platform/mpam/mpam_internal.h
+++ b/drivers/platform/mpam/mpam_internal.h
@@ -35,6 +35,9 @@  struct mpam_msc
 	u32			nrdy_usec;
 	cpumask_t		accessibility;
 	bool			has_extd_esr;
+	bool			mbwu_has_capture;
+	bool                    mbwu_has_long;
+	bool                    mbwu_lwd;
 
 	int				reenable_error_ppi;
 	struct mpam_msc * __percpu	*error_dev_id;
@@ -328,6 +331,8 @@  void mpam_resctrl_exit(void);
 #define MSMON_CSU_CAPTURE       0x0848  /* last cache-usage value captured */
 #define MSMON_MBWU              0x0860  /* current mem-bw usage value */
 #define MSMON_MBWU_CAPTURE      0x0868  /* last mem-bw value captured */
+#define MSMON_MBWU_L            0x0880  /* current mem-bw usage value, LONG version*/
+#define MSMON_MBWU_CAPTURE_L    0x0890  /* last mem-bw value captured, LONG version */
 #define MSMON_CAPT_EVNT         0x0808  /* signal a capture event */
 #define MPAMF_ESR               0x00F8  /* error status register */
 #define MPAMF_ECR               0x00F0  /* error control register */
@@ -384,6 +389,9 @@  void mpam_resctrl_exit(void);
 /* MPAMF_MBWUMON_IDR - MPAM memory bandwidth usage monitor ID register */
 #define MPAMF_MBWUMON_IDR_NUM_MON       GENMASK(15, 0)
 #define MPAMF_MBWUMON_IDR_HAS_CAPTURE   BIT(31)
+#define MPAMF_MBWUMON_IDR_HAS_LWD       BIT(29)
+#define MPAMF_MBWUMON_IDR_HAS_LONG      BIT(30)
+
 
 /* MPAMF_PARTID_NRW_IDR - MPAM PARTID narrowing ID register */
 #define MPAMF_PARTID_NRW_IDR_INTPARTID_MAX      GENMASK(15, 0)
@@ -525,9 +533,10 @@  void mpam_resctrl_exit(void);
  * MSMON_MBWU_CAPTURE - Memory system performance monitor memory bandwidth usage
  *                     capture register
  */
-#define MSMON___VALUE          GENMASK(30, 0)
-#define MSMON___NRDY           BIT(31)
-#define MSMON_MBWU_L_VALUE     GENMASK(62, 0)
+#define MSMON___VALUE              GENMASK(30, 0)
+#define MSMON___NRDY               BIT(31)
+#define MSMON_MBWU_L_VALUE         GENMASK(62, 0)
+#define MSMON_MBWU_L_VALUE_LWD     GENMASK(43, 0)
 /*
  * MSMON_CAPT_EVNT - Memory system performance monitoring capture event
  *                  generation register