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