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