DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH] drivers: add external clock support for cnxk timer
@ 2021-07-28 15:24 Shijith Thotton
  2021-09-15 16:03 ` [dpdk-dev] [PATCH v2] " Shijith Thotton
  0 siblings, 1 reply; 11+ messages in thread
From: Shijith Thotton @ 2021-07-28 15:24 UTC (permalink / raw)
  To: dev
  Cc: Shijith Thotton, thomas, jerinj, pbhagavatula, Nithin Dabilpuram,
	Kiran Kumar K, Sunil Kumar Kori, Satha Rao

To configure tim with external clock, requested resolution should be
adjusted based on core and external clock frequency for accuracy.

tim_ext_clk is the devarg used to pass external clock frequency.

E.g. -a 0002:0e:00.0,tim_ext_clk=122880000

Signed-off-by: Shijith Thotton <sthotton@marvell.com>
Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
---
Depends-on: series-18039 ("eal: add macro to swap two numbers")

 doc/guides/eventdevs/cnxk.rst       |   9 ++
 drivers/common/cnxk/roc_platform.h  |   1 +
 drivers/event/cnxk/cnxk_tim_evdev.c | 124 ++++++++++++++++++++++++++--
 drivers/event/cnxk/cnxk_tim_evdev.h |   6 +-
 4 files changed, 131 insertions(+), 9 deletions(-)

diff --git a/doc/guides/eventdevs/cnxk.rst b/doc/guides/eventdevs/cnxk.rst
index 53560d3830..238b71f81f 100644
--- a/doc/guides/eventdevs/cnxk.rst
+++ b/doc/guides/eventdevs/cnxk.rst
@@ -164,6 +164,15 @@ Runtime Config Options
 
     -a 0002:0e:00.0,tim_ring_ctl=[2-1023-1-0]
 
+- ``TIM external clock frequency``
+
+  The ``tim_ext_clk`` devagrs can be used to pass external clock frequency when
+  external clock source is selected.
+
+  For Example::
+
+    -a 0002:0e:00.0,tim_ext_clk=122880000
+
 Debugging Options
 -----------------
 
diff --git a/drivers/common/cnxk/roc_platform.h b/drivers/common/cnxk/roc_platform.h
index 285b24b82d..7e73972b80 100644
--- a/drivers/common/cnxk/roc_platform.h
+++ b/drivers/common/cnxk/roc_platform.h
@@ -43,6 +43,7 @@
 #define PLT_MAX			 RTE_MAX
 #define PLT_DIM			 RTE_DIM
 #define PLT_SET_USED		 RTE_SET_USED
+#define PLT_SWAP		 RTE_SWAP
 #define PLT_STATIC_ASSERT(s)	 _Static_assert(s, #s)
 #define PLT_ALIGN		 RTE_ALIGN
 #define PLT_ALIGN_MUL_CEIL	 RTE_ALIGN_MUL_CEIL
diff --git a/drivers/event/cnxk/cnxk_tim_evdev.c b/drivers/event/cnxk/cnxk_tim_evdev.c
index 9d40e336d7..702686e68e 100644
--- a/drivers/event/cnxk/cnxk_tim_evdev.c
+++ b/drivers/event/cnxk/cnxk_tim_evdev.c
@@ -2,6 +2,8 @@
  * Copyright(C) 2021 Marvell.
  */
 
+#include <math.h>
+
 #include "cnxk_eventdev.h"
 #include "cnxk_tim_evdev.h"
 
@@ -115,12 +117,88 @@ cnxk_tim_ring_info_get(const struct rte_event_timer_adapter *adptr,
 		   sizeof(struct rte_event_timer_adapter_conf));
 }
 
+static inline void
+sort_multi_array(double ref_arr[], uint64_t arr1[], uint64_t arr2[],
+		 uint64_t arr3[], uint8_t sz)
+{
+	int x;
+
+	for (x = 0; x < sz - 1; x++) {
+		if (ref_arr[x] > ref_arr[x + 1]) {
+			PLT_SWAP(ref_arr[x], ref_arr[x + 1]);
+			PLT_SWAP(arr1[x], arr1[x + 1]);
+			PLT_SWAP(arr2[x], arr2[x + 1]);
+			PLT_SWAP(arr3[x], arr3[x + 1]);
+			x = -1;
+		}
+	}
+}
+
+static inline void
+populate_sample(uint64_t tck[], uint64_t ns[], double diff[], uint64_t dst[],
+		uint64_t req_tck, uint64_t clk_freq, double tck_ns, uint8_t sz,
+		bool mov_fwd)
+{
+	int i;
+
+	for (i = 0; i < sz; i++) {
+		tck[i] = i ? tck[i - 1] : req_tck;
+		do {
+			mov_fwd ? tck[i]++ : tck[i]--;
+			ns[i] = round((double)tck[i] * tck_ns);
+			if (round((double)tck[i] * tck_ns) >
+			    ((double)tck[i] * tck_ns))
+				continue;
+		} while (ns[i] % cnxk_tim_min_resolution_ns(clk_freq));
+		diff[i] = PLT_MAX((double)ns[i], (double)tck[i] * tck_ns) -
+			  PLT_MIN((double)ns[i], (double)tck[i] * tck_ns);
+		dst[i] = mov_fwd ? tck[i] - req_tck : req_tck - tck[i];
+	}
+}
+
+static void
+tim_adjust_resolution(uint64_t *req_ns, uint64_t *req_tck, double tck_ns,
+		      uint64_t clk_freq, uint64_t max_tmo)
+{
+#define MAX_SAMPLES 5
+	double rmax_diff[MAX_SAMPLES], rmin_diff[MAX_SAMPLES];
+	uint64_t min_tck[MAX_SAMPLES], max_tck[MAX_SAMPLES];
+	uint64_t min_dst[MAX_SAMPLES], max_dst[MAX_SAMPLES];
+	uint64_t min_ns[MAX_SAMPLES], max_ns[MAX_SAMPLES];
+	uint64_t m_tck = cnxk_tim_min_tmo_ticks(cnxk_tim_cntfrq());
+	int i;
+
+	populate_sample(max_tck, max_ns, rmax_diff, max_dst, *req_tck, clk_freq,
+			tck_ns, MAX_SAMPLES, true);
+	sort_multi_array(rmax_diff, max_dst, max_tck, max_ns, MAX_SAMPLES);
+
+	populate_sample(min_tck, min_ns, rmin_diff, min_dst, *req_tck, clk_freq,
+			tck_ns, MAX_SAMPLES, false);
+	sort_multi_array(rmin_diff, min_dst, min_tck, min_ns, MAX_SAMPLES);
+
+	for (i = 0; i < MAX_SAMPLES; i++) {
+		if (min_dst[i] < max_dst[i] && min_tck[i] > m_tck &&
+		    (max_tmo / min_ns[i]) <=
+			    (TIM_MAX_BUCKET_SIZE - TIM_MIN_BUCKET_SIZE)) {
+			*req_tck = min_tck[i];
+			*req_ns = min_ns[i];
+			break;
+		} else if ((max_tmo / max_ns[i]) <
+			   (TIM_MAX_BUCKET_SIZE - TIM_MIN_BUCKET_SIZE)) {
+			*req_tck = max_tck[i];
+			*req_ns = max_ns[i];
+			break;
+		}
+	}
+}
+
 static int
 cnxk_tim_ring_create(struct rte_event_timer_adapter *adptr)
 {
 	struct rte_event_timer_adapter_conf *rcfg = &adptr->data->conf;
 	struct cnxk_tim_evdev *dev = cnxk_tim_priv_get();
 	struct cnxk_tim_ring *tim_ring;
+	uint64_t interval;
 	int i, rc;
 
 	if (dev == NULL)
@@ -153,11 +231,35 @@ cnxk_tim_ring_create(struct rte_event_timer_adapter *adptr)
 			goto tim_hw_free;
 		}
 	}
+
 	tim_ring->ring_id = adptr->data->id;
 	tim_ring->clk_src = (int)rcfg->clk_src;
-	tim_ring->tck_nsec = RTE_ALIGN_MUL_CEIL(
-		rcfg->timer_tick_ns,
-		cnxk_tim_min_resolution_ns(cnxk_tim_cntfrq()));
+	if (rcfg->clk_src == RTE_EVENT_TIMER_ADAPTER_CPU_CLK) {
+		rcfg->timer_tick_ns = RTE_ALIGN_MUL_CEIL(
+			rcfg->timer_tick_ns,
+			cnxk_tim_min_resolution_ns(cnxk_tim_cntfrq()));
+	} else { /* External clock */
+		uint64_t req_ns, req_tck;
+		double tck_ns;
+
+		if (dev->ext_clk_frq == 0) {
+			rc = -ENODEV;
+			goto tim_hw_free;
+		}
+
+		req_ns = rcfg->timer_tick_ns;
+		tck_ns = NSECPERSEC / dev->ext_clk_frq;
+		req_tck = round(rcfg->timer_tick_ns / tck_ns);
+		tim_adjust_resolution(&req_ns, &req_tck, tck_ns,
+				      cnxk_tim_cntfrq(), rcfg->max_tmo_ns);
+		if ((rcfg->timer_tick_ns != req_ns) &&
+		    !(rcfg->flags & RTE_EVENT_TIMER_ADAPTER_F_ADJUST_RES)) {
+			rc = -ERANGE;
+			goto tim_hw_free;
+		}
+		rcfg->timer_tick_ns = ceil(req_tck * tck_ns);
+	}
+	tim_ring->tck_nsec = rcfg->timer_tick_ns;
 	tim_ring->max_tout = rcfg->max_tmo_ns;
 	tim_ring->nb_bkts = (tim_ring->max_tout / tim_ring->tck_nsec);
 	tim_ring->nb_timers = rcfg->nb_timers;
@@ -201,11 +303,15 @@ cnxk_tim_ring_create(struct rte_event_timer_adapter *adptr)
 	if (rc < 0)
 		goto tim_bkt_free;
 
-	rc = roc_tim_lf_config(
-		&dev->tim, tim_ring->ring_id,
-		cnxk_tim_convert_clk_src(tim_ring->clk_src), 0, 0,
-		tim_ring->nb_bkts, tim_ring->chunk_sz,
-		NSEC2TICK(tim_ring->tck_nsec, cnxk_tim_cntfrq()));
+	if (rcfg->clk_src == RTE_EVENT_TIMER_ADAPTER_CPU_CLK)
+		interval = NSEC2TICK(tim_ring->tck_nsec, cnxk_tim_cntfrq());
+	else
+		interval = NSEC2TICK(tim_ring->tck_nsec, dev->ext_clk_frq);
+
+	rc = roc_tim_lf_config(&dev->tim, tim_ring->ring_id,
+			       cnxk_tim_convert_clk_src(tim_ring->clk_src), 0,
+			       0, tim_ring->nb_bkts, tim_ring->chunk_sz,
+			       interval);
 	if (rc < 0) {
 		plt_err("Failed to configure timer ring");
 		goto tim_chnk_free;
@@ -480,6 +586,8 @@ cnxk_tim_parse_devargs(struct rte_devargs *devargs, struct cnxk_tim_evdev *dev)
 			   &dev->enable_stats);
 	rte_kvargs_process(kvlist, CNXK_TIM_RINGS_LMT, &parse_kvargs_value,
 			   &dev->min_ring_cnt);
+	rte_kvargs_process(kvlist, CNXK_TIM_EXT_CLK, &parse_kvargs_value,
+			   &dev->ext_clk_frq);
 	rte_kvargs_process(kvlist, CNXK_TIM_RING_CTL,
 			   &cnxk_tim_parse_kvargs_dict, &dev);
 
diff --git a/drivers/event/cnxk/cnxk_tim_evdev.h b/drivers/event/cnxk/cnxk_tim_evdev.h
index c369f6f472..b6e975dd50 100644
--- a/drivers/event/cnxk/cnxk_tim_evdev.h
+++ b/drivers/event/cnxk/cnxk_tim_evdev.h
@@ -39,6 +39,7 @@
 #define CNXK_TIM_STATS_ENA   "tim_stats_ena"
 #define CNXK_TIM_RINGS_LMT   "tim_rings_lmt"
 #define CNXK_TIM_RING_CTL    "tim_ring_ctl"
+#define CNXK_TIM_EXT_CLK     "tim_ext_clk"
 
 #define CNXK_TIM_SP	   0x1
 #define CNXK_TIM_MP	   0x2
@@ -94,6 +95,7 @@ struct cnxk_tim_evdev {
 	uint16_t min_ring_cnt;
 	uint8_t enable_stats;
 	uint16_t ring_ctl_cnt;
+	uint64_t ext_clk_frq;
 	struct cnxk_tim_ctl *ring_ctl_data;
 };
 
@@ -187,7 +189,9 @@ cnxk_tim_convert_clk_src(enum cnxk_tim_clk_src clk_src)
 	switch (clk_src) {
 	case RTE_EVENT_TIMER_ADAPTER_CPU_CLK:
 		return roc_model_runtime_is_cn9k() ? ROC_TIM_CLK_SRC_10NS :
-							   ROC_TIM_CLK_SRC_GTI;
+						     ROC_TIM_CLK_SRC_GTI;
+	case RTE_EVENT_TIMER_ADAPTER_EXT_CLK0:
+		return ROC_TIM_CLK_SRC_GPIO;
 	default:
 		return ROC_TIM_CLK_SRC_INVALID;
 	}
-- 
2.25.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [dpdk-dev] [PATCH v2] drivers: add external clock support for cnxk timer
  2021-07-28 15:24 [dpdk-dev] [PATCH] drivers: add external clock support for cnxk timer Shijith Thotton
@ 2021-09-15 16:03 ` Shijith Thotton
  2021-09-23 21:30   ` [dpdk-dev] [PATCH v3 1/2] event/cnxk: update min interval calculation pbhagavatula
  0 siblings, 1 reply; 11+ messages in thread
From: Shijith Thotton @ 2021-09-15 16:03 UTC (permalink / raw)
  To: dev
  Cc: Shijith Thotton, jerinj, Pavan Nikhilesh, Nithin Dabilpuram,
	Kiran Kumar K, Sunil Kumar Kori, Satha Rao

To configure tim with external clock, requested resolution should be
adjusted based on core and external clock frequency for accuracy.

tim_ext_clk is the devarg used to pass external clock frequency.

E.g. -a 0002:0e:00.0,tim_ext_clk=122880000

Signed-off-by: Shijith Thotton <sthotton@marvell.com>
Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
---
Depends-on: series-18039 ("eal: add macro to swap two numbers")

v2:
- Fixed devargs parsing and rebased.

 doc/guides/eventdevs/cnxk.rst       |   9 ++
 drivers/common/cnxk/roc_platform.h  |   1 +
 drivers/common/cnxk/roc_tim.h       |   2 +
 drivers/event/cnxk/cnxk_eventdev.h  |   9 ++
 drivers/event/cnxk/cnxk_tim_evdev.c | 124 ++++++++++++++++++++++++++--
 drivers/event/cnxk/cnxk_tim_evdev.h |   6 +-
 6 files changed, 142 insertions(+), 9 deletions(-)

diff --git a/doc/guides/eventdevs/cnxk.rst b/doc/guides/eventdevs/cnxk.rst
index 53560d3830..238b71f81f 100644
--- a/doc/guides/eventdevs/cnxk.rst
+++ b/doc/guides/eventdevs/cnxk.rst
@@ -164,6 +164,15 @@ Runtime Config Options
 
     -a 0002:0e:00.0,tim_ring_ctl=[2-1023-1-0]
 
+- ``TIM external clock frequency``
+
+  The ``tim_ext_clk`` devagrs can be used to pass external clock frequency when
+  external clock source is selected.
+
+  For Example::
+
+    -a 0002:0e:00.0,tim_ext_clk=122880000
+
 Debugging Options
 -----------------
 
diff --git a/drivers/common/cnxk/roc_platform.h b/drivers/common/cnxk/roc_platform.h
index 285b24b82d..7e73972b80 100644
--- a/drivers/common/cnxk/roc_platform.h
+++ b/drivers/common/cnxk/roc_platform.h
@@ -43,6 +43,7 @@
 #define PLT_MAX			 RTE_MAX
 #define PLT_DIM			 RTE_DIM
 #define PLT_SET_USED		 RTE_SET_USED
+#define PLT_SWAP		 RTE_SWAP
 #define PLT_STATIC_ASSERT(s)	 _Static_assert(s, #s)
 #define PLT_ALIGN		 RTE_ALIGN
 #define PLT_ALIGN_MUL_CEIL	 RTE_ALIGN_MUL_CEIL
diff --git a/drivers/common/cnxk/roc_tim.h b/drivers/common/cnxk/roc_tim.h
index 159b021a31..205113f24f 100644
--- a/drivers/common/cnxk/roc_tim.h
+++ b/drivers/common/cnxk/roc_tim.h
@@ -10,6 +10,8 @@ enum roc_tim_clk_src {
 	ROC_TIM_CLK_SRC_GPIO,
 	ROC_TIM_CLK_SRC_GTI,
 	ROC_TIM_CLK_SRC_PTP,
+	ROC_TIM_CLK_SRC_SYNCE,
+	ROC_TIM_CLK_SRC_BTS,
 	ROC_TIM_CLK_SRC_INVALID,
 };
 
diff --git a/drivers/event/cnxk/cnxk_eventdev.h b/drivers/event/cnxk/cnxk_eventdev.h
index fc49b88d6f..7c3fcbe6f8 100644
--- a/drivers/event/cnxk/cnxk_eventdev.h
+++ b/drivers/event/cnxk/cnxk_eventdev.h
@@ -200,6 +200,15 @@ parse_kvargs_value(const char *key, const char *value, void *opaque)
 	return 0;
 }
 
+static inline int
+parse_kvargs_long(const char *key, const char *value, void *opaque)
+{
+	RTE_SET_USED(key);
+
+	*(uint64_t *)opaque = (uint64_t)atol(value);
+	return 0;
+}
+
 static inline struct cnxk_sso_evdev *
 cnxk_sso_pmd_priv(const struct rte_eventdev *event_dev)
 {
diff --git a/drivers/event/cnxk/cnxk_tim_evdev.c b/drivers/event/cnxk/cnxk_tim_evdev.c
index c3e9dc508c..5b117da1b1 100644
--- a/drivers/event/cnxk/cnxk_tim_evdev.c
+++ b/drivers/event/cnxk/cnxk_tim_evdev.c
@@ -2,6 +2,8 @@
  * Copyright(C) 2021 Marvell.
  */
 
+#include <math.h>
+
 #include "cnxk_eventdev.h"
 #include "cnxk_tim_evdev.h"
 
@@ -115,12 +117,88 @@ cnxk_tim_ring_info_get(const struct rte_event_timer_adapter *adptr,
 		   sizeof(struct rte_event_timer_adapter_conf));
 }
 
+static inline void
+sort_multi_array(double ref_arr[], uint64_t arr1[], uint64_t arr2[],
+		 uint64_t arr3[], uint8_t sz)
+{
+	int x;
+
+	for (x = 0; x < sz - 1; x++) {
+		if (ref_arr[x] > ref_arr[x + 1]) {
+			PLT_SWAP(ref_arr[x], ref_arr[x + 1]);
+			PLT_SWAP(arr1[x], arr1[x + 1]);
+			PLT_SWAP(arr2[x], arr2[x + 1]);
+			PLT_SWAP(arr3[x], arr3[x + 1]);
+			x = -1;
+		}
+	}
+}
+
+static inline void
+populate_sample(uint64_t tck[], uint64_t ns[], double diff[], uint64_t dst[],
+		uint64_t req_tck, uint64_t clk_freq, double tck_ns, uint8_t sz,
+		bool mov_fwd)
+{
+	int i;
+
+	for (i = 0; i < sz; i++) {
+		tck[i] = i ? tck[i - 1] : req_tck;
+		do {
+			mov_fwd ? tck[i]++ : tck[i]--;
+			ns[i] = round((double)tck[i] * tck_ns);
+			if (round((double)tck[i] * tck_ns) >
+			    ((double)tck[i] * tck_ns))
+				continue;
+		} while (ns[i] % cnxk_tim_min_resolution_ns(clk_freq));
+		diff[i] = PLT_MAX((double)ns[i], (double)tck[i] * tck_ns) -
+			  PLT_MIN((double)ns[i], (double)tck[i] * tck_ns);
+		dst[i] = mov_fwd ? tck[i] - req_tck : req_tck - tck[i];
+	}
+}
+
+static void
+tim_adjust_resolution(uint64_t *req_ns, uint64_t *req_tck, double tck_ns,
+		      uint64_t clk_freq, uint64_t max_tmo)
+{
+#define MAX_SAMPLES 5
+	double rmax_diff[MAX_SAMPLES], rmin_diff[MAX_SAMPLES];
+	uint64_t min_tck[MAX_SAMPLES], max_tck[MAX_SAMPLES];
+	uint64_t min_dst[MAX_SAMPLES], max_dst[MAX_SAMPLES];
+	uint64_t min_ns[MAX_SAMPLES], max_ns[MAX_SAMPLES];
+	uint64_t m_tck = cnxk_tim_min_tmo_ticks(cnxk_tim_cntfrq());
+	int i;
+
+	populate_sample(max_tck, max_ns, rmax_diff, max_dst, *req_tck, clk_freq,
+			tck_ns, MAX_SAMPLES, true);
+	sort_multi_array(rmax_diff, max_dst, max_tck, max_ns, MAX_SAMPLES);
+
+	populate_sample(min_tck, min_ns, rmin_diff, min_dst, *req_tck, clk_freq,
+			tck_ns, MAX_SAMPLES, false);
+	sort_multi_array(rmin_diff, min_dst, min_tck, min_ns, MAX_SAMPLES);
+
+	for (i = 0; i < MAX_SAMPLES; i++) {
+		if (min_dst[i] < max_dst[i] && min_tck[i] > m_tck &&
+		    (max_tmo / min_ns[i]) <=
+			    (TIM_MAX_BUCKET_SIZE - TIM_MIN_BUCKET_SIZE)) {
+			*req_tck = min_tck[i];
+			*req_ns = min_ns[i];
+			break;
+		} else if ((max_tmo / max_ns[i]) <
+			   (TIM_MAX_BUCKET_SIZE - TIM_MIN_BUCKET_SIZE)) {
+			*req_tck = max_tck[i];
+			*req_ns = max_ns[i];
+			break;
+		}
+	}
+}
+
 static int
 cnxk_tim_ring_create(struct rte_event_timer_adapter *adptr)
 {
 	struct rte_event_timer_adapter_conf *rcfg = &adptr->data->conf;
 	struct cnxk_tim_evdev *dev = cnxk_tim_priv_get();
 	struct cnxk_tim_ring *tim_ring;
+	uint64_t interval;
 	int i, rc;
 
 	if (dev == NULL)
@@ -153,11 +231,35 @@ cnxk_tim_ring_create(struct rte_event_timer_adapter *adptr)
 			goto tim_hw_free;
 		}
 	}
+
 	tim_ring->ring_id = adptr->data->id;
 	tim_ring->clk_src = (int)rcfg->clk_src;
-	tim_ring->tck_nsec = RTE_ALIGN_MUL_CEIL(
-		rcfg->timer_tick_ns,
-		cnxk_tim_min_resolution_ns(cnxk_tim_cntfrq()));
+	if (rcfg->clk_src == RTE_EVENT_TIMER_ADAPTER_CPU_CLK) {
+		rcfg->timer_tick_ns = RTE_ALIGN_MUL_CEIL(
+			rcfg->timer_tick_ns,
+			cnxk_tim_min_resolution_ns(cnxk_tim_cntfrq()));
+	} else { /* External clock */
+		uint64_t req_ns, req_tck;
+		double tck_ns;
+
+		if (dev->ext_clk_frq == 0) {
+			rc = -ENODEV;
+			goto tim_hw_free;
+		}
+
+		req_ns = rcfg->timer_tick_ns;
+		tck_ns = NSECPERSEC / dev->ext_clk_frq;
+		req_tck = round(rcfg->timer_tick_ns / tck_ns);
+		tim_adjust_resolution(&req_ns, &req_tck, tck_ns,
+				      cnxk_tim_cntfrq(), rcfg->max_tmo_ns);
+		if ((rcfg->timer_tick_ns != req_ns) &&
+		    !(rcfg->flags & RTE_EVENT_TIMER_ADAPTER_F_ADJUST_RES)) {
+			rc = -ERANGE;
+			goto tim_hw_free;
+		}
+		rcfg->timer_tick_ns = ceil(req_tck * tck_ns);
+	}
+	tim_ring->tck_nsec = rcfg->timer_tick_ns;
 	tim_ring->max_tout = rcfg->max_tmo_ns;
 	tim_ring->nb_bkts = (tim_ring->max_tout / tim_ring->tck_nsec);
 	tim_ring->nb_timers = rcfg->nb_timers;
@@ -201,11 +303,15 @@ cnxk_tim_ring_create(struct rte_event_timer_adapter *adptr)
 	if (rc < 0)
 		goto tim_bkt_free;
 
-	rc = roc_tim_lf_config(
-		&dev->tim, tim_ring->ring_id,
-		cnxk_tim_convert_clk_src(tim_ring->clk_src), 0, 0,
-		tim_ring->nb_bkts, tim_ring->chunk_sz,
-		NSEC2TICK(tim_ring->tck_nsec, cnxk_tim_cntfrq()));
+	if (rcfg->clk_src == RTE_EVENT_TIMER_ADAPTER_CPU_CLK)
+		interval = NSEC2TICK(tim_ring->tck_nsec, cnxk_tim_cntfrq());
+	else
+		interval = NSEC2TICK(tim_ring->tck_nsec, dev->ext_clk_frq);
+
+	rc = roc_tim_lf_config(&dev->tim, tim_ring->ring_id,
+			       cnxk_tim_convert_clk_src(tim_ring->clk_src), 0,
+			       0, tim_ring->nb_bkts, tim_ring->chunk_sz,
+			       interval);
 	if (rc < 0) {
 		plt_err("Failed to configure timer ring");
 		goto tim_chnk_free;
@@ -480,6 +586,8 @@ cnxk_tim_parse_devargs(struct rte_devargs *devargs, struct cnxk_tim_evdev *dev)
 			   &dev->enable_stats);
 	rte_kvargs_process(kvlist, CNXK_TIM_RINGS_LMT, &parse_kvargs_value,
 			   &dev->min_ring_cnt);
+	rte_kvargs_process(kvlist, CNXK_TIM_EXT_CLK, &parse_kvargs_long,
+			   &dev->ext_clk_frq);
 	rte_kvargs_process(kvlist, CNXK_TIM_RING_CTL,
 			   &cnxk_tim_parse_kvargs_dict, &dev);
 
diff --git a/drivers/event/cnxk/cnxk_tim_evdev.h b/drivers/event/cnxk/cnxk_tim_evdev.h
index 9a23952a91..6fc86c88d7 100644
--- a/drivers/event/cnxk/cnxk_tim_evdev.h
+++ b/drivers/event/cnxk/cnxk_tim_evdev.h
@@ -40,6 +40,7 @@
 #define CNXK_TIM_STATS_ENA   "tim_stats_ena"
 #define CNXK_TIM_RINGS_LMT   "tim_rings_lmt"
 #define CNXK_TIM_RING_CTL    "tim_ring_ctl"
+#define CNXK_TIM_EXT_CLK     "tim_ext_clk"
 
 #define CNXK_TIM_SP	   0x1
 #define CNXK_TIM_MP	   0x2
@@ -95,6 +96,7 @@ struct cnxk_tim_evdev {
 	uint32_t min_ring_cnt;
 	uint8_t enable_stats;
 	uint16_t ring_ctl_cnt;
+	uint64_t ext_clk_frq;
 	struct cnxk_tim_ctl *ring_ctl_data;
 };
 
@@ -188,7 +190,9 @@ cnxk_tim_convert_clk_src(enum cnxk_tim_clk_src clk_src)
 	switch (clk_src) {
 	case RTE_EVENT_TIMER_ADAPTER_CPU_CLK:
 		return roc_model_runtime_is_cn9k() ? ROC_TIM_CLK_SRC_10NS :
-							   ROC_TIM_CLK_SRC_GTI;
+						     ROC_TIM_CLK_SRC_GTI;
+	case RTE_EVENT_TIMER_ADAPTER_EXT_CLK0:
+		return ROC_TIM_CLK_SRC_GPIO;
 	default:
 		return ROC_TIM_CLK_SRC_INVALID;
 	}
-- 
2.25.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [dpdk-dev] [PATCH v3 1/2] event/cnxk: update min interval calculation
  2021-09-15 16:03 ` [dpdk-dev] [PATCH v2] " Shijith Thotton
@ 2021-09-23 21:30   ` pbhagavatula
  2021-09-23 21:30     ` [dpdk-dev] [PATCH v3 2/2] event/cnxk: add external clock support for timer pbhagavatula
  2021-10-09  8:04     ` [dpdk-dev] [PATCH v4 1/2] event/cnxk: update min interval calculation pbhagavatula
  0 siblings, 2 replies; 11+ messages in thread
From: pbhagavatula @ 2021-09-23 21:30 UTC (permalink / raw)
  To: jerinj, Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori,
	Satha Rao, Ray Kinsella, Pavan Nikhilesh, Shijith Thotton
  Cc: dev

From: Pavan Nikhilesh <pbhagavatula@marvell.com>

Minimum supported interval should now be retrieved from
mailbox based on the clock source and clock frequency.

Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
---
v3:
- Add new mbox interface.
v2:
- Fixed devargs parsing and rebased.

 drivers/common/cnxk/roc_mbox.h      | 17 +++++++
 drivers/common/cnxk/roc_tim.c       | 32 +++++++++++-
 drivers/common/cnxk/roc_tim.h       |  9 +++-
 drivers/common/cnxk/version.map     |  1 +
 drivers/event/cnxk/cnxk_tim_evdev.c | 69 +++++++++++++++++--------
 drivers/event/cnxk/cnxk_tim_evdev.h | 79 ++++++++++++++++++-----------
 6 files changed, 155 insertions(+), 52 deletions(-)

diff --git a/drivers/common/cnxk/roc_mbox.h b/drivers/common/cnxk/roc_mbox.h
index b5da931b81..07485c1b6b 100644
--- a/drivers/common/cnxk/roc_mbox.h
+++ b/drivers/common/cnxk/roc_mbox.h
@@ -131,6 +131,8 @@ struct mbox_msghdr {
 	M(TIM_ENABLE_RING, 0x803, tim_enable_ring, tim_ring_req,               \
 	  tim_enable_rsp)                                                      \
 	M(TIM_DISABLE_RING, 0x804, tim_disable_ring, tim_ring_req, msg_rsp)    \
+	M(TIM_GET_MIN_INTVL, 0x805, tim_get_min_intvl, tim_intvl_req,          \
+	  tim_intvl_rsp)                                                       \
 	/* CPT mbox IDs (range 0xA00 - 0xBFF) */                               \
 	M(CPT_LF_ALLOC, 0xA00, cpt_lf_alloc, cpt_lf_alloc_req_msg, msg_rsp)    \
 	M(CPT_LF_FREE, 0xA01, cpt_lf_free, msg_req, msg_rsp)                   \
@@ -1755,6 +1757,9 @@ struct tim_config_req {
 	uint32_t __io chunksize;
 	uint32_t __io interval;
 	uint8_t __io gpioedge;
+	uint8_t __io rsvd[7];
+	uint64_t __io intervalns;
+	uint64_t __io clockfreq;
 };

 struct tim_lf_alloc_rsp {
@@ -1768,6 +1773,18 @@ struct tim_enable_rsp {
 	uint32_t __io currentbucket;
 };

+struct tim_intvl_req {
+	struct mbox_msghdr hdr;
+	uint8_t __io clocksource;
+	uint64_t __io clockfreq;
+};
+
+struct tim_intvl_rsp {
+	struct mbox_msghdr hdr;
+	uint64_t __io intvl_cyc;
+	uint64_t __io intvl_ns;
+};
+
 struct sdp_node_info {
 	/* Node to which this PF belons to */
 	uint8_t __io node_id;
diff --git a/drivers/common/cnxk/roc_tim.c b/drivers/common/cnxk/roc_tim.c
index 387164bb1d..eefa8253bc 100644
--- a/drivers/common/cnxk/roc_tim.c
+++ b/drivers/common/cnxk/roc_tim.c
@@ -145,7 +145,7 @@ int
 roc_tim_lf_config(struct roc_tim *roc_tim, uint8_t ring_id,
 		  enum roc_tim_clk_src clk_src, uint8_t ena_periodic,
 		  uint8_t ena_dfb, uint32_t bucket_sz, uint32_t chunk_sz,
-		  uint32_t interval)
+		  uint32_t interval, uint64_t intervalns, uint64_t clockfreq)
 {
 	struct dev *dev = &roc_sso_to_sso_priv(roc_tim->roc_sso)->dev;
 	struct tim_config_req *req;
@@ -162,6 +162,8 @@ roc_tim_lf_config(struct roc_tim *roc_tim, uint8_t ring_id,
 	req->enableperiodic = ena_periodic;
 	req->enabledontfreebuffer = ena_dfb;
 	req->interval = interval;
+	req->intervalns = intervalns;
+	req->clockfreq = clockfreq;
 	req->gpioedge = TIM_GPIO_LTOH_TRANS;

 	rc = mbox_process(dev->mbox);
@@ -173,6 +175,34 @@ roc_tim_lf_config(struct roc_tim *roc_tim, uint8_t ring_id,
 	return 0;
 }

+int
+roc_tim_lf_interval(struct roc_tim *roc_tim, enum roc_tim_clk_src clk_src,
+		    uint64_t clockfreq, uint64_t *intervalns,
+		    uint64_t *interval)
+{
+	struct dev *dev = &roc_sso_to_sso_priv(roc_tim->roc_sso)->dev;
+	struct tim_intvl_req *req;
+	struct tim_intvl_rsp *rsp;
+	int rc = -ENOSPC;
+
+	req = mbox_alloc_msg_tim_get_min_intvl(dev->mbox);
+	if (req == NULL)
+		return rc;
+
+	req->clockfreq = clockfreq;
+	req->clocksource = clk_src;
+	rc = mbox_process_msg(dev->mbox, (void **)&rsp);
+	if (rc < 0) {
+		tim_err_desc(rc);
+		return rc;
+	}
+
+	*intervalns = rsp->intvl_ns;
+	*interval = rsp->intvl_cyc;
+
+	return 0;
+}
+
 int
 roc_tim_lf_alloc(struct roc_tim *roc_tim, uint8_t ring_id, uint64_t *clk)
 {
diff --git a/drivers/common/cnxk/roc_tim.h b/drivers/common/cnxk/roc_tim.h
index 159b021a31..392732eae2 100644
--- a/drivers/common/cnxk/roc_tim.h
+++ b/drivers/common/cnxk/roc_tim.h
@@ -10,6 +10,8 @@ enum roc_tim_clk_src {
 	ROC_TIM_CLK_SRC_GPIO,
 	ROC_TIM_CLK_SRC_GTI,
 	ROC_TIM_CLK_SRC_PTP,
+	ROC_TIM_CLK_SRC_SYNCE,
+	ROC_TIM_CLK_SRC_BTS,
 	ROC_TIM_CLK_SRC_INVALID,
 };

@@ -33,7 +35,12 @@ int __roc_api roc_tim_lf_config(struct roc_tim *roc_tim, uint8_t ring_id,
 				enum roc_tim_clk_src clk_src,
 				uint8_t ena_periodic, uint8_t ena_dfb,
 				uint32_t bucket_sz, uint32_t chunk_sz,
-				uint32_t interval);
+				uint32_t interval, uint64_t intervalns,
+				uint64_t clockfreq);
+int __roc_api roc_tim_lf_interval(struct roc_tim *roc_tim,
+				  enum roc_tim_clk_src clk_src,
+				  uint64_t clockfreq, uint64_t *intervalns,
+				  uint64_t *interval);
 int __roc_api roc_tim_lf_alloc(struct roc_tim *roc_tim, uint8_t ring_id,
 			       uint64_t *clk);
 int __roc_api roc_tim_lf_free(struct roc_tim *roc_tim, uint8_t ring_id);
diff --git a/drivers/common/cnxk/version.map b/drivers/common/cnxk/version.map
index 5df2e56ce6..e8073d5f55 100644
--- a/drivers/common/cnxk/version.map
+++ b/drivers/common/cnxk/version.map
@@ -269,6 +269,7 @@ INTERNAL {
 	roc_tim_lf_disable;
 	roc_tim_lf_enable;
 	roc_tim_lf_free;
+	roc_tim_lf_interval;
 	roc_se_ctx_swap;

 	local: *;
diff --git a/drivers/event/cnxk/cnxk_tim_evdev.c b/drivers/event/cnxk/cnxk_tim_evdev.c
index 9d40e336d7..369f198444 100644
--- a/drivers/event/cnxk/cnxk_tim_evdev.c
+++ b/drivers/event/cnxk/cnxk_tim_evdev.c
@@ -2,6 +2,8 @@
  * Copyright(C) 2021 Marvell.
  */

+#include <math.h>
+
 #include "cnxk_eventdev.h"
 #include "cnxk_tim_evdev.h"

@@ -120,7 +122,10 @@ cnxk_tim_ring_create(struct rte_event_timer_adapter *adptr)
 {
 	struct rte_event_timer_adapter_conf *rcfg = &adptr->data->conf;
 	struct cnxk_tim_evdev *dev = cnxk_tim_priv_get();
+	uint64_t min_intvl_ns, min_intvl_cyc;
 	struct cnxk_tim_ring *tim_ring;
+	enum roc_tim_clk_src clk_src;
+	uint64_t clk_freq = 0;
 	int i, rc;

 	if (dev == NULL)
@@ -139,25 +144,52 @@ cnxk_tim_ring_create(struct rte_event_timer_adapter *adptr)
 		goto tim_ring_free;
 	}

-	if (NSEC2TICK(RTE_ALIGN_MUL_CEIL(
-			      rcfg->timer_tick_ns,
-			      cnxk_tim_min_resolution_ns(cnxk_tim_cntfrq())),
-		      cnxk_tim_cntfrq()) <
-	    cnxk_tim_min_tmo_ticks(cnxk_tim_cntfrq())) {
-		if (rcfg->flags & RTE_EVENT_TIMER_ADAPTER_F_ADJUST_RES)
-			rcfg->timer_tick_ns = TICK2NSEC(
-				cnxk_tim_min_tmo_ticks(cnxk_tim_cntfrq()),
-				cnxk_tim_cntfrq());
-		else {
+	clk_src = cnxk_tim_convert_clk_src(rcfg->clk_src);
+	if (clk_src == ROC_TIM_CLK_SRC_INVALID) {
+		plt_err("Invalid clock source");
+		goto tim_hw_free;
+	}
+
+	rc = cnxk_tim_get_clk_freq(dev, clk_src, &clk_freq);
+	if (rc < 0) {
+		plt_err("Failed to get clock frequency");
+		goto tim_hw_free;
+	}
+
+	rc = roc_tim_lf_interval(&dev->tim, clk_src, clk_freq, &min_intvl_ns,
+				 &min_intvl_cyc);
+	if (rc < 0) {
+		plt_err("Failed to get min interval details");
+		goto tim_hw_free;
+	}
+
+	if (rcfg->timer_tick_ns < min_intvl_ns) {
+		if (rcfg->flags & RTE_EVENT_TIMER_ADAPTER_F_ADJUST_RES) {
+			rcfg->timer_tick_ns = min_intvl_ns;
+		} else {
 			rc = -ERANGE;
 			goto tim_hw_free;
 		}
 	}
+
+	if (rcfg->timer_tick_ns > rcfg->max_tmo_ns) {
+		plt_err("Max timeout to too high");
+		rc = -ERANGE;
+		goto tim_hw_free;
+	}
+
+	/* Round */
+	tim_ring->tck_nsec =
+		round(RTE_ALIGN_MUL_NEAR((long double)rcfg->timer_tick_ns,
+					 cnxk_tim_ns_per_tck(clk_freq)));
+
+	tim_ring->tck_int = round((long double)tim_ring->tck_nsec /
+				  cnxk_tim_ns_per_tck(clk_freq));
+	tim_ring->tck_nsec =
+		ceil(tim_ring->tck_int * cnxk_tim_ns_per_tck(clk_freq));
+
 	tim_ring->ring_id = adptr->data->id;
-	tim_ring->clk_src = (int)rcfg->clk_src;
-	tim_ring->tck_nsec = RTE_ALIGN_MUL_CEIL(
-		rcfg->timer_tick_ns,
-		cnxk_tim_min_resolution_ns(cnxk_tim_cntfrq()));
+	tim_ring->clk_src = clk_src;
 	tim_ring->max_tout = rcfg->max_tmo_ns;
 	tim_ring->nb_bkts = (tim_ring->max_tout / tim_ring->tck_nsec);
 	tim_ring->nb_timers = rcfg->nb_timers;
@@ -201,11 +233,9 @@ cnxk_tim_ring_create(struct rte_event_timer_adapter *adptr)
 	if (rc < 0)
 		goto tim_bkt_free;

-	rc = roc_tim_lf_config(
-		&dev->tim, tim_ring->ring_id,
-		cnxk_tim_convert_clk_src(tim_ring->clk_src), 0, 0,
-		tim_ring->nb_bkts, tim_ring->chunk_sz,
-		NSEC2TICK(tim_ring->tck_nsec, cnxk_tim_cntfrq()));
+	rc = roc_tim_lf_config(&dev->tim, tim_ring->ring_id, clk_src, 0, 0,
+			       tim_ring->nb_bkts, tim_ring->chunk_sz,
+			       tim_ring->tck_int, tim_ring->tck_nsec, clk_freq);
 	if (rc < 0) {
 		plt_err("Failed to configure timer ring");
 		goto tim_chnk_free;
@@ -300,7 +330,6 @@ cnxk_tim_ring_start(const struct rte_event_timer_adapter *adptr)
 	if (rc < 0)
 		return rc;

-	tim_ring->tck_int = NSEC2TICK(tim_ring->tck_nsec, cnxk_tim_cntfrq());
 	tim_ring->tot_int = tim_ring->tck_int * tim_ring->nb_bkts;
 	tim_ring->fast_div = rte_reciprocal_value_u64(tim_ring->tck_int);
 	tim_ring->fast_bkt = rte_reciprocal_value_u64(tim_ring->nb_bkts);
diff --git a/drivers/event/cnxk/cnxk_tim_evdev.h b/drivers/event/cnxk/cnxk_tim_evdev.h
index c369f6f472..7d401fccbd 100644
--- a/drivers/event/cnxk/cnxk_tim_evdev.h
+++ b/drivers/event/cnxk/cnxk_tim_evdev.h
@@ -97,13 +97,6 @@ struct cnxk_tim_evdev {
 	struct cnxk_tim_ctl *ring_ctl_data;
 };

-enum cnxk_tim_clk_src {
-	CNXK_TIM_CLK_SRC_10NS = RTE_EVENT_TIMER_ADAPTER_CPU_CLK,
-	CNXK_TIM_CLK_SRC_GPIO = RTE_EVENT_TIMER_ADAPTER_EXT_CLK0,
-	CNXK_TIM_CLK_SRC_GTI = RTE_EVENT_TIMER_ADAPTER_EXT_CLK1,
-	CNXK_TIM_CLK_SRC_PTP = RTE_EVENT_TIMER_ADAPTER_EXT_CLK2,
-};
-
 struct cnxk_tim_bkt {
 	uint64_t first_chunk;
 	union {
@@ -146,7 +139,7 @@ struct cnxk_tim_ring {
 	uint64_t max_tout;
 	uint64_t nb_chunks;
 	uint64_t chunk_sz;
-	enum cnxk_tim_clk_src clk_src;
+	enum roc_tim_clk_src clk_src;
 } __rte_cache_aligned;

 struct cnxk_tim_ent {
@@ -166,32 +159,13 @@ cnxk_tim_priv_get(void)
 	return mz->addr;
 }

-static inline uint64_t
-cnxk_tim_min_tmo_ticks(uint64_t freq)
+static inline long double
+cnxk_tim_ns_per_tck(uint64_t freq)
 {
-	if (roc_model_runtime_is_cn9k())
-		return CN9K_TIM_MIN_TMO_TKS;
-	else /* CN10K min tick is of 1us */
-		return freq / USECPERSEC;
+	return (long double)NSECPERSEC / freq;
 }

-static inline uint64_t
-cnxk_tim_min_resolution_ns(uint64_t freq)
-{
-	return NSECPERSEC / freq;
-}

-static inline enum roc_tim_clk_src
-cnxk_tim_convert_clk_src(enum cnxk_tim_clk_src clk_src)
-{
-	switch (clk_src) {
-	case RTE_EVENT_TIMER_ADAPTER_CPU_CLK:
-		return roc_model_runtime_is_cn9k() ? ROC_TIM_CLK_SRC_10NS :
-							   ROC_TIM_CLK_SRC_GTI;
-	default:
-		return ROC_TIM_CLK_SRC_INVALID;
-	}
-}

 #ifdef RTE_ARCH_ARM64
 static inline uint64_t
@@ -225,6 +199,51 @@ cnxk_tim_cntfrq(void)
 }
 #endif

+static inline enum roc_tim_clk_src
+cnxk_tim_convert_clk_src(enum rte_event_timer_adapter_clk_src clk_src)
+{
+	switch (clk_src) {
+	case RTE_EVENT_TIMER_ADAPTER_CPU_CLK:
+		return ROC_TIM_CLK_SRC_GTI;
+	case RTE_EVENT_TIMER_ADAPTER_EXT_CLK0:
+		return ROC_TIM_CLK_SRC_10NS;
+	case RTE_EVENT_TIMER_ADAPTER_EXT_CLK1:
+		return ROC_TIM_CLK_SRC_GPIO;
+	case RTE_EVENT_TIMER_ADAPTER_EXT_CLK2:
+		return ROC_TIM_CLK_SRC_PTP;
+	case RTE_EVENT_TIMER_ADAPTER_EXT_CLK3:
+		return roc_model_constant_is_cn9k() ? ROC_TIM_CLK_SRC_INVALID :
+						      ROC_TIM_CLK_SRC_SYNCE;
+	default:
+		return ROC_TIM_CLK_SRC_INVALID;
+	}
+}
+
+static inline int
+cnxk_tim_get_clk_freq(struct cnxk_tim_evdev *dev, enum roc_tim_clk_src clk_src,
+		      uint64_t *freq)
+{
+	if (freq == NULL)
+		return -EINVAL;
+
+	PLT_SET_USED(dev);
+	switch (clk_src) {
+	case ROC_TIM_CLK_SRC_GTI:
+		*freq = cnxk_tim_cntfrq();
+		break;
+	case ROC_TIM_CLK_SRC_10NS:
+		*freq = 1E8;
+		break;
+	case ROC_TIM_CLK_SRC_GPIO:
+	case ROC_TIM_CLK_SRC_PTP:
+	case ROC_TIM_CLK_SRC_SYNCE:
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 #define TIM_ARM_FASTPATH_MODES                                                 \
 	FP(sp, 0, 0, 0, CNXK_TIM_ENA_DFB | CNXK_TIM_SP)                        \
 	FP(mp, 0, 0, 1, CNXK_TIM_ENA_DFB | CNXK_TIM_MP)                        \
--
2.17.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [dpdk-dev] [PATCH v3 2/2] event/cnxk: add external clock support for timer
  2021-09-23 21:30   ` [dpdk-dev] [PATCH v3 1/2] event/cnxk: update min interval calculation pbhagavatula
@ 2021-09-23 21:30     ` pbhagavatula
  2021-10-09  8:04     ` [dpdk-dev] [PATCH v4 1/2] event/cnxk: update min interval calculation pbhagavatula
  1 sibling, 0 replies; 11+ messages in thread
From: pbhagavatula @ 2021-09-23 21:30 UTC (permalink / raw)
  To: jerinj, Pavan Nikhilesh, Shijith Thotton, Nithin Dabilpuram,
	Kiran Kumar K, Sunil Kumar Kori, Satha Rao
  Cc: dev

From: Pavan Nikhilesh <pbhagavatula@marvell.com>

Add external clock support for cnxk timer adapter.

External clock mapping is as follows:
RTE_EVENT_TIMER_ADAPTER_EXT_CLK0 = TIM_CLK_SRC_10NS,
RTE_EVENT_TIMER_ADAPTER_EXT_CLK1 = TIM_CLK_SRC_GPIO,
RTE_EVENT_TIMER_ADAPTER_EXT_CLK2 = TIM_CLK_SRC_PTP,
RTE_EVENT_TIMER_ADAPTER_EXT_CLK3 = TIM_CLK_SRC_SYNCE,

TIM supports clock input from external GPIO, PTP, SYNCE clocks.
Input resolution is adjusted based on CNTVCT frequency for better
estimation.

Since TIM is unaware of input clock frequency, application is
expected to pass the frequency.
Example:
	-a 0002:0e:00.0,tim_eclk_freq=122880000-0-0

The order of frequencies above is GPIO-PTP-SYNCE.

Signed-off-by: Shijith Thotton <sthotton@marvell.com>
Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
---
 doc/guides/eventdevs/cnxk.rst       |  18 ++++
 drivers/common/cnxk/roc_platform.h  |   1 +
 drivers/event/cnxk/cn10k_eventdev.c |   3 +-
 drivers/event/cnxk/cnxk_tim_evdev.c | 130 +++++++++++++++++++++++++++-
 drivers/event/cnxk/cnxk_tim_evdev.h |   4 +
 5 files changed, 154 insertions(+), 2 deletions(-)

diff --git a/doc/guides/eventdevs/cnxk.rst b/doc/guides/eventdevs/cnxk.rst
index 53560d3830..18540dc911 100644
--- a/doc/guides/eventdevs/cnxk.rst
+++ b/doc/guides/eventdevs/cnxk.rst
@@ -164,6 +164,24 @@ Runtime Config Options
 
     -a 0002:0e:00.0,tim_ring_ctl=[2-1023-1-0]
 
+- ``TIM external clock frequency``
+
+  The ``tim_eclk_freq`` devagrs can be used to pass external clock frequencies
+  when external clock source is selected.
+
+  External clock frequencies are mapped as follows::
+
+    RTE_EVENT_TIMER_ADAPTER_EXT_CLK0 = TIM_CLK_SRC_10NS,
+    RTE_EVENT_TIMER_ADAPTER_EXT_CLK1 = TIM_CLK_SRC_GPIO,
+    RTE_EVENT_TIMER_ADAPTER_EXT_CLK2 = TIM_CLK_SRC_PTP,
+    RTE_EVENT_TIMER_ADAPTER_EXT_CLK3 = TIM_CLK_SRC_SYNCE
+
+  The order of frequencies supplied to device args should be GPIO-PTP-SYNCE.
+
+  For Example::
+
+    -a 0002:0e:00.0,tim_eclk_freq=122880000-1000000000-0
+
 Debugging Options
 -----------------
 
diff --git a/drivers/common/cnxk/roc_platform.h b/drivers/common/cnxk/roc_platform.h
index 285b24b82d..7e73972b80 100644
--- a/drivers/common/cnxk/roc_platform.h
+++ b/drivers/common/cnxk/roc_platform.h
@@ -43,6 +43,7 @@
 #define PLT_MAX			 RTE_MAX
 #define PLT_DIM			 RTE_DIM
 #define PLT_SET_USED		 RTE_SET_USED
+#define PLT_SWAP		 RTE_SWAP
 #define PLT_STATIC_ASSERT(s)	 _Static_assert(s, #s)
 #define PLT_ALIGN		 RTE_ALIGN
 #define PLT_ALIGN_MUL_CEIL	 RTE_ALIGN_MUL_CEIL
diff --git a/drivers/event/cnxk/cn10k_eventdev.c b/drivers/event/cnxk/cn10k_eventdev.c
index 8af273a01b..cf0a7d2325 100644
--- a/drivers/event/cnxk/cn10k_eventdev.c
+++ b/drivers/event/cnxk/cn10k_eventdev.c
@@ -976,4 +976,5 @@ RTE_PMD_REGISTER_PARAM_STRING(event_cn10k, CNXK_SSO_XAE_CNT "=<int>"
 			      CNXK_TIM_DISABLE_NPA "=1"
 			      CNXK_TIM_CHNK_SLOTS "=<int>"
 			      CNXK_TIM_RINGS_LMT "=<int>"
-			      CNXK_TIM_STATS_ENA "=1");
+			      CNXK_TIM_STATS_ENA "=1"
+			      CNXK_TIM_EXT_CLK "=<string>");
diff --git a/drivers/event/cnxk/cnxk_tim_evdev.c b/drivers/event/cnxk/cnxk_tim_evdev.c
index 369f198444..21071c2d27 100644
--- a/drivers/event/cnxk/cnxk_tim_evdev.c
+++ b/drivers/event/cnxk/cnxk_tim_evdev.c
@@ -117,6 +117,80 @@ cnxk_tim_ring_info_get(const struct rte_event_timer_adapter *adptr,
 		   sizeof(struct rte_event_timer_adapter_conf));
 }
 
+static inline void
+sort_multi_array(double ref_arr[], uint64_t arr1[], uint64_t arr2[],
+		 uint64_t arr3[], uint8_t sz)
+{
+	int x;
+
+	for (x = 0; x < sz - 1; x++) {
+		if (ref_arr[x] > ref_arr[x + 1]) {
+			PLT_SWAP(ref_arr[x], ref_arr[x + 1]);
+			PLT_SWAP(arr1[x], arr1[x + 1]);
+			PLT_SWAP(arr2[x], arr2[x + 1]);
+			PLT_SWAP(arr3[x], arr3[x + 1]);
+			x = -1;
+		}
+	}
+}
+
+static inline void
+populate_sample(uint64_t tck[], uint64_t ns[], double diff[], uint64_t dst[],
+		uint64_t req_tck, uint64_t clk_freq, double tck_ns, uint8_t sz,
+		bool mov_fwd)
+{
+	int i;
+
+	for (i = 0; i < sz; i++) {
+		tck[i] = i ? tck[i - 1] : req_tck;
+		do {
+			mov_fwd ? tck[i]++ : tck[i]--;
+			ns[i] = round((double)tck[i] * tck_ns);
+			if (round((double)tck[i] * tck_ns) >
+			    ((double)tck[i] * tck_ns))
+				continue;
+		} while (ns[i] % (uint64_t)cnxk_tim_ns_per_tck(clk_freq));
+		diff[i] = PLT_MAX((double)ns[i], (double)tck[i] * tck_ns) -
+			  PLT_MIN((double)ns[i], (double)tck[i] * tck_ns);
+		dst[i] = mov_fwd ? tck[i] - req_tck : req_tck - tck[i];
+	}
+}
+
+static void
+tim_adjust_resolution(uint64_t *req_ns, uint64_t *req_tck, double tck_ns,
+		      uint64_t clk_freq, uint64_t max_tmo, uint64_t m_tck)
+{
+#define MAX_SAMPLES 5
+	double rmax_diff[MAX_SAMPLES], rmin_diff[MAX_SAMPLES];
+	uint64_t min_tck[MAX_SAMPLES], max_tck[MAX_SAMPLES];
+	uint64_t min_dst[MAX_SAMPLES], max_dst[MAX_SAMPLES];
+	uint64_t min_ns[MAX_SAMPLES], max_ns[MAX_SAMPLES];
+	int i;
+
+	populate_sample(max_tck, max_ns, rmax_diff, max_dst, *req_tck, clk_freq,
+			tck_ns, MAX_SAMPLES, true);
+	sort_multi_array(rmax_diff, max_dst, max_tck, max_ns, MAX_SAMPLES);
+
+	populate_sample(min_tck, min_ns, rmin_diff, min_dst, *req_tck, clk_freq,
+			tck_ns, MAX_SAMPLES, false);
+	sort_multi_array(rmin_diff, min_dst, min_tck, min_ns, MAX_SAMPLES);
+
+	for (i = 0; i < MAX_SAMPLES; i++) {
+		if (min_dst[i] < max_dst[i] && min_tck[i] > m_tck &&
+		    (max_tmo / min_ns[i]) <=
+			    (TIM_MAX_BUCKET_SIZE - TIM_MIN_BUCKET_SIZE)) {
+			*req_tck = min_tck[i];
+			*req_ns = min_ns[i];
+			break;
+		} else if ((max_tmo / max_ns[i]) <
+			   (TIM_MAX_BUCKET_SIZE - TIM_MIN_BUCKET_SIZE)) {
+			*req_tck = max_tck[i];
+			*req_ns = max_ns[i];
+			break;
+		}
+	}
+}
+
 static int
 cnxk_tim_ring_create(struct rte_event_timer_adapter *adptr)
 {
@@ -178,10 +252,25 @@ cnxk_tim_ring_create(struct rte_event_timer_adapter *adptr)
 		goto tim_hw_free;
 	}
 
-	/* Round */
 	tim_ring->tck_nsec =
 		round(RTE_ALIGN_MUL_NEAR((long double)rcfg->timer_tick_ns,
 					 cnxk_tim_ns_per_tck(clk_freq)));
+	if (log10(clk_freq) - floor(log10(clk_freq)) != 0.0) {
+		uint64_t req_ns, req_tck;
+		double tck_ns;
+
+		req_ns = tim_ring->tck_nsec;
+		tck_ns = NSECPERSEC / clk_freq;
+		req_tck = round(rcfg->timer_tick_ns / tck_ns);
+		tim_adjust_resolution(&req_ns, &req_tck, tck_ns, clk_freq,
+				      rcfg->max_tmo_ns, min_intvl_cyc);
+		if ((tim_ring->tck_nsec != req_ns) &&
+		    !(rcfg->flags & RTE_EVENT_TIMER_ADAPTER_F_ADJUST_RES)) {
+			rc = -ERANGE;
+			goto tim_hw_free;
+		}
+		tim_ring->tck_nsec = ceil(req_tck * tck_ns);
+	}
 
 	tim_ring->tck_int = round((long double)tim_ring->tck_nsec /
 				  cnxk_tim_ns_per_tck(clk_freq));
@@ -489,6 +578,43 @@ cnxk_tim_parse_kvargs_dict(const char *key, const char *value, void *opaque)
 	return 0;
 }
 
+static void
+cnxk_tim_parse_clk_list(const char *value, void *opaque)
+{
+	enum roc_tim_clk_src src[] = {ROC_TIM_CLK_SRC_GPIO, ROC_TIM_CLK_SRC_PTP,
+				      ROC_TIM_CLK_SRC_SYNCE,
+				      ROC_TIM_CLK_SRC_INVALID};
+	struct cnxk_tim_evdev *dev = opaque;
+	char *str = strdup(value);
+	char *tok;
+	int i = 0;
+
+	if (!strlen(str))
+		return;
+
+	tok = strtok(str, "-");
+	while (tok != NULL && src[i] != ROC_TIM_CLK_SRC_INVALID) {
+		dev->ext_clk_freq[src[i]] = strtoull(tok, NULL, 10);
+		tok = strtok(NULL, "-");
+		i++;
+	}
+
+	free(str);
+}
+
+static int
+cnxk_tim_parse_kvargs_dsv(const char *key, const char *value, void *opaque)
+{
+	RTE_SET_USED(key);
+
+	/* DSV format GPIO-PTP-SYNCE-BTS use '-' as ','
+	 * isn't allowed. 0 represents default.
+	 */
+	cnxk_tim_parse_clk_list(value, opaque);
+
+	return 0;
+}
+
 static void
 cnxk_tim_parse_devargs(struct rte_devargs *devargs, struct cnxk_tim_evdev *dev)
 {
@@ -511,6 +637,8 @@ cnxk_tim_parse_devargs(struct rte_devargs *devargs, struct cnxk_tim_evdev *dev)
 			   &dev->min_ring_cnt);
 	rte_kvargs_process(kvlist, CNXK_TIM_RING_CTL,
 			   &cnxk_tim_parse_kvargs_dict, &dev);
+	rte_kvargs_process(kvlist, CNXK_TIM_EXT_CLK, &cnxk_tim_parse_kvargs_dsv,
+			   dev);
 
 	rte_kvargs_free(kvlist);
 }
diff --git a/drivers/event/cnxk/cnxk_tim_evdev.h b/drivers/event/cnxk/cnxk_tim_evdev.h
index 7d401fccbd..4ce22ed7a4 100644
--- a/drivers/event/cnxk/cnxk_tim_evdev.h
+++ b/drivers/event/cnxk/cnxk_tim_evdev.h
@@ -39,6 +39,7 @@
 #define CNXK_TIM_STATS_ENA   "tim_stats_ena"
 #define CNXK_TIM_RINGS_LMT   "tim_rings_lmt"
 #define CNXK_TIM_RING_CTL    "tim_ring_ctl"
+#define CNXK_TIM_EXT_CLK     "tim_eclk_freq"
 
 #define CNXK_TIM_SP	   0x1
 #define CNXK_TIM_MP	   0x2
@@ -94,6 +95,7 @@ struct cnxk_tim_evdev {
 	uint16_t min_ring_cnt;
 	uint8_t enable_stats;
 	uint16_t ring_ctl_cnt;
+	uint64_t ext_clk_freq[ROC_TIM_CLK_SRC_INVALID];
 	struct cnxk_tim_ctl *ring_ctl_data;
 };
 
@@ -237,6 +239,8 @@ cnxk_tim_get_clk_freq(struct cnxk_tim_evdev *dev, enum roc_tim_clk_src clk_src,
 	case ROC_TIM_CLK_SRC_GPIO:
 	case ROC_TIM_CLK_SRC_PTP:
 	case ROC_TIM_CLK_SRC_SYNCE:
+		*freq = dev->ext_clk_freq[clk_src];
+		break;
 	default:
 		return -EINVAL;
 	}
-- 
2.17.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [dpdk-dev] [PATCH v4 1/2] event/cnxk: update min interval calculation
  2021-09-23 21:30   ` [dpdk-dev] [PATCH v3 1/2] event/cnxk: update min interval calculation pbhagavatula
  2021-09-23 21:30     ` [dpdk-dev] [PATCH v3 2/2] event/cnxk: add external clock support for timer pbhagavatula
@ 2021-10-09  8:04     ` pbhagavatula
  2021-10-09  8:04       ` [dpdk-dev] [PATCH v4 2/2] event/cnxk: add external clock support for timer pbhagavatula
                         ` (2 more replies)
  1 sibling, 3 replies; 11+ messages in thread
From: pbhagavatula @ 2021-10-09  8:04 UTC (permalink / raw)
  To: jerinj, Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori,
	Satha Rao, Ray Kinsella, Pavan Nikhilesh, Shijith Thotton
  Cc: dev

From: Pavan Nikhilesh <pbhagavatula@marvell.com>

Minimum supported interval should now be retrieved from
mailbox based on the clock source and clock frequency.

Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
---
v4:
- Rebase on master, fix NULL checks.
v3:
- Add new mbox interface.
v2:
- Fixed devargs parsing and rebased.

 drivers/common/cnxk/roc_mbox.h      | 17 +++++++
 drivers/common/cnxk/roc_tim.c       | 32 +++++++++++-
 drivers/common/cnxk/roc_tim.h       |  9 +++-
 drivers/common/cnxk/version.map     |  1 +
 drivers/event/cnxk/cnxk_tim_evdev.c | 69 +++++++++++++++++--------
 drivers/event/cnxk/cnxk_tim_evdev.h | 79 ++++++++++++++++++-----------
 6 files changed, 155 insertions(+), 52 deletions(-)

diff --git a/drivers/common/cnxk/roc_mbox.h b/drivers/common/cnxk/roc_mbox.h
index 75d1ff1ef3..c3688de065 100644
--- a/drivers/common/cnxk/roc_mbox.h
+++ b/drivers/common/cnxk/roc_mbox.h
@@ -131,6 +131,8 @@ struct mbox_msghdr {
 	M(TIM_ENABLE_RING, 0x803, tim_enable_ring, tim_ring_req,               \
 	  tim_enable_rsp)                                                      \
 	M(TIM_DISABLE_RING, 0x804, tim_disable_ring, tim_ring_req, msg_rsp)    \
+	M(TIM_GET_MIN_INTVL, 0x805, tim_get_min_intvl, tim_intvl_req,          \
+	  tim_intvl_rsp)                                                       \
 	/* CPT mbox IDs (range 0xA00 - 0xBFF) */                               \
 	M(CPT_LF_ALLOC, 0xA00, cpt_lf_alloc, cpt_lf_alloc_req_msg, msg_rsp)    \
 	M(CPT_LF_FREE, 0xA01, cpt_lf_free, msg_req, msg_rsp)                   \
@@ -1756,6 +1758,9 @@ struct tim_config_req {
 	uint32_t __io chunksize;
 	uint32_t __io interval;
 	uint8_t __io gpioedge;
+	uint8_t __io rsvd[7];
+	uint64_t __io intervalns;
+	uint64_t __io clockfreq;
 };

 struct tim_lf_alloc_rsp {
@@ -1769,6 +1774,18 @@ struct tim_enable_rsp {
 	uint32_t __io currentbucket;
 };

+struct tim_intvl_req {
+	struct mbox_msghdr hdr;
+	uint8_t __io clocksource;
+	uint64_t __io clockfreq;
+};
+
+struct tim_intvl_rsp {
+	struct mbox_msghdr hdr;
+	uint64_t __io intvl_cyc;
+	uint64_t __io intvl_ns;
+};
+
 struct sdp_node_info {
 	/* Node to which this PF belons to */
 	uint8_t __io node_id;
diff --git a/drivers/common/cnxk/roc_tim.c b/drivers/common/cnxk/roc_tim.c
index 387164bb1d..eefa8253bc 100644
--- a/drivers/common/cnxk/roc_tim.c
+++ b/drivers/common/cnxk/roc_tim.c
@@ -145,7 +145,7 @@ int
 roc_tim_lf_config(struct roc_tim *roc_tim, uint8_t ring_id,
 		  enum roc_tim_clk_src clk_src, uint8_t ena_periodic,
 		  uint8_t ena_dfb, uint32_t bucket_sz, uint32_t chunk_sz,
-		  uint32_t interval)
+		  uint32_t interval, uint64_t intervalns, uint64_t clockfreq)
 {
 	struct dev *dev = &roc_sso_to_sso_priv(roc_tim->roc_sso)->dev;
 	struct tim_config_req *req;
@@ -162,6 +162,8 @@ roc_tim_lf_config(struct roc_tim *roc_tim, uint8_t ring_id,
 	req->enableperiodic = ena_periodic;
 	req->enabledontfreebuffer = ena_dfb;
 	req->interval = interval;
+	req->intervalns = intervalns;
+	req->clockfreq = clockfreq;
 	req->gpioedge = TIM_GPIO_LTOH_TRANS;

 	rc = mbox_process(dev->mbox);
@@ -173,6 +175,34 @@ roc_tim_lf_config(struct roc_tim *roc_tim, uint8_t ring_id,
 	return 0;
 }

+int
+roc_tim_lf_interval(struct roc_tim *roc_tim, enum roc_tim_clk_src clk_src,
+		    uint64_t clockfreq, uint64_t *intervalns,
+		    uint64_t *interval)
+{
+	struct dev *dev = &roc_sso_to_sso_priv(roc_tim->roc_sso)->dev;
+	struct tim_intvl_req *req;
+	struct tim_intvl_rsp *rsp;
+	int rc = -ENOSPC;
+
+	req = mbox_alloc_msg_tim_get_min_intvl(dev->mbox);
+	if (req == NULL)
+		return rc;
+
+	req->clockfreq = clockfreq;
+	req->clocksource = clk_src;
+	rc = mbox_process_msg(dev->mbox, (void **)&rsp);
+	if (rc < 0) {
+		tim_err_desc(rc);
+		return rc;
+	}
+
+	*intervalns = rsp->intvl_ns;
+	*interval = rsp->intvl_cyc;
+
+	return 0;
+}
+
 int
 roc_tim_lf_alloc(struct roc_tim *roc_tim, uint8_t ring_id, uint64_t *clk)
 {
diff --git a/drivers/common/cnxk/roc_tim.h b/drivers/common/cnxk/roc_tim.h
index 159b021a31..392732eae2 100644
--- a/drivers/common/cnxk/roc_tim.h
+++ b/drivers/common/cnxk/roc_tim.h
@@ -10,6 +10,8 @@ enum roc_tim_clk_src {
 	ROC_TIM_CLK_SRC_GPIO,
 	ROC_TIM_CLK_SRC_GTI,
 	ROC_TIM_CLK_SRC_PTP,
+	ROC_TIM_CLK_SRC_SYNCE,
+	ROC_TIM_CLK_SRC_BTS,
 	ROC_TIM_CLK_SRC_INVALID,
 };

@@ -33,7 +35,12 @@ int __roc_api roc_tim_lf_config(struct roc_tim *roc_tim, uint8_t ring_id,
 				enum roc_tim_clk_src clk_src,
 				uint8_t ena_periodic, uint8_t ena_dfb,
 				uint32_t bucket_sz, uint32_t chunk_sz,
-				uint32_t interval);
+				uint32_t interval, uint64_t intervalns,
+				uint64_t clockfreq);
+int __roc_api roc_tim_lf_interval(struct roc_tim *roc_tim,
+				  enum roc_tim_clk_src clk_src,
+				  uint64_t clockfreq, uint64_t *intervalns,
+				  uint64_t *interval);
 int __roc_api roc_tim_lf_alloc(struct roc_tim *roc_tim, uint8_t ring_id,
 			       uint64_t *clk);
 int __roc_api roc_tim_lf_free(struct roc_tim *roc_tim, uint8_t ring_id);
diff --git a/drivers/common/cnxk/version.map b/drivers/common/cnxk/version.map
index fff7902b25..5791629ce9 100644
--- a/drivers/common/cnxk/version.map
+++ b/drivers/common/cnxk/version.map
@@ -279,6 +279,7 @@ INTERNAL {
 	roc_tim_lf_disable;
 	roc_tim_lf_enable;
 	roc_tim_lf_free;
+	roc_tim_lf_interval;
 	roc_se_ctx_swap;

 	local: *;
diff --git a/drivers/event/cnxk/cnxk_tim_evdev.c b/drivers/event/cnxk/cnxk_tim_evdev.c
index 9d40e336d7..369f198444 100644
--- a/drivers/event/cnxk/cnxk_tim_evdev.c
+++ b/drivers/event/cnxk/cnxk_tim_evdev.c
@@ -2,6 +2,8 @@
  * Copyright(C) 2021 Marvell.
  */

+#include <math.h>
+
 #include "cnxk_eventdev.h"
 #include "cnxk_tim_evdev.h"

@@ -120,7 +122,10 @@ cnxk_tim_ring_create(struct rte_event_timer_adapter *adptr)
 {
 	struct rte_event_timer_adapter_conf *rcfg = &adptr->data->conf;
 	struct cnxk_tim_evdev *dev = cnxk_tim_priv_get();
+	uint64_t min_intvl_ns, min_intvl_cyc;
 	struct cnxk_tim_ring *tim_ring;
+	enum roc_tim_clk_src clk_src;
+	uint64_t clk_freq = 0;
 	int i, rc;

 	if (dev == NULL)
@@ -139,25 +144,52 @@ cnxk_tim_ring_create(struct rte_event_timer_adapter *adptr)
 		goto tim_ring_free;
 	}

-	if (NSEC2TICK(RTE_ALIGN_MUL_CEIL(
-			      rcfg->timer_tick_ns,
-			      cnxk_tim_min_resolution_ns(cnxk_tim_cntfrq())),
-		      cnxk_tim_cntfrq()) <
-	    cnxk_tim_min_tmo_ticks(cnxk_tim_cntfrq())) {
-		if (rcfg->flags & RTE_EVENT_TIMER_ADAPTER_F_ADJUST_RES)
-			rcfg->timer_tick_ns = TICK2NSEC(
-				cnxk_tim_min_tmo_ticks(cnxk_tim_cntfrq()),
-				cnxk_tim_cntfrq());
-		else {
+	clk_src = cnxk_tim_convert_clk_src(rcfg->clk_src);
+	if (clk_src == ROC_TIM_CLK_SRC_INVALID) {
+		plt_err("Invalid clock source");
+		goto tim_hw_free;
+	}
+
+	rc = cnxk_tim_get_clk_freq(dev, clk_src, &clk_freq);
+	if (rc < 0) {
+		plt_err("Failed to get clock frequency");
+		goto tim_hw_free;
+	}
+
+	rc = roc_tim_lf_interval(&dev->tim, clk_src, clk_freq, &min_intvl_ns,
+				 &min_intvl_cyc);
+	if (rc < 0) {
+		plt_err("Failed to get min interval details");
+		goto tim_hw_free;
+	}
+
+	if (rcfg->timer_tick_ns < min_intvl_ns) {
+		if (rcfg->flags & RTE_EVENT_TIMER_ADAPTER_F_ADJUST_RES) {
+			rcfg->timer_tick_ns = min_intvl_ns;
+		} else {
 			rc = -ERANGE;
 			goto tim_hw_free;
 		}
 	}
+
+	if (rcfg->timer_tick_ns > rcfg->max_tmo_ns) {
+		plt_err("Max timeout to too high");
+		rc = -ERANGE;
+		goto tim_hw_free;
+	}
+
+	/* Round */
+	tim_ring->tck_nsec =
+		round(RTE_ALIGN_MUL_NEAR((long double)rcfg->timer_tick_ns,
+					 cnxk_tim_ns_per_tck(clk_freq)));
+
+	tim_ring->tck_int = round((long double)tim_ring->tck_nsec /
+				  cnxk_tim_ns_per_tck(clk_freq));
+	tim_ring->tck_nsec =
+		ceil(tim_ring->tck_int * cnxk_tim_ns_per_tck(clk_freq));
+
 	tim_ring->ring_id = adptr->data->id;
-	tim_ring->clk_src = (int)rcfg->clk_src;
-	tim_ring->tck_nsec = RTE_ALIGN_MUL_CEIL(
-		rcfg->timer_tick_ns,
-		cnxk_tim_min_resolution_ns(cnxk_tim_cntfrq()));
+	tim_ring->clk_src = clk_src;
 	tim_ring->max_tout = rcfg->max_tmo_ns;
 	tim_ring->nb_bkts = (tim_ring->max_tout / tim_ring->tck_nsec);
 	tim_ring->nb_timers = rcfg->nb_timers;
@@ -201,11 +233,9 @@ cnxk_tim_ring_create(struct rte_event_timer_adapter *adptr)
 	if (rc < 0)
 		goto tim_bkt_free;

-	rc = roc_tim_lf_config(
-		&dev->tim, tim_ring->ring_id,
-		cnxk_tim_convert_clk_src(tim_ring->clk_src), 0, 0,
-		tim_ring->nb_bkts, tim_ring->chunk_sz,
-		NSEC2TICK(tim_ring->tck_nsec, cnxk_tim_cntfrq()));
+	rc = roc_tim_lf_config(&dev->tim, tim_ring->ring_id, clk_src, 0, 0,
+			       tim_ring->nb_bkts, tim_ring->chunk_sz,
+			       tim_ring->tck_int, tim_ring->tck_nsec, clk_freq);
 	if (rc < 0) {
 		plt_err("Failed to configure timer ring");
 		goto tim_chnk_free;
@@ -300,7 +330,6 @@ cnxk_tim_ring_start(const struct rte_event_timer_adapter *adptr)
 	if (rc < 0)
 		return rc;

-	tim_ring->tck_int = NSEC2TICK(tim_ring->tck_nsec, cnxk_tim_cntfrq());
 	tim_ring->tot_int = tim_ring->tck_int * tim_ring->nb_bkts;
 	tim_ring->fast_div = rte_reciprocal_value_u64(tim_ring->tck_int);
 	tim_ring->fast_bkt = rte_reciprocal_value_u64(tim_ring->nb_bkts);
diff --git a/drivers/event/cnxk/cnxk_tim_evdev.h b/drivers/event/cnxk/cnxk_tim_evdev.h
index c369f6f472..4afbcb8fb2 100644
--- a/drivers/event/cnxk/cnxk_tim_evdev.h
+++ b/drivers/event/cnxk/cnxk_tim_evdev.h
@@ -97,13 +97,6 @@ struct cnxk_tim_evdev {
 	struct cnxk_tim_ctl *ring_ctl_data;
 };

-enum cnxk_tim_clk_src {
-	CNXK_TIM_CLK_SRC_10NS = RTE_EVENT_TIMER_ADAPTER_CPU_CLK,
-	CNXK_TIM_CLK_SRC_GPIO = RTE_EVENT_TIMER_ADAPTER_EXT_CLK0,
-	CNXK_TIM_CLK_SRC_GTI = RTE_EVENT_TIMER_ADAPTER_EXT_CLK1,
-	CNXK_TIM_CLK_SRC_PTP = RTE_EVENT_TIMER_ADAPTER_EXT_CLK2,
-};
-
 struct cnxk_tim_bkt {
 	uint64_t first_chunk;
 	union {
@@ -146,7 +139,7 @@ struct cnxk_tim_ring {
 	uint64_t max_tout;
 	uint64_t nb_chunks;
 	uint64_t chunk_sz;
-	enum cnxk_tim_clk_src clk_src;
+	enum roc_tim_clk_src clk_src;
 } __rte_cache_aligned;

 struct cnxk_tim_ent {
@@ -166,32 +159,13 @@ cnxk_tim_priv_get(void)
 	return mz->addr;
 }

-static inline uint64_t
-cnxk_tim_min_tmo_ticks(uint64_t freq)
+static inline long double
+cnxk_tim_ns_per_tck(uint64_t freq)
 {
-	if (roc_model_runtime_is_cn9k())
-		return CN9K_TIM_MIN_TMO_TKS;
-	else /* CN10K min tick is of 1us */
-		return freq / USECPERSEC;
+	return (long double)NSECPERSEC / freq;
 }

-static inline uint64_t
-cnxk_tim_min_resolution_ns(uint64_t freq)
-{
-	return NSECPERSEC / freq;
-}

-static inline enum roc_tim_clk_src
-cnxk_tim_convert_clk_src(enum cnxk_tim_clk_src clk_src)
-{
-	switch (clk_src) {
-	case RTE_EVENT_TIMER_ADAPTER_CPU_CLK:
-		return roc_model_runtime_is_cn9k() ? ROC_TIM_CLK_SRC_10NS :
-							   ROC_TIM_CLK_SRC_GTI;
-	default:
-		return ROC_TIM_CLK_SRC_INVALID;
-	}
-}

 #ifdef RTE_ARCH_ARM64
 static inline uint64_t
@@ -225,6 +199,51 @@ cnxk_tim_cntfrq(void)
 }
 #endif

+static inline enum roc_tim_clk_src
+cnxk_tim_convert_clk_src(enum rte_event_timer_adapter_clk_src clk_src)
+{
+	switch (clk_src) {
+	case RTE_EVENT_TIMER_ADAPTER_CPU_CLK:
+		return ROC_TIM_CLK_SRC_GTI;
+	case RTE_EVENT_TIMER_ADAPTER_EXT_CLK0:
+		return ROC_TIM_CLK_SRC_10NS;
+	case RTE_EVENT_TIMER_ADAPTER_EXT_CLK1:
+		return ROC_TIM_CLK_SRC_GPIO;
+	case RTE_EVENT_TIMER_ADAPTER_EXT_CLK2:
+		return ROC_TIM_CLK_SRC_PTP;
+	case RTE_EVENT_TIMER_ADAPTER_EXT_CLK3:
+		return roc_model_constant_is_cn9k() ? ROC_TIM_CLK_SRC_INVALID :
+						      ROC_TIM_CLK_SRC_SYNCE;
+	default:
+		return ROC_TIM_CLK_SRC_INVALID;
+	}
+}
+
+static inline int
+cnxk_tim_get_clk_freq(struct cnxk_tim_evdev *dev, enum roc_tim_clk_src clk_src,
+		      uint64_t *freq)
+{
+	if (freq == NULL)
+		return -EINVAL;
+
+	PLT_SET_USED(dev);
+	switch (clk_src) {
+	case ROC_TIM_CLK_SRC_GTI:
+		*freq = cnxk_tim_cntfrq();
+		break;
+	case ROC_TIM_CLK_SRC_10NS:
+		*freq = 1E8;
+		break;
+	case ROC_TIM_CLK_SRC_GPIO:
+	case ROC_TIM_CLK_SRC_PTP:
+	case ROC_TIM_CLK_SRC_SYNCE:
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 #define TIM_ARM_FASTPATH_MODES                                                 \
 	FP(sp, 0, 0, 0, CNXK_TIM_ENA_DFB | CNXK_TIM_SP)                        \
 	FP(mp, 0, 0, 1, CNXK_TIM_ENA_DFB | CNXK_TIM_MP)                        \
--
2.17.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [dpdk-dev] [PATCH v4 2/2] event/cnxk: add external clock support for timer
  2021-10-09  8:04     ` [dpdk-dev] [PATCH v4 1/2] event/cnxk: update min interval calculation pbhagavatula
@ 2021-10-09  8:04       ` pbhagavatula
  2021-10-14 11:51       ` [dpdk-dev] [PATCH v4 1/2] event/cnxk: update min interval calculation Jerin Jacob
  2021-12-13 11:13       ` [PATCH v5 " pbhagavatula
  2 siblings, 0 replies; 11+ messages in thread
From: pbhagavatula @ 2021-10-09  8:04 UTC (permalink / raw)
  To: jerinj, Pavan Nikhilesh, Shijith Thotton, Nithin Dabilpuram,
	Kiran Kumar K, Sunil Kumar Kori, Satha Rao, Anatoly Burakov
  Cc: dev

From: Pavan Nikhilesh <pbhagavatula@marvell.com>

Add external clock support for cnxk timer adapter.

External clock mapping is as follows:
RTE_EVENT_TIMER_ADAPTER_EXT_CLK0 = TIM_CLK_SRC_10NS,
RTE_EVENT_TIMER_ADAPTER_EXT_CLK1 = TIM_CLK_SRC_GPIO,
RTE_EVENT_TIMER_ADAPTER_EXT_CLK2 = TIM_CLK_SRC_PTP,
RTE_EVENT_TIMER_ADAPTER_EXT_CLK3 = TIM_CLK_SRC_SYNCE,

TIM supports clock input from external GPIO, PTP, SYNCE clocks.
Input resolution is adjusted based on CNTVCT frequency for better
estimation.

Since TIM is unaware of input clock frequency, application is
expected to pass the frequency.
Example:
	-a 0002:0e:00.0,tim_eclk_freq=122880000-0-0

The order of frequencies above is GPIO-PTP-SYNCE.

Signed-off-by: Shijith Thotton <sthotton@marvell.com>
Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
---
 doc/guides/eventdevs/cnxk.rst       |  18 ++++
 drivers/common/cnxk/roc_platform.h  |   1 +
 drivers/event/cnxk/cn10k_eventdev.c |   3 +-
 drivers/event/cnxk/cnxk_tim_evdev.c | 141 +++++++++++++++++++++++++++-
 drivers/event/cnxk/cnxk_tim_evdev.h |  11 ++-
 5 files changed, 165 insertions(+), 9 deletions(-)

diff --git a/doc/guides/eventdevs/cnxk.rst b/doc/guides/eventdevs/cnxk.rst
index 53560d3830..18540dc911 100644
--- a/doc/guides/eventdevs/cnxk.rst
+++ b/doc/guides/eventdevs/cnxk.rst
@@ -164,6 +164,24 @@ Runtime Config Options
 
     -a 0002:0e:00.0,tim_ring_ctl=[2-1023-1-0]
 
+- ``TIM external clock frequency``
+
+  The ``tim_eclk_freq`` devagrs can be used to pass external clock frequencies
+  when external clock source is selected.
+
+  External clock frequencies are mapped as follows::
+
+    RTE_EVENT_TIMER_ADAPTER_EXT_CLK0 = TIM_CLK_SRC_10NS,
+    RTE_EVENT_TIMER_ADAPTER_EXT_CLK1 = TIM_CLK_SRC_GPIO,
+    RTE_EVENT_TIMER_ADAPTER_EXT_CLK2 = TIM_CLK_SRC_PTP,
+    RTE_EVENT_TIMER_ADAPTER_EXT_CLK3 = TIM_CLK_SRC_SYNCE
+
+  The order of frequencies supplied to device args should be GPIO-PTP-SYNCE.
+
+  For Example::
+
+    -a 0002:0e:00.0,tim_eclk_freq=122880000-1000000000-0
+
 Debugging Options
 -----------------
 
diff --git a/drivers/common/cnxk/roc_platform.h b/drivers/common/cnxk/roc_platform.h
index 285b24b82d..7e73972b80 100644
--- a/drivers/common/cnxk/roc_platform.h
+++ b/drivers/common/cnxk/roc_platform.h
@@ -43,6 +43,7 @@
 #define PLT_MAX			 RTE_MAX
 #define PLT_DIM			 RTE_DIM
 #define PLT_SET_USED		 RTE_SET_USED
+#define PLT_SWAP		 RTE_SWAP
 #define PLT_STATIC_ASSERT(s)	 _Static_assert(s, #s)
 #define PLT_ALIGN		 RTE_ALIGN
 #define PLT_ALIGN_MUL_CEIL	 RTE_ALIGN_MUL_CEIL
diff --git a/drivers/event/cnxk/cn10k_eventdev.c b/drivers/event/cnxk/cn10k_eventdev.c
index 8af273a01b..cf0a7d2325 100644
--- a/drivers/event/cnxk/cn10k_eventdev.c
+++ b/drivers/event/cnxk/cn10k_eventdev.c
@@ -976,4 +976,5 @@ RTE_PMD_REGISTER_PARAM_STRING(event_cn10k, CNXK_SSO_XAE_CNT "=<int>"
 			      CNXK_TIM_DISABLE_NPA "=1"
 			      CNXK_TIM_CHNK_SLOTS "=<int>"
 			      CNXK_TIM_RINGS_LMT "=<int>"
-			      CNXK_TIM_STATS_ENA "=1");
+			      CNXK_TIM_STATS_ENA "=1"
+			      CNXK_TIM_EXT_CLK "=<string>");
diff --git a/drivers/event/cnxk/cnxk_tim_evdev.c b/drivers/event/cnxk/cnxk_tim_evdev.c
index 369f198444..cb0ad194b5 100644
--- a/drivers/event/cnxk/cnxk_tim_evdev.c
+++ b/drivers/event/cnxk/cnxk_tim_evdev.c
@@ -29,8 +29,8 @@ cnxk_tim_chnk_pool_create(struct cnxk_tim_ring *tim_ring,
 	snprintf(pool_name, sizeof(pool_name), "cnxk_tim_chunk_pool%d",
 		 tim_ring->ring_id);
 
-	if (cache_sz > RTE_MEMPOOL_CACHE_MAX_SIZE)
-		cache_sz = RTE_MEMPOOL_CACHE_MAX_SIZE;
+	if (cache_sz > CNXK_TIM_MAX_POOL_CACHE_SZ)
+		cache_sz = CNXK_TIM_MAX_POOL_CACHE_SZ;
 	cache_sz = cache_sz != 0 ? cache_sz : 2;
 	tim_ring->nb_chunks += (cache_sz * rte_lcore_count());
 	if (!tim_ring->disable_npa) {
@@ -117,6 +117,80 @@ cnxk_tim_ring_info_get(const struct rte_event_timer_adapter *adptr,
 		   sizeof(struct rte_event_timer_adapter_conf));
 }
 
+static inline void
+sort_multi_array(double ref_arr[], uint64_t arr1[], uint64_t arr2[],
+		 uint64_t arr3[], uint8_t sz)
+{
+	int x;
+
+	for (x = 0; x < sz - 1; x++) {
+		if (ref_arr[x] > ref_arr[x + 1]) {
+			PLT_SWAP(ref_arr[x], ref_arr[x + 1]);
+			PLT_SWAP(arr1[x], arr1[x + 1]);
+			PLT_SWAP(arr2[x], arr2[x + 1]);
+			PLT_SWAP(arr3[x], arr3[x + 1]);
+			x = -1;
+		}
+	}
+}
+
+static inline void
+populate_sample(uint64_t tck[], uint64_t ns[], double diff[], uint64_t dst[],
+		uint64_t req_tck, uint64_t clk_freq, double tck_ns, uint8_t sz,
+		bool mov_fwd)
+{
+	int i;
+
+	for (i = 0; i < sz; i++) {
+		tck[i] = i ? tck[i - 1] : req_tck;
+		do {
+			mov_fwd ? tck[i]++ : tck[i]--;
+			ns[i] = round((double)tck[i] * tck_ns);
+			if (round((double)tck[i] * tck_ns) >
+			    ((double)tck[i] * tck_ns))
+				continue;
+		} while (ns[i] % (uint64_t)cnxk_tim_ns_per_tck(clk_freq));
+		diff[i] = PLT_MAX((double)ns[i], (double)tck[i] * tck_ns) -
+			  PLT_MIN((double)ns[i], (double)tck[i] * tck_ns);
+		dst[i] = mov_fwd ? tck[i] - req_tck : req_tck - tck[i];
+	}
+}
+
+static void
+tim_adjust_resolution(uint64_t *req_ns, uint64_t *req_tck, double tck_ns,
+		      uint64_t clk_freq, uint64_t max_tmo, uint64_t m_tck)
+{
+#define MAX_SAMPLES 5
+	double rmax_diff[MAX_SAMPLES], rmin_diff[MAX_SAMPLES];
+	uint64_t min_tck[MAX_SAMPLES], max_tck[MAX_SAMPLES];
+	uint64_t min_dst[MAX_SAMPLES], max_dst[MAX_SAMPLES];
+	uint64_t min_ns[MAX_SAMPLES], max_ns[MAX_SAMPLES];
+	int i;
+
+	populate_sample(max_tck, max_ns, rmax_diff, max_dst, *req_tck, clk_freq,
+			tck_ns, MAX_SAMPLES, true);
+	sort_multi_array(rmax_diff, max_dst, max_tck, max_ns, MAX_SAMPLES);
+
+	populate_sample(min_tck, min_ns, rmin_diff, min_dst, *req_tck, clk_freq,
+			tck_ns, MAX_SAMPLES, false);
+	sort_multi_array(rmin_diff, min_dst, min_tck, min_ns, MAX_SAMPLES);
+
+	for (i = 0; i < MAX_SAMPLES; i++) {
+		if (min_dst[i] < max_dst[i] && min_tck[i] > m_tck &&
+		    (max_tmo / min_ns[i]) <=
+			    (TIM_MAX_BUCKET_SIZE - TIM_MIN_BUCKET_SIZE)) {
+			*req_tck = min_tck[i];
+			*req_ns = min_ns[i];
+			break;
+		} else if ((max_tmo / max_ns[i]) <
+			   (TIM_MAX_BUCKET_SIZE - TIM_MIN_BUCKET_SIZE)) {
+			*req_tck = max_tck[i];
+			*req_ns = max_ns[i];
+			break;
+		}
+	}
+}
+
 static int
 cnxk_tim_ring_create(struct rte_event_timer_adapter *adptr)
 {
@@ -178,10 +252,25 @@ cnxk_tim_ring_create(struct rte_event_timer_adapter *adptr)
 		goto tim_hw_free;
 	}
 
-	/* Round */
 	tim_ring->tck_nsec =
 		round(RTE_ALIGN_MUL_NEAR((long double)rcfg->timer_tick_ns,
 					 cnxk_tim_ns_per_tck(clk_freq)));
+	if (log10(clk_freq) - floor(log10(clk_freq)) != 0.0) {
+		uint64_t req_ns, req_tck;
+		double tck_ns;
+
+		req_ns = tim_ring->tck_nsec;
+		tck_ns = NSECPERSEC / clk_freq;
+		req_tck = round(rcfg->timer_tick_ns / tck_ns);
+		tim_adjust_resolution(&req_ns, &req_tck, tck_ns, clk_freq,
+				      rcfg->max_tmo_ns, min_intvl_cyc);
+		if ((tim_ring->tck_nsec != req_ns) &&
+		    !(rcfg->flags & RTE_EVENT_TIMER_ADAPTER_F_ADJUST_RES)) {
+			rc = -ERANGE;
+			goto tim_hw_free;
+		}
+		tim_ring->tck_nsec = ceil(req_tck * tck_ns);
+	}
 
 	tim_ring->tck_int = round((long double)tim_ring->tck_nsec /
 				  cnxk_tim_ns_per_tck(clk_freq));
@@ -458,11 +547,16 @@ cnxk_tim_parse_ring_ctl_list(const char *value, void *opaque)
 	char *end = NULL;
 	char *f = s;
 
+	if (s == NULL || !strlen(s))
+		return;
+
 	while (*s) {
 		if (*s == '[')
 			start = s;
 		else if (*s == ']')
 			end = s;
+		else
+			continue;
 
 		if (start && start < end) {
 			*end = 0;
@@ -489,6 +583,43 @@ cnxk_tim_parse_kvargs_dict(const char *key, const char *value, void *opaque)
 	return 0;
 }
 
+static void
+cnxk_tim_parse_clk_list(const char *value, void *opaque)
+{
+	enum roc_tim_clk_src src[] = {ROC_TIM_CLK_SRC_GPIO, ROC_TIM_CLK_SRC_PTP,
+				      ROC_TIM_CLK_SRC_SYNCE,
+				      ROC_TIM_CLK_SRC_INVALID};
+	struct cnxk_tim_evdev *dev = opaque;
+	char *str = strdup(value);
+	char *tok;
+	int i = 0;
+
+	if (str == NULL || !strlen(str))
+		return;
+
+	tok = strtok(str, "-");
+	while (tok != NULL && src[i] != ROC_TIM_CLK_SRC_INVALID) {
+		dev->ext_clk_freq[src[i]] = strtoull(tok, NULL, 10);
+		tok = strtok(NULL, "-");
+		i++;
+	}
+
+	free(str);
+}
+
+static int
+cnxk_tim_parse_kvargs_dsv(const char *key, const char *value, void *opaque)
+{
+	RTE_SET_USED(key);
+
+	/* DSV format GPIO-PTP-SYNCE-BTS use '-' as ','
+	 * isn't allowed. 0 represents default.
+	 */
+	cnxk_tim_parse_clk_list(value, opaque);
+
+	return 0;
+}
+
 static void
 cnxk_tim_parse_devargs(struct rte_devargs *devargs, struct cnxk_tim_evdev *dev)
 {
@@ -511,6 +642,8 @@ cnxk_tim_parse_devargs(struct rte_devargs *devargs, struct cnxk_tim_evdev *dev)
 			   &dev->min_ring_cnt);
 	rte_kvargs_process(kvlist, CNXK_TIM_RING_CTL,
 			   &cnxk_tim_parse_kvargs_dict, &dev);
+	rte_kvargs_process(kvlist, CNXK_TIM_EXT_CLK, &cnxk_tim_parse_kvargs_dsv,
+			   dev);
 
 	rte_kvargs_free(kvlist);
 }
@@ -559,7 +692,7 @@ cnxk_tim_fini(void)
 {
 	struct cnxk_tim_evdev *dev = cnxk_tim_priv_get();
 
-	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+	if (dev == NULL || rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return;
 
 	roc_tim_fini(&dev->tim);
diff --git a/drivers/event/cnxk/cnxk_tim_evdev.h b/drivers/event/cnxk/cnxk_tim_evdev.h
index 4afbcb8fb2..35ca6d2362 100644
--- a/drivers/event/cnxk/cnxk_tim_evdev.h
+++ b/drivers/event/cnxk/cnxk_tim_evdev.h
@@ -31,6 +31,7 @@
 #define CNXK_TIM_NB_CHUNK_SLOTS(sz) (((sz) / CNXK_TIM_CHUNK_ALIGNMENT) - 1)
 #define CNXK_TIM_MIN_CHUNK_SLOTS    (0x1)
 #define CNXK_TIM_MAX_CHUNK_SLOTS    (0x1FFE)
+#define CNXK_TIM_MAX_POOL_CACHE_SZ  (128)
 
 #define CN9K_TIM_MIN_TMO_TKS (256)
 
@@ -39,6 +40,7 @@
 #define CNXK_TIM_STATS_ENA   "tim_stats_ena"
 #define CNXK_TIM_RINGS_LMT   "tim_rings_lmt"
 #define CNXK_TIM_RING_CTL    "tim_ring_ctl"
+#define CNXK_TIM_EXT_CLK     "tim_eclk_freq"
 
 #define CNXK_TIM_SP	   0x1
 #define CNXK_TIM_MP	   0x2
@@ -90,10 +92,11 @@ struct cnxk_tim_evdev {
 	uint32_t chunk_sz;
 	/* Dev args */
 	uint8_t disable_npa;
-	uint16_t chunk_slots;
-	uint16_t min_ring_cnt;
+	uint32_t chunk_slots;
+	uint32_t min_ring_cnt;
 	uint8_t enable_stats;
 	uint16_t ring_ctl_cnt;
+	uint64_t ext_clk_freq[ROC_TIM_CLK_SRC_INVALID];
 	struct cnxk_tim_ctl *ring_ctl_data;
 };
 
@@ -165,8 +168,6 @@ cnxk_tim_ns_per_tck(uint64_t freq)
 	return (long double)NSECPERSEC / freq;
 }
 
-
-
 #ifdef RTE_ARCH_ARM64
 static inline uint64_t
 cnxk_tim_cntvct(void)
@@ -237,6 +238,8 @@ cnxk_tim_get_clk_freq(struct cnxk_tim_evdev *dev, enum roc_tim_clk_src clk_src,
 	case ROC_TIM_CLK_SRC_GPIO:
 	case ROC_TIM_CLK_SRC_PTP:
 	case ROC_TIM_CLK_SRC_SYNCE:
+		*freq = dev->ext_clk_freq[clk_src];
+		break;
 	default:
 		return -EINVAL;
 	}
-- 
2.17.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [dpdk-dev] [PATCH v4 1/2] event/cnxk: update min interval calculation
  2021-10-09  8:04     ` [dpdk-dev] [PATCH v4 1/2] event/cnxk: update min interval calculation pbhagavatula
  2021-10-09  8:04       ` [dpdk-dev] [PATCH v4 2/2] event/cnxk: add external clock support for timer pbhagavatula
@ 2021-10-14 11:51       ` Jerin Jacob
  2021-12-13 11:13       ` [PATCH v5 " pbhagavatula
  2 siblings, 0 replies; 11+ messages in thread
From: Jerin Jacob @ 2021-10-14 11:51 UTC (permalink / raw)
  To: Pavan Nikhilesh
  Cc: Jerin Jacob, Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori,
	Satha Rao, Ray Kinsella, Shijith Thotton, dpdk-dev

On Sat, Oct 9, 2021 at 1:34 PM <pbhagavatula@marvell.com> wrote:
>
> From: Pavan Nikhilesh <pbhagavatula@marvell.com>
>
> Minimum supported interval should now be retrieved from
> mailbox based on the clock source and clock frequency.
>
> Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
> ---
> v4:
> - Rebase on master, fix NULL checks.
> v3:
> - Add new mbox interface.
> v2:
> - Fixed devargs parsing and rebased.


Please rebase
[for-main]dell[dpdk-next-eventdev] $ git pw series apply 19482
Applying: event/cnxk: update min interval calculation
Applying: event/cnxk: add external clock support for timer
error: sha1 information is lacking or useless
(drivers/event/cnxk/cnxk_tim_evdev.c).
error: could not build fake ancestor
hint: Use 'git am --show-current-patch=diff' to see the failed patch
Patch failed at 0002 event/cnxk: add external clock support for timer
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".


>
>  drivers/common/cnxk/roc_mbox.h      | 17 +++++++
>  drivers/common/cnxk/roc_tim.c       | 32 +++++++++++-
>  drivers/common/cnxk/roc_tim.h       |  9 +++-
>  drivers/common/cnxk/version.map     |  1 +
>  drivers/event/cnxk/cnxk_tim_evdev.c | 69 +++++++++++++++++--------
>  drivers/event/cnxk/cnxk_tim_evdev.h | 79 ++++++++++++++++++-----------
>  6 files changed, 155 insertions(+), 52 deletions(-)
>
> diff --git a/drivers/common/cnxk/roc_mbox.h b/drivers/common/cnxk/roc_mbox.h
> index 75d1ff1ef3..c3688de065 100644
> --- a/drivers/common/cnxk/roc_mbox.h
> +++ b/drivers/common/cnxk/roc_mbox.h
> @@ -131,6 +131,8 @@ struct mbox_msghdr {
>         M(TIM_ENABLE_RING, 0x803, tim_enable_ring, tim_ring_req,               \
>           tim_enable_rsp)                                                      \
>         M(TIM_DISABLE_RING, 0x804, tim_disable_ring, tim_ring_req, msg_rsp)    \
> +       M(TIM_GET_MIN_INTVL, 0x805, tim_get_min_intvl, tim_intvl_req,          \
> +         tim_intvl_rsp)                                                       \
>         /* CPT mbox IDs (range 0xA00 - 0xBFF) */                               \
>         M(CPT_LF_ALLOC, 0xA00, cpt_lf_alloc, cpt_lf_alloc_req_msg, msg_rsp)    \
>         M(CPT_LF_FREE, 0xA01, cpt_lf_free, msg_req, msg_rsp)                   \
> @@ -1756,6 +1758,9 @@ struct tim_config_req {
>         uint32_t __io chunksize;
>         uint32_t __io interval;
>         uint8_t __io gpioedge;
> +       uint8_t __io rsvd[7];
> +       uint64_t __io intervalns;
> +       uint64_t __io clockfreq;
>  };
>
>  struct tim_lf_alloc_rsp {
> @@ -1769,6 +1774,18 @@ struct tim_enable_rsp {
>         uint32_t __io currentbucket;
>  };
>
> +struct tim_intvl_req {
> +       struct mbox_msghdr hdr;
> +       uint8_t __io clocksource;
> +       uint64_t __io clockfreq;
> +};
> +
> +struct tim_intvl_rsp {
> +       struct mbox_msghdr hdr;
> +       uint64_t __io intvl_cyc;
> +       uint64_t __io intvl_ns;
> +};
> +
>  struct sdp_node_info {
>         /* Node to which this PF belons to */
>         uint8_t __io node_id;
> diff --git a/drivers/common/cnxk/roc_tim.c b/drivers/common/cnxk/roc_tim.c
> index 387164bb1d..eefa8253bc 100644
> --- a/drivers/common/cnxk/roc_tim.c
> +++ b/drivers/common/cnxk/roc_tim.c
> @@ -145,7 +145,7 @@ int
>  roc_tim_lf_config(struct roc_tim *roc_tim, uint8_t ring_id,
>                   enum roc_tim_clk_src clk_src, uint8_t ena_periodic,
>                   uint8_t ena_dfb, uint32_t bucket_sz, uint32_t chunk_sz,
> -                 uint32_t interval)
> +                 uint32_t interval, uint64_t intervalns, uint64_t clockfreq)
>  {
>         struct dev *dev = &roc_sso_to_sso_priv(roc_tim->roc_sso)->dev;
>         struct tim_config_req *req;
> @@ -162,6 +162,8 @@ roc_tim_lf_config(struct roc_tim *roc_tim, uint8_t ring_id,
>         req->enableperiodic = ena_periodic;
>         req->enabledontfreebuffer = ena_dfb;
>         req->interval = interval;
> +       req->intervalns = intervalns;
> +       req->clockfreq = clockfreq;
>         req->gpioedge = TIM_GPIO_LTOH_TRANS;
>
>         rc = mbox_process(dev->mbox);
> @@ -173,6 +175,34 @@ roc_tim_lf_config(struct roc_tim *roc_tim, uint8_t ring_id,
>         return 0;
>  }
>
> +int
> +roc_tim_lf_interval(struct roc_tim *roc_tim, enum roc_tim_clk_src clk_src,
> +                   uint64_t clockfreq, uint64_t *intervalns,
> +                   uint64_t *interval)
> +{
> +       struct dev *dev = &roc_sso_to_sso_priv(roc_tim->roc_sso)->dev;
> +       struct tim_intvl_req *req;
> +       struct tim_intvl_rsp *rsp;
> +       int rc = -ENOSPC;
> +
> +       req = mbox_alloc_msg_tim_get_min_intvl(dev->mbox);
> +       if (req == NULL)
> +               return rc;
> +
> +       req->clockfreq = clockfreq;
> +       req->clocksource = clk_src;
> +       rc = mbox_process_msg(dev->mbox, (void **)&rsp);
> +       if (rc < 0) {
> +               tim_err_desc(rc);
> +               return rc;
> +       }
> +
> +       *intervalns = rsp->intvl_ns;
> +       *interval = rsp->intvl_cyc;
> +
> +       return 0;
> +}
> +
>  int
>  roc_tim_lf_alloc(struct roc_tim *roc_tim, uint8_t ring_id, uint64_t *clk)
>  {
> diff --git a/drivers/common/cnxk/roc_tim.h b/drivers/common/cnxk/roc_tim.h
> index 159b021a31..392732eae2 100644
> --- a/drivers/common/cnxk/roc_tim.h
> +++ b/drivers/common/cnxk/roc_tim.h
> @@ -10,6 +10,8 @@ enum roc_tim_clk_src {
>         ROC_TIM_CLK_SRC_GPIO,
>         ROC_TIM_CLK_SRC_GTI,
>         ROC_TIM_CLK_SRC_PTP,
> +       ROC_TIM_CLK_SRC_SYNCE,
> +       ROC_TIM_CLK_SRC_BTS,
>         ROC_TIM_CLK_SRC_INVALID,
>  };
>
> @@ -33,7 +35,12 @@ int __roc_api roc_tim_lf_config(struct roc_tim *roc_tim, uint8_t ring_id,
>                                 enum roc_tim_clk_src clk_src,
>                                 uint8_t ena_periodic, uint8_t ena_dfb,
>                                 uint32_t bucket_sz, uint32_t chunk_sz,
> -                               uint32_t interval);
> +                               uint32_t interval, uint64_t intervalns,
> +                               uint64_t clockfreq);
> +int __roc_api roc_tim_lf_interval(struct roc_tim *roc_tim,
> +                                 enum roc_tim_clk_src clk_src,
> +                                 uint64_t clockfreq, uint64_t *intervalns,
> +                                 uint64_t *interval);
>  int __roc_api roc_tim_lf_alloc(struct roc_tim *roc_tim, uint8_t ring_id,
>                                uint64_t *clk);
>  int __roc_api roc_tim_lf_free(struct roc_tim *roc_tim, uint8_t ring_id);
> diff --git a/drivers/common/cnxk/version.map b/drivers/common/cnxk/version.map
> index fff7902b25..5791629ce9 100644
> --- a/drivers/common/cnxk/version.map
> +++ b/drivers/common/cnxk/version.map
> @@ -279,6 +279,7 @@ INTERNAL {
>         roc_tim_lf_disable;
>         roc_tim_lf_enable;
>         roc_tim_lf_free;
> +       roc_tim_lf_interval;
>         roc_se_ctx_swap;
>
>         local: *;
> diff --git a/drivers/event/cnxk/cnxk_tim_evdev.c b/drivers/event/cnxk/cnxk_tim_evdev.c
> index 9d40e336d7..369f198444 100644
> --- a/drivers/event/cnxk/cnxk_tim_evdev.c
> +++ b/drivers/event/cnxk/cnxk_tim_evdev.c
> @@ -2,6 +2,8 @@
>   * Copyright(C) 2021 Marvell.
>   */
>
> +#include <math.h>
> +
>  #include "cnxk_eventdev.h"
>  #include "cnxk_tim_evdev.h"
>
> @@ -120,7 +122,10 @@ cnxk_tim_ring_create(struct rte_event_timer_adapter *adptr)
>  {
>         struct rte_event_timer_adapter_conf *rcfg = &adptr->data->conf;
>         struct cnxk_tim_evdev *dev = cnxk_tim_priv_get();
> +       uint64_t min_intvl_ns, min_intvl_cyc;
>         struct cnxk_tim_ring *tim_ring;
> +       enum roc_tim_clk_src clk_src;
> +       uint64_t clk_freq = 0;
>         int i, rc;
>
>         if (dev == NULL)
> @@ -139,25 +144,52 @@ cnxk_tim_ring_create(struct rte_event_timer_adapter *adptr)
>                 goto tim_ring_free;
>         }
>
> -       if (NSEC2TICK(RTE_ALIGN_MUL_CEIL(
> -                             rcfg->timer_tick_ns,
> -                             cnxk_tim_min_resolution_ns(cnxk_tim_cntfrq())),
> -                     cnxk_tim_cntfrq()) <
> -           cnxk_tim_min_tmo_ticks(cnxk_tim_cntfrq())) {
> -               if (rcfg->flags & RTE_EVENT_TIMER_ADAPTER_F_ADJUST_RES)
> -                       rcfg->timer_tick_ns = TICK2NSEC(
> -                               cnxk_tim_min_tmo_ticks(cnxk_tim_cntfrq()),
> -                               cnxk_tim_cntfrq());
> -               else {
> +       clk_src = cnxk_tim_convert_clk_src(rcfg->clk_src);
> +       if (clk_src == ROC_TIM_CLK_SRC_INVALID) {
> +               plt_err("Invalid clock source");
> +               goto tim_hw_free;
> +       }
> +
> +       rc = cnxk_tim_get_clk_freq(dev, clk_src, &clk_freq);
> +       if (rc < 0) {
> +               plt_err("Failed to get clock frequency");
> +               goto tim_hw_free;
> +       }
> +
> +       rc = roc_tim_lf_interval(&dev->tim, clk_src, clk_freq, &min_intvl_ns,
> +                                &min_intvl_cyc);
> +       if (rc < 0) {
> +               plt_err("Failed to get min interval details");
> +               goto tim_hw_free;
> +       }
> +
> +       if (rcfg->timer_tick_ns < min_intvl_ns) {
> +               if (rcfg->flags & RTE_EVENT_TIMER_ADAPTER_F_ADJUST_RES) {
> +                       rcfg->timer_tick_ns = min_intvl_ns;
> +               } else {
>                         rc = -ERANGE;
>                         goto tim_hw_free;
>                 }
>         }
> +
> +       if (rcfg->timer_tick_ns > rcfg->max_tmo_ns) {
> +               plt_err("Max timeout to too high");
> +               rc = -ERANGE;
> +               goto tim_hw_free;
> +       }
> +
> +       /* Round */
> +       tim_ring->tck_nsec =
> +               round(RTE_ALIGN_MUL_NEAR((long double)rcfg->timer_tick_ns,
> +                                        cnxk_tim_ns_per_tck(clk_freq)));
> +
> +       tim_ring->tck_int = round((long double)tim_ring->tck_nsec /
> +                                 cnxk_tim_ns_per_tck(clk_freq));
> +       tim_ring->tck_nsec =
> +               ceil(tim_ring->tck_int * cnxk_tim_ns_per_tck(clk_freq));
> +
>         tim_ring->ring_id = adptr->data->id;
> -       tim_ring->clk_src = (int)rcfg->clk_src;
> -       tim_ring->tck_nsec = RTE_ALIGN_MUL_CEIL(
> -               rcfg->timer_tick_ns,
> -               cnxk_tim_min_resolution_ns(cnxk_tim_cntfrq()));
> +       tim_ring->clk_src = clk_src;
>         tim_ring->max_tout = rcfg->max_tmo_ns;
>         tim_ring->nb_bkts = (tim_ring->max_tout / tim_ring->tck_nsec);
>         tim_ring->nb_timers = rcfg->nb_timers;
> @@ -201,11 +233,9 @@ cnxk_tim_ring_create(struct rte_event_timer_adapter *adptr)
>         if (rc < 0)
>                 goto tim_bkt_free;
>
> -       rc = roc_tim_lf_config(
> -               &dev->tim, tim_ring->ring_id,
> -               cnxk_tim_convert_clk_src(tim_ring->clk_src), 0, 0,
> -               tim_ring->nb_bkts, tim_ring->chunk_sz,
> -               NSEC2TICK(tim_ring->tck_nsec, cnxk_tim_cntfrq()));
> +       rc = roc_tim_lf_config(&dev->tim, tim_ring->ring_id, clk_src, 0, 0,
> +                              tim_ring->nb_bkts, tim_ring->chunk_sz,
> +                              tim_ring->tck_int, tim_ring->tck_nsec, clk_freq);
>         if (rc < 0) {
>                 plt_err("Failed to configure timer ring");
>                 goto tim_chnk_free;
> @@ -300,7 +330,6 @@ cnxk_tim_ring_start(const struct rte_event_timer_adapter *adptr)
>         if (rc < 0)
>                 return rc;
>
> -       tim_ring->tck_int = NSEC2TICK(tim_ring->tck_nsec, cnxk_tim_cntfrq());
>         tim_ring->tot_int = tim_ring->tck_int * tim_ring->nb_bkts;
>         tim_ring->fast_div = rte_reciprocal_value_u64(tim_ring->tck_int);
>         tim_ring->fast_bkt = rte_reciprocal_value_u64(tim_ring->nb_bkts);
> diff --git a/drivers/event/cnxk/cnxk_tim_evdev.h b/drivers/event/cnxk/cnxk_tim_evdev.h
> index c369f6f472..4afbcb8fb2 100644
> --- a/drivers/event/cnxk/cnxk_tim_evdev.h
> +++ b/drivers/event/cnxk/cnxk_tim_evdev.h
> @@ -97,13 +97,6 @@ struct cnxk_tim_evdev {
>         struct cnxk_tim_ctl *ring_ctl_data;
>  };
>
> -enum cnxk_tim_clk_src {
> -       CNXK_TIM_CLK_SRC_10NS = RTE_EVENT_TIMER_ADAPTER_CPU_CLK,
> -       CNXK_TIM_CLK_SRC_GPIO = RTE_EVENT_TIMER_ADAPTER_EXT_CLK0,
> -       CNXK_TIM_CLK_SRC_GTI = RTE_EVENT_TIMER_ADAPTER_EXT_CLK1,
> -       CNXK_TIM_CLK_SRC_PTP = RTE_EVENT_TIMER_ADAPTER_EXT_CLK2,
> -};
> -
>  struct cnxk_tim_bkt {
>         uint64_t first_chunk;
>         union {
> @@ -146,7 +139,7 @@ struct cnxk_tim_ring {
>         uint64_t max_tout;
>         uint64_t nb_chunks;
>         uint64_t chunk_sz;
> -       enum cnxk_tim_clk_src clk_src;
> +       enum roc_tim_clk_src clk_src;
>  } __rte_cache_aligned;
>
>  struct cnxk_tim_ent {
> @@ -166,32 +159,13 @@ cnxk_tim_priv_get(void)
>         return mz->addr;
>  }
>
> -static inline uint64_t
> -cnxk_tim_min_tmo_ticks(uint64_t freq)
> +static inline long double
> +cnxk_tim_ns_per_tck(uint64_t freq)
>  {
> -       if (roc_model_runtime_is_cn9k())
> -               return CN9K_TIM_MIN_TMO_TKS;
> -       else /* CN10K min tick is of 1us */
> -               return freq / USECPERSEC;
> +       return (long double)NSECPERSEC / freq;
>  }
>
> -static inline uint64_t
> -cnxk_tim_min_resolution_ns(uint64_t freq)
> -{
> -       return NSECPERSEC / freq;
> -}
>
> -static inline enum roc_tim_clk_src
> -cnxk_tim_convert_clk_src(enum cnxk_tim_clk_src clk_src)
> -{
> -       switch (clk_src) {
> -       case RTE_EVENT_TIMER_ADAPTER_CPU_CLK:
> -               return roc_model_runtime_is_cn9k() ? ROC_TIM_CLK_SRC_10NS :
> -                                                          ROC_TIM_CLK_SRC_GTI;
> -       default:
> -               return ROC_TIM_CLK_SRC_INVALID;
> -       }
> -}
>
>  #ifdef RTE_ARCH_ARM64
>  static inline uint64_t
> @@ -225,6 +199,51 @@ cnxk_tim_cntfrq(void)
>  }
>  #endif
>
> +static inline enum roc_tim_clk_src
> +cnxk_tim_convert_clk_src(enum rte_event_timer_adapter_clk_src clk_src)
> +{
> +       switch (clk_src) {
> +       case RTE_EVENT_TIMER_ADAPTER_CPU_CLK:
> +               return ROC_TIM_CLK_SRC_GTI;
> +       case RTE_EVENT_TIMER_ADAPTER_EXT_CLK0:
> +               return ROC_TIM_CLK_SRC_10NS;
> +       case RTE_EVENT_TIMER_ADAPTER_EXT_CLK1:
> +               return ROC_TIM_CLK_SRC_GPIO;
> +       case RTE_EVENT_TIMER_ADAPTER_EXT_CLK2:
> +               return ROC_TIM_CLK_SRC_PTP;
> +       case RTE_EVENT_TIMER_ADAPTER_EXT_CLK3:
> +               return roc_model_constant_is_cn9k() ? ROC_TIM_CLK_SRC_INVALID :
> +                                                     ROC_TIM_CLK_SRC_SYNCE;
> +       default:
> +               return ROC_TIM_CLK_SRC_INVALID;
> +       }
> +}
> +
> +static inline int
> +cnxk_tim_get_clk_freq(struct cnxk_tim_evdev *dev, enum roc_tim_clk_src clk_src,
> +                     uint64_t *freq)
> +{
> +       if (freq == NULL)
> +               return -EINVAL;
> +
> +       PLT_SET_USED(dev);
> +       switch (clk_src) {
> +       case ROC_TIM_CLK_SRC_GTI:
> +               *freq = cnxk_tim_cntfrq();
> +               break;
> +       case ROC_TIM_CLK_SRC_10NS:
> +               *freq = 1E8;
> +               break;
> +       case ROC_TIM_CLK_SRC_GPIO:
> +       case ROC_TIM_CLK_SRC_PTP:
> +       case ROC_TIM_CLK_SRC_SYNCE:
> +       default:
> +               return -EINVAL;
> +       }
> +
> +       return 0;
> +}
> +
>  #define TIM_ARM_FASTPATH_MODES                                                 \
>         FP(sp, 0, 0, 0, CNXK_TIM_ENA_DFB | CNXK_TIM_SP)                        \
>         FP(mp, 0, 0, 1, CNXK_TIM_ENA_DFB | CNXK_TIM_MP)                        \
> --
> 2.17.1
>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v5 1/2] event/cnxk: update min interval calculation
  2021-10-09  8:04     ` [dpdk-dev] [PATCH v4 1/2] event/cnxk: update min interval calculation pbhagavatula
  2021-10-09  8:04       ` [dpdk-dev] [PATCH v4 2/2] event/cnxk: add external clock support for timer pbhagavatula
  2021-10-14 11:51       ` [dpdk-dev] [PATCH v4 1/2] event/cnxk: update min interval calculation Jerin Jacob
@ 2021-12-13 11:13       ` pbhagavatula
  2021-12-13 11:13         ` [PATCH v5 2/2] event/cnxk: add external clock support for timer pbhagavatula
                           ` (2 more replies)
  2 siblings, 3 replies; 11+ messages in thread
From: pbhagavatula @ 2021-12-13 11:13 UTC (permalink / raw)
  To: jerinj, Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori,
	Satha Rao, Ray Kinsella, Pavan Nikhilesh, Shijith Thotton
  Cc: dev

From: Pavan Nikhilesh <pbhagavatula@marvell.com>

Minimum supported interval should now be retrieved from
mailbox based on the clock source and clock frequency.

Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
---
v5:
- Rebase on master.
v4:
- Rebase on master, fix NULL checks.
v3:
- Add new mbox interface.
v2:
- Fixed devargs parsing and rebased.

 drivers/common/cnxk/roc_tim.c       | 32 +++++++++++-
 drivers/common/cnxk/roc_tim.h       |  9 +++-
 drivers/common/cnxk/version.map     |  1 +
 drivers/event/cnxk/cnxk_tim_evdev.c | 69 +++++++++++++++++-------
 drivers/event/cnxk/cnxk_tim_evdev.h | 81 +++++++++++++++++------------
 5 files changed, 138 insertions(+), 54 deletions(-)

diff --git a/drivers/common/cnxk/roc_tim.c b/drivers/common/cnxk/roc_tim.c
index 534b697bee..cefd9bc89d 100644
--- a/drivers/common/cnxk/roc_tim.c
+++ b/drivers/common/cnxk/roc_tim.c
@@ -145,7 +145,7 @@ int
 roc_tim_lf_config(struct roc_tim *roc_tim, uint8_t ring_id,
 		  enum roc_tim_clk_src clk_src, uint8_t ena_periodic,
 		  uint8_t ena_dfb, uint32_t bucket_sz, uint32_t chunk_sz,
-		  uint32_t interval)
+		  uint32_t interval, uint64_t intervalns, uint64_t clockfreq)
 {
 	struct dev *dev = &roc_sso_to_sso_priv(roc_tim->roc_sso)->dev;
 	struct tim_config_req *req;
@@ -162,6 +162,8 @@ roc_tim_lf_config(struct roc_tim *roc_tim, uint8_t ring_id,
 	req->enableperiodic = ena_periodic;
 	req->enabledontfreebuffer = ena_dfb;
 	req->interval = interval;
+	req->intervalns = intervalns;
+	req->clockfreq = clockfreq;
 	req->gpioedge = TIM_GPIO_LTOH_TRANS;

 	rc = mbox_process(dev->mbox);
@@ -173,6 +175,34 @@ roc_tim_lf_config(struct roc_tim *roc_tim, uint8_t ring_id,
 	return 0;
 }

+int
+roc_tim_lf_interval(struct roc_tim *roc_tim, enum roc_tim_clk_src clk_src,
+		    uint64_t clockfreq, uint64_t *intervalns,
+		    uint64_t *interval)
+{
+	struct dev *dev = &roc_sso_to_sso_priv(roc_tim->roc_sso)->dev;
+	struct tim_intvl_req *req;
+	struct tim_intvl_rsp *rsp;
+	int rc = -ENOSPC;
+
+	req = mbox_alloc_msg_tim_get_min_intvl(dev->mbox);
+	if (req == NULL)
+		return rc;
+
+	req->clockfreq = clockfreq;
+	req->clocksource = clk_src;
+	rc = mbox_process_msg(dev->mbox, (void **)&rsp);
+	if (rc < 0) {
+		tim_err_desc(rc);
+		return rc;
+	}
+
+	*intervalns = rsp->intvl_ns;
+	*interval = rsp->intvl_cyc;
+
+	return 0;
+}
+
 int
 roc_tim_lf_alloc(struct roc_tim *roc_tim, uint8_t ring_id, uint64_t *clk)
 {
diff --git a/drivers/common/cnxk/roc_tim.h b/drivers/common/cnxk/roc_tim.h
index 159b021a31..392732eae2 100644
--- a/drivers/common/cnxk/roc_tim.h
+++ b/drivers/common/cnxk/roc_tim.h
@@ -10,6 +10,8 @@ enum roc_tim_clk_src {
 	ROC_TIM_CLK_SRC_GPIO,
 	ROC_TIM_CLK_SRC_GTI,
 	ROC_TIM_CLK_SRC_PTP,
+	ROC_TIM_CLK_SRC_SYNCE,
+	ROC_TIM_CLK_SRC_BTS,
 	ROC_TIM_CLK_SRC_INVALID,
 };

@@ -33,7 +35,12 @@ int __roc_api roc_tim_lf_config(struct roc_tim *roc_tim, uint8_t ring_id,
 				enum roc_tim_clk_src clk_src,
 				uint8_t ena_periodic, uint8_t ena_dfb,
 				uint32_t bucket_sz, uint32_t chunk_sz,
-				uint32_t interval);
+				uint32_t interval, uint64_t intervalns,
+				uint64_t clockfreq);
+int __roc_api roc_tim_lf_interval(struct roc_tim *roc_tim,
+				  enum roc_tim_clk_src clk_src,
+				  uint64_t clockfreq, uint64_t *intervalns,
+				  uint64_t *interval);
 int __roc_api roc_tim_lf_alloc(struct roc_tim *roc_tim, uint8_t ring_id,
 			       uint64_t *clk);
 int __roc_api roc_tim_lf_free(struct roc_tim *roc_tim, uint8_t ring_id);
diff --git a/drivers/common/cnxk/version.map b/drivers/common/cnxk/version.map
index 07c6720f0c..5379ed2d39 100644
--- a/drivers/common/cnxk/version.map
+++ b/drivers/common/cnxk/version.map
@@ -346,6 +346,7 @@ INTERNAL {
 	roc_tim_lf_disable;
 	roc_tim_lf_enable;
 	roc_tim_lf_free;
+	roc_tim_lf_interval;
 	roc_se_ctx_swap;

 	local: *;
diff --git a/drivers/event/cnxk/cnxk_tim_evdev.c b/drivers/event/cnxk/cnxk_tim_evdev.c
index 99b3acee7c..becab1d1b1 100644
--- a/drivers/event/cnxk/cnxk_tim_evdev.c
+++ b/drivers/event/cnxk/cnxk_tim_evdev.c
@@ -2,6 +2,8 @@
  * Copyright(C) 2021 Marvell.
  */

+#include <math.h>
+
 #include "cnxk_eventdev.h"
 #include "cnxk_tim_evdev.h"

@@ -120,7 +122,10 @@ cnxk_tim_ring_create(struct rte_event_timer_adapter *adptr)
 {
 	struct rte_event_timer_adapter_conf *rcfg = &adptr->data->conf;
 	struct cnxk_tim_evdev *dev = cnxk_tim_priv_get();
+	uint64_t min_intvl_ns, min_intvl_cyc;
 	struct cnxk_tim_ring *tim_ring;
+	enum roc_tim_clk_src clk_src;
+	uint64_t clk_freq = 0;
 	int i, rc;

 	if (dev == NULL)
@@ -139,25 +144,52 @@ cnxk_tim_ring_create(struct rte_event_timer_adapter *adptr)
 		goto tim_ring_free;
 	}

-	if (NSEC2TICK(RTE_ALIGN_MUL_CEIL(
-			      rcfg->timer_tick_ns,
-			      cnxk_tim_min_resolution_ns(cnxk_tim_cntfrq())),
-		      cnxk_tim_cntfrq()) <
-	    cnxk_tim_min_tmo_ticks(cnxk_tim_cntfrq())) {
-		if (rcfg->flags & RTE_EVENT_TIMER_ADAPTER_F_ADJUST_RES)
-			rcfg->timer_tick_ns = TICK2NSEC(
-				cnxk_tim_min_tmo_ticks(cnxk_tim_cntfrq()),
-				cnxk_tim_cntfrq());
-		else {
+	clk_src = cnxk_tim_convert_clk_src(rcfg->clk_src);
+	if (clk_src == ROC_TIM_CLK_SRC_INVALID) {
+		plt_err("Invalid clock source");
+		goto tim_hw_free;
+	}
+
+	rc = cnxk_tim_get_clk_freq(dev, clk_src, &clk_freq);
+	if (rc < 0) {
+		plt_err("Failed to get clock frequency");
+		goto tim_hw_free;
+	}
+
+	rc = roc_tim_lf_interval(&dev->tim, clk_src, clk_freq, &min_intvl_ns,
+				 &min_intvl_cyc);
+	if (rc < 0) {
+		plt_err("Failed to get min interval details");
+		goto tim_hw_free;
+	}
+
+	if (rcfg->timer_tick_ns < min_intvl_ns) {
+		if (rcfg->flags & RTE_EVENT_TIMER_ADAPTER_F_ADJUST_RES) {
+			rcfg->timer_tick_ns = min_intvl_ns;
+		} else {
 			rc = -ERANGE;
 			goto tim_hw_free;
 		}
 	}
+
+	if (rcfg->timer_tick_ns > rcfg->max_tmo_ns) {
+		plt_err("Max timeout to too high");
+		rc = -ERANGE;
+		goto tim_hw_free;
+	}
+
+	/* Round */
+	tim_ring->tck_nsec =
+		round(RTE_ALIGN_MUL_NEAR((long double)rcfg->timer_tick_ns,
+					 cnxk_tim_ns_per_tck(clk_freq)));
+
+	tim_ring->tck_int = round((long double)tim_ring->tck_nsec /
+				  cnxk_tim_ns_per_tck(clk_freq));
+	tim_ring->tck_nsec =
+		ceil(tim_ring->tck_int * cnxk_tim_ns_per_tck(clk_freq));
+
 	tim_ring->ring_id = adptr->data->id;
-	tim_ring->clk_src = (int)rcfg->clk_src;
-	tim_ring->tck_nsec = RTE_ALIGN_MUL_CEIL(
-		rcfg->timer_tick_ns,
-		cnxk_tim_min_resolution_ns(cnxk_tim_cntfrq()));
+	tim_ring->clk_src = clk_src;
 	tim_ring->max_tout = rcfg->max_tmo_ns;
 	tim_ring->nb_bkts = (tim_ring->max_tout / tim_ring->tck_nsec);
 	tim_ring->nb_timers = rcfg->nb_timers;
@@ -201,11 +233,9 @@ cnxk_tim_ring_create(struct rte_event_timer_adapter *adptr)
 	if (rc < 0)
 		goto tim_bkt_free;

-	rc = roc_tim_lf_config(
-		&dev->tim, tim_ring->ring_id,
-		cnxk_tim_convert_clk_src(tim_ring->clk_src), 0, 0,
-		tim_ring->nb_bkts, tim_ring->chunk_sz,
-		NSEC2TICK(tim_ring->tck_nsec, cnxk_tim_cntfrq()));
+	rc = roc_tim_lf_config(&dev->tim, tim_ring->ring_id, clk_src, 0, 0,
+			       tim_ring->nb_bkts, tim_ring->chunk_sz,
+			       tim_ring->tck_int, tim_ring->tck_nsec, clk_freq);
 	if (rc < 0) {
 		plt_err("Failed to configure timer ring");
 		goto tim_chnk_free;
@@ -300,7 +330,6 @@ cnxk_tim_ring_start(const struct rte_event_timer_adapter *adptr)
 	if (rc < 0)
 		return rc;

-	tim_ring->tck_int = NSEC2TICK(tim_ring->tck_nsec, cnxk_tim_cntfrq());
 	tim_ring->tot_int = tim_ring->tck_int * tim_ring->nb_bkts;
 	tim_ring->fast_div = rte_reciprocal_value_u64(tim_ring->tck_int);
 	tim_ring->fast_bkt = rte_reciprocal_value_u64(tim_ring->nb_bkts);
diff --git a/drivers/event/cnxk/cnxk_tim_evdev.h b/drivers/event/cnxk/cnxk_tim_evdev.h
index 2478a5c1df..1fb17f571d 100644
--- a/drivers/event/cnxk/cnxk_tim_evdev.h
+++ b/drivers/event/cnxk/cnxk_tim_evdev.h
@@ -98,13 +98,6 @@ struct cnxk_tim_evdev {
 	struct cnxk_tim_ctl *ring_ctl_data;
 };

-enum cnxk_tim_clk_src {
-	CNXK_TIM_CLK_SRC_10NS = RTE_EVENT_TIMER_ADAPTER_CPU_CLK,
-	CNXK_TIM_CLK_SRC_GPIO = RTE_EVENT_TIMER_ADAPTER_EXT_CLK0,
-	CNXK_TIM_CLK_SRC_GTI = RTE_EVENT_TIMER_ADAPTER_EXT_CLK1,
-	CNXK_TIM_CLK_SRC_PTP = RTE_EVENT_TIMER_ADAPTER_EXT_CLK2,
-};
-
 struct cnxk_tim_bkt {
 	uint64_t first_chunk;
 	union {
@@ -147,7 +140,7 @@ struct cnxk_tim_ring {
 	uint64_t max_tout;
 	uint64_t nb_chunks;
 	uint64_t chunk_sz;
-	enum cnxk_tim_clk_src clk_src;
+	enum roc_tim_clk_src clk_src;
 } __rte_cache_aligned;

 struct cnxk_tim_ent {
@@ -167,31 +160,10 @@ cnxk_tim_priv_get(void)
 	return mz->addr;
 }

-static inline uint64_t
-cnxk_tim_min_tmo_ticks(uint64_t freq)
+static inline long double
+cnxk_tim_ns_per_tck(uint64_t freq)
 {
-	if (roc_model_runtime_is_cn9k())
-		return CN9K_TIM_MIN_TMO_TKS;
-	else /* CN10K min tick is of 1us */
-		return freq / USECPERSEC;
-}
-
-static inline uint64_t
-cnxk_tim_min_resolution_ns(uint64_t freq)
-{
-	return NSECPERSEC / freq;
-}
-
-static inline enum roc_tim_clk_src
-cnxk_tim_convert_clk_src(enum cnxk_tim_clk_src clk_src)
-{
-	switch (clk_src) {
-	case RTE_EVENT_TIMER_ADAPTER_CPU_CLK:
-		return roc_model_runtime_is_cn9k() ? ROC_TIM_CLK_SRC_10NS :
-							   ROC_TIM_CLK_SRC_GTI;
-	default:
-		return ROC_TIM_CLK_SRC_INVALID;
-	}
+	return (long double)NSECPERSEC / freq;
 }

 #ifdef RTE_ARCH_ARM64
@@ -226,6 +198,51 @@ cnxk_tim_cntfrq(void)
 }
 #endif

+static inline enum roc_tim_clk_src
+cnxk_tim_convert_clk_src(enum rte_event_timer_adapter_clk_src clk_src)
+{
+	switch (clk_src) {
+	case RTE_EVENT_TIMER_ADAPTER_CPU_CLK:
+		return ROC_TIM_CLK_SRC_GTI;
+	case RTE_EVENT_TIMER_ADAPTER_EXT_CLK0:
+		return ROC_TIM_CLK_SRC_10NS;
+	case RTE_EVENT_TIMER_ADAPTER_EXT_CLK1:
+		return ROC_TIM_CLK_SRC_GPIO;
+	case RTE_EVENT_TIMER_ADAPTER_EXT_CLK2:
+		return ROC_TIM_CLK_SRC_PTP;
+	case RTE_EVENT_TIMER_ADAPTER_EXT_CLK3:
+		return roc_model_constant_is_cn9k() ? ROC_TIM_CLK_SRC_INVALID :
+						      ROC_TIM_CLK_SRC_SYNCE;
+	default:
+		return ROC_TIM_CLK_SRC_INVALID;
+	}
+}
+
+static inline int
+cnxk_tim_get_clk_freq(struct cnxk_tim_evdev *dev, enum roc_tim_clk_src clk_src,
+		      uint64_t *freq)
+{
+	if (freq == NULL)
+		return -EINVAL;
+
+	PLT_SET_USED(dev);
+	switch (clk_src) {
+	case ROC_TIM_CLK_SRC_GTI:
+		*freq = cnxk_tim_cntfrq();
+		break;
+	case ROC_TIM_CLK_SRC_10NS:
+		*freq = 1E8;
+		break;
+	case ROC_TIM_CLK_SRC_GPIO:
+	case ROC_TIM_CLK_SRC_PTP:
+	case ROC_TIM_CLK_SRC_SYNCE:
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 #define TIM_ARM_FASTPATH_MODES                                                 \
 	FP(sp, 0, 0, 0, CNXK_TIM_ENA_DFB | CNXK_TIM_SP)                        \
 	FP(mp, 0, 0, 1, CNXK_TIM_ENA_DFB | CNXK_TIM_MP)                        \
--
2.17.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v5 2/2] event/cnxk: add external clock support for timer
  2021-12-13 11:13       ` [PATCH v5 " pbhagavatula
@ 2021-12-13 11:13         ` pbhagavatula
  2022-01-21 10:18         ` [PATCH v5 1/2] event/cnxk: update min interval calculation Jerin Jacob
  2022-01-25  9:54         ` Ray Kinsella
  2 siblings, 0 replies; 11+ messages in thread
From: pbhagavatula @ 2021-12-13 11:13 UTC (permalink / raw)
  To: jerinj, Pavan Nikhilesh, Shijith Thotton, Nithin Dabilpuram,
	Kiran Kumar K, Sunil Kumar Kori, Satha Rao, Anatoly Burakov
  Cc: dev

From: Pavan Nikhilesh <pbhagavatula@marvell.com>

Add external clock support for cnxk timer adapter.

External clock mapping is as follows:
RTE_EVENT_TIMER_ADAPTER_EXT_CLK0 = TIM_CLK_SRC_10NS,
RTE_EVENT_TIMER_ADAPTER_EXT_CLK1 = TIM_CLK_SRC_GPIO,
RTE_EVENT_TIMER_ADAPTER_EXT_CLK2 = TIM_CLK_SRC_PTP,
RTE_EVENT_TIMER_ADAPTER_EXT_CLK3 = TIM_CLK_SRC_SYNCE,

TIM supports clock input from external GPIO, PTP, SYNCE clocks.
Input resolution is adjusted based on CNTVCT frequency for better
estimation.

Since TIM is unaware of input clock frequency, application is
expected to pass the frequency.
Example:
	-a 0002:0e:00.0,tim_eclk_freq=122880000-0-0

The order of frequencies above is GPIO-PTP-SYNCE.

Signed-off-by: Shijith Thotton <sthotton@marvell.com>
Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
---
 doc/guides/eventdevs/cnxk.rst       |  18 ++++
 drivers/common/cnxk/roc_platform.h  |   1 +
 drivers/event/cnxk/cn10k_eventdev.c |   3 +-
 drivers/event/cnxk/cnxk_tim_evdev.c | 137 +++++++++++++++++++++++++++-
 drivers/event/cnxk/cnxk_tim_evdev.h |   4 +
 5 files changed, 160 insertions(+), 3 deletions(-)

diff --git a/doc/guides/eventdevs/cnxk.rst b/doc/guides/eventdevs/cnxk.rst
index 1c0ea988f2..8537f6257e 100644
--- a/doc/guides/eventdevs/cnxk.rst
+++ b/doc/guides/eventdevs/cnxk.rst
@@ -164,6 +164,24 @@ Runtime Config Options

     -a 0002:0e:00.0,tim_ring_ctl=[2-1023-1-0]

+- ``TIM external clock frequency``
+
+  The ``tim_eclk_freq`` devagrs can be used to pass external clock frequencies
+  when external clock source is selected.
+
+  External clock frequencies are mapped as follows::
+
+    RTE_EVENT_TIMER_ADAPTER_EXT_CLK0 = TIM_CLK_SRC_10NS,
+    RTE_EVENT_TIMER_ADAPTER_EXT_CLK1 = TIM_CLK_SRC_GPIO,
+    RTE_EVENT_TIMER_ADAPTER_EXT_CLK2 = TIM_CLK_SRC_PTP,
+    RTE_EVENT_TIMER_ADAPTER_EXT_CLK3 = TIM_CLK_SRC_SYNCE
+
+  The order of frequencies supplied to device args should be GPIO-PTP-SYNCE.
+
+  For Example::
+
+    -a 0002:0e:00.0,tim_eclk_freq=122880000-1000000000-0
+
 Debugging Options
 -----------------

diff --git a/drivers/common/cnxk/roc_platform.h b/drivers/common/cnxk/roc_platform.h
index 61d4781209..2742a09190 100644
--- a/drivers/common/cnxk/roc_platform.h
+++ b/drivers/common/cnxk/roc_platform.h
@@ -45,6 +45,7 @@
 #define PLT_MAX			 RTE_MAX
 #define PLT_DIM			 RTE_DIM
 #define PLT_SET_USED		 RTE_SET_USED
+#define PLT_SWAP		 RTE_SWAP
 #define PLT_STATIC_ASSERT(s)	 _Static_assert(s, #s)
 #define PLT_ALIGN		 RTE_ALIGN
 #define PLT_ALIGN_MUL_CEIL	 RTE_ALIGN_MUL_CEIL
diff --git a/drivers/event/cnxk/cn10k_eventdev.c b/drivers/event/cnxk/cn10k_eventdev.c
index b56426960a..70e2aa5555 100644
--- a/drivers/event/cnxk/cn10k_eventdev.c
+++ b/drivers/event/cnxk/cn10k_eventdev.c
@@ -916,4 +916,5 @@ RTE_PMD_REGISTER_PARAM_STRING(event_cn10k, CNXK_SSO_XAE_CNT "=<int>"
 			      CNXK_TIM_DISABLE_NPA "=1"
 			      CNXK_TIM_CHNK_SLOTS "=<int>"
 			      CNXK_TIM_RINGS_LMT "=<int>"
-			      CNXK_TIM_STATS_ENA "=1");
+			      CNXK_TIM_STATS_ENA "=1"
+			      CNXK_TIM_EXT_CLK "=<string>");
diff --git a/drivers/event/cnxk/cnxk_tim_evdev.c b/drivers/event/cnxk/cnxk_tim_evdev.c
index becab1d1b1..5d52a39752 100644
--- a/drivers/event/cnxk/cnxk_tim_evdev.c
+++ b/drivers/event/cnxk/cnxk_tim_evdev.c
@@ -117,6 +117,80 @@ cnxk_tim_ring_info_get(const struct rte_event_timer_adapter *adptr,
 		   sizeof(struct rte_event_timer_adapter_conf));
 }

+static inline void
+sort_multi_array(double ref_arr[], uint64_t arr1[], uint64_t arr2[],
+		 uint64_t arr3[], uint8_t sz)
+{
+	int x;
+
+	for (x = 0; x < sz - 1; x++) {
+		if (ref_arr[x] > ref_arr[x + 1]) {
+			PLT_SWAP(ref_arr[x], ref_arr[x + 1]);
+			PLT_SWAP(arr1[x], arr1[x + 1]);
+			PLT_SWAP(arr2[x], arr2[x + 1]);
+			PLT_SWAP(arr3[x], arr3[x + 1]);
+			x = -1;
+		}
+	}
+}
+
+static inline void
+populate_sample(uint64_t tck[], uint64_t ns[], double diff[], uint64_t dst[],
+		uint64_t req_tck, uint64_t clk_freq, double tck_ns, uint8_t sz,
+		bool mov_fwd)
+{
+	int i;
+
+	for (i = 0; i < sz; i++) {
+		tck[i] = i ? tck[i - 1] : req_tck;
+		do {
+			mov_fwd ? tck[i]++ : tck[i]--;
+			ns[i] = round((double)tck[i] * tck_ns);
+			if (round((double)tck[i] * tck_ns) >
+			    ((double)tck[i] * tck_ns))
+				continue;
+		} while (ns[i] % (uint64_t)cnxk_tim_ns_per_tck(clk_freq));
+		diff[i] = PLT_MAX((double)ns[i], (double)tck[i] * tck_ns) -
+			  PLT_MIN((double)ns[i], (double)tck[i] * tck_ns);
+		dst[i] = mov_fwd ? tck[i] - req_tck : req_tck - tck[i];
+	}
+}
+
+static void
+tim_adjust_resolution(uint64_t *req_ns, uint64_t *req_tck, double tck_ns,
+		      uint64_t clk_freq, uint64_t max_tmo, uint64_t m_tck)
+{
+#define MAX_SAMPLES 5
+	double rmax_diff[MAX_SAMPLES], rmin_diff[MAX_SAMPLES];
+	uint64_t min_tck[MAX_SAMPLES], max_tck[MAX_SAMPLES];
+	uint64_t min_dst[MAX_SAMPLES], max_dst[MAX_SAMPLES];
+	uint64_t min_ns[MAX_SAMPLES], max_ns[MAX_SAMPLES];
+	int i;
+
+	populate_sample(max_tck, max_ns, rmax_diff, max_dst, *req_tck, clk_freq,
+			tck_ns, MAX_SAMPLES, true);
+	sort_multi_array(rmax_diff, max_dst, max_tck, max_ns, MAX_SAMPLES);
+
+	populate_sample(min_tck, min_ns, rmin_diff, min_dst, *req_tck, clk_freq,
+			tck_ns, MAX_SAMPLES, false);
+	sort_multi_array(rmin_diff, min_dst, min_tck, min_ns, MAX_SAMPLES);
+
+	for (i = 0; i < MAX_SAMPLES; i++) {
+		if (min_dst[i] < max_dst[i] && min_tck[i] > m_tck &&
+		    (max_tmo / min_ns[i]) <=
+			    (TIM_MAX_BUCKET_SIZE - TIM_MIN_BUCKET_SIZE)) {
+			*req_tck = min_tck[i];
+			*req_ns = min_ns[i];
+			break;
+		} else if ((max_tmo / max_ns[i]) <
+			   (TIM_MAX_BUCKET_SIZE - TIM_MIN_BUCKET_SIZE)) {
+			*req_tck = max_tck[i];
+			*req_ns = max_ns[i];
+			break;
+		}
+	}
+}
+
 static int
 cnxk_tim_ring_create(struct rte_event_timer_adapter *adptr)
 {
@@ -178,10 +252,25 @@ cnxk_tim_ring_create(struct rte_event_timer_adapter *adptr)
 		goto tim_hw_free;
 	}

-	/* Round */
 	tim_ring->tck_nsec =
 		round(RTE_ALIGN_MUL_NEAR((long double)rcfg->timer_tick_ns,
 					 cnxk_tim_ns_per_tck(clk_freq)));
+	if (log10(clk_freq) - floor(log10(clk_freq)) != 0.0) {
+		uint64_t req_ns, req_tck;
+		double tck_ns;
+
+		req_ns = tim_ring->tck_nsec;
+		tck_ns = NSECPERSEC / clk_freq;
+		req_tck = round(rcfg->timer_tick_ns / tck_ns);
+		tim_adjust_resolution(&req_ns, &req_tck, tck_ns, clk_freq,
+				      rcfg->max_tmo_ns, min_intvl_cyc);
+		if ((tim_ring->tck_nsec != req_ns) &&
+		    !(rcfg->flags & RTE_EVENT_TIMER_ADAPTER_F_ADJUST_RES)) {
+			rc = -ERANGE;
+			goto tim_hw_free;
+		}
+		tim_ring->tck_nsec = ceil(req_tck * tck_ns);
+	}

 	tim_ring->tck_int = round((long double)tim_ring->tck_nsec /
 				  cnxk_tim_ns_per_tck(clk_freq));
@@ -457,11 +546,16 @@ cnxk_tim_parse_ring_ctl_list(const char *value, void *opaque)
 	char *end = NULL;
 	char *f = s;

+	if (s == NULL || !strlen(s))
+		return;
+
 	while (*s) {
 		if (*s == '[')
 			start = s;
 		else if (*s == ']')
 			end = s;
+		else
+			continue;

 		if (start && start < end) {
 			*end = 0;
@@ -488,6 +582,43 @@ cnxk_tim_parse_kvargs_dict(const char *key, const char *value, void *opaque)
 	return 0;
 }

+static void
+cnxk_tim_parse_clk_list(const char *value, void *opaque)
+{
+	enum roc_tim_clk_src src[] = {ROC_TIM_CLK_SRC_GPIO, ROC_TIM_CLK_SRC_PTP,
+				      ROC_TIM_CLK_SRC_SYNCE,
+				      ROC_TIM_CLK_SRC_INVALID};
+	struct cnxk_tim_evdev *dev = opaque;
+	char *str = strdup(value);
+	char *tok;
+	int i = 0;
+
+	if (str == NULL || !strlen(str))
+		return;
+
+	tok = strtok(str, "-");
+	while (tok != NULL && src[i] != ROC_TIM_CLK_SRC_INVALID) {
+		dev->ext_clk_freq[src[i]] = strtoull(tok, NULL, 10);
+		tok = strtok(NULL, "-");
+		i++;
+	}
+
+	free(str);
+}
+
+static int
+cnxk_tim_parse_kvargs_dsv(const char *key, const char *value, void *opaque)
+{
+	RTE_SET_USED(key);
+
+	/* DSV format GPIO-PTP-SYNCE-BTS use '-' as ','
+	 * isn't allowed. 0 represents default.
+	 */
+	cnxk_tim_parse_clk_list(value, opaque);
+
+	return 0;
+}
+
 static void
 cnxk_tim_parse_devargs(struct rte_devargs *devargs, struct cnxk_tim_evdev *dev)
 {
@@ -510,6 +641,8 @@ cnxk_tim_parse_devargs(struct rte_devargs *devargs, struct cnxk_tim_evdev *dev)
 			   &dev->min_ring_cnt);
 	rte_kvargs_process(kvlist, CNXK_TIM_RING_CTL,
 			   &cnxk_tim_parse_kvargs_dict, &dev);
+	rte_kvargs_process(kvlist, CNXK_TIM_EXT_CLK, &cnxk_tim_parse_kvargs_dsv,
+			   dev);

 	rte_kvargs_free(kvlist);
 }
@@ -558,7 +691,7 @@ cnxk_tim_fini(void)
 {
 	struct cnxk_tim_evdev *dev = cnxk_tim_priv_get();

-	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+	if (dev == NULL || rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return;

 	roc_tim_fini(&dev->tim);
diff --git a/drivers/event/cnxk/cnxk_tim_evdev.h b/drivers/event/cnxk/cnxk_tim_evdev.h
index 1fb17f571d..6b5342cc34 100644
--- a/drivers/event/cnxk/cnxk_tim_evdev.h
+++ b/drivers/event/cnxk/cnxk_tim_evdev.h
@@ -40,6 +40,7 @@
 #define CNXK_TIM_STATS_ENA   "tim_stats_ena"
 #define CNXK_TIM_RINGS_LMT   "tim_rings_lmt"
 #define CNXK_TIM_RING_CTL    "tim_ring_ctl"
+#define CNXK_TIM_EXT_CLK     "tim_eclk_freq"

 #define CNXK_TIM_SP	   0x1
 #define CNXK_TIM_MP	   0x2
@@ -95,6 +96,7 @@ struct cnxk_tim_evdev {
 	uint32_t min_ring_cnt;
 	uint8_t enable_stats;
 	uint16_t ring_ctl_cnt;
+	uint64_t ext_clk_freq[ROC_TIM_CLK_SRC_INVALID];
 	struct cnxk_tim_ctl *ring_ctl_data;
 };

@@ -236,6 +238,8 @@ cnxk_tim_get_clk_freq(struct cnxk_tim_evdev *dev, enum roc_tim_clk_src clk_src,
 	case ROC_TIM_CLK_SRC_GPIO:
 	case ROC_TIM_CLK_SRC_PTP:
 	case ROC_TIM_CLK_SRC_SYNCE:
+		*freq = dev->ext_clk_freq[clk_src];
+		break;
 	default:
 		return -EINVAL;
 	}
--
2.17.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v5 1/2] event/cnxk: update min interval calculation
  2021-12-13 11:13       ` [PATCH v5 " pbhagavatula
  2021-12-13 11:13         ` [PATCH v5 2/2] event/cnxk: add external clock support for timer pbhagavatula
@ 2022-01-21 10:18         ` Jerin Jacob
  2022-01-25  9:54         ` Ray Kinsella
  2 siblings, 0 replies; 11+ messages in thread
From: Jerin Jacob @ 2022-01-21 10:18 UTC (permalink / raw)
  To: Pavan Nikhilesh
  Cc: Jerin Jacob, Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori,
	Satha Rao, Ray Kinsella, Shijith Thotton, dpdk-dev

On Mon, Dec 13, 2021 at 4:44 PM <pbhagavatula@marvell.com> wrote:
>
> From: Pavan Nikhilesh <pbhagavatula@marvell.com>
>
> Minimum supported interval should now be retrieved from
> mailbox based on the clock source and clock frequency.
>
> Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
> ---
> v5:
> - Rebase on master.


Applied to dpdk-next-net-eventdev/for-main. Thanks


> v4:
> - Rebase on master, fix NULL checks.
> v3:
> - Add new mbox interface.
> v2:
> - Fixed devargs parsing and rebased.
>
>  drivers/common/cnxk/roc_tim.c       | 32 +++++++++++-
>  drivers/common/cnxk/roc_tim.h       |  9 +++-
>  drivers/common/cnxk/version.map     |  1 +
>  drivers/event/cnxk/cnxk_tim_evdev.c | 69 +++++++++++++++++-------
>  drivers/event/cnxk/cnxk_tim_evdev.h | 81 +++++++++++++++++------------
>  5 files changed, 138 insertions(+), 54 deletions(-)
>
> diff --git a/drivers/common/cnxk/roc_tim.c b/drivers/common/cnxk/roc_tim.c
> index 534b697bee..cefd9bc89d 100644
> --- a/drivers/common/cnxk/roc_tim.c
> +++ b/drivers/common/cnxk/roc_tim.c
> @@ -145,7 +145,7 @@ int
>  roc_tim_lf_config(struct roc_tim *roc_tim, uint8_t ring_id,
>                   enum roc_tim_clk_src clk_src, uint8_t ena_periodic,
>                   uint8_t ena_dfb, uint32_t bucket_sz, uint32_t chunk_sz,
> -                 uint32_t interval)
> +                 uint32_t interval, uint64_t intervalns, uint64_t clockfreq)
>  {
>         struct dev *dev = &roc_sso_to_sso_priv(roc_tim->roc_sso)->dev;
>         struct tim_config_req *req;
> @@ -162,6 +162,8 @@ roc_tim_lf_config(struct roc_tim *roc_tim, uint8_t ring_id,
>         req->enableperiodic = ena_periodic;
>         req->enabledontfreebuffer = ena_dfb;
>         req->interval = interval;
> +       req->intervalns = intervalns;
> +       req->clockfreq = clockfreq;
>         req->gpioedge = TIM_GPIO_LTOH_TRANS;
>
>         rc = mbox_process(dev->mbox);
> @@ -173,6 +175,34 @@ roc_tim_lf_config(struct roc_tim *roc_tim, uint8_t ring_id,
>         return 0;
>  }
>
> +int
> +roc_tim_lf_interval(struct roc_tim *roc_tim, enum roc_tim_clk_src clk_src,
> +                   uint64_t clockfreq, uint64_t *intervalns,
> +                   uint64_t *interval)
> +{
> +       struct dev *dev = &roc_sso_to_sso_priv(roc_tim->roc_sso)->dev;
> +       struct tim_intvl_req *req;
> +       struct tim_intvl_rsp *rsp;
> +       int rc = -ENOSPC;
> +
> +       req = mbox_alloc_msg_tim_get_min_intvl(dev->mbox);
> +       if (req == NULL)
> +               return rc;
> +
> +       req->clockfreq = clockfreq;
> +       req->clocksource = clk_src;
> +       rc = mbox_process_msg(dev->mbox, (void **)&rsp);
> +       if (rc < 0) {
> +               tim_err_desc(rc);
> +               return rc;
> +       }
> +
> +       *intervalns = rsp->intvl_ns;
> +       *interval = rsp->intvl_cyc;
> +
> +       return 0;
> +}
> +
>  int
>  roc_tim_lf_alloc(struct roc_tim *roc_tim, uint8_t ring_id, uint64_t *clk)
>  {
> diff --git a/drivers/common/cnxk/roc_tim.h b/drivers/common/cnxk/roc_tim.h
> index 159b021a31..392732eae2 100644
> --- a/drivers/common/cnxk/roc_tim.h
> +++ b/drivers/common/cnxk/roc_tim.h
> @@ -10,6 +10,8 @@ enum roc_tim_clk_src {
>         ROC_TIM_CLK_SRC_GPIO,
>         ROC_TIM_CLK_SRC_GTI,
>         ROC_TIM_CLK_SRC_PTP,
> +       ROC_TIM_CLK_SRC_SYNCE,
> +       ROC_TIM_CLK_SRC_BTS,
>         ROC_TIM_CLK_SRC_INVALID,
>  };
>
> @@ -33,7 +35,12 @@ int __roc_api roc_tim_lf_config(struct roc_tim *roc_tim, uint8_t ring_id,
>                                 enum roc_tim_clk_src clk_src,
>                                 uint8_t ena_periodic, uint8_t ena_dfb,
>                                 uint32_t bucket_sz, uint32_t chunk_sz,
> -                               uint32_t interval);
> +                               uint32_t interval, uint64_t intervalns,
> +                               uint64_t clockfreq);
> +int __roc_api roc_tim_lf_interval(struct roc_tim *roc_tim,
> +                                 enum roc_tim_clk_src clk_src,
> +                                 uint64_t clockfreq, uint64_t *intervalns,
> +                                 uint64_t *interval);
>  int __roc_api roc_tim_lf_alloc(struct roc_tim *roc_tim, uint8_t ring_id,
>                                uint64_t *clk);
>  int __roc_api roc_tim_lf_free(struct roc_tim *roc_tim, uint8_t ring_id);
> diff --git a/drivers/common/cnxk/version.map b/drivers/common/cnxk/version.map
> index 07c6720f0c..5379ed2d39 100644
> --- a/drivers/common/cnxk/version.map
> +++ b/drivers/common/cnxk/version.map
> @@ -346,6 +346,7 @@ INTERNAL {
>         roc_tim_lf_disable;
>         roc_tim_lf_enable;
>         roc_tim_lf_free;
> +       roc_tim_lf_interval;
>         roc_se_ctx_swap;
>
>         local: *;
> diff --git a/drivers/event/cnxk/cnxk_tim_evdev.c b/drivers/event/cnxk/cnxk_tim_evdev.c
> index 99b3acee7c..becab1d1b1 100644
> --- a/drivers/event/cnxk/cnxk_tim_evdev.c
> +++ b/drivers/event/cnxk/cnxk_tim_evdev.c
> @@ -2,6 +2,8 @@
>   * Copyright(C) 2021 Marvell.
>   */
>
> +#include <math.h>
> +
>  #include "cnxk_eventdev.h"
>  #include "cnxk_tim_evdev.h"
>
> @@ -120,7 +122,10 @@ cnxk_tim_ring_create(struct rte_event_timer_adapter *adptr)
>  {
>         struct rte_event_timer_adapter_conf *rcfg = &adptr->data->conf;
>         struct cnxk_tim_evdev *dev = cnxk_tim_priv_get();
> +       uint64_t min_intvl_ns, min_intvl_cyc;
>         struct cnxk_tim_ring *tim_ring;
> +       enum roc_tim_clk_src clk_src;
> +       uint64_t clk_freq = 0;
>         int i, rc;
>
>         if (dev == NULL)
> @@ -139,25 +144,52 @@ cnxk_tim_ring_create(struct rte_event_timer_adapter *adptr)
>                 goto tim_ring_free;
>         }
>
> -       if (NSEC2TICK(RTE_ALIGN_MUL_CEIL(
> -                             rcfg->timer_tick_ns,
> -                             cnxk_tim_min_resolution_ns(cnxk_tim_cntfrq())),
> -                     cnxk_tim_cntfrq()) <
> -           cnxk_tim_min_tmo_ticks(cnxk_tim_cntfrq())) {
> -               if (rcfg->flags & RTE_EVENT_TIMER_ADAPTER_F_ADJUST_RES)
> -                       rcfg->timer_tick_ns = TICK2NSEC(
> -                               cnxk_tim_min_tmo_ticks(cnxk_tim_cntfrq()),
> -                               cnxk_tim_cntfrq());
> -               else {
> +       clk_src = cnxk_tim_convert_clk_src(rcfg->clk_src);
> +       if (clk_src == ROC_TIM_CLK_SRC_INVALID) {
> +               plt_err("Invalid clock source");
> +               goto tim_hw_free;
> +       }
> +
> +       rc = cnxk_tim_get_clk_freq(dev, clk_src, &clk_freq);
> +       if (rc < 0) {
> +               plt_err("Failed to get clock frequency");
> +               goto tim_hw_free;
> +       }
> +
> +       rc = roc_tim_lf_interval(&dev->tim, clk_src, clk_freq, &min_intvl_ns,
> +                                &min_intvl_cyc);
> +       if (rc < 0) {
> +               plt_err("Failed to get min interval details");
> +               goto tim_hw_free;
> +       }
> +
> +       if (rcfg->timer_tick_ns < min_intvl_ns) {
> +               if (rcfg->flags & RTE_EVENT_TIMER_ADAPTER_F_ADJUST_RES) {
> +                       rcfg->timer_tick_ns = min_intvl_ns;
> +               } else {
>                         rc = -ERANGE;
>                         goto tim_hw_free;
>                 }
>         }
> +
> +       if (rcfg->timer_tick_ns > rcfg->max_tmo_ns) {
> +               plt_err("Max timeout to too high");
> +               rc = -ERANGE;
> +               goto tim_hw_free;
> +       }
> +
> +       /* Round */
> +       tim_ring->tck_nsec =
> +               round(RTE_ALIGN_MUL_NEAR((long double)rcfg->timer_tick_ns,
> +                                        cnxk_tim_ns_per_tck(clk_freq)));
> +
> +       tim_ring->tck_int = round((long double)tim_ring->tck_nsec /
> +                                 cnxk_tim_ns_per_tck(clk_freq));
> +       tim_ring->tck_nsec =
> +               ceil(tim_ring->tck_int * cnxk_tim_ns_per_tck(clk_freq));
> +
>         tim_ring->ring_id = adptr->data->id;
> -       tim_ring->clk_src = (int)rcfg->clk_src;
> -       tim_ring->tck_nsec = RTE_ALIGN_MUL_CEIL(
> -               rcfg->timer_tick_ns,
> -               cnxk_tim_min_resolution_ns(cnxk_tim_cntfrq()));
> +       tim_ring->clk_src = clk_src;
>         tim_ring->max_tout = rcfg->max_tmo_ns;
>         tim_ring->nb_bkts = (tim_ring->max_tout / tim_ring->tck_nsec);
>         tim_ring->nb_timers = rcfg->nb_timers;
> @@ -201,11 +233,9 @@ cnxk_tim_ring_create(struct rte_event_timer_adapter *adptr)
>         if (rc < 0)
>                 goto tim_bkt_free;
>
> -       rc = roc_tim_lf_config(
> -               &dev->tim, tim_ring->ring_id,
> -               cnxk_tim_convert_clk_src(tim_ring->clk_src), 0, 0,
> -               tim_ring->nb_bkts, tim_ring->chunk_sz,
> -               NSEC2TICK(tim_ring->tck_nsec, cnxk_tim_cntfrq()));
> +       rc = roc_tim_lf_config(&dev->tim, tim_ring->ring_id, clk_src, 0, 0,
> +                              tim_ring->nb_bkts, tim_ring->chunk_sz,
> +                              tim_ring->tck_int, tim_ring->tck_nsec, clk_freq);
>         if (rc < 0) {
>                 plt_err("Failed to configure timer ring");
>                 goto tim_chnk_free;
> @@ -300,7 +330,6 @@ cnxk_tim_ring_start(const struct rte_event_timer_adapter *adptr)
>         if (rc < 0)
>                 return rc;
>
> -       tim_ring->tck_int = NSEC2TICK(tim_ring->tck_nsec, cnxk_tim_cntfrq());
>         tim_ring->tot_int = tim_ring->tck_int * tim_ring->nb_bkts;
>         tim_ring->fast_div = rte_reciprocal_value_u64(tim_ring->tck_int);
>         tim_ring->fast_bkt = rte_reciprocal_value_u64(tim_ring->nb_bkts);
> diff --git a/drivers/event/cnxk/cnxk_tim_evdev.h b/drivers/event/cnxk/cnxk_tim_evdev.h
> index 2478a5c1df..1fb17f571d 100644
> --- a/drivers/event/cnxk/cnxk_tim_evdev.h
> +++ b/drivers/event/cnxk/cnxk_tim_evdev.h
> @@ -98,13 +98,6 @@ struct cnxk_tim_evdev {
>         struct cnxk_tim_ctl *ring_ctl_data;
>  };
>
> -enum cnxk_tim_clk_src {
> -       CNXK_TIM_CLK_SRC_10NS = RTE_EVENT_TIMER_ADAPTER_CPU_CLK,
> -       CNXK_TIM_CLK_SRC_GPIO = RTE_EVENT_TIMER_ADAPTER_EXT_CLK0,
> -       CNXK_TIM_CLK_SRC_GTI = RTE_EVENT_TIMER_ADAPTER_EXT_CLK1,
> -       CNXK_TIM_CLK_SRC_PTP = RTE_EVENT_TIMER_ADAPTER_EXT_CLK2,
> -};
> -
>  struct cnxk_tim_bkt {
>         uint64_t first_chunk;
>         union {
> @@ -147,7 +140,7 @@ struct cnxk_tim_ring {
>         uint64_t max_tout;
>         uint64_t nb_chunks;
>         uint64_t chunk_sz;
> -       enum cnxk_tim_clk_src clk_src;
> +       enum roc_tim_clk_src clk_src;
>  } __rte_cache_aligned;
>
>  struct cnxk_tim_ent {
> @@ -167,31 +160,10 @@ cnxk_tim_priv_get(void)
>         return mz->addr;
>  }
>
> -static inline uint64_t
> -cnxk_tim_min_tmo_ticks(uint64_t freq)
> +static inline long double
> +cnxk_tim_ns_per_tck(uint64_t freq)
>  {
> -       if (roc_model_runtime_is_cn9k())
> -               return CN9K_TIM_MIN_TMO_TKS;
> -       else /* CN10K min tick is of 1us */
> -               return freq / USECPERSEC;
> -}
> -
> -static inline uint64_t
> -cnxk_tim_min_resolution_ns(uint64_t freq)
> -{
> -       return NSECPERSEC / freq;
> -}
> -
> -static inline enum roc_tim_clk_src
> -cnxk_tim_convert_clk_src(enum cnxk_tim_clk_src clk_src)
> -{
> -       switch (clk_src) {
> -       case RTE_EVENT_TIMER_ADAPTER_CPU_CLK:
> -               return roc_model_runtime_is_cn9k() ? ROC_TIM_CLK_SRC_10NS :
> -                                                          ROC_TIM_CLK_SRC_GTI;
> -       default:
> -               return ROC_TIM_CLK_SRC_INVALID;
> -       }
> +       return (long double)NSECPERSEC / freq;
>  }
>
>  #ifdef RTE_ARCH_ARM64
> @@ -226,6 +198,51 @@ cnxk_tim_cntfrq(void)
>  }
>  #endif
>
> +static inline enum roc_tim_clk_src
> +cnxk_tim_convert_clk_src(enum rte_event_timer_adapter_clk_src clk_src)
> +{
> +       switch (clk_src) {
> +       case RTE_EVENT_TIMER_ADAPTER_CPU_CLK:
> +               return ROC_TIM_CLK_SRC_GTI;
> +       case RTE_EVENT_TIMER_ADAPTER_EXT_CLK0:
> +               return ROC_TIM_CLK_SRC_10NS;
> +       case RTE_EVENT_TIMER_ADAPTER_EXT_CLK1:
> +               return ROC_TIM_CLK_SRC_GPIO;
> +       case RTE_EVENT_TIMER_ADAPTER_EXT_CLK2:
> +               return ROC_TIM_CLK_SRC_PTP;
> +       case RTE_EVENT_TIMER_ADAPTER_EXT_CLK3:
> +               return roc_model_constant_is_cn9k() ? ROC_TIM_CLK_SRC_INVALID :
> +                                                     ROC_TIM_CLK_SRC_SYNCE;
> +       default:
> +               return ROC_TIM_CLK_SRC_INVALID;
> +       }
> +}
> +
> +static inline int
> +cnxk_tim_get_clk_freq(struct cnxk_tim_evdev *dev, enum roc_tim_clk_src clk_src,
> +                     uint64_t *freq)
> +{
> +       if (freq == NULL)
> +               return -EINVAL;
> +
> +       PLT_SET_USED(dev);
> +       switch (clk_src) {
> +       case ROC_TIM_CLK_SRC_GTI:
> +               *freq = cnxk_tim_cntfrq();
> +               break;
> +       case ROC_TIM_CLK_SRC_10NS:
> +               *freq = 1E8;
> +               break;
> +       case ROC_TIM_CLK_SRC_GPIO:
> +       case ROC_TIM_CLK_SRC_PTP:
> +       case ROC_TIM_CLK_SRC_SYNCE:
> +       default:
> +               return -EINVAL;
> +       }
> +
> +       return 0;
> +}
> +
>  #define TIM_ARM_FASTPATH_MODES                                                 \
>         FP(sp, 0, 0, 0, CNXK_TIM_ENA_DFB | CNXK_TIM_SP)                        \
>         FP(mp, 0, 0, 1, CNXK_TIM_ENA_DFB | CNXK_TIM_MP)                        \
> --
> 2.17.1
>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v5 1/2] event/cnxk: update min interval calculation
  2021-12-13 11:13       ` [PATCH v5 " pbhagavatula
  2021-12-13 11:13         ` [PATCH v5 2/2] event/cnxk: add external clock support for timer pbhagavatula
  2022-01-21 10:18         ` [PATCH v5 1/2] event/cnxk: update min interval calculation Jerin Jacob
@ 2022-01-25  9:54         ` Ray Kinsella
  2 siblings, 0 replies; 11+ messages in thread
From: Ray Kinsella @ 2022-01-25  9:54 UTC (permalink / raw)
  To: pbhagavatula
  Cc: jerinj, Nithin Dabilpuram, Kiran Kumar K, Sunil Kumar Kori,
	Satha Rao, Shijith Thotton, dev


pbhagavatula@marvell.com writes:

> From: Pavan Nikhilesh <pbhagavatula@marvell.com>
>
> Minimum supported interval should now be retrieved from
> mailbox based on the clock source and clock frequency.
>
> Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
> ---
> v5:
> - Rebase on master.
> v4:
> - Rebase on master, fix NULL checks.
> v3:
> - Add new mbox interface.
> v2:
> - Fixed devargs parsing and rebased.
>
>  drivers/common/cnxk/roc_tim.c       | 32 +++++++++++-
>  drivers/common/cnxk/roc_tim.h       |  9 +++-
>  drivers/common/cnxk/version.map     |  1 +
>  drivers/event/cnxk/cnxk_tim_evdev.c | 69 +++++++++++++++++-------
>  drivers/event/cnxk/cnxk_tim_evdev.h | 81 +++++++++++++++++------------
>  5 files changed, 138 insertions(+), 54 deletions(-)
>
Acked-by: Ray Kinsella <mdr@ashroe.eu>

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2022-01-25  9:54 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-28 15:24 [dpdk-dev] [PATCH] drivers: add external clock support for cnxk timer Shijith Thotton
2021-09-15 16:03 ` [dpdk-dev] [PATCH v2] " Shijith Thotton
2021-09-23 21:30   ` [dpdk-dev] [PATCH v3 1/2] event/cnxk: update min interval calculation pbhagavatula
2021-09-23 21:30     ` [dpdk-dev] [PATCH v3 2/2] event/cnxk: add external clock support for timer pbhagavatula
2021-10-09  8:04     ` [dpdk-dev] [PATCH v4 1/2] event/cnxk: update min interval calculation pbhagavatula
2021-10-09  8:04       ` [dpdk-dev] [PATCH v4 2/2] event/cnxk: add external clock support for timer pbhagavatula
2021-10-14 11:51       ` [dpdk-dev] [PATCH v4 1/2] event/cnxk: update min interval calculation Jerin Jacob
2021-12-13 11:13       ` [PATCH v5 " pbhagavatula
2021-12-13 11:13         ` [PATCH v5 2/2] event/cnxk: add external clock support for timer pbhagavatula
2022-01-21 10:18         ` [PATCH v5 1/2] event/cnxk: update min interval calculation Jerin Jacob
2022-01-25  9:54         ` Ray Kinsella

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).