-----Original Message----- > Date: Tue, 3 Apr 2018 20:35:06 +0530 > From: Pavan Nikhilesh <pbhagavat...@caviumnetworks.com> > To: jerin.ja...@caviumnetworks.com, santosh.shu...@caviumnetworks.com, > erik.g.carri...@intel.com > Cc: dev@dpdk.org, Pavan Nikhilesh <pbhagavat...@caviumnetworks.com> > Subject: [dpdk-dev] [PATCH v3 04/12] event/octeontx: add support to start > and stop timer device > X-Mailer: git-send-email 2.16.3 > > When application requests to start the timer adapter through > `rte_event_timer_adapter_start`, Octeontx TIMvf ring does the > following: > - Uses mbox to communicate TIMpf driver about, > * SCLK frequency used to convert ns<->cycles. > * program the ring control parameters and start the ring. > * get the exact cycle at which the TIMvf ring has started which can be > used to estimate the bucket position. > > On `rte_event_timer_adapter_stop` i.e stop, Octeontx TIMvf ring does the > following: > - Use mbox to communicate TIMpf driver about, > * reset the ring control parameters and stop the ring. > > Signed-off-by: Pavan Nikhilesh <pbhagavat...@caviumnetworks.com> > --- > drivers/event/octeontx/timvf_evdev.c | 140 > +++++++++++++++++++++++++++++++++++ > drivers/event/octeontx/timvf_evdev.h | 5 ++ > 2 files changed, 145 insertions(+) > > +/* Response messages */ > +enum { > + MBOX_RET_SUCCESS, > + MBOX_RET_INVALID, > + MBOX_RET_INTERNAL_ERR, > +};
If it is duplicate definition then remove it. > + > +static int > +timvf_mbox_dev_info_get(struct timvf_mbox_dev_info *info) > +{ > + struct octeontx_mbox_hdr hdr = {0}; > + uint16_t len = sizeof(struct timvf_mbox_dev_info); > + > + hdr.coproc = TIM_COPROC; > + hdr.msg = TIM_GET_DEV_INFO; > + hdr.vfid = 0; /* TIM DEV is always 0. TIM RING ID changes. */ > + > + memset(info, 0, len); > + return octeontx_ssovf_mbox_send(&hdr, NULL, 0, info, len); rebase to latest dpdk-next-eventdev where mbox api changed to octeontx_mbox_send > +} > + > static void > timvf_ring_info_get(const struct rte_event_timer_adapter *adptr, > struct rte_event_timer_adapter_info *adptr_info) > @@ -27,6 +53,118 @@ timvf_ring_info_get(const struct rte_event_timer_adapter > *adptr, > sizeof(struct rte_event_timer_adapter_conf)); > } > > +static int > +timvf_ring_start(const struct rte_event_timer_adapter *adptr) > +{ > + int ret; > + uint64_t interval = 0; This assignment can be avoided. > + struct timvf_ctrl_reg rctrl = {0}; > + struct timvf_mbox_dev_info dinfo; > + struct timvf_ring *timr = adptr->data->adapter_priv; > + > + ret = timvf_mbox_dev_info_get(&dinfo); > + if (ret < 0 || ret != sizeof(struct timvf_mbox_dev_info)) > + return -EINVAL; > + > + /* Calculate the interval cycles according to clock source. */ > + switch (timr->clk_src) { > + case TIM_CLK_SRC_SCLK: > + interval = NSEC2CLK(timr->tck_nsec, dinfo.clk_freq); > + break; > + case TIM_CLK_SRC_GPIO: > + /* GPIO doesn't work on tck_nsec. */ > + interval = 0; > + break; > + case TIM_CLK_SRC_GTI: > + interval = NSEC2CLK(timr->tck_nsec, dinfo.clk_freq); > + break; > + case TIM_CLK_SRC_PTP: > + interval = NSEC2CLK(timr->tck_nsec, dinfo.clk_freq); > + break; Shouldn't we return error if clock source is not supported? > + } > + > + /*CTRL0 register.*/ > + rctrl.rctrl0 = interval; > + > + /*CTRL1 register.*/ > + rctrl.rctrl1 = (uint64_t)(timr->clk_src) << 51 | > + 1ull << 48 | > + 1ull << 47 | > + 1ull << 44 | Add comments to this bit definitions. > + (timr->meta.nb_bkts - 1); > + > + rctrl.rctrl2 = (uint64_t)(TIM_CHUNK_SIZE / 16) << 40; > + > + timvf_write64((uint64_t)timr->meta.bkt, > + (uint8_t *)timr->vbar0 + TIM_VRING_BASE); > + if (timvf_ring_conf_set(&rctrl, timr->tim_ring_id)) { > + ret = -EACCES; > + goto error; > + } > + > + if (timvf_get_start_cyc(&timr->meta.ring_start_cyc, > + timr->tim_ring_id) < 0) { > + ret = -EACCES; > + goto error; > + } > + timr->meta.tck_int = NSEC2CLK(timr->tck_nsec, rte_get_timer_hz()); > + timr->meta.fast_div = rte_reciprocal_value_u64(timr->meta.tck_int); > + timvf_log_info("nb_bkts %d min_ns %"PRIu64" min_cyc %"PRIu64"" > + " maxtmo %"PRIu64"\n", > + timr->meta.nb_bkts, timr->tck_nsec, interval, > + timr->max_tout); > + > + return 0; > +error: > + rte_free(timr->meta.bkt); > + rte_mempool_free(timr->meta.chunk_pool); > + return ret; > +} > + > +static int > +timvf_ring_stop(const struct rte_event_timer_adapter *adptr) > +{ > + struct timvf_ring *timr = adptr->data->adapter_priv; > + struct timvf_ctrl_reg rctrl = {0}; > + rctrl.rctrl0 = timvf_read64((uint8_t *)timr->vbar0 + TIM_VRING_CTL0); > + rctrl.rctrl1 = timvf_read64((uint8_t *)timr->vbar0 + TIM_VRING_CTL1); > + rctrl.rctrl1 &= ~(1ull << 47); /* Disable */ > + rctrl.rctrl2 = timvf_read64((uint8_t *)timr->vbar0 + TIM_VRING_CTL2); > + > + if (timvf_ring_conf_set(&rctrl, timr->tim_ring_id)) > + return -EACCES; > + return 0; > +} > + > static int > timvf_ring_create(struct rte_event_timer_adapter *adptr) > { > @@ -146,6 +284,8 @@ timvf_ring_free(struct rte_event_timer_adapter *adptr) > static struct rte_event_timer_adapter_ops timvf_ops = { can be 'const'? > .init = timvf_ring_create, > .uninit = timvf_ring_free, > + .start = timvf_ring_start, > + .stop = timvf_ring_stop, Found two tabs > .get_info = timvf_ring_info_get, > }; > > diff --git a/drivers/event/octeontx/timvf_evdev.h > b/drivers/event/octeontx/timvf_evdev.h > index e3f558e10..e155b6ce2 100644 > --- a/drivers/event/octeontx/timvf_evdev.h > +++ b/drivers/event/octeontx/timvf_evdev.h > @@ -75,6 +75,11 @@ > #define TIM_VRING_AURA (0x108) > #define TIM_VRING_REL (0x110) > > + > +#define NSEC_PER_SEC 1E9 > +#define NSEC2CLK(__ns, __freq) (((__ns) * (__freq)) / NSEC_PER_SEC) > +#define CLK2NSEC(__clk, __freq) (((__clk) * NSEC_PER_SEC) / (__freq)) > + > #define timvf_read64 rte_read64_relaxed > #define timvf_write64 rte_write64_relaxed > > -- > 2.16.3 >