1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
3 * Copyright 2008-2016 Freescale Semiconductor Inc.
4 * Copyright 2017,2019 NXP
10 #include "qman_priv.h"
11 #include <sys/ioctl.h>
12 #include <rte_branch_prediction.h>
14 /* Global variable containing revision id (even on non-control plane systems
15 * where CCSR isn't available).
18 u16 qm_channel_pool1 = QMAN_CHANNEL_POOL1;
19 u16 qm_channel_caam = QMAN_CHANNEL_CAAM;
20 u16 qm_channel_pme = QMAN_CHANNEL_PME;
22 /* Ccsr map address to access ccsrbased register */
23 static void *qman_ccsr_map;
24 /* The qman clock frequency */
27 static __thread int qmfd = -1;
28 static __thread struct qm_portal_config qpcfg;
29 static __thread struct dpaa_ioctl_portal_map map = {
30 .type = dpaa_portal_qman
33 u16 dpaa_get_qm_channel_caam(void)
35 return qm_channel_caam;
38 u16 dpaa_get_qm_channel_pool(void)
40 return qm_channel_pool1;
43 static int fsl_qman_portal_init(uint32_t index, int is_shared)
45 struct qman_portal *portal;
46 struct dpaa_ioctl_irq_map irq_map;
49 /* Allocate and map a qman portal */
51 ret = process_portal_map(&map);
53 error(0, ret, "process_portal_map()");
56 qpcfg.channel = map.channel;
57 qpcfg.pools = map.pools;
58 qpcfg.index = map.index;
60 /* Make the portal's cache-[enabled|inhibited] regions */
61 qpcfg.addr_virt[DPAA_PORTAL_CE] = map.addr.cena;
62 qpcfg.addr_virt[DPAA_PORTAL_CI] = map.addr.cinh;
64 qmfd = open(QMAN_PORTAL_IRQ_PATH, O_RDONLY);
66 pr_err("QMan irq init failed\n");
67 process_portal_unmap(&map.addr);
71 qpcfg.is_shared = is_shared;
75 portal = qman_create_affine_portal(&qpcfg, NULL);
77 pr_err("Qman portal initialisation failed (%d)\n",
79 process_portal_unmap(&map.addr);
83 irq_map.type = dpaa_portal_qman;
84 irq_map.portal_cinh = map.addr.cinh;
85 process_portal_irq_map(qmfd, &irq_map);
89 static int fsl_qman_portal_finish(void)
91 __maybe_unused const struct qm_portal_config *cfg;
94 process_portal_irq_unmap(qmfd);
96 cfg = qman_destroy_affine_portal(NULL);
97 DPAA_BUG_ON(cfg != &qpcfg);
98 ret = process_portal_unmap(&map.addr);
100 error(0, ret, "process_portal_unmap()");
104 int qman_thread_fd(void)
109 int qman_thread_init(void)
111 /* Convert from contiguous/virtual cpu numbering to real cpu when
112 * calling into the code that is dependent on the device naming.
114 return fsl_qman_portal_init(QBMAN_ANY_PORTAL_IDX, 0);
117 int qman_thread_finish(void)
119 return fsl_qman_portal_finish();
122 void qman_thread_irq(void)
124 qbman_invoke_irq(qpcfg.irq);
126 /* Now we need to uninhibit interrupts. This is the only code outside
127 * the regular portal driver that manipulates any portal register, so
128 * rather than breaking that encapsulation I am simply hard-coding the
129 * offset to the inhibit register here.
131 out_be32(qpcfg.addr_virt[DPAA_PORTAL_CI] + 0x36C0, 0);
134 void qman_fq_portal_thread_irq(struct qman_portal *qp)
136 qman_portal_uninhibit_isr(qp);
139 struct qman_portal *fsl_qman_fq_portal_create(int *fd)
141 struct qman_portal *portal = NULL;
142 struct qm_portal_config *q_pcfg;
143 struct dpaa_ioctl_irq_map irq_map;
144 struct dpaa_ioctl_portal_map q_map = {0};
147 q_pcfg = kzalloc((sizeof(struct qm_portal_config)), 0);
149 error(0, -1, "q_pcfg kzalloc failed");
153 /* Allocate and map a qman portal */
154 q_map.type = dpaa_portal_qman;
155 q_map.index = QBMAN_ANY_PORTAL_IDX;
156 ret = process_portal_map(&q_map);
158 error(0, ret, "process_portal_map()");
162 q_pcfg->channel = q_map.channel;
163 q_pcfg->pools = q_map.pools;
164 q_pcfg->index = q_map.index;
166 /* Make the portal's cache-[enabled|inhibited] regions */
167 q_pcfg->addr_virt[DPAA_PORTAL_CE] = q_map.addr.cena;
168 q_pcfg->addr_virt[DPAA_PORTAL_CI] = q_map.addr.cinh;
170 q_fd = open(QMAN_PORTAL_IRQ_PATH, O_RDONLY);
172 pr_err("QMan irq init failed\n");
178 portal = qman_alloc_global_portal(q_pcfg);
180 pr_err("Qman portal initialisation failed (%d)\n",
185 irq_map.type = dpaa_portal_qman;
186 irq_map.portal_cinh = q_map.addr.cinh;
187 process_portal_irq_map(q_fd, &irq_map);
194 process_portal_unmap(&q_map.addr);
199 int fsl_qman_fq_portal_init(struct qman_portal *qp)
201 struct qman_portal *res;
203 res = qman_init_portal(qp, NULL, NULL);
205 pr_err("Qman portal initialisation failed\n");
212 int fsl_qman_fq_portal_destroy(struct qman_portal *qp)
214 const struct qm_portal_config *cfg;
215 struct dpaa_portal_map addr;
218 cfg = qman_destroy_affine_portal(qp);
220 ret = qman_free_global_portal(qp);
222 pr_err("qman_free_global_portal() (%d)\n", ret);
226 process_portal_irq_unmap(cfg->irq);
228 addr.cena = cfg->addr_virt[DPAA_PORTAL_CE];
229 addr.cinh = cfg->addr_virt[DPAA_PORTAL_CI];
231 ret = process_portal_unmap(&addr);
233 pr_err("process_portal_unmap() (%d)\n", ret);
240 int qman_global_init(void)
242 const struct device_node *dt_node;
245 static int ccsr_map_fd;
246 const uint32_t *qman_addr;
256 /* Use the device-tree to determine IP revision until something better
259 dt_node = of_find_compatible_node(NULL, NULL, "fsl,qman-portal");
261 pr_err("No qman portals available for any CPU\n");
264 if (of_device_is_compatible(dt_node, "fsl,qman-portal-1.0") ||
265 of_device_is_compatible(dt_node, "fsl,qman-portal-1.0.0"))
266 pr_err("QMan rev1.0 on P4080 rev1 is not supported!\n");
267 else if (of_device_is_compatible(dt_node, "fsl,qman-portal-1.1") ||
268 of_device_is_compatible(dt_node, "fsl,qman-portal-1.1.0"))
269 qman_ip_rev = QMAN_REV11;
270 else if (of_device_is_compatible(dt_node, "fsl,qman-portal-1.2") ||
271 of_device_is_compatible(dt_node, "fsl,qman-portal-1.2.0"))
272 qman_ip_rev = QMAN_REV12;
273 else if (of_device_is_compatible(dt_node, "fsl,qman-portal-2.0") ||
274 of_device_is_compatible(dt_node, "fsl,qman-portal-2.0.0"))
275 qman_ip_rev = QMAN_REV20;
276 else if (of_device_is_compatible(dt_node, "fsl,qman-portal-3.0.0") ||
277 of_device_is_compatible(dt_node, "fsl,qman-portal-3.0.1"))
278 qman_ip_rev = QMAN_REV30;
279 else if (of_device_is_compatible(dt_node, "fsl,qman-portal-3.1.0") ||
280 of_device_is_compatible(dt_node, "fsl,qman-portal-3.1.1") ||
281 of_device_is_compatible(dt_node, "fsl,qman-portal-3.1.2") ||
282 of_device_is_compatible(dt_node, "fsl,qman-portal-3.1.3"))
283 qman_ip_rev = QMAN_REV31;
284 else if (of_device_is_compatible(dt_node, "fsl,qman-portal-3.2.0") ||
285 of_device_is_compatible(dt_node, "fsl,qman-portal-3.2.1"))
286 qman_ip_rev = QMAN_REV32;
288 qman_ip_rev = QMAN_REV11;
291 pr_err("Unknown qman portal version\n");
294 if ((qman_ip_rev & 0xFF00) >= QMAN_REV30) {
295 qm_channel_pool1 = QMAN_CHANNEL_POOL1_REV3;
296 qm_channel_caam = QMAN_CHANNEL_CAAM_REV3;
297 qm_channel_pme = QMAN_CHANNEL_PME_REV3;
300 dt_node = of_find_compatible_node(NULL, NULL, "fsl,pool-channel-range");
302 pr_err("No qman pool channel range available\n");
305 chanid = of_get_property(dt_node, "fsl,pool-channel-range", &lenp);
307 pr_err("Can not get pool-channel-range property\n");
312 dt_node = of_find_compatible_node(NULL, NULL, "fsl,qman");
314 pr_err("No qman device node available\n");
317 qman_addr = of_get_address(dt_node, 0, ®s_size, NULL);
319 pr_err("of_get_address cannot return qman address\n");
322 phys_addr = of_translate_address(dt_node, qman_addr);
324 pr_err("of_translate_address failed\n");
328 ccsr_map_fd = open("/dev/mem", O_RDWR);
329 if (unlikely(ccsr_map_fd < 0)) {
330 pr_err("Can not open /dev/mem for qman ccsr map\n");
334 qman_ccsr_map = mmap(NULL, regs_size, PROT_READ | PROT_WRITE,
335 MAP_SHARED, ccsr_map_fd, phys_addr);
336 if (qman_ccsr_map == MAP_FAILED) {
337 pr_err("Can not map qman ccsr base\n");
341 clk = of_get_property(dt_node, "clock-frequency", NULL);
343 pr_warn("Can't find Qman clock frequency\n");
345 qman_clk = be32_to_cpu(*clk);
347 #ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
348 return qman_setup_fq_lookup_table(CONFIG_FSL_QMAN_FQ_LOOKUP_MAX);