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