From patchwork Wed Jul 28 15:24:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shijith Thotton X-Patchwork-Id: 96356 X-Patchwork-Delegate: jerinj@marvell.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 03474A0A0C; Wed, 28 Jul 2021 17:24:58 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 78B6B40E64; Wed, 28 Jul 2021 17:24:58 +0200 (CEST) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by mails.dpdk.org (Postfix) with ESMTP id B82EC40142 for ; Wed, 28 Jul 2021 17:24:56 +0200 (CEST) Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.16.0.43/8.16.0.43) with SMTP id 16SFAh10010443; Wed, 28 Jul 2021 08:24:56 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : mime-version : content-transfer-encoding : content-type; s=pfpt0220; bh=UD7rWWujI7ut83FSXJUOFa8sNCcdgteDUQC9owRNMb4=; b=PVKpxSqdhXjQZztrRkT1vaW8anoZbvoAzwwAyakiQDu7RQplFOovq9dydjAgi4MP0cWO FXkpiUo1LRcoI0njTOcYpNswoqbTHuXzs9R7AlPWZxrMUHZz43ns7zN9a7RrdwsQHDSc K3Cb9dJPAjyO9MPZWOk6c5JrTWFXzkqlr6l8gdtjpT7qjrgaeetbX2szwPWJxNWXblfh pduMhVJdDk6Lgh3IlTm7oyaLYLSBI87aL5t45zWL/dHh+ywqB5ScOe/Kifi4isN0m3gr la3QoQv8bHVDMmf7GGwewTeLfxG9QjDIL4h4tXkm/nlSR1gzCOWxBkcPBk0raZ0G7lM3 XQ== Received: from dc5-exch02.marvell.com ([199.233.59.182]) by mx0b-0016f401.pphosted.com with ESMTP id 3a35pr0xnv-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Wed, 28 Jul 2021 08:24:55 -0700 Received: from DC5-EXCH01.marvell.com (10.69.176.38) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Wed, 28 Jul 2021 08:24:53 -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, 28 Jul 2021 08:24:53 -0700 Received: from localhost.localdomain (unknown [10.28.34.29]) by maili.marvell.com (Postfix) with ESMTP id 31E745E6880; Wed, 28 Jul 2021 08:24:50 -0700 (PDT) From: Shijith Thotton To: CC: Shijith Thotton , , , , Nithin Dabilpuram , Kiran Kumar K , "Sunil Kumar Kori" , Satha Rao Date: Wed, 28 Jul 2021 20:54:23 +0530 Message-ID: X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: nDPdfEEsRlWrA5TpJQppM3StB5IHSSMr X-Proofpoint-GUID: nDPdfEEsRlWrA5TpJQppM3StB5IHSSMr X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.391, 18.0.790 definitions=2021-07-28_08:2021-07-27, 2021-07-28 signatures=0 Subject: [dpdk-dev] [PATCH] 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") 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 + #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; }