xref: /freebsd/sys/dev/dpaa/fman.c (revision bac7bd5038e09d12dfdbf79a87b25443e02d0ba9)
1 /*
2  * Copyright (c) 2026 Justin Hibbits
3  *
4  * SPDX-License-Identifier: BSD-2-Clause
5  */
6 
7 #include <sys/param.h>
8 #include <sys/systm.h>
9 #include <sys/kernel.h>
10 #include <sys/module.h>
11 #include <sys/bus.h>
12 #include <sys/rman.h>
13 #include <sys/malloc.h>
14 
15 #include <dev/fdt/simplebus.h>
16 #include <dev/fdt/fdt_common.h>
17 #include <dev/ofw/ofw_bus.h>
18 #include <dev/ofw/ofw_bus_subr.h>
19 
20 #include <machine/bus.h>
21 
22 #include "opt_platform.h"
23 
24 #include <powerpc/mpc85xx/mpc85xx.h>
25 
26 #include "fman.h"
27 
28 #define	FMAN_BMI_OFFSET		0x80000
29 #define	FMAN_QMI_OFFSET		0x80400
30 #define	FMAN_KG_OFFSET		0xc1000
31 #define	FMAN_DMA_OFFSET		0xc2000
32 #define	FMAN_FPM_OFFSET		0xc3000
33 #define	FMAN_IMEM_OFFSET	0xc4000
34 #define	FMAN_HWP_OFFSET		0xc7000
35 #define	FMAN_CGP_OFFSET		0xdb000
36 
37 #define	FM_IP_REV_1		(FMAN_FPM_OFFSET + 0x0c4)
38 #define	  IP_REV_1_MAJ_M	  0x0000ff00
39 #define	  IP_REV_1_MAJ_S	  8
40 #define	  IP_REV_1_MIN_M	  0x000000ff
41 #define	FM_RSTC			(FMAN_FPM_OFFSET + 0x0cc)
42 #define	  FM_RSTC_FM_RESET	  0x80000000
43 
44 #define	FMBM_INIT	(FMAN_BMI_OFFSET + 0x000)
45 #define	  INIT_STR	  0x80000000
46 #define	FMBM_CFG1	(FMAN_BMI_OFFSET + 0x0004)
47 #define	  FBPS_M	  0x07ff0000
48 #define	  FBPS_S	  16
49 #define	  FBPO_M	  0x000007ff
50 #define	FMBM_CFG2	(FMAN_BMI_OFFSET + 0x0008)
51 #define	  TNTSKS_M	  0x007f0000
52 #define	  TNTSKS_S	  16
53 #define	FMBM_IEVR	(FMAN_BMI_OFFSET + 0x0020)
54 #define	  IEVR_SPEC	  0x80000000
55 #define	  IEVR_LEC	  0x40000000
56 #define	  IEVR_STEC	  0x20000000
57 #define	  IEVR_DEC	  0x10000000
58 #define	FMBM_IER	(FMAN_BMI_OFFSET + 0x0024)
59 #define	  IER_SPECE	  0x80000000
60 #define	  IER_LECE	  0x40000000
61 #define	  IER_STECE	  0x20000000
62 #define	  IER_DECE	  0x10000000
63 #define	FMBM_PP(n)	(FMAN_BMI_OFFSET + 0x104 + ((n - 1) * 4))
64 #define	  PP_MXT_M	  0x3f000000
65 #define	  PP_MXT_S	  24
66 #define	  PP_EXT_M	  0x000f0000
67 #define	  PP_EXT_S	  16
68 #define	  PP_MXD_M	  0x00000f00
69 #define	  PP_MXD_S	  8
70 #define	  PP_EXD_M	  0x0000000f
71 #define	FMBM_PFS(n)	(FMAN_BMI_OFFSET + 0x204 + ((n - 1) * 4))
72 #define	  PFS_EXBS_M	  0x03ff0000
73 #define	  PFS_EXBS_S	  16
74 #define	  PFS_IFSZ_M	  0x000003ff
75 #define	FMQM_GC		(FMAN_QMI_OFFSET + 0x000)
76 #define	  GC_STEN	  0x10000000
77 #define	  GC_ENQ_THR_S	  8
78 #define	  GC_ENQ_THR_M	  0x00003f00
79 #define	  GC_DEQ_THR_M	  0x0000003f
80 #define	FMQM_EIE	(FMAN_QMI_OFFSET + 0x008)
81 #define	  EIE_DEE	  0x80000000
82 #define	  EIE_DFUPE	  0x40000000
83 #define	FMQM_EIEN	(FMAN_QMI_OFFSET + 0x00c)
84 #define	  EIEN_DEE	  0x80000000
85 #define	  EIEN_DFUPE	  0x40000000
86 #define FMQM_IE
87 #define	IRAM_ADDR	(FMAN_IMEM_OFFSET + 0x000)
88 #define	  IADD_AIE	  0x80000000
89 #define	IRAM_DATA	(FMAN_IMEM_OFFSET + 0x004)
90 #define	IRAM_READY	(FMAN_IMEM_OFFSET + 0x0c)
91 #define	  IREADY_READY	  0x80000000
92 
93 #define	FMPR_RPIMAC	(FMAN_HWP_OFFSET + 0x844)
94 #define	  HWP_RPIMAC_PEN	  0x00000001
95 
96 #define	FMDM_SR		(FMAN_DMA_OFFSET + 0x000)
97 #define	  SR_CMDQNE	  0x10000000
98 #define	  SR_BER	  0x08000000
99 #define	  SR_RDB_ECC	  0x04000000
100 #define	  SR_WRB_SECC	  0x02000000
101 #define	FMDM_MR		(FMAN_DMA_OFFSET + 0x004)
102 #define	  MR_CEN_M	  0x0000e000
103 #define	  MR_CEN_S	  13
104 #define	FMDM_SETR	(FMAN_DMA_OFFSET + 0x010)
105 #define	FMDM_EBCR	(FMAN_DMA_OFFSET + 0x2c)
106 #define	FMDM_PLRn(n)	(FMAN_DMA_OFFSET + 0x060 + (4 * (n / 2)))
107 #define	PLRN_LIODN_M(n)	  (0xfff << PLRN_LIODN_S(n))
108 #define	PLRN_LIODN_S(n)	  ((n & 1) ? 0 : 16)
109 
110 #define	FMFP_TSC1	(FMAN_FPM_OFFSET + 0x060)
111 #define	  TSC1_TEN	  0x80000000
112 #define	FMFP_TSC2	(FMAN_FPM_OFFSET + 0x064)
113 #define	  TSC2_TSIV_INT_S	  16
114 #define	FM_RCR		(FMAN_FPM_OFFSET + 0x070)
115 #define	  RCR_FEE	  0x80000000
116 #define	  RCR_IEE	  0x40000000
117 #define	  RCR_MET	  0x20000000
118 #define	  RCR_IET	  0x10000000
119 #define	  RCR_SFE	  0x08000000
120 #define	FMFP_EE		(FMAN_FPM_OFFSET + 0x0dc)
121 #define	  EE_DECC	  0x80000000
122 #define	  EE_STL	  0x40000000
123 #define	  EE_SECC	  0x20000000
124 #define	  EE_RFM	  0x00010000
125 #define	  EE_DECC_EN	  0x00008000
126 #define	  EE_STL_EN	  0x00004000
127 #define	  EE_SECC_EN	  0x00002000
128 #define	  EE_EHM	  0x00000008
129 #define	  EE_CER	  0x00000002
130 #define	  EE_DER	  0x00000001
131 #define	FMFP_CEV0	(FMAN_FPM_OFFSET + 0x0e0)
132 #define	FMFP_CEV1	(FMAN_FPM_OFFSET + 0x0e4)
133 #define	FMFP_CEV2	(FMAN_FPM_OFFSET + 0x0e8)
134 #define	FMFP_CEV3	(FMAN_FPM_OFFSET + 0x0ec)
135 
136 /* DMA constants */
137 #define	DMA_CAM_UNITS	8
138 #define	DMA_CAM_SIZE	64
139 #define	DMA_CAM_ALIGN	64
140 
141 
142 /* Timestamp counter */
143 #define	FM_TIMESTAMP_1US_BIT	8
144 
145 static MALLOC_DEFINE(M_FMAN, "fman", "fman devices information");
146 
147 static void fman_intr(void *arg);
148 
149 /**
150  * @group FMan private defines.
151  * @{
152  */
153 
154 /**
155  * @group FMan private methods/members.
156  * @{
157  */
158 
159 int
160 fman_activate_resource(device_t bus, device_t child, struct resource *res)
161 {
162 	struct fman_softc *sc;
163 	bus_space_tag_t bt;
164 	bus_space_handle_t bh;
165 	int i, rv;
166 
167 	sc = device_get_softc(bus);
168 	if (rman_get_type(res) != SYS_RES_IRQ) {
169 		for (i = 0; i < sc->sc_base.nranges; i++) {
170 			if (rman_is_region_manager(res, &sc->rman) != 0) {
171 				bt = rman_get_bustag(sc->mem_res);
172 				rv = bus_space_subregion(bt,
173 				    rman_get_bushandle(sc->mem_res),
174 				    rman_get_start(res) -
175 				    rman_get_start(sc->mem_res),
176 				    rman_get_size(res), &bh);
177 				if (rv != 0)
178 					return (rv);
179 				rman_set_bustag(res, bt);
180 				rman_set_bushandle(res, bh);
181 				return (rman_activate_resource(res));
182 			}
183 		}
184 		return (EINVAL);
185 	}
186 	return (bus_generic_activate_resource(bus, child, res));
187 }
188 
189 int
190 fman_release_resource(device_t bus, device_t child, struct resource *res)
191 {
192 	struct resource_list *rl;
193 	struct resource_list_entry *rle;
194 	int passthrough, rv;
195 
196 	passthrough = (device_get_parent(child) != bus);
197 	rl = BUS_GET_RESOURCE_LIST(bus, child);
198 	if (rman_get_type(res) != SYS_RES_IRQ) {
199 		if ((rman_get_flags(res) & RF_ACTIVE) != 0) {
200 			rv = bus_deactivate_resource(child, res);
201 			if (rv != 0)
202 				return (rv);
203 		}
204 		rv = rman_release_resource(res);
205 		if (rv != 0)
206 			return (rv);
207 		if (!passthrough) {
208 			rle = resource_list_find(rl, rman_get_type(res),
209 			    rman_get_rid(res));
210 			KASSERT(rle != NULL,
211 			    ("%s: resource entry not found!", __func__));
212 			KASSERT(rle->res != NULL,
213 			   ("%s: resource entry is not busy", __func__));
214 			rle->res = NULL;
215 		}
216 		return (0);
217 	}
218 	return (resource_list_release(rl, bus, child, res));
219 }
220 
221 struct resource *
222 fman_alloc_resource(device_t bus, device_t child, int type, int rid,
223     rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
224 {
225 	struct fman_softc *sc;
226 	struct resource_list *rl;
227 	struct resource_list_entry *rle = NULL;
228 	struct resource *res;
229 	int i, isdefault, passthrough;
230 
231 	isdefault = RMAN_IS_DEFAULT_RANGE(start, end);
232 	passthrough = (device_get_parent(child) != bus);
233 	sc = device_get_softc(bus);
234 	rl = BUS_GET_RESOURCE_LIST(bus, child);
235 	switch (type) {
236 	case SYS_RES_MEMORY:
237 		KASSERT(!(isdefault && passthrough),
238 		    ("%s: passthrough of default allocation", __func__));
239 		if (!passthrough) {
240 			rle = resource_list_find(rl, type, rid);
241 			if (rle == NULL)
242 				return (NULL);
243 			KASSERT(rle->res == NULL,
244 			    ("%s: resource entry is busy", __func__));
245 			if (isdefault) {
246 				start = rle->start;
247 				count = ulmax(count, rle->count);
248 				end = ulmax(rle->end, start + count - 1);
249 			}
250 		}
251 
252 		res = NULL;
253 		/* Map fman ranges to nexus ranges. */
254 		for (i = 0; i < sc->sc_base.nranges; i++) {
255 			if (start >= sc->sc_base.ranges[i].bus && end <
256 			    sc->sc_base.ranges[i].bus + sc->sc_base.ranges[i].size) {
257 				start += rman_get_start(sc->mem_res);
258 				end += rman_get_start(sc->mem_res);
259 				res = rman_reserve_resource(&sc->rman, start,
260 				    end, count, flags & ~RF_ACTIVE, child);
261 				if (res == NULL)
262 					return (NULL);
263 				rman_set_rid(res, rid);
264 				rman_set_type(res, type);
265 				if ((flags & RF_ACTIVE) != 0 && bus_activate_resource(
266 				    child, type, rid, res) != 0) {
267 					rman_release_resource(res);
268 					return (NULL);
269 				}
270 				break;
271 			}
272 		}
273 		if (!passthrough)
274 			rle->res = res;
275 		return (res);
276 	case SYS_RES_IRQ:
277 		return (resource_list_alloc(rl, bus, child, type, rid, start,
278 		    end, count, flags));
279 	}
280 	return (NULL);
281 }
282 
283 
284 static int
285 fman_get_revision_major(struct fman_softc *sc)
286 {
287 	uint32_t reg;
288 
289 	reg = bus_read_4(sc->mem_res, FM_IP_REV_1);
290 
291 	return ((reg & IP_REV_1_MAJ_M) >> IP_REV_1_MAJ_S);
292 }
293 
294 static int
295 fman_get_revision_minor(struct fman_softc *sc)
296 {
297 	uint32_t reg;
298 
299 	reg = bus_read_4(sc->mem_res, FM_IP_REV_1);
300 
301 	return ((reg & IP_REV_1_MIN_M));
302 }
303 
304 static void
305 fman_fill_soc_params(struct fman_softc *sc)
306 {
307 
308 	switch (sc->sc_revision_major) {
309 	case 2:
310 		sc->bmi_max_fifo_size = 160 * 1024;
311 		sc->iram_size = 64 * 1024;
312 		sc->dma_thresh_max_commq = 31;
313 		sc->dma_thresh_max_buf = 127;
314 		sc->qmi_max_tnums = 64;
315 		sc->qmi_def_tnums_thresh = 48;
316 		sc->bmi_max_tasks = 128;
317 		sc->max_open_dmas = 32;
318 		sc->dma_cam_num_entries = 32;
319 		sc->port_cgs = 256;
320 		sc->rx_ports = 5;
321 		sc->total_fifo_size = 100 * 1024;
322 		break;
323 	case 3:
324 		sc->bmi_max_fifo_size = 160 * 1024;
325 		sc->iram_size = 64 * 1024;
326 		sc->dma_thresh_max_commq = 31;
327 		sc->dma_thresh_max_buf = 127;
328 		sc->qmi_max_tnums = 64;
329 		sc->qmi_def_tnums_thresh = 48;
330 		sc->bmi_max_tasks = 128;
331 		sc->max_open_dmas = 32;
332 		sc->dma_cam_num_entries = 32;
333 		sc->port_cgs = 256;
334 		sc->rx_ports = 6;
335 		sc->total_fifo_size = 136 * 1024;
336 		break;
337 	case 6:
338 		sc->dma_thresh_max_commq = 31;
339 		sc->dma_thresh_max_buf = 127;
340 		sc->qmi_max_tnums = 64;
341 		sc->qmi_def_tnums_thresh = 48;
342 		sc->dma_cam_num_entries = 64;
343 		sc->port_cgs = 256;
344 		switch (sc->sc_revision_minor) {
345 		case 1:
346 		case 4:
347 			sc->bmi_max_fifo_size = 192 * 1024;
348 			sc->bmi_max_tasks = 64;
349 			sc->max_open_dmas = 32;
350 			sc->rx_ports = 5;
351 			sc->total_fifo_size = 156 * 1024;
352 			if (sc->sc_revision_minor == 1)
353 				sc->iram_size = 32 * 1024;
354 			else
355 				sc->iram_size = 64 * 1024;
356 			break;
357 		case 0:
358 		case 2:
359 		case 3:
360 			sc->bmi_max_fifo_size = 384 * 1024;
361 			sc->bmi_max_tasks = 128;
362 			sc->max_open_dmas = 84;
363 			sc->rx_ports = 8;
364 			sc->iram_size = 64 * 1024;
365 			sc->total_fifo_size = 295 * 1024;
366 			break;
367 		default:
368 			device_printf(sc->sc_base.dev,
369 			    "Unsupported FManv3 revision: %d\n",
370 			    sc->sc_revision_minor);
371 			break;
372 		}
373 		break;
374 	default:
375 		device_printf(sc->sc_base.dev,
376 		    "Unsupported FMan version: %d\n", sc->sc_revision_major);
377 		break;
378 	}
379 }
380 
381 static int
382 fman_reset(struct fman_softc *sc)
383 {
384 	unsigned int count;
385 
386 	if (sc->sc_revision_major < 6) {
387 		bus_write_4(sc->mem_res, FM_RSTC, FM_RSTC_FM_RESET);
388 		count = 100;
389 		do {
390 			DELAY(1);
391 		} while ((bus_read_4(sc->mem_res, FM_RSTC) & FM_RSTC_FM_RESET) &&
392 		    --count);
393 		if (count == 0)
394 			return (EBUSY);
395 		return (0);
396 	} else {
397 #ifdef __powerpc__
398 		phandle_t node;
399 		u_long base, size;
400 		uint32_t devdisr2;
401 #define	GUTS_DEVDISR2	0x0074
402 #define	DEVDISR2_FMAN1	0xfcc00000
403 #define	DEVDISR2_FMAN2	0x000fcc00
404 
405 		node = ofw_bus_get_node(device_get_parent(sc->sc_base.dev));
406 		node = fdt_find_compatible(node, "fsl,qoriq-device-config-2.0",
407 		    false);
408 
409 		if (node == 0) {
410 			device_printf(sc->sc_base.dev,
411 			    "missing device-config node in FDT.  Cannot reset FMAN");
412 			return (0);
413 		}
414 		fdt_regsize(node, &base, &size);
415 
416 		devdisr2 = ccsr_read4(ccsrbar_va + base + GUTS_DEVDISR2);
417 		if (sc->fm_id == 0)
418 			ccsr_write4(ccsrbar_va + base + GUTS_DEVDISR2,
419 			    devdisr2 & ~DEVDISR2_FMAN1);
420 		else
421 			ccsr_write4(ccsrbar_va + base + GUTS_DEVDISR2,
422 			    devdisr2 & ~DEVDISR2_FMAN2);
423 #endif
424 		bus_write_4(sc->mem_res, FM_RSTC, FM_RSTC_FM_RESET);
425 		count = 100;
426 		do {
427 			DELAY(1);
428 		} while ((bus_read_4(sc->mem_res, FM_RSTC) & FM_RSTC_FM_RESET) &&
429 		    --count);
430 #ifdef __powerpc__
431 		ccsr_write4(ccsrbar_va + base + GUTS_DEVDISR2, devdisr2);
432 #endif
433 		if (count == 0)
434 			return (EBUSY);
435 		return (0);
436 	}
437 }
438 
439 static int
440 fman_clear_iram(struct fman_softc *sc)
441 {
442 #ifdef notyet
443 	int i;
444 
445 	/*
446 	 * TODO: Allow clearing the IRAM and loading new firmware.  Currently
447 	 * this is not supported, so assume that there's already firmware
448 	 * loaded, and don't clear it just yet.
449 	 */
450 	bus_write_4(sc->mem_res, IRAM_ADDR, IADD_AIE);
451 	for (i = 0; i < 100 && bus_read_4(sc->mem_res, IRAM_ADDR) != IADD_AIE; i++)
452 		DELAY(1);
453 
454 	if (i == 100)
455 		return (EBUSY);
456 
457 	for (i = 0; i < sc->iram_size / 4; i++)
458 		bus_write_4(sc->mem_res, IRAM_DATA, 0xffffffff);
459 
460 	bus_write_4(sc->mem_res, IRAM_ADDR, sc->iram_size - 4);
461 	for (i = 0; i < 100 &&
462 	    bus_read_4(sc->mem_res, IRAM_DATA) != 0xffffffff; i++)
463 		DELAY(1);
464 
465 	if (i == 100)
466 		return (EBUSY);
467 #endif
468 
469 	return (0);
470 }
471 
472 static int
473 fman_dma_init(struct fman_softc *sc)
474 {
475 	vmem_addr_t addr;
476 	uint32_t reg;
477 	int err;
478 
479 	reg = bus_read_4(sc->mem_res, FMDM_SR);
480 	bus_write_4(sc->mem_res, FMDM_SR, reg | SR_BER);
481 	reg = bus_read_4(sc->mem_res, FMDM_MR) & ~MR_CEN_M;
482 	reg |= ((sc->dma_cam_num_entries / DMA_CAM_UNITS) - 1) << MR_CEN_S;
483 	bus_write_4(sc->mem_res, FMDM_MR, reg);
484 
485 	err = vmem_xalloc(sc->muram_vmem,
486 	    sc->dma_cam_num_entries * DMA_CAM_SIZE, DMA_CAM_ALIGN, 0, 0,
487 	    VMEM_ADDR_MIN, VMEM_ADDR_MAX, M_BESTFIT | M_WAITOK, &addr);
488 	if (err != 0)
489 		device_printf(sc->sc_base.dev,
490 		    "failed to allocate DMA buffer\n");
491 	reg = addr;
492 	bus_write_4(sc->mem_res, FMDM_EBCR, reg);
493 	return (0);
494 }
495 
496 static int
497 fman_bmi_init(struct fman_softc *sc)
498 {
499 	uint32_t reg;
500 
501 	reg = sc->bmi_fifo_base / FMAN_BMI_FIFO_ALIGN;
502 	reg |= (sc->total_fifo_size / FMAN_BMI_FIFO_UNITS - 1) << FBPS_S;
503 	bus_write_4(sc->mem_res, FMBM_CFG1, reg);
504 
505 	reg = ((sc->bmi_max_tasks - 1) << TNTSKS_S) & TNTSKS_M;
506 	//bus_write_4(sc->mem_res, FMBM_CFG2, reg);
507 
508 	bus_write_4(sc->mem_res, FMBM_IEVR,
509 	    IEVR_SPEC | IEVR_LEC | IEVR_STEC | IEVR_DEC);
510 
511 	bus_write_4(sc->mem_res, FMBM_IER,
512 	    IER_SPECE | IER_LECE | IER_STECE | IER_DECE);
513 
514 	return (0);
515 }
516 
517 static int
518 fman_qmi_init(struct fman_softc *sc)
519 {
520 	bus_write_4(sc->mem_res, FMQM_EIE, EIE_DEE | EIE_DFUPE);
521 	bus_write_4(sc->mem_res, FMQM_EIEN, EIEN_DEE | EIEN_DFUPE);
522 	return (0);
523 }
524 
525 static void
526 fman_hwp_init(struct fman_softc *sc)
527 {
528 	/* Start up the parser */
529 	bus_write_4(sc->mem_res, FMPR_RPIMAC, HWP_RPIMAC_PEN);
530 }
531 
532 static int
533 fman_enable(struct fman_softc *sc)
534 {
535 	bus_write_4(sc->mem_res, FMBM_INIT, INIT_STR);
536 	bus_write_4(sc->mem_res, FMQM_GC, 0xc0000000 |
537 	    GC_STEN | (sc->qmi_def_tnums_thresh << GC_ENQ_THR_S) |
538 	    sc->qmi_def_tnums_thresh);
539 
540 	return (0);
541 }
542 
543 /*
544  * Enable timestamp counting.  Matching Freescale's reference code, generate the
545  * timestamp incrementer to be roughly 256MHz, such that bit 23 would update
546  * every microsecond.
547  */
548 static int
549 fman_enable_timestamp(struct fman_softc *sc)
550 {
551 	uint64_t frac;
552 	uint32_t clock = fman_get_clock(sc) / 1000000;
553 	uint32_t intgr, tmp;
554 	uint32_t ts_freq = 1 << FM_TIMESTAMP_1US_BIT;
555 
556 	intgr = ts_freq / clock;
557 
558 	frac = ((uint64_t)ts_freq << 16) - ((uint64_t)intgr << 16) * clock;
559 	frac = (frac % clock ? 1 : 0) + (frac / clock);
560 
561 	tmp = (intgr << TSC2_TSIV_INT_S) | (uint32_t)frac;
562 
563 	bus_write_4(sc->mem_res, FMFP_TSC2, tmp);
564 	bus_write_4(sc->mem_res, FMFP_TSC1, TSC1_TEN);
565 
566 	return (0);
567 }
568 
569 static int
570 fman_keygen_init(struct fman_softc *sc)
571 {
572 	/* TODO: keygen */
573 	return (0);
574 }
575 
576 static int
577 fman_fpm_init(struct fman_softc *sc)
578 {
579 	/* Clear all events, and enable interrupts. */
580 	bus_write_4(sc->mem_res, FMFP_EE,
581 	    EE_DECC | EE_STL | EE_SECC | EE_EHM |
582 	    EE_DECC_EN | EE_STL_EN | EE_SECC_EN);
583 
584 	bus_write_4(sc->mem_res, FMFP_CEV0, 0xffffffff);
585 	bus_write_4(sc->mem_res, FMFP_CEV1, 0xffffffff);
586 	bus_write_4(sc->mem_res, FMFP_CEV2, 0xffffffff);
587 	bus_write_4(sc->mem_res, FMFP_CEV3, 0xffffffff);
588 
589 	bus_write_4(sc->mem_res, FM_RCR, RCR_FEE | RCR_IEE);
590 
591 	return (0);
592 }
593 
594 static int
595 fman_init(struct fman_softc *sc)
596 {
597 	vmem_addr_t base_addr;
598 	sc->sc_revision_major = fman_get_revision_major(sc);
599 	sc->sc_revision_minor = fman_get_revision_minor(sc);
600 
601 	if (bootverbose)
602 		device_printf(sc->sc_base.dev, "Hardware version: %d.%d.\n",
603 		    sc->sc_revision_major, sc->sc_revision_minor);
604 
605 	fman_fill_soc_params(sc);
606 	bus_set_region_4(sc->mem_res, FMAN_CGP_OFFSET, 0, sc->port_cgs / 4);
607 
608 	if (fman_reset(sc) != 0)
609 		goto err;
610 
611 	if (fman_clear_iram(sc) != 0)
612 		goto err;
613 
614 	if (fman_dma_init(sc) != 0)
615 		goto err;
616 
617 	fman_fpm_init(sc);
618 
619 	vmem_alloc(sc->muram_vmem, sc->total_fifo_size, M_BESTFIT | M_WAITOK,
620 	    &base_addr);
621 	sc->bmi_fifo_base = base_addr;
622 
623 	fman_bmi_init(sc);
624 	fman_qmi_init(sc);
625 	fman_hwp_init(sc);
626 	if (fman_keygen_init(sc) != 0)
627 		goto err;
628 
629 	if (fman_enable(sc) != 0)
630 		goto err;
631 
632 	fman_enable_timestamp(sc);
633 
634 	return (0);
635 err:
636 	return (ENXIO);
637 }
638 
639 void
640 fman_get_revision(device_t dev, int *major, int *minor)
641 {
642 	struct fman_softc *sc = device_get_softc(dev);
643 
644 	if (major)
645 		*major = sc->sc_revision_major;
646 	if (minor)
647 		*minor = sc->sc_revision_minor;
648 }
649 
650 /** @} */
651 
652 static int
653 fman_init_muram(struct fman_softc *sc)
654 {
655 	u_long base, size;
656 	phandle_t node;
657 
658 	node = ofw_bus_get_node(sc->sc_base.dev);
659 	for (node = OF_child(node); node != 0; node = OF_peer(node)) {
660 		char compat[255];
661 
662 		if (OF_getprop(node, "compatible", compat, sizeof(compat)) < 0)
663 			continue;
664 		if (strcmp(compat, "fsl,fman-muram") == 0)
665 			break;
666 	}
667 	if (node == 0) {
668 		device_printf(sc->sc_base.dev, "no muram node\n");
669 		return (ENXIO);
670 	}
671 	if (fdt_regsize(node, &base, &size) != 0) {
672 		device_printf(sc->sc_base.dev, "failed to get muram reg\n");
673 		return (ENXIO);
674 	}
675 	sc->muram_vmem = vmem_create("MURAM",
676 	    base, size, 1, 0, M_WAITOK);
677 
678 	return (0);
679 }
680 
681 int
682 fman_attach(device_t dev)
683 {
684 	struct fman_softc *sc;
685 	pcell_t qchan_range[2];
686 	pcell_t cell;
687 	phandle_t node;
688 
689 	sc = device_get_softc(dev);
690 	sc->sc_base.dev = dev;
691 
692 	cell = 0;
693 	node = ofw_bus_get_node(dev);
694 	OF_getencprop(node, "cell-index", &cell, sizeof(cell));
695 	sc->fm_id = cell;
696 
697 	if (OF_getencprop(node, "fsl,qman-channel-range", qchan_range,
698 	    sizeof(qchan_range)) <= 0) {
699 		device_printf(dev, "Missing QMan channel range property!\n");
700 		return (ENXIO);
701 	}
702 	sc->qman_chan_base = qchan_range[0];
703 	sc->qman_chan_count = qchan_range[1];
704 	sc->mem_rid = 0;
705 	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->mem_rid,
706 	    RF_ACTIVE | RF_SHAREABLE);
707 	if (!sc->mem_res) {
708 		device_printf(dev, "could not allocate memory.\n");
709 		return (ENXIO);
710 	}
711 
712 	sc->irq_rid = 0;
713 	sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid,
714 	    RF_ACTIVE);
715 	if (!sc->irq_res) {
716 		device_printf(dev, "could not allocate interrupt.\n");
717 		goto err;
718 	}
719 
720 	if (bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE,
721 	    NULL, fman_intr, sc, &sc->irq_cookie) != 0) {
722 		device_printf(dev, "error setting up interrupt handler.\n");
723 		goto err;
724 	}
725 
726 	sc->err_irq_rid = 1;
727 	sc->err_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
728 	    &sc->err_irq_rid, RF_ACTIVE | RF_SHAREABLE);
729 	if (!sc->err_irq_res) {
730 		device_printf(dev, "could not allocate error interrupt.\n");
731 		goto err;
732 	}
733 
734 	/* Initialize the simplebus part of things */
735 	sc->rman.rm_type = RMAN_ARRAY;
736 	sc->rman.rm_descr = "FMan range";
737 	rman_init_from_resource(&sc->rman, sc->mem_res);
738 	simplebus_attach_impl(sc->sc_base.dev);
739 
740 	if (fman_init_muram(sc) != 0)
741 		goto err;
742 
743 	/* TODO: Interrupts... */
744 
745 	if (fman_init(sc) != 0)
746 		goto err;
747 
748 	bus_attach_children(dev);
749 	return (0);
750 
751 err:
752 	fman_detach(dev);
753 	return (ENXIO);
754 }
755 
756 int
757 fman_detach(device_t dev)
758 {
759 	struct fman_softc *sc;
760 	int rv;
761 
762 	rv = simplebus_detach(dev);
763 
764 	if (rv != 0)
765 		return (rv);
766 
767 	sc = device_get_softc(dev);
768 
769 	if (sc->mem_res) {
770 		bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid,
771 		    sc->mem_res);
772 	}
773 
774 	if (sc->irq_res) {
775 		bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid,
776 		    sc->irq_res);
777 	}
778 
779 	if (sc->irq_res) {
780 		bus_release_resource(dev, SYS_RES_IRQ, sc->err_irq_rid,
781 		    sc->err_irq_res);
782 	}
783 
784 	if (sc->muram_vmem != NULL)
785 		vmem_destroy(sc->muram_vmem);
786 
787 	return (0);
788 }
789 
790 int
791 fman_suspend(device_t dev)
792 {
793 
794 	return (0);
795 }
796 
797 int
798 fman_resume_dev(device_t dev)
799 {
800 
801 	return (0);
802 }
803 
804 int
805 fman_shutdown(device_t dev)
806 {
807 
808 	return (0);
809 }
810 
811 static void
812 fman_intr(void *arg)
813 {
814 	/* TODO: All FMAN interrupts */
815 }
816 
817 int
818 fman_qman_channel_id(device_t dev, int port)
819 {
820 	struct fman_softc *sc;
821 	int i;
822 
823 	sc = device_get_softc(dev);
824 	if (sc->sc_revision_major >= 6) {
825 		static const int qman_port_id[] = {
826 		    0x30, 0x31, 0x28, 0x29, 0x2a, 0x2b,
827 		    0x2c, 0x2d, 0x02, 0x03, 0x04, 0x05, 0x07, 0x07
828 		};
829 		for (i = 0; i < sc->qman_chan_count; i++) {
830 			if (qman_port_id[i] == port)
831 				return (sc->qman_chan_base + i);
832 		}
833 	} else {
834 		static const int qman_port_id[] = {
835 		    0x31, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x01,
836 		    0x02, 0x03, 0x04, 0x05, 0x07, 0x07
837 		};
838 		for (i = 0; i < sc->qman_chan_count; i++) {
839 			if (qman_port_id[i] == port)
840 				return (sc->qman_chan_base + i);
841 		}
842 	}
843 
844 	return (0);
845 }
846 
847 size_t
848 fman_get_bmi_max_fifo_size(device_t dev)
849 {
850 	struct fman_softc *sc = device_get_softc(dev);
851 
852 	return (sc->bmi_max_fifo_size);
853 }
854 
855 int
856 fman_reset_mac(device_t dev, int mac_id)
857 {
858 	struct fman_softc *sc = device_get_softc(dev);
859 	int timeout = 100;
860 	uint32_t mask;
861 
862 	if (mac_id < 0 || mac_id > 9)
863 		return (EINVAL);
864 
865 	/* MAC bits start at bit 1 for MAC0, and go down */
866 	mask = (1 << (30 - mac_id));
867 	bus_write_4(sc->mem_res, FM_RSTC, mask);
868 	while ((bus_read_4(sc->mem_res, FM_RSTC) & mask) && --timeout)
869 		DELAY(10);
870 
871 	if (timeout == 0)
872 		return (EIO);
873 
874 	return (0);
875 }
876 
877 static int
878 fman_set_port_tasks(struct fman_softc *sc, int port_id,
879     uint8_t tasks, uint8_t extra)
880 {
881 	uint32_t reg;
882 
883 	reg = bus_read_4(sc->mem_res, FMBM_PP(port_id));
884 
885 	reg &= ~(PP_MXT_M | PP_EXT_M);
886 	reg |= ((uint32_t)(tasks - 1) << PP_MXT_S) |
887 	    ((uint32_t)extra << PP_EXT_S);
888 	bus_write_4(sc->mem_res, FMBM_PP(port_id), reg);
889 
890 	return (0);
891 }
892 
893 static int
894 fman_set_port_fifo_size(struct fman_softc *sc, int port_id,
895     uint32_t fifo_size, uint32_t extra)
896 {
897 	uint32_t reg;
898 
899 	reg = (fifo_size / FMAN_BMI_FIFO_UNITS - 1) |
900 	    ((extra / FMAN_BMI_FIFO_UNITS) << PFS_EXBS_S);
901 
902 	/* TODO: Make sure fifo size doesn't overrun */
903 	/* See Linux driver, fman set_size_of_fifo */
904 
905 	bus_write_4(sc->mem_res, FMBM_PFS(port_id), reg);
906 	return (0);
907 }
908 
909 static int
910 fman_set_port_dmas(struct fman_softc *sc, int port_id,
911     int open_dmas, int extra_dmas)
912 {
913 	/* TODO: set port DMAs */
914 	return (0);
915 }
916 
917 static void
918 fman_set_port_liodn(struct fman_softc *sc, int port_id, uint32_t liodn)
919 {
920 	uint32_t reg;
921 
922 	reg = bus_read_4(sc->mem_res, FMDM_PLRn(port_id));
923 	reg &= ~PLRN_LIODN_M(port_id);
924 	reg |= liodn << PLRN_LIODN_S(port_id);
925 	bus_write_4(sc->mem_res, FMDM_PLRn(port_id), reg);
926 }
927 
928 int
929 fman_set_port_params(device_t dev, struct fman_port_init_params *params)
930 {
931 	struct fman_softc *sc = device_get_softc(dev);
932 	int error;
933 
934 	error = fman_set_port_tasks(sc, params->port_id,
935 	    params->num_tasks, params->extra_tasks);
936 
937 	if (error != 0)
938 		return (error);
939 
940 	if (!params->is_rx_port) {
941 	}
942 	error = fman_set_port_fifo_size(sc, params->port_id, params->fifo_size,
943 	    params->extra_fifo_size);
944 
945 	if (error != 0)
946 		return (error);
947 
948 	error = fman_set_port_dmas(sc, params->port_id,
949 	    params->open_dmas, params->extra_dmas);
950 
951 	if (error != 0)
952 		return (error);
953 
954 	fman_set_port_liodn(sc, params->port_id, params->liodn);
955 
956 	return (0);
957 }
958 
959 /** @} */
960