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