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
fman_activate_resource(device_t bus,device_t child,struct resource * res)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
fman_release_resource(device_t bus,device_t child,struct resource * res)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 *
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)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
fman_get_revision_major(struct fman_softc * sc)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
fman_get_revision_minor(struct fman_softc * sc)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
fman_fill_soc_params(struct fman_softc * sc)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
fman_reset(struct fman_softc * sc)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
fman_clear_iram(struct fman_softc * sc)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
fman_dma_init(struct fman_softc * sc)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
fman_bmi_init(struct fman_softc * sc)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
fman_qmi_init(struct fman_softc * sc)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
fman_hwp_init(struct fman_softc * sc)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
fman_enable(struct fman_softc * sc)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
fman_enable_timestamp(struct fman_softc * sc)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
fman_keygen_init(struct fman_softc * sc)570 fman_keygen_init(struct fman_softc *sc)
571 {
572 /* TODO: keygen */
573 return (0);
574 }
575
576 static int
fman_fpm_init(struct fman_softc * sc)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
fman_init(struct fman_softc * sc)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
fman_get_revision(device_t dev,int * major,int * minor)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
fman_init_muram(struct fman_softc * sc)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
fman_attach(device_t dev)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
fman_detach(device_t dev)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
fman_suspend(device_t dev)791 fman_suspend(device_t dev)
792 {
793
794 return (0);
795 }
796
797 int
fman_resume_dev(device_t dev)798 fman_resume_dev(device_t dev)
799 {
800
801 return (0);
802 }
803
804 int
fman_shutdown(device_t dev)805 fman_shutdown(device_t dev)
806 {
807
808 return (0);
809 }
810
811 static void
fman_intr(void * arg)812 fman_intr(void *arg)
813 {
814 /* TODO: All FMAN interrupts */
815 }
816
817 int
fman_qman_channel_id(device_t dev,int port)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
fman_get_bmi_max_fifo_size(device_t dev)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
fman_reset_mac(device_t dev,int mac_id)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
fman_set_port_tasks(struct fman_softc * sc,int port_id,uint8_t tasks,uint8_t extra)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
fman_set_port_fifo_size(struct fman_softc * sc,int port_id,uint32_t fifo_size,uint32_t extra)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
fman_set_port_dmas(struct fman_softc * sc,int port_id,int open_dmas,int extra_dmas)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
fman_set_port_liodn(struct fman_softc * sc,int port_id,uint32_t liodn)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
fman_set_port_params(device_t dev,struct fman_port_init_params * params)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