Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

fsl/qe: setup clock source for TDM mode

Add tdm clock configuration in both qe clock system and ucc
fast controller.

Signed-off-by: Zhao Qiang <qiang.zhao@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Zhao Qiang and committed by
David S. Miller
bb8b2062 68f047e3

+507
+450
drivers/soc/fsl/qe/ucc.c
··· 25 25 #include <soc/fsl/qe/qe.h> 26 26 #include <soc/fsl/qe/ucc.h> 27 27 28 + #define UCC_TDM_NUM 8 29 + #define RX_SYNC_SHIFT_BASE 30 30 + #define TX_SYNC_SHIFT_BASE 14 31 + #define RX_CLK_SHIFT_BASE 28 32 + #define TX_CLK_SHIFT_BASE 12 33 + 28 34 int ucc_set_qe_mux_mii_mng(unsigned int ucc_num) 29 35 { 30 36 unsigned long flags; ··· 213 207 214 208 clrsetbits_be32(cmxucr, QE_CMXUCR_TX_CLK_SRC_MASK << shift, 215 209 clock_bits << shift); 210 + 211 + return 0; 212 + } 213 + 214 + static int ucc_get_tdm_common_clk(u32 tdm_num, enum qe_clock clock) 215 + { 216 + int clock_bits = -EINVAL; 217 + 218 + /* 219 + * for TDM[0, 1, 2, 3], TX and RX use common 220 + * clock source BRG3,4 and CLK1,2 221 + * for TDM[4, 5, 6, 7], TX and RX use common 222 + * clock source BRG12,13 and CLK23,24 223 + */ 224 + switch (tdm_num) { 225 + case 0: 226 + case 1: 227 + case 2: 228 + case 3: 229 + switch (clock) { 230 + case QE_BRG3: 231 + clock_bits = 1; 232 + break; 233 + case QE_BRG4: 234 + clock_bits = 2; 235 + break; 236 + case QE_CLK1: 237 + clock_bits = 4; 238 + break; 239 + case QE_CLK2: 240 + clock_bits = 5; 241 + break; 242 + default: 243 + break; 244 + } 245 + break; 246 + case 4: 247 + case 5: 248 + case 6: 249 + case 7: 250 + switch (clock) { 251 + case QE_BRG12: 252 + clock_bits = 1; 253 + break; 254 + case QE_BRG13: 255 + clock_bits = 2; 256 + break; 257 + case QE_CLK23: 258 + clock_bits = 4; 259 + break; 260 + case QE_CLK24: 261 + clock_bits = 5; 262 + break; 263 + default: 264 + break; 265 + } 266 + break; 267 + default: 268 + break; 269 + } 270 + 271 + return clock_bits; 272 + } 273 + 274 + static int ucc_get_tdm_rx_clk(u32 tdm_num, enum qe_clock clock) 275 + { 276 + int clock_bits = -EINVAL; 277 + 278 + switch (tdm_num) { 279 + case 0: 280 + switch (clock) { 281 + case QE_CLK3: 282 + clock_bits = 6; 283 + break; 284 + case QE_CLK8: 285 + clock_bits = 7; 286 + break; 287 + default: 288 + break; 289 + } 290 + break; 291 + case 1: 292 + switch (clock) { 293 + case QE_CLK5: 294 + clock_bits = 6; 295 + break; 296 + case QE_CLK10: 297 + clock_bits = 7; 298 + break; 299 + default: 300 + break; 301 + } 302 + break; 303 + case 2: 304 + switch (clock) { 305 + case QE_CLK7: 306 + clock_bits = 6; 307 + break; 308 + case QE_CLK12: 309 + clock_bits = 7; 310 + break; 311 + default: 312 + break; 313 + } 314 + break; 315 + case 3: 316 + switch (clock) { 317 + case QE_CLK9: 318 + clock_bits = 6; 319 + break; 320 + case QE_CLK14: 321 + clock_bits = 7; 322 + break; 323 + default: 324 + break; 325 + } 326 + break; 327 + case 4: 328 + switch (clock) { 329 + case QE_CLK11: 330 + clock_bits = 6; 331 + break; 332 + case QE_CLK16: 333 + clock_bits = 7; 334 + break; 335 + default: 336 + break; 337 + } 338 + break; 339 + case 5: 340 + switch (clock) { 341 + case QE_CLK13: 342 + clock_bits = 6; 343 + break; 344 + case QE_CLK18: 345 + clock_bits = 7; 346 + break; 347 + default: 348 + break; 349 + } 350 + break; 351 + case 6: 352 + switch (clock) { 353 + case QE_CLK15: 354 + clock_bits = 6; 355 + break; 356 + case QE_CLK20: 357 + clock_bits = 7; 358 + break; 359 + default: 360 + break; 361 + } 362 + break; 363 + case 7: 364 + switch (clock) { 365 + case QE_CLK17: 366 + clock_bits = 6; 367 + break; 368 + case QE_CLK22: 369 + clock_bits = 7; 370 + break; 371 + default: 372 + break; 373 + } 374 + break; 375 + } 376 + 377 + return clock_bits; 378 + } 379 + 380 + static int ucc_get_tdm_tx_clk(u32 tdm_num, enum qe_clock clock) 381 + { 382 + int clock_bits = -EINVAL; 383 + 384 + switch (tdm_num) { 385 + case 0: 386 + switch (clock) { 387 + case QE_CLK4: 388 + clock_bits = 6; 389 + break; 390 + case QE_CLK9: 391 + clock_bits = 7; 392 + break; 393 + default: 394 + break; 395 + } 396 + break; 397 + case 1: 398 + switch (clock) { 399 + case QE_CLK6: 400 + clock_bits = 6; 401 + break; 402 + case QE_CLK11: 403 + clock_bits = 7; 404 + break; 405 + default: 406 + break; 407 + } 408 + break; 409 + case 2: 410 + switch (clock) { 411 + case QE_CLK8: 412 + clock_bits = 6; 413 + break; 414 + case QE_CLK13: 415 + clock_bits = 7; 416 + break; 417 + default: 418 + break; 419 + } 420 + break; 421 + case 3: 422 + switch (clock) { 423 + case QE_CLK10: 424 + clock_bits = 6; 425 + break; 426 + case QE_CLK15: 427 + clock_bits = 7; 428 + break; 429 + default: 430 + break; 431 + } 432 + break; 433 + case 4: 434 + switch (clock) { 435 + case QE_CLK12: 436 + clock_bits = 6; 437 + break; 438 + case QE_CLK17: 439 + clock_bits = 7; 440 + break; 441 + default: 442 + break; 443 + } 444 + break; 445 + case 5: 446 + switch (clock) { 447 + case QE_CLK14: 448 + clock_bits = 6; 449 + break; 450 + case QE_CLK19: 451 + clock_bits = 7; 452 + break; 453 + default: 454 + break; 455 + } 456 + break; 457 + case 6: 458 + switch (clock) { 459 + case QE_CLK16: 460 + clock_bits = 6; 461 + break; 462 + case QE_CLK21: 463 + clock_bits = 7; 464 + break; 465 + default: 466 + break; 467 + } 468 + break; 469 + case 7: 470 + switch (clock) { 471 + case QE_CLK18: 472 + clock_bits = 6; 473 + break; 474 + case QE_CLK3: 475 + clock_bits = 7; 476 + break; 477 + default: 478 + break; 479 + } 480 + break; 481 + } 482 + 483 + return clock_bits; 484 + } 485 + 486 + /* tdm_num: TDM A-H port num is 0-7 */ 487 + static int ucc_get_tdm_rxtx_clk(enum comm_dir mode, u32 tdm_num, 488 + enum qe_clock clock) 489 + { 490 + int clock_bits; 491 + 492 + clock_bits = ucc_get_tdm_common_clk(tdm_num, clock); 493 + if (clock_bits > 0) 494 + return clock_bits; 495 + if (mode == COMM_DIR_RX) 496 + clock_bits = ucc_get_tdm_rx_clk(tdm_num, clock); 497 + if (mode == COMM_DIR_TX) 498 + clock_bits = ucc_get_tdm_tx_clk(tdm_num, clock); 499 + return clock_bits; 500 + } 501 + 502 + static u32 ucc_get_tdm_clk_shift(enum comm_dir mode, u32 tdm_num) 503 + { 504 + u32 shift; 505 + 506 + shift = (mode == COMM_DIR_RX) ? RX_CLK_SHIFT_BASE : TX_CLK_SHIFT_BASE; 507 + if (tdm_num < 4) 508 + shift -= tdm_num * 4; 509 + else 510 + shift -= (tdm_num - 4) * 4; 511 + 512 + return shift; 513 + } 514 + 515 + int ucc_set_tdm_rxtx_clk(u32 tdm_num, enum qe_clock clock, 516 + enum comm_dir mode) 517 + { 518 + int clock_bits; 519 + u32 shift; 520 + struct qe_mux __iomem *qe_mux_reg; 521 + __be32 __iomem *cmxs1cr; 522 + 523 + qe_mux_reg = &qe_immr->qmx; 524 + 525 + if (tdm_num > 7 || tdm_num < 0) 526 + return -EINVAL; 527 + 528 + /* The communications direction must be RX or TX */ 529 + if (mode != COMM_DIR_RX && mode != COMM_DIR_TX) 530 + return -EINVAL; 531 + 532 + clock_bits = ucc_get_tdm_rxtx_clk(mode, tdm_num, clock); 533 + if (clock_bits < 0) 534 + return -EINVAL; 535 + 536 + shift = ucc_get_tdm_clk_shift(mode, tdm_num); 537 + 538 + cmxs1cr = (tdm_num < 4) ? &qe_mux_reg->cmxsi1cr_l : 539 + &qe_mux_reg->cmxsi1cr_h; 540 + 541 + qe_clrsetbits32(cmxs1cr, QE_CMXUCR_TX_CLK_SRC_MASK << shift, 542 + clock_bits << shift); 543 + 544 + return 0; 545 + } 546 + 547 + static int ucc_get_tdm_sync_source(u32 tdm_num, enum qe_clock clock, 548 + enum comm_dir mode) 549 + { 550 + int source = -EINVAL; 551 + 552 + if (mode == COMM_DIR_RX && clock == QE_RSYNC_PIN) { 553 + source = 0; 554 + return source; 555 + } 556 + if (mode == COMM_DIR_TX && clock == QE_TSYNC_PIN) { 557 + source = 0; 558 + return source; 559 + } 560 + 561 + switch (tdm_num) { 562 + case 0: 563 + case 1: 564 + switch (clock) { 565 + case QE_BRG9: 566 + source = 1; 567 + break; 568 + case QE_BRG10: 569 + source = 2; 570 + break; 571 + default: 572 + break; 573 + } 574 + break; 575 + case 2: 576 + case 3: 577 + switch (clock) { 578 + case QE_BRG9: 579 + source = 1; 580 + break; 581 + case QE_BRG11: 582 + source = 2; 583 + break; 584 + default: 585 + break; 586 + } 587 + break; 588 + case 4: 589 + case 5: 590 + switch (clock) { 591 + case QE_BRG13: 592 + source = 1; 593 + break; 594 + case QE_BRG14: 595 + source = 2; 596 + break; 597 + default: 598 + break; 599 + } 600 + break; 601 + case 6: 602 + case 7: 603 + switch (clock) { 604 + case QE_BRG13: 605 + source = 1; 606 + break; 607 + case QE_BRG15: 608 + source = 2; 609 + break; 610 + default: 611 + break; 612 + } 613 + break; 614 + } 615 + 616 + return source; 617 + } 618 + 619 + static u32 ucc_get_tdm_sync_shift(enum comm_dir mode, u32 tdm_num) 620 + { 621 + u32 shift; 622 + 623 + shift = (mode == COMM_DIR_RX) ? RX_SYNC_SHIFT_BASE : RX_SYNC_SHIFT_BASE; 624 + shift -= tdm_num * 2; 625 + 626 + return shift; 627 + } 628 + 629 + int ucc_set_tdm_rxtx_sync(u32 tdm_num, enum qe_clock clock, 630 + enum comm_dir mode) 631 + { 632 + int source; 633 + u32 shift; 634 + struct qe_mux *qe_mux_reg; 635 + 636 + qe_mux_reg = &qe_immr->qmx; 637 + 638 + if (tdm_num >= UCC_TDM_NUM) 639 + return -EINVAL; 640 + 641 + /* The communications direction must be RX or TX */ 642 + if (mode != COMM_DIR_RX && mode != COMM_DIR_TX) 643 + return -EINVAL; 644 + 645 + source = ucc_get_tdm_sync_source(tdm_num, clock, mode); 646 + if (source < 0) 647 + return -EINVAL; 648 + 649 + shift = ucc_get_tdm_sync_shift(mode, tdm_num); 650 + 651 + qe_clrsetbits32(&qe_mux_reg->cmxsi1syr, 652 + QE_CMXUCR_TX_CLK_SRC_MASK << shift, 653 + source << shift); 216 654 217 655 return 0; 218 656 }
+36
drivers/soc/fsl/qe/ucc_fast.c
··· 327 327 ucc_fast_free(uccf); 328 328 return -EINVAL; 329 329 } 330 + } else { 331 + /* tdm Rx clock routing */ 332 + if ((uf_info->rx_clock != QE_CLK_NONE) && 333 + ucc_set_tdm_rxtx_clk(uf_info->tdm_num, uf_info->rx_clock, 334 + COMM_DIR_RX)) { 335 + pr_err("%s: illegal value for RX clock", __func__); 336 + ucc_fast_free(uccf); 337 + return -EINVAL; 338 + } 339 + 340 + /* tdm Tx clock routing */ 341 + if ((uf_info->tx_clock != QE_CLK_NONE) && 342 + ucc_set_tdm_rxtx_clk(uf_info->tdm_num, uf_info->tx_clock, 343 + COMM_DIR_TX)) { 344 + pr_err("%s: illegal value for TX clock", __func__); 345 + ucc_fast_free(uccf); 346 + return -EINVAL; 347 + } 348 + 349 + /* tdm Rx sync clock routing */ 350 + if ((uf_info->rx_sync != QE_CLK_NONE) && 351 + ucc_set_tdm_rxtx_sync(uf_info->tdm_num, uf_info->rx_sync, 352 + COMM_DIR_RX)) { 353 + pr_err("%s: illegal value for RX clock", __func__); 354 + ucc_fast_free(uccf); 355 + return -EINVAL; 356 + } 357 + 358 + /* tdm Tx sync clock routing */ 359 + if ((uf_info->tx_sync != QE_CLK_NONE) && 360 + ucc_set_tdm_rxtx_sync(uf_info->tdm_num, uf_info->tx_sync, 361 + COMM_DIR_TX)) { 362 + pr_err("%s: illegal value for TX clock", __func__); 363 + ucc_fast_free(uccf); 364 + return -EINVAL; 365 + } 330 366 } 331 367 332 368 /* Set interrupt mask register at UCC level. */
+16
include/soc/fsl/qe/qe.h
··· 244 244 #define qe_muram_addr cpm_muram_addr 245 245 #define qe_muram_offset cpm_muram_offset 246 246 247 + #define qe_setbits32(_addr, _v) iowrite32be(ioread32be(_addr) | (_v), (_addr)) 248 + #define qe_clrbits32(_addr, _v) iowrite32be(ioread32be(_addr) & ~(_v), (_addr)) 249 + 250 + #define qe_setbits16(_addr, _v) iowrite16be(ioread16be(_addr) | (_v), (_addr)) 251 + #define qe_clrbits16(_addr, _v) iowrite16be(ioread16be(_addr) & ~(_v), (_addr)) 252 + 253 + #define qe_setbits8(_addr, _v) iowrite8(ioread8(_addr) | (_v), (_addr)) 254 + #define qe_clrbits8(_addr, _v) iowrite8(ioread8(_addr) & ~(_v), (_addr)) 255 + 256 + #define qe_clrsetbits32(addr, clear, set) \ 257 + iowrite32be((ioread32be(addr) & ~(clear)) | (set), (addr)) 258 + #define qe_clrsetbits16(addr, clear, set) \ 259 + iowrite16be((ioread16be(addr) & ~(clear)) | (set), (addr)) 260 + #define qe_clrsetbits8(addr, clear, set) \ 261 + iowrite8((ioread8(addr) & ~(clear)) | (set), (addr)) 262 + 247 263 /* Structure that defines QE firmware binary files. 248 264 * 249 265 * See Documentation/powerpc/qe_firmware.txt for a description of these
+4
include/soc/fsl/qe/ucc.h
··· 41 41 42 42 int ucc_set_qe_mux_rxtx(unsigned int ucc_num, enum qe_clock clock, 43 43 enum comm_dir mode); 44 + int ucc_set_tdm_rxtx_clk(unsigned int tdm_num, enum qe_clock clock, 45 + enum comm_dir mode); 46 + int ucc_set_tdm_rxtx_sync(unsigned int tdm_num, enum qe_clock clock, 47 + enum comm_dir mode); 44 48 45 49 int ucc_mux_set_grant_tsa_bkpt(unsigned int ucc_num, int set, u32 mask); 46 50
+1
include/soc/fsl/qe/ucc_fast.h
··· 118 118 /* Fast UCC initialization structure */ 119 119 struct ucc_fast_info { 120 120 int ucc_num; 121 + int tdm_num; 121 122 enum qe_clock rx_clock; 122 123 enum qe_clock tx_clock; 123 124 enum qe_clock rx_sync;