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 0D664A0C41; Sat, 9 Oct 2021 10:04:49 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 4CBC74067E; Sat, 9 Oct 2021 10:04:45 +0200 (CEST) Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by mails.dpdk.org (Postfix) with ESMTP id AAAD640143 for ; Sat, 9 Oct 2021 10:04:43 +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 1997PRYO003556; Sat, 9 Oct 2021 01:04:42 -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=zC+TEqqgWrB3xfbRDIo2ISHCYNcvLMzQaBjlVXc25zs=; b=KLzUzApO3NdNRcb7bedfSqXsRfOVIHVWMkQmzLrd0ZhZpffmddL29vkwm5ePEnSKpIIu FLtk5j5GKl9iHgQwk96nBWZCyCKYJfIt2vkvLSZGftQtbiRhSQpjsWqFN1Pbi01Lt/o/ k+RRkDOqiMklluh5iL+JXv/Ab8uYw6qwfgsX+cDk4jVjT4S255RbebTlhVp7MsoiPUvk dMPQUfFGXow7LyjJzMgqGHJ+hpSHiUa4pMHZhNIyzIQ7EPRojhPgkHNKLTYvpm35SGy1 btEo96y2SZXeNJcO5C3u+HCnFW7vOVrSVhc1aiqAjkbFX12jOc5tNUnnmtrJ4IRPoUbm PQ== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0a-0016f401.pphosted.com with ESMTP id 3bk4jhrdcu-3 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Sat, 09 Oct 2021 01:04:42 -0700 Received: from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Sat, 9 Oct 2021 01:04:40 -0700 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.18 via Frontend Transport; Sat, 9 Oct 2021 01:04:40 -0700 Received: from BG-LT7430.marvell.com (BG-LT7430.marvell.com [10.28.177.176]) by maili.marvell.com (Postfix) with ESMTP id CB3813F706D; Sat, 9 Oct 2021 01:04:37 -0700 (PDT) From: To: , Pavan Nikhilesh , "Shijith Thotton" , Nithin Dabilpuram , Kiran Kumar K , Sunil Kumar Kori , Satha Rao , Anatoly Burakov CC: Date: Sat, 9 Oct 2021 13:34:25 +0530 Message-ID: <20211009080426.18482-2-pbhagavatula@marvell.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211009080426.18482-1-pbhagavatula@marvell.com> References: <20210923213046.3157-1-pbhagavatula@marvell.com> <20211009080426.18482-1-pbhagavatula@marvell.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-Proofpoint-ORIG-GUID: B1U5gG9DWtzX_HvGVQFH-O0AVNbMiu5E X-Proofpoint-GUID: B1U5gG9DWtzX_HvGVQFH-O0AVNbMiu5E 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-10-09_01,2021-10-07_02,2020-04-07_01 Subject: [dpdk-dev] [PATCH v4 2/2] event/cnxk: add external clock support for 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" From: Pavan Nikhilesh 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 Signed-off-by: Pavan Nikhilesh --- 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 "=" CNXK_TIM_DISABLE_NPA "=1" CNXK_TIM_CHNK_SLOTS "=" CNXK_TIM_RINGS_LMT "=" - CNXK_TIM_STATS_ENA "=1"); + CNXK_TIM_STATS_ENA "=1" + CNXK_TIM_EXT_CLK "="); 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