[v5,1/2] event/cnxk: update min interval calculation

Message ID 20211213111345.5046-1-pbhagavatula@marvell.com (mailing list archive)
State Accepted, archived
Delegated to: Jerin Jacob
Headers
Series [v5,1/2] event/cnxk: update min interval calculation |

Checks

Context Check Description
ci/checkpatch warning coding style issues

Commit Message

Pavan Nikhilesh Bhagavatula Dec. 13, 2021, 11:13 a.m. UTC
  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(-)

--
2.17.1
  

Comments

Jerin Jacob Jan. 21, 2022, 10:18 a.m. UTC | #1
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
>
  
Ray Kinsella Jan. 25, 2022, 9:54 a.m. UTC | #2
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>
  

Patch

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)                        \