xref: /dpdk/drivers/event/octeontx/timvf_evdev.c (revision f874c1eb1519185feba05a0542413492e5f56ae9)
1 /*
2  * SPDX-License-Identifier: BSD-3-Clause
3  * Copyright(c) 2017 Cavium, Inc
4  */
5 
6 #include "timvf_evdev.h"
7 
8 int otx_logtype_timvf;
9 
10 RTE_INIT(otx_timvf_init_log);
11 static void
12 otx_timvf_init_log(void)
13 {
14 	otx_logtype_timvf = rte_log_register("pmd.event.octeontx.timer");
15 	if (otx_logtype_timvf >= 0)
16 		rte_log_set_level(otx_logtype_timvf, RTE_LOG_NOTICE);
17 }
18 
19 static void
20 timvf_ring_info_get(const struct rte_event_timer_adapter *adptr,
21 		struct rte_event_timer_adapter_info *adptr_info)
22 {
23 	struct timvf_ring *timr = adptr->data->adapter_priv;
24 	adptr_info->max_tmo_ns = timr->max_tout;
25 	adptr_info->min_resolution_ns = timr->tck_nsec;
26 	rte_memcpy(&adptr_info->conf, &adptr->data->conf,
27 			sizeof(struct rte_event_timer_adapter_conf));
28 }
29 
30 static int
31 timvf_ring_create(struct rte_event_timer_adapter *adptr)
32 {
33 	char pool_name[25];
34 	int ret;
35 	uint64_t nb_timers;
36 	struct rte_event_timer_adapter_conf *rcfg = &adptr->data->conf;
37 	struct timvf_ring *timr;
38 	struct timvf_info tinfo;
39 	const char *mempool_ops;
40 
41 	if (timvf_info(&tinfo) < 0)
42 		return -ENODEV;
43 
44 	if (adptr->data->id >= tinfo.total_timvfs)
45 		return -ENODEV;
46 
47 	timr = rte_zmalloc("octeontx_timvf_priv",
48 			sizeof(struct timvf_ring), 0);
49 	if (timr == NULL)
50 		return -ENOMEM;
51 
52 	adptr->data->adapter_priv = timr;
53 	/* Check config parameters. */
54 	if ((rcfg->clk_src != RTE_EVENT_TIMER_ADAPTER_CPU_CLK) &&
55 			(!rcfg->timer_tick_ns ||
56 			 rcfg->timer_tick_ns < TIM_MIN_INTERVAL)) {
57 		timvf_log_err("Too low timer ticks");
58 		goto cfg_err;
59 	}
60 
61 	timr->clk_src = (int) rcfg->clk_src;
62 	timr->tim_ring_id = adptr->data->id;
63 	timr->tck_nsec = rcfg->timer_tick_ns;
64 	timr->max_tout = rcfg->max_tmo_ns;
65 	timr->nb_bkts = (timr->max_tout / timr->tck_nsec);
66 	timr->vbar0 = timvf_bar(timr->tim_ring_id, 0);
67 	timr->bkt_pos = (uint8_t *)timr->vbar0 + TIM_VRING_REL;
68 	nb_timers = rcfg->nb_timers;
69 	timr->get_target_bkt = bkt_mod;
70 
71 	timr->nb_chunks = nb_timers / nb_chunk_slots;
72 
73 	timr->bkt = rte_zmalloc("octeontx_timvf_bucket",
74 			(timr->nb_bkts) * sizeof(struct tim_mem_bucket),
75 			0);
76 	if (timr->bkt == NULL)
77 		goto mem_err;
78 
79 	snprintf(pool_name, 30, "timvf_chunk_pool%d", timr->tim_ring_id);
80 	timr->chunk_pool = (void *)rte_mempool_create_empty(pool_name,
81 			timr->nb_chunks, TIM_CHUNK_SIZE, 0, 0, rte_socket_id(),
82 			0);
83 
84 	if (!timr->chunk_pool) {
85 		rte_free(timr->bkt);
86 		timvf_log_err("Unable to create chunkpool.");
87 		return -ENOMEM;
88 	}
89 
90 	mempool_ops = rte_mbuf_best_mempool_ops();
91 	ret = rte_mempool_set_ops_byname(timr->chunk_pool,
92 			mempool_ops, NULL);
93 
94 	if (ret != 0) {
95 		timvf_log_err("Unable to set chunkpool ops.");
96 		goto mem_err;
97 	}
98 
99 	ret = rte_mempool_populate_default(timr->chunk_pool);
100 	if (ret < 0) {
101 		timvf_log_err("Unable to set populate chunkpool.");
102 		goto mem_err;
103 	}
104 	timvf_write64(0, (uint8_t *)timr->vbar0 + TIM_VRING_BASE);
105 	timvf_write64(0, (uint8_t *)timr->vbar0 + TIM_VF_NRSPERR_INT);
106 	timvf_write64(0, (uint8_t *)timr->vbar0 + TIM_VF_NRSPERR_INT_W1S);
107 	timvf_write64(0x7, (uint8_t *)timr->vbar0 + TIM_VF_NRSPERR_ENA_W1C);
108 	timvf_write64(0x7, (uint8_t *)timr->vbar0 + TIM_VF_NRSPERR_ENA_W1S);
109 
110 	return 0;
111 mem_err:
112 	rte_free(timr);
113 	return -ENOMEM;
114 cfg_err:
115 	rte_free(timr);
116 	return -EINVAL;
117 }
118 
119 static int
120 timvf_ring_free(struct rte_event_timer_adapter *adptr)
121 {
122 	struct timvf_ring *timr = adptr->data->adapter_priv;
123 	rte_mempool_free(timr->chunk_pool);
124 	rte_free(timr->bkt);
125 	rte_free(adptr->data->adapter_priv);
126 	return 0;
127 }
128 
129 static struct rte_event_timer_adapter_ops timvf_ops = {
130 	.init		= timvf_ring_create,
131 	.uninit		= timvf_ring_free,
132 	.get_info	= timvf_ring_info_get,
133 };
134 
135 int
136 timvf_timer_adapter_caps_get(const struct rte_eventdev *dev, uint64_t flags,
137 		uint32_t *caps, const struct rte_event_timer_adapter_ops **ops,
138 		uint8_t enable_stats)
139 {
140 	RTE_SET_USED(dev);
141 	RTE_SET_USED(flags);
142 	RTE_SET_USED(enable_stats);
143 	*caps = RTE_EVENT_TIMER_ADAPTER_CAP_INTERNAL_PORT;
144 	*ops = &timvf_ops;
145 	return -EINVAL;
146 }
147