1db6a330bSPavan Nikhilesh /* SPDX-License-Identifier: BSD-3-Clause 2f874c1ebSPavan Nikhilesh * Copyright(c) 2017 Cavium, Inc 3f874c1ebSPavan Nikhilesh */ 4f874c1ebSPavan Nikhilesh 5227f2835SPavan Nikhilesh #include "ssovf_evdev.h" 6f874c1ebSPavan Nikhilesh #include "timvf_evdev.h" 7f874c1ebSPavan Nikhilesh 8eeded204SDavid Marchand RTE_LOG_REGISTER_SUFFIX(otx_logtype_timvf, timer, NOTICE); 9f874c1ebSPavan Nikhilesh 10227f2835SPavan Nikhilesh static struct rte_eventdev *event_dev; 11227f2835SPavan Nikhilesh 12*e7750639SAndre Muezerie struct __rte_packed_begin timvf_mbox_dev_info { 13ea73fed2SPavan Nikhilesh uint64_t ring_active[4]; 14ea73fed2SPavan Nikhilesh uint64_t clk_freq; 15*e7750639SAndre Muezerie } __rte_packed_end; 16ea73fed2SPavan Nikhilesh 17ea73fed2SPavan Nikhilesh /* Response messages */ 18ea73fed2SPavan Nikhilesh enum { 19ea73fed2SPavan Nikhilesh MBOX_RET_SUCCESS, 20ea73fed2SPavan Nikhilesh MBOX_RET_INVALID, 21ea73fed2SPavan Nikhilesh MBOX_RET_INTERNAL_ERR, 22ea73fed2SPavan Nikhilesh }; 23ea73fed2SPavan Nikhilesh 24ea73fed2SPavan Nikhilesh static int 25ea73fed2SPavan Nikhilesh timvf_mbox_dev_info_get(struct timvf_mbox_dev_info *info) 26ea73fed2SPavan Nikhilesh { 27ea73fed2SPavan Nikhilesh struct octeontx_mbox_hdr hdr = {0}; 28ea73fed2SPavan Nikhilesh uint16_t len = sizeof(struct timvf_mbox_dev_info); 29ea73fed2SPavan Nikhilesh 30ea73fed2SPavan Nikhilesh hdr.coproc = TIM_COPROC; 31ea73fed2SPavan Nikhilesh hdr.msg = TIM_GET_DEV_INFO; 32ea73fed2SPavan Nikhilesh hdr.vfid = 0; /* TIM DEV is always 0. TIM RING ID changes. */ 33ea73fed2SPavan Nikhilesh 34ea73fed2SPavan Nikhilesh memset(info, 0, len); 35ea73fed2SPavan Nikhilesh return octeontx_mbox_send(&hdr, NULL, 0, info, len); 36ea73fed2SPavan Nikhilesh } 37ea73fed2SPavan Nikhilesh 38f874c1ebSPavan Nikhilesh static void 39f874c1ebSPavan Nikhilesh timvf_ring_info_get(const struct rte_event_timer_adapter *adptr, 40f874c1ebSPavan Nikhilesh struct rte_event_timer_adapter_info *adptr_info) 41f874c1ebSPavan Nikhilesh { 42f874c1ebSPavan Nikhilesh struct timvf_ring *timr = adptr->data->adapter_priv; 43f874c1ebSPavan Nikhilesh adptr_info->max_tmo_ns = timr->max_tout; 44f874c1ebSPavan Nikhilesh adptr_info->min_resolution_ns = timr->tck_nsec; 45f874c1ebSPavan Nikhilesh rte_memcpy(&adptr_info->conf, &adptr->data->conf, 46f874c1ebSPavan Nikhilesh sizeof(struct rte_event_timer_adapter_conf)); 47f874c1ebSPavan Nikhilesh } 48f874c1ebSPavan Nikhilesh 49f874c1ebSPavan Nikhilesh static int 50ea73fed2SPavan Nikhilesh timvf_ring_conf_set(struct timvf_ctrl_reg *rctl, uint8_t ring_id) 51ea73fed2SPavan Nikhilesh { 52ea73fed2SPavan Nikhilesh struct octeontx_mbox_hdr hdr = {0}; 53ea73fed2SPavan Nikhilesh uint16_t len = sizeof(struct timvf_ctrl_reg); 54ea73fed2SPavan Nikhilesh int ret; 55ea73fed2SPavan Nikhilesh 56ea73fed2SPavan Nikhilesh hdr.coproc = TIM_COPROC; 57ea73fed2SPavan Nikhilesh hdr.msg = TIM_SET_RING_INFO; 58ea73fed2SPavan Nikhilesh hdr.vfid = ring_id; 59ea73fed2SPavan Nikhilesh 60ea73fed2SPavan Nikhilesh ret = octeontx_mbox_send(&hdr, rctl, len, NULL, 0); 61ea73fed2SPavan Nikhilesh if (ret < 0 || hdr.res_code != MBOX_RET_SUCCESS) 62ea73fed2SPavan Nikhilesh return -EACCES; 63ea73fed2SPavan Nikhilesh return 0; 64ea73fed2SPavan Nikhilesh } 65ea73fed2SPavan Nikhilesh 66ea73fed2SPavan Nikhilesh static int 67ea73fed2SPavan Nikhilesh timvf_get_start_cyc(uint64_t *now, uint8_t ring_id) 68ea73fed2SPavan Nikhilesh { 69ea73fed2SPavan Nikhilesh struct octeontx_mbox_hdr hdr = {0}; 70ea73fed2SPavan Nikhilesh 71ea73fed2SPavan Nikhilesh hdr.coproc = TIM_COPROC; 72ea73fed2SPavan Nikhilesh hdr.msg = TIM_RING_START_CYC_GET; 73ea73fed2SPavan Nikhilesh hdr.vfid = ring_id; 74ea73fed2SPavan Nikhilesh *now = 0; 75ea73fed2SPavan Nikhilesh return octeontx_mbox_send(&hdr, NULL, 0, now, sizeof(uint64_t)); 76ea73fed2SPavan Nikhilesh } 77ea73fed2SPavan Nikhilesh 78ea73fed2SPavan Nikhilesh static int 794cec5aaeSPavan Nikhilesh optimize_bucket_parameters(struct timvf_ring *timr) 804cec5aaeSPavan Nikhilesh { 814cec5aaeSPavan Nikhilesh uint32_t hbkts; 824cec5aaeSPavan Nikhilesh uint32_t lbkts; 834cec5aaeSPavan Nikhilesh uint64_t tck_nsec; 844cec5aaeSPavan Nikhilesh 854cec5aaeSPavan Nikhilesh hbkts = rte_align32pow2(timr->nb_bkts); 864cec5aaeSPavan Nikhilesh tck_nsec = RTE_ALIGN_MUL_CEIL(timr->max_tout / (hbkts - 1), 10); 874cec5aaeSPavan Nikhilesh 884cec5aaeSPavan Nikhilesh if ((tck_nsec < 1000 || hbkts > TIM_MAX_BUCKETS)) 894cec5aaeSPavan Nikhilesh hbkts = 0; 904cec5aaeSPavan Nikhilesh 914cec5aaeSPavan Nikhilesh lbkts = rte_align32prevpow2(timr->nb_bkts); 924cec5aaeSPavan Nikhilesh tck_nsec = RTE_ALIGN_MUL_CEIL((timr->max_tout / (lbkts - 1)), 10); 934cec5aaeSPavan Nikhilesh 944cec5aaeSPavan Nikhilesh if ((tck_nsec < 1000 || hbkts > TIM_MAX_BUCKETS)) 954cec5aaeSPavan Nikhilesh lbkts = 0; 964cec5aaeSPavan Nikhilesh 974cec5aaeSPavan Nikhilesh if (!hbkts && !lbkts) 984cec5aaeSPavan Nikhilesh return 0; 994cec5aaeSPavan Nikhilesh 1004cec5aaeSPavan Nikhilesh if (!hbkts) { 1014cec5aaeSPavan Nikhilesh timr->nb_bkts = lbkts; 1024cec5aaeSPavan Nikhilesh goto end; 1034cec5aaeSPavan Nikhilesh } else if (!lbkts) { 1044cec5aaeSPavan Nikhilesh timr->nb_bkts = hbkts; 1054cec5aaeSPavan Nikhilesh goto end; 1064cec5aaeSPavan Nikhilesh } 1074cec5aaeSPavan Nikhilesh 1084cec5aaeSPavan Nikhilesh timr->nb_bkts = (hbkts - timr->nb_bkts) < 1094cec5aaeSPavan Nikhilesh (timr->nb_bkts - lbkts) ? hbkts : lbkts; 1104cec5aaeSPavan Nikhilesh end: 1114cec5aaeSPavan Nikhilesh timr->get_target_bkt = bkt_and; 1124cec5aaeSPavan Nikhilesh timr->tck_nsec = RTE_ALIGN_MUL_CEIL((timr->max_tout / 1134cec5aaeSPavan Nikhilesh (timr->nb_bkts - 1)), 10); 1144cec5aaeSPavan Nikhilesh return 1; 1154cec5aaeSPavan Nikhilesh } 1164cec5aaeSPavan Nikhilesh 1174cec5aaeSPavan Nikhilesh static int 118ea73fed2SPavan Nikhilesh timvf_ring_start(const struct rte_event_timer_adapter *adptr) 119ea73fed2SPavan Nikhilesh { 120ea73fed2SPavan Nikhilesh int ret; 1213e249bc5SPavan Nikhilesh uint8_t use_fpa = 0; 122ea73fed2SPavan Nikhilesh uint64_t interval; 1233e249bc5SPavan Nikhilesh uintptr_t pool; 124ea73fed2SPavan Nikhilesh struct timvf_ctrl_reg rctrl; 125ea73fed2SPavan Nikhilesh struct timvf_mbox_dev_info dinfo; 126ea73fed2SPavan Nikhilesh struct timvf_ring *timr = adptr->data->adapter_priv; 127ea73fed2SPavan Nikhilesh 128ea73fed2SPavan Nikhilesh ret = timvf_mbox_dev_info_get(&dinfo); 129ea73fed2SPavan Nikhilesh if (ret < 0 || ret != sizeof(struct timvf_mbox_dev_info)) 130ea73fed2SPavan Nikhilesh return -EINVAL; 131ea73fed2SPavan Nikhilesh 132ea73fed2SPavan Nikhilesh /* Calculate the interval cycles according to clock source. */ 133ea73fed2SPavan Nikhilesh switch (timr->clk_src) { 134ea73fed2SPavan Nikhilesh case TIM_CLK_SRC_SCLK: 135ea73fed2SPavan Nikhilesh interval = NSEC2CLK(timr->tck_nsec, dinfo.clk_freq); 136ea73fed2SPavan Nikhilesh break; 137ea73fed2SPavan Nikhilesh case TIM_CLK_SRC_GPIO: 138ea73fed2SPavan Nikhilesh /* GPIO doesn't work on tck_nsec. */ 139ea73fed2SPavan Nikhilesh interval = 0; 140ea73fed2SPavan Nikhilesh break; 141ea73fed2SPavan Nikhilesh case TIM_CLK_SRC_GTI: 142ea73fed2SPavan Nikhilesh interval = NSEC2CLK(timr->tck_nsec, dinfo.clk_freq); 143ea73fed2SPavan Nikhilesh break; 144ea73fed2SPavan Nikhilesh case TIM_CLK_SRC_PTP: 145ea73fed2SPavan Nikhilesh interval = NSEC2CLK(timr->tck_nsec, dinfo.clk_freq); 146ea73fed2SPavan Nikhilesh break; 147ea73fed2SPavan Nikhilesh default: 148ea73fed2SPavan Nikhilesh timvf_log_err("Unsupported clock source configured %d", 149ea73fed2SPavan Nikhilesh timr->clk_src); 150ea73fed2SPavan Nikhilesh return -EINVAL; 151ea73fed2SPavan Nikhilesh } 152ea73fed2SPavan Nikhilesh 1533e249bc5SPavan Nikhilesh if (!strcmp(rte_mbuf_best_mempool_ops(), "octeontx_fpavf")) 1543e249bc5SPavan Nikhilesh use_fpa = 1; 1553e249bc5SPavan Nikhilesh 156ea73fed2SPavan Nikhilesh /*CTRL0 register.*/ 157ea73fed2SPavan Nikhilesh rctrl.rctrl0 = interval; 158ea73fed2SPavan Nikhilesh 159ea73fed2SPavan Nikhilesh /*CTRL1 register.*/ 160ea73fed2SPavan Nikhilesh rctrl.rctrl1 = (uint64_t)(timr->clk_src) << 51 | 161ea73fed2SPavan Nikhilesh 1ull << 48 /* LOCK_EN (Enable hw bucket lock mechanism) */ | 162ea73fed2SPavan Nikhilesh 1ull << 47 /* ENA */ | 163ea73fed2SPavan Nikhilesh 1ull << 44 /* ENA_LDWB */ | 164ea73fed2SPavan Nikhilesh (timr->nb_bkts - 1); 165ea73fed2SPavan Nikhilesh 166ea73fed2SPavan Nikhilesh rctrl.rctrl2 = (uint64_t)(TIM_CHUNK_SIZE / 16) << 40; 167ea73fed2SPavan Nikhilesh 1683e249bc5SPavan Nikhilesh if (use_fpa) { 1693e249bc5SPavan Nikhilesh pool = (uintptr_t)((struct rte_mempool *) 1703e249bc5SPavan Nikhilesh timr->chunk_pool)->pool_id; 171179c7e89SPavan Nikhilesh ret = octeontx_fpa_bufpool_gaura(pool); 1723e249bc5SPavan Nikhilesh if (ret < 0) { 1733e249bc5SPavan Nikhilesh timvf_log_dbg("Unable to get gaura id"); 1743e249bc5SPavan Nikhilesh ret = -ENOMEM; 1753e249bc5SPavan Nikhilesh goto error; 1763e249bc5SPavan Nikhilesh } 1773e249bc5SPavan Nikhilesh timvf_write64((uint64_t)ret, 1783e249bc5SPavan Nikhilesh (uint8_t *)timr->vbar0 + TIM_VRING_AURA); 1793e249bc5SPavan Nikhilesh } else { 1803e249bc5SPavan Nikhilesh rctrl.rctrl1 |= 1ull << 43 /* ENA_DFB (Enable don't free) */; 1813e249bc5SPavan Nikhilesh } 1823e249bc5SPavan Nikhilesh 183ea73fed2SPavan Nikhilesh timvf_write64((uintptr_t)timr->bkt, 184ea73fed2SPavan Nikhilesh (uint8_t *)timr->vbar0 + TIM_VRING_BASE); 1853e249bc5SPavan Nikhilesh timvf_set_chunk_refill(timr, use_fpa); 186ea73fed2SPavan Nikhilesh if (timvf_ring_conf_set(&rctrl, timr->tim_ring_id)) { 187ea73fed2SPavan Nikhilesh ret = -EACCES; 188ea73fed2SPavan Nikhilesh goto error; 189ea73fed2SPavan Nikhilesh } 190ea73fed2SPavan Nikhilesh 191ea73fed2SPavan Nikhilesh if (timvf_get_start_cyc(&timr->ring_start_cyc, 192ea73fed2SPavan Nikhilesh timr->tim_ring_id) < 0) { 193ea73fed2SPavan Nikhilesh ret = -EACCES; 194ea73fed2SPavan Nikhilesh goto error; 195ea73fed2SPavan Nikhilesh } 196ea73fed2SPavan Nikhilesh timr->tck_int = NSEC2CLK(timr->tck_nsec, rte_get_timer_hz()); 197ea73fed2SPavan Nikhilesh timr->fast_div = rte_reciprocal_value_u64(timr->tck_int); 198ea73fed2SPavan Nikhilesh timvf_log_info("nb_bkts %d min_ns %"PRIu64" min_cyc %"PRIu64"" 199f665790aSDavid Marchand " maxtmo %"PRIu64, 200ea73fed2SPavan Nikhilesh timr->nb_bkts, timr->tck_nsec, interval, 201ea73fed2SPavan Nikhilesh timr->max_tout); 202ea73fed2SPavan Nikhilesh 203ea73fed2SPavan Nikhilesh return 0; 204ea73fed2SPavan Nikhilesh error: 205ea73fed2SPavan Nikhilesh rte_free(timr->bkt); 206ea73fed2SPavan Nikhilesh rte_mempool_free(timr->chunk_pool); 207ea73fed2SPavan Nikhilesh return ret; 208ea73fed2SPavan Nikhilesh } 209ea73fed2SPavan Nikhilesh 210ea73fed2SPavan Nikhilesh static int 211ea73fed2SPavan Nikhilesh timvf_ring_stop(const struct rte_event_timer_adapter *adptr) 212ea73fed2SPavan Nikhilesh { 213ea73fed2SPavan Nikhilesh struct timvf_ring *timr = adptr->data->adapter_priv; 214ea73fed2SPavan Nikhilesh struct timvf_ctrl_reg rctrl = {0}; 215ea73fed2SPavan Nikhilesh rctrl.rctrl0 = timvf_read64((uint8_t *)timr->vbar0 + TIM_VRING_CTL0); 216ea73fed2SPavan Nikhilesh rctrl.rctrl1 = timvf_read64((uint8_t *)timr->vbar0 + TIM_VRING_CTL1); 217ea73fed2SPavan Nikhilesh rctrl.rctrl1 &= ~(1ull << 47); /* Disable */ 218ea73fed2SPavan Nikhilesh rctrl.rctrl2 = timvf_read64((uint8_t *)timr->vbar0 + TIM_VRING_CTL2); 219ea73fed2SPavan Nikhilesh 220ea73fed2SPavan Nikhilesh if (timvf_ring_conf_set(&rctrl, timr->tim_ring_id)) 221ea73fed2SPavan Nikhilesh return -EACCES; 222ea73fed2SPavan Nikhilesh return 0; 223ea73fed2SPavan Nikhilesh } 224ea73fed2SPavan Nikhilesh 225ea73fed2SPavan Nikhilesh static int 226f874c1ebSPavan Nikhilesh timvf_ring_create(struct rte_event_timer_adapter *adptr) 227f874c1ebSPavan Nikhilesh { 228f874c1ebSPavan Nikhilesh struct rte_event_timer_adapter_conf *rcfg = &adptr->data->conf; 229227f2835SPavan Nikhilesh uint16_t free_idx = UINT16_MAX; 230227f2835SPavan Nikhilesh unsigned int mp_flags = 0; 231227f2835SPavan Nikhilesh struct ssovf_evdev *edev; 232f874c1ebSPavan Nikhilesh struct timvf_ring *timr; 233f874c1ebSPavan Nikhilesh const char *mempool_ops; 234227f2835SPavan Nikhilesh uint8_t tim_ring_id; 235227f2835SPavan Nikhilesh char pool_name[25]; 236227f2835SPavan Nikhilesh int i, ret; 237f874c1ebSPavan Nikhilesh 2383639b4adSPavan Nikhilesh tim_ring_id = timvf_get_ring(); 2393639b4adSPavan Nikhilesh if (tim_ring_id == UINT8_MAX) 240f874c1ebSPavan Nikhilesh return -ENODEV; 241f874c1ebSPavan Nikhilesh 242227f2835SPavan Nikhilesh edev = ssovf_pmd_priv(event_dev); 243f874c1ebSPavan Nikhilesh timr = rte_zmalloc("octeontx_timvf_priv", 244f874c1ebSPavan Nikhilesh sizeof(struct timvf_ring), 0); 245f874c1ebSPavan Nikhilesh if (timr == NULL) 246f874c1ebSPavan Nikhilesh return -ENOMEM; 247f874c1ebSPavan Nikhilesh 248f874c1ebSPavan Nikhilesh adptr->data->adapter_priv = timr; 249f874c1ebSPavan Nikhilesh /* Check config parameters. */ 250f874c1ebSPavan Nikhilesh if ((rcfg->clk_src != RTE_EVENT_TIMER_ADAPTER_CPU_CLK) && 251f874c1ebSPavan Nikhilesh (!rcfg->timer_tick_ns || 252f874c1ebSPavan Nikhilesh rcfg->timer_tick_ns < TIM_MIN_INTERVAL)) { 253f874c1ebSPavan Nikhilesh timvf_log_err("Too low timer ticks"); 254f874c1ebSPavan Nikhilesh goto cfg_err; 255f874c1ebSPavan Nikhilesh } 256f874c1ebSPavan Nikhilesh 257f874c1ebSPavan Nikhilesh timr->clk_src = (int) rcfg->clk_src; 2583639b4adSPavan Nikhilesh timr->tim_ring_id = tim_ring_id; 2594cec5aaeSPavan Nikhilesh timr->tck_nsec = RTE_ALIGN_MUL_CEIL(rcfg->timer_tick_ns, 10); 260f874c1ebSPavan Nikhilesh timr->max_tout = rcfg->max_tmo_ns; 261f874c1ebSPavan Nikhilesh timr->nb_bkts = (timr->max_tout / timr->tck_nsec); 262f874c1ebSPavan Nikhilesh timr->vbar0 = timvf_bar(timr->tim_ring_id, 0); 263f874c1ebSPavan Nikhilesh timr->bkt_pos = (uint8_t *)timr->vbar0 + TIM_VRING_REL; 264227f2835SPavan Nikhilesh timr->nb_timers = rcfg->nb_timers; 265f874c1ebSPavan Nikhilesh timr->get_target_bkt = bkt_mod; 266f874c1ebSPavan Nikhilesh 267227f2835SPavan Nikhilesh if (edev->available_events < timr->nb_timers) { 268227f2835SPavan Nikhilesh timvf_log_err( 269227f2835SPavan Nikhilesh "Max available events %"PRIu32" requested timer events %"PRIu64"", 270227f2835SPavan Nikhilesh edev->available_events, timr->nb_timers); 271227f2835SPavan Nikhilesh return -ENOMEM; 272227f2835SPavan Nikhilesh } 273227f2835SPavan Nikhilesh 274227f2835SPavan Nikhilesh for (i = 0; i < edev->tim_ring_cnt; i++) { 275227f2835SPavan Nikhilesh if (edev->tim_ring_ids[i] == UINT16_MAX) 276227f2835SPavan Nikhilesh free_idx = i; 277227f2835SPavan Nikhilesh } 278227f2835SPavan Nikhilesh 279227f2835SPavan Nikhilesh if (free_idx == UINT16_MAX) { 280227f2835SPavan Nikhilesh void *old_ptr; 281227f2835SPavan Nikhilesh 282227f2835SPavan Nikhilesh edev->tim_ring_cnt++; 283227f2835SPavan Nikhilesh old_ptr = edev->tim_ring_ids; 284227f2835SPavan Nikhilesh edev->tim_ring_ids = 285227f2835SPavan Nikhilesh rte_realloc(edev->tim_ring_ids, 286227f2835SPavan Nikhilesh sizeof(uint16_t) * edev->tim_ring_cnt, 0); 287227f2835SPavan Nikhilesh if (edev->tim_ring_ids == NULL) { 288227f2835SPavan Nikhilesh edev->tim_ring_ids = old_ptr; 289227f2835SPavan Nikhilesh edev->tim_ring_cnt--; 290227f2835SPavan Nikhilesh return -ENOMEM; 291227f2835SPavan Nikhilesh } 292227f2835SPavan Nikhilesh 293227f2835SPavan Nikhilesh edev->available_events -= timr->nb_timers; 294227f2835SPavan Nikhilesh } else { 295227f2835SPavan Nikhilesh edev->tim_ring_ids[free_idx] = tim_ring_id; 296227f2835SPavan Nikhilesh edev->available_events -= timr->nb_timers; 297227f2835SPavan Nikhilesh } 298227f2835SPavan Nikhilesh 299227f2835SPavan Nikhilesh timr->nb_chunks = timr->nb_timers / nb_chunk_slots; 300f874c1ebSPavan Nikhilesh 3014cec5aaeSPavan Nikhilesh /* Try to optimize the bucket parameters. */ 3024cec5aaeSPavan Nikhilesh if ((rcfg->flags & RTE_EVENT_TIMER_ADAPTER_F_ADJUST_RES) 3034cec5aaeSPavan Nikhilesh && !rte_is_power_of_2(timr->nb_bkts)) { 3044cec5aaeSPavan Nikhilesh if (optimize_bucket_parameters(timr)) { 3054cec5aaeSPavan Nikhilesh timvf_log_info("Optimized configured values"); 3064cec5aaeSPavan Nikhilesh timvf_log_dbg("nb_bkts : %"PRIu32"", timr->nb_bkts); 3074cec5aaeSPavan Nikhilesh timvf_log_dbg("tck_nsec : %"PRIu64"", timr->tck_nsec); 3084cec5aaeSPavan Nikhilesh } else 3094cec5aaeSPavan Nikhilesh timvf_log_info("Failed to Optimize configured values"); 3104cec5aaeSPavan Nikhilesh } 3114cec5aaeSPavan Nikhilesh 3127684fcf1SPavan Nikhilesh if (rcfg->flags & RTE_EVENT_TIMER_ADAPTER_F_SP_PUT) { 313c47d7b90SAndrew Rybchenko mp_flags = RTE_MEMPOOL_F_SP_PUT | RTE_MEMPOOL_F_SC_GET; 3147684fcf1SPavan Nikhilesh timvf_log_info("Using single producer mode"); 3157684fcf1SPavan Nikhilesh } 3167684fcf1SPavan Nikhilesh 317f874c1ebSPavan Nikhilesh timr->bkt = rte_zmalloc("octeontx_timvf_bucket", 318f874c1ebSPavan Nikhilesh (timr->nb_bkts) * sizeof(struct tim_mem_bucket), 319f874c1ebSPavan Nikhilesh 0); 320f874c1ebSPavan Nikhilesh if (timr->bkt == NULL) 321f874c1ebSPavan Nikhilesh goto mem_err; 322f874c1ebSPavan Nikhilesh 32313573bd3SPavan Nikhilesh snprintf(pool_name, sizeof(pool_name), "timvf_chunk_pool%d", 32413573bd3SPavan Nikhilesh timr->tim_ring_id); 325f874c1ebSPavan Nikhilesh timr->chunk_pool = (void *)rte_mempool_create_empty(pool_name, 326f874c1ebSPavan Nikhilesh timr->nb_chunks, TIM_CHUNK_SIZE, 0, 0, rte_socket_id(), 3277684fcf1SPavan Nikhilesh mp_flags); 328f874c1ebSPavan Nikhilesh 329f874c1ebSPavan Nikhilesh if (!timr->chunk_pool) { 330f874c1ebSPavan Nikhilesh rte_free(timr->bkt); 331f874c1ebSPavan Nikhilesh timvf_log_err("Unable to create chunkpool."); 332f874c1ebSPavan Nikhilesh return -ENOMEM; 333f874c1ebSPavan Nikhilesh } 334f874c1ebSPavan Nikhilesh 335f874c1ebSPavan Nikhilesh mempool_ops = rte_mbuf_best_mempool_ops(); 336f874c1ebSPavan Nikhilesh ret = rte_mempool_set_ops_byname(timr->chunk_pool, 337f874c1ebSPavan Nikhilesh mempool_ops, NULL); 338f874c1ebSPavan Nikhilesh 339f874c1ebSPavan Nikhilesh if (ret != 0) { 340f874c1ebSPavan Nikhilesh timvf_log_err("Unable to set chunkpool ops."); 341f874c1ebSPavan Nikhilesh goto mem_err; 342f874c1ebSPavan Nikhilesh } 343f874c1ebSPavan Nikhilesh 344f874c1ebSPavan Nikhilesh ret = rte_mempool_populate_default(timr->chunk_pool); 345f874c1ebSPavan Nikhilesh if (ret < 0) { 346f874c1ebSPavan Nikhilesh timvf_log_err("Unable to set populate chunkpool."); 347f874c1ebSPavan Nikhilesh goto mem_err; 348f874c1ebSPavan Nikhilesh } 349f874c1ebSPavan Nikhilesh timvf_write64(0, (uint8_t *)timr->vbar0 + TIM_VRING_BASE); 350f874c1ebSPavan Nikhilesh timvf_write64(0, (uint8_t *)timr->vbar0 + TIM_VF_NRSPERR_INT); 351f874c1ebSPavan Nikhilesh timvf_write64(0, (uint8_t *)timr->vbar0 + TIM_VF_NRSPERR_INT_W1S); 352f874c1ebSPavan Nikhilesh timvf_write64(0x7, (uint8_t *)timr->vbar0 + TIM_VF_NRSPERR_ENA_W1C); 353f874c1ebSPavan Nikhilesh timvf_write64(0x7, (uint8_t *)timr->vbar0 + TIM_VF_NRSPERR_ENA_W1S); 354f874c1ebSPavan Nikhilesh 355f874c1ebSPavan Nikhilesh return 0; 356f874c1ebSPavan Nikhilesh mem_err: 357f874c1ebSPavan Nikhilesh rte_free(timr); 358f874c1ebSPavan Nikhilesh return -ENOMEM; 359f874c1ebSPavan Nikhilesh cfg_err: 360f874c1ebSPavan Nikhilesh rte_free(timr); 361f874c1ebSPavan Nikhilesh return -EINVAL; 362f874c1ebSPavan Nikhilesh } 363f874c1ebSPavan Nikhilesh 364f874c1ebSPavan Nikhilesh static int 365f874c1ebSPavan Nikhilesh timvf_ring_free(struct rte_event_timer_adapter *adptr) 366f874c1ebSPavan Nikhilesh { 367f874c1ebSPavan Nikhilesh struct timvf_ring *timr = adptr->data->adapter_priv; 368227f2835SPavan Nikhilesh struct ssovf_evdev *edev; 369227f2835SPavan Nikhilesh int i; 370227f2835SPavan Nikhilesh 371227f2835SPavan Nikhilesh edev = ssovf_pmd_priv(event_dev); 372227f2835SPavan Nikhilesh for (i = 0; i < edev->tim_ring_cnt; i++) { 373227f2835SPavan Nikhilesh if (edev->tim_ring_ids[i] == timr->tim_ring_id) { 374227f2835SPavan Nikhilesh edev->available_events += timr->nb_timers; 375227f2835SPavan Nikhilesh edev->tim_ring_ids[i] = UINT16_MAX; 376227f2835SPavan Nikhilesh break; 377227f2835SPavan Nikhilesh } 378227f2835SPavan Nikhilesh } 3793639b4adSPavan Nikhilesh 380f874c1ebSPavan Nikhilesh rte_mempool_free(timr->chunk_pool); 381f874c1ebSPavan Nikhilesh rte_free(timr->bkt); 3823639b4adSPavan Nikhilesh timvf_release_ring(timr->tim_ring_id); 383f874c1ebSPavan Nikhilesh rte_free(adptr->data->adapter_priv); 384f874c1ebSPavan Nikhilesh return 0; 385f874c1ebSPavan Nikhilesh } 386f874c1ebSPavan Nikhilesh 387d1925c87SPavan Nikhilesh static int 388d1925c87SPavan Nikhilesh timvf_stats_get(const struct rte_event_timer_adapter *adapter, 389d1925c87SPavan Nikhilesh struct rte_event_timer_adapter_stats *stats) 390d1925c87SPavan Nikhilesh { 391d1925c87SPavan Nikhilesh struct timvf_ring *timr = adapter->data->adapter_priv; 392d1925c87SPavan Nikhilesh uint64_t bkt_cyc = rte_rdtsc() - timr->ring_start_cyc; 393d1925c87SPavan Nikhilesh 394d1925c87SPavan Nikhilesh stats->evtim_exp_count = timr->tim_arm_cnt; 395d1925c87SPavan Nikhilesh stats->ev_enq_count = timr->tim_arm_cnt; 396d1925c87SPavan Nikhilesh stats->adapter_tick_count = rte_reciprocal_divide_u64(bkt_cyc, 397d1925c87SPavan Nikhilesh &timr->fast_div); 398d1925c87SPavan Nikhilesh return 0; 399d1925c87SPavan Nikhilesh } 400d1925c87SPavan Nikhilesh 401d1925c87SPavan Nikhilesh static int 402d1925c87SPavan Nikhilesh timvf_stats_reset(const struct rte_event_timer_adapter *adapter) 403d1925c87SPavan Nikhilesh { 404d1925c87SPavan Nikhilesh struct timvf_ring *timr = adapter->data->adapter_priv; 405d1925c87SPavan Nikhilesh 406d1925c87SPavan Nikhilesh timr->tim_arm_cnt = 0; 407d1925c87SPavan Nikhilesh return 0; 408d1925c87SPavan Nikhilesh } 409d1925c87SPavan Nikhilesh 41053548ad3SPavan Nikhilesh static struct event_timer_adapter_ops timvf_ops = { 411f874c1ebSPavan Nikhilesh .init = timvf_ring_create, 412f874c1ebSPavan Nikhilesh .uninit = timvf_ring_free, 413ea73fed2SPavan Nikhilesh .start = timvf_ring_start, 414ea73fed2SPavan Nikhilesh .stop = timvf_ring_stop, 415f874c1ebSPavan Nikhilesh .get_info = timvf_ring_info_get, 416f874c1ebSPavan Nikhilesh }; 417f874c1ebSPavan Nikhilesh 418f874c1ebSPavan Nikhilesh int 419f874c1ebSPavan Nikhilesh timvf_timer_adapter_caps_get(const struct rte_eventdev *dev, uint64_t flags, 42053548ad3SPavan Nikhilesh uint32_t *caps, 42153548ad3SPavan Nikhilesh const struct event_timer_adapter_ops **ops, 422f874c1ebSPavan Nikhilesh uint8_t enable_stats) 423f874c1ebSPavan Nikhilesh { 424f874c1ebSPavan Nikhilesh RTE_SET_USED(dev); 425d1925c87SPavan Nikhilesh 426d1925c87SPavan Nikhilesh if (enable_stats) { 427d1925c87SPavan Nikhilesh timvf_ops.stats_get = timvf_stats_get; 428d1925c87SPavan Nikhilesh timvf_ops.stats_reset = timvf_stats_reset; 429d1925c87SPavan Nikhilesh } 430d1925c87SPavan Nikhilesh 4317684fcf1SPavan Nikhilesh if (flags & RTE_EVENT_TIMER_ADAPTER_F_SP_PUT) 4327684fcf1SPavan Nikhilesh timvf_ops.arm_burst = enable_stats ? 4337684fcf1SPavan Nikhilesh timvf_timer_arm_burst_sp_stats : 4347684fcf1SPavan Nikhilesh timvf_timer_arm_burst_sp; 435b6d814d8SPavan Nikhilesh else 4367684fcf1SPavan Nikhilesh timvf_ops.arm_burst = enable_stats ? 4377684fcf1SPavan Nikhilesh timvf_timer_arm_burst_mp_stats : 4387684fcf1SPavan Nikhilesh timvf_timer_arm_burst_mp; 439b6d814d8SPavan Nikhilesh 4400896f7e0SPavan Nikhilesh timvf_ops.arm_tmo_tick_burst = enable_stats ? 4410896f7e0SPavan Nikhilesh timvf_timer_arm_tmo_brst_stats : 4420896f7e0SPavan Nikhilesh timvf_timer_arm_tmo_brst; 443b6d814d8SPavan Nikhilesh timvf_ops.cancel_burst = timvf_timer_cancel_burst; 444f874c1ebSPavan Nikhilesh *caps = RTE_EVENT_TIMER_ADAPTER_CAP_INTERNAL_PORT; 445f874c1ebSPavan Nikhilesh *ops = &timvf_ops; 446b6d814d8SPavan Nikhilesh return 0; 447f874c1ebSPavan Nikhilesh } 448227f2835SPavan Nikhilesh 449227f2835SPavan Nikhilesh void 450227f2835SPavan Nikhilesh timvf_set_eventdevice(struct rte_eventdev *dev) 451227f2835SPavan Nikhilesh { 452227f2835SPavan Nikhilesh event_dev = dev; 453227f2835SPavan Nikhilesh } 454