From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 81FE2A0C45; Wed, 15 Sep 2021 18:05:39 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 3D1D341123; Wed, 15 Sep 2021 18:05:39 +0200 (CEST) Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by mails.dpdk.org (Postfix) with ESMTP id 559354068F for ; Wed, 15 Sep 2021 18:05:37 +0200 (CEST) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 18F9dTu8022190 for ; Wed, 15 Sep 2021 09:05:36 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=pfpt0220; bh=btohyvzKbzJNfDTMTblx3s4ePF9elo5kOAYtPJJF0Vo=; b=cgrZw5l63GVJEiIKoywnOMVKZLr2KB0i4xyosnLHlhSGoBVCbOKEaMta71VQs9cClBIJ KyyGllXki/6gTD6foOfbT6WU0ZJOwKx5SHQW+TfwEejBwkUvJqA5USpROL3oJY/FPuys R2/biHD2YfuBvwCZad+SGxCGUs/bDHTasOOa/Gze3rgNSUe22NosnvdWB5Dspiu9X5Xi +2y5dKzeW+GYRSx4xxrezd8jBAY63G9WcecSJbNb/KswZ1EQ4F9t9CCbEXWwnhkYLccN 6C5rSH6e0iZqe9L3ywfUdARf/3l16u+OS++3vni+8mBqQUwvIaVmKiHOlgW3JQW0tvMD JQ== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0a-0016f401.pphosted.com with ESMTP id 3b3ed01f2x-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT) for ; Wed, 15 Sep 2021 09:05:36 -0700 Received: from DC5-EXCH01.marvell.com (10.69.176.38) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Wed, 15 Sep 2021 09:05:34 -0700 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server id 15.0.1497.18 via Frontend Transport; Wed, 15 Sep 2021 09:05:34 -0700 Received: from localhost.localdomain (unknown [10.28.34.29]) by maili.marvell.com (Postfix) with ESMTP id 18C573F706D; Wed, 15 Sep 2021 09:05:31 -0700 (PDT) From: Shijith Thotton To: CC: Shijith Thotton , , "Pavan Nikhilesh" , Nithin Dabilpuram , Kiran Kumar K , "Sunil Kumar Kori" , Satha Rao Date: Wed, 15 Sep 2021 21:33:27 +0530 Message-ID: X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-Proofpoint-GUID: LAAnrubuUwOqYX3zKHRTghJTfQ1FJC60 X-Proofpoint-ORIG-GUID: LAAnrubuUwOqYX3zKHRTghJTfQ1FJC60 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.182.1,Aquarius:18.0.790,Hydra:6.0.391,FMLib:17.0.607.475 definitions=2021-09-15_04,2021-09-15_01,2020-04-07_01 Subject: [dpdk-dev] [PATCH v2] drivers: add external clock support for cnxk timer X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" 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 Signed-off-by: Pavan Nikhilesh --- 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 + #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