]> git.droids-corp.org - dpdk.git/commitdiff
event/cnxk: update minimum interval calculation
authorPavan Nikhilesh <pbhagavatula@marvell.com>
Mon, 13 Dec 2021 11:13:43 +0000 (16:43 +0530)
committerJerin Jacob <jerinj@marvell.com>
Thu, 20 Jan 2022 13:27:06 +0000 (14:27 +0100)
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>
drivers/common/cnxk/roc_tim.c
drivers/common/cnxk/roc_tim.h
drivers/common/cnxk/version.map
drivers/event/cnxk/cnxk_tim_evdev.c
drivers/event/cnxk/cnxk_tim_evdev.h

index 534b697bee95d52b43c3faa70c9ac6161d57014c..cefd9bc89d5637c0394ce30b9fa8da8709c16eb5 100644 (file)
@@ -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)
 {
index 159b021a310af6a99f5b6fad6dc57a11eaea958f..392732eae2ea2b95d8d297d90a5256f06ee8c675 100644 (file)
@@ -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);
index 5a03b91784625e7b09508e8f94a836cf3e9cbacb..90db3211f29fac60dd76b5e684c4e78ca9facf0a 100644 (file)
@@ -347,6 +347,7 @@ INTERNAL {
        roc_tim_lf_disable;
        roc_tim_lf_enable;
        roc_tim_lf_free;
+       roc_tim_lf_interval;
        roc_se_ctx_swap;
        roc_ree_af_reg_read;
        roc_ree_af_reg_write;
index 99b3acee7ce39bf3009152b5b526a6637a03f52a..becab1d1b12848a942489a7e3c05763267b95289 100644 (file)
@@ -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);
index 2478a5c1df480e4e356c89d036c08b6fdb1a3626..1fb17f571d97f7732feb0fb9399e6ae73f193fc3 100644 (file)
@@ -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)                        \