1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2014-2026 NVIDIA CORPORATION. All rights reserved. 4 */ 5 6 #include <linux/device.h> 7 #include <linux/of.h> 8 #include <linux/mm.h> 9 10 #include <dt-bindings/memory/tegra114-mc.h> 11 12 #include "mc.h" 13 14 static const struct tegra_mc_client tegra114_mc_clients[] = { 15 { 16 .id = 0x00, 17 .name = "ptcr", 18 .swgroup = TEGRA_SWGROUP_PTC, 19 .regs = { 20 .la = { 21 .reg = 0x34c, 22 .shift = 0, 23 .mask = 0xff, 24 .def = 0x0, 25 }, 26 }, 27 }, { 28 .id = 0x01, 29 .name = "display0a", 30 .swgroup = TEGRA_SWGROUP_DC, 31 .regs = { 32 .smmu = { 33 .reg = 0x228, 34 .bit = 1, 35 }, 36 .la = { 37 .reg = 0x2e8, 38 .shift = 0, 39 .mask = 0xff, 40 .def = 0x4e, 41 }, 42 }, 43 }, { 44 .id = 0x02, 45 .name = "display0ab", 46 .swgroup = TEGRA_SWGROUP_DCB, 47 .regs = { 48 .smmu = { 49 .reg = 0x228, 50 .bit = 2, 51 }, 52 .la = { 53 .reg = 0x2f4, 54 .shift = 0, 55 .mask = 0xff, 56 .def = 0x4e, 57 }, 58 }, 59 }, { 60 .id = 0x03, 61 .name = "display0b", 62 .swgroup = TEGRA_SWGROUP_DC, 63 .regs = { 64 .smmu = { 65 .reg = 0x228, 66 .bit = 3, 67 }, 68 .la = { 69 .reg = 0x2e8, 70 .shift = 16, 71 .mask = 0xff, 72 .def = 0x4e, 73 }, 74 }, 75 }, { 76 .id = 0x04, 77 .name = "display0bb", 78 .swgroup = TEGRA_SWGROUP_DCB, 79 .regs = { 80 .smmu = { 81 .reg = 0x228, 82 .bit = 4, 83 }, 84 .la = { 85 .reg = 0x2f4, 86 .shift = 16, 87 .mask = 0xff, 88 .def = 0x4e, 89 }, 90 }, 91 }, { 92 .id = 0x05, 93 .name = "display0c", 94 .swgroup = TEGRA_SWGROUP_DC, 95 .regs = { 96 .smmu = { 97 .reg = 0x228, 98 .bit = 5, 99 }, 100 .la = { 101 .reg = 0x2ec, 102 .shift = 0, 103 .mask = 0xff, 104 .def = 0x4e, 105 }, 106 }, 107 }, { 108 .id = 0x06, 109 .name = "display0cb", 110 .swgroup = TEGRA_SWGROUP_DCB, 111 .regs = { 112 .smmu = { 113 .reg = 0x228, 114 .bit = 6, 115 }, 116 .la = { 117 .reg = 0x2f8, 118 .shift = 0, 119 .mask = 0xff, 120 .def = 0x4e, 121 }, 122 }, 123 }, { 124 .id = 0x09, 125 .name = "eppup", 126 .swgroup = TEGRA_SWGROUP_EPP, 127 .regs = { 128 .smmu = { 129 .reg = 0x228, 130 .bit = 9, 131 }, 132 .la = { 133 .reg = 0x300, 134 .shift = 0, 135 .mask = 0xff, 136 .def = 0x33, 137 }, 138 }, 139 }, { 140 .id = 0x0a, 141 .name = "g2pr", 142 .swgroup = TEGRA_SWGROUP_G2, 143 .regs = { 144 .smmu = { 145 .reg = 0x228, 146 .bit = 10, 147 }, 148 .la = { 149 .reg = 0x308, 150 .shift = 0, 151 .mask = 0xff, 152 .def = 0x09, 153 }, 154 }, 155 }, { 156 .id = 0x0b, 157 .name = "g2sr", 158 .swgroup = TEGRA_SWGROUP_G2, 159 .regs = { 160 .smmu = { 161 .reg = 0x228, 162 .bit = 11, 163 }, 164 .la = { 165 .reg = 0x308, 166 .shift = 16, 167 .mask = 0xff, 168 .def = 0x09, 169 }, 170 }, 171 }, { 172 .id = 0x0f, 173 .name = "avpcarm7r", 174 .swgroup = TEGRA_SWGROUP_AVPC, 175 .regs = { 176 .smmu = { 177 .reg = 0x228, 178 .bit = 15, 179 }, 180 .la = { 181 .reg = 0x2e4, 182 .shift = 0, 183 .mask = 0xff, 184 .def = 0x04, 185 }, 186 }, 187 }, { 188 .id = 0x10, 189 .name = "displayhc", 190 .swgroup = TEGRA_SWGROUP_DC, 191 .regs = { 192 .smmu = { 193 .reg = 0x228, 194 .bit = 16, 195 }, 196 .la = { 197 .reg = 0x2f0, 198 .shift = 0, 199 .mask = 0xff, 200 .def = 0x68, 201 }, 202 }, 203 }, { 204 .id = 0x11, 205 .name = "displayhcb", 206 .swgroup = TEGRA_SWGROUP_DCB, 207 .regs = { 208 .smmu = { 209 .reg = 0x228, 210 .bit = 17, 211 }, 212 .la = { 213 .reg = 0x2fc, 214 .shift = 0, 215 .mask = 0xff, 216 .def = 0x68, 217 }, 218 }, 219 }, { 220 .id = 0x12, 221 .name = "fdcdrd", 222 .swgroup = TEGRA_SWGROUP_NV, 223 .regs = { 224 .smmu = { 225 .reg = 0x228, 226 .bit = 18, 227 }, 228 .la = { 229 .reg = 0x334, 230 .shift = 0, 231 .mask = 0xff, 232 .def = 0x0c, 233 }, 234 }, 235 }, { 236 .id = 0x13, 237 .name = "fdcdrd2", 238 .swgroup = TEGRA_SWGROUP_NV, 239 .regs = { 240 .smmu = { 241 .reg = 0x228, 242 .bit = 19, 243 }, 244 .la = { 245 .reg = 0x33c, 246 .shift = 0, 247 .mask = 0xff, 248 .def = 0x0c, 249 }, 250 }, 251 }, { 252 .id = 0x14, 253 .name = "g2dr", 254 .swgroup = TEGRA_SWGROUP_G2, 255 .regs = { 256 .smmu = { 257 .reg = 0x228, 258 .bit = 20, 259 }, 260 .la = { 261 .reg = 0x30c, 262 .shift = 0, 263 .mask = 0xff, 264 .def = 0x0a, 265 }, 266 }, 267 }, { 268 .id = 0x15, 269 .name = "hdar", 270 .swgroup = TEGRA_SWGROUP_HDA, 271 .regs = { 272 .smmu = { 273 .reg = 0x228, 274 .bit = 21, 275 }, 276 .la = { 277 .reg = 0x318, 278 .shift = 0, 279 .mask = 0xff, 280 .def = 0xff, 281 }, 282 }, 283 }, { 284 .id = 0x16, 285 .name = "host1xdmar", 286 .swgroup = TEGRA_SWGROUP_HC, 287 .regs = { 288 .smmu = { 289 .reg = 0x228, 290 .bit = 22, 291 }, 292 .la = { 293 .reg = 0x310, 294 .shift = 0, 295 .mask = 0xff, 296 .def = 0x10, 297 }, 298 }, 299 }, { 300 .id = 0x17, 301 .name = "host1xr", 302 .swgroup = TEGRA_SWGROUP_HC, 303 .regs = { 304 .smmu = { 305 .reg = 0x228, 306 .bit = 23, 307 }, 308 .la = { 309 .reg = 0x310, 310 .shift = 16, 311 .mask = 0xff, 312 .def = 0xa5, 313 }, 314 }, 315 }, { 316 .id = 0x18, 317 .name = "idxsrd", 318 .swgroup = TEGRA_SWGROUP_NV, 319 .regs = { 320 .smmu = { 321 .reg = 0x228, 322 .bit = 24, 323 }, 324 .la = { 325 .reg = 0x334, 326 .shift = 16, 327 .mask = 0xff, 328 .def = 0x0b, 329 }, 330 }, 331 }, { 332 .id = 0x1c, 333 .name = "msencsrd", 334 .swgroup = TEGRA_SWGROUP_MSENC, 335 .regs = { 336 .smmu = { 337 .reg = 0x228, 338 .bit = 28, 339 }, 340 .la = { 341 .reg = 0x328, 342 .shift = 0, 343 .mask = 0xff, 344 .def = 0x80, 345 }, 346 }, 347 }, { 348 .id = 0x1d, 349 .name = "ppcsahbdmar", 350 .swgroup = TEGRA_SWGROUP_PPCS, 351 .regs = { 352 .smmu = { 353 .reg = 0x228, 354 .bit = 29, 355 }, 356 .la = { 357 .reg = 0x344, 358 .shift = 0, 359 .mask = 0xff, 360 .def = 0x50, 361 }, 362 }, 363 }, { 364 .id = 0x1e, 365 .name = "ppcsahbslvr", 366 .swgroup = TEGRA_SWGROUP_PPCS, 367 .regs = { 368 .smmu = { 369 .reg = 0x228, 370 .bit = 30, 371 }, 372 .la = { 373 .reg = 0x344, 374 .shift = 16, 375 .mask = 0xff, 376 .def = 0xe8, 377 }, 378 }, 379 }, { 380 .id = 0x20, 381 .name = "texl2srd", 382 .swgroup = TEGRA_SWGROUP_NV, 383 .regs = { 384 .smmu = { 385 .reg = 0x22c, 386 .bit = 0, 387 }, 388 .la = { 389 .reg = 0x338, 390 .shift = 0, 391 .mask = 0xff, 392 .def = 0x0c, 393 }, 394 }, 395 }, { 396 .id = 0x22, 397 .name = "vdebsevr", 398 .swgroup = TEGRA_SWGROUP_VDE, 399 .regs = { 400 .smmu = { 401 .reg = 0x22c, 402 .bit = 2, 403 }, 404 .la = { 405 .reg = 0x354, 406 .shift = 0, 407 .mask = 0xff, 408 .def = 0xff, 409 }, 410 }, 411 }, { 412 .id = 0x23, 413 .name = "vdember", 414 .swgroup = TEGRA_SWGROUP_VDE, 415 .regs = { 416 .smmu = { 417 .reg = 0x22c, 418 .bit = 3, 419 }, 420 .la = { 421 .reg = 0x354, 422 .shift = 16, 423 .mask = 0xff, 424 .def = 0xff, 425 }, 426 }, 427 }, { 428 .id = 0x24, 429 .name = "vdemcer", 430 .swgroup = TEGRA_SWGROUP_VDE, 431 .regs = { 432 .smmu = { 433 .reg = 0x22c, 434 .bit = 4, 435 }, 436 .la = { 437 .reg = 0x358, 438 .shift = 0, 439 .mask = 0xff, 440 .def = 0xb8, 441 }, 442 }, 443 }, { 444 .id = 0x25, 445 .name = "vdetper", 446 .swgroup = TEGRA_SWGROUP_VDE, 447 .regs = { 448 .smmu = { 449 .reg = 0x22c, 450 .bit = 5, 451 }, 452 .la = { 453 .reg = 0x358, 454 .shift = 16, 455 .mask = 0xff, 456 .def = 0xee, 457 }, 458 }, 459 }, { 460 .id = 0x26, 461 .name = "mpcorelpr", 462 .swgroup = TEGRA_SWGROUP_MPCORELP, 463 .regs = { 464 .la = { 465 .reg = 0x324, 466 .shift = 0, 467 .mask = 0xff, 468 .def = 0x04, 469 }, 470 }, 471 }, { 472 .id = 0x27, 473 .name = "mpcorer", 474 .swgroup = TEGRA_SWGROUP_MPCORE, 475 .regs = { 476 .la = { 477 .reg = 0x320, 478 .shift = 0, 479 .mask = 0xff, 480 .def = 0x04, 481 }, 482 }, 483 }, { 484 .id = 0x28, 485 .name = "eppu", 486 .swgroup = TEGRA_SWGROUP_EPP, 487 .regs = { 488 .smmu = { 489 .reg = 0x22c, 490 .bit = 8, 491 }, 492 .la = { 493 .reg = 0x300, 494 .shift = 16, 495 .mask = 0xff, 496 .def = 0x33, 497 }, 498 }, 499 }, { 500 .id = 0x29, 501 .name = "eppv", 502 .swgroup = TEGRA_SWGROUP_EPP, 503 .regs = { 504 .smmu = { 505 .reg = 0x22c, 506 .bit = 9, 507 }, 508 .la = { 509 .reg = 0x304, 510 .shift = 0, 511 .mask = 0xff, 512 .def = 0x6c, 513 }, 514 }, 515 }, { 516 .id = 0x2a, 517 .name = "eppy", 518 .swgroup = TEGRA_SWGROUP_EPP, 519 .regs = { 520 .smmu = { 521 .reg = 0x22c, 522 .bit = 10, 523 }, 524 .la = { 525 .reg = 0x304, 526 .shift = 16, 527 .mask = 0xff, 528 .def = 0x6c, 529 }, 530 }, 531 }, { 532 .id = 0x2b, 533 .name = "msencswr", 534 .swgroup = TEGRA_SWGROUP_MSENC, 535 .regs = { 536 .smmu = { 537 .reg = 0x22c, 538 .bit = 11, 539 }, 540 .la = { 541 .reg = 0x328, 542 .shift = 16, 543 .mask = 0xff, 544 .def = 0x80, 545 }, 546 }, 547 }, { 548 .id = 0x2c, 549 .name = "viwsb", 550 .swgroup = TEGRA_SWGROUP_VI, 551 .regs = { 552 .smmu = { 553 .reg = 0x22c, 554 .bit = 12, 555 }, 556 .la = { 557 .reg = 0x364, 558 .shift = 0, 559 .mask = 0xff, 560 .def = 0x47, 561 }, 562 }, 563 }, { 564 .id = 0x2d, 565 .name = "viwu", 566 .swgroup = TEGRA_SWGROUP_VI, 567 .regs = { 568 .smmu = { 569 .reg = 0x22c, 570 .bit = 13, 571 }, 572 .la = { 573 .reg = 0x368, 574 .shift = 0, 575 .mask = 0xff, 576 .def = 0xff, 577 }, 578 }, 579 }, { 580 .id = 0x2e, 581 .name = "viwv", 582 .swgroup = TEGRA_SWGROUP_VI, 583 .regs = { 584 .smmu = { 585 .reg = 0x22c, 586 .bit = 14, 587 }, 588 .la = { 589 .reg = 0x368, 590 .shift = 16, 591 .mask = 0xff, 592 .def = 0xff, 593 }, 594 }, 595 }, { 596 .id = 0x2f, 597 .name = "viwy", 598 .swgroup = TEGRA_SWGROUP_VI, 599 .regs = { 600 .smmu = { 601 .reg = 0x22c, 602 .bit = 15, 603 }, 604 .la = { 605 .reg = 0x36c, 606 .shift = 0, 607 .mask = 0xff, 608 .def = 0x47, 609 }, 610 }, 611 }, { 612 .id = 0x30, 613 .name = "g2dw", 614 .swgroup = TEGRA_SWGROUP_G2, 615 .regs = { 616 .smmu = { 617 .reg = 0x22c, 618 .bit = 16, 619 }, 620 .la = { 621 .reg = 0x30c, 622 .shift = 16, 623 .mask = 0xff, 624 .def = 0x9, 625 }, 626 }, 627 }, { 628 .id = 0x32, 629 .name = "avpcarm7w", 630 .swgroup = TEGRA_SWGROUP_AVPC, 631 .regs = { 632 .smmu = { 633 .reg = 0x22c, 634 .bit = 18, 635 }, 636 .la = { 637 .reg = 0x2e4, 638 .shift = 16, 639 .mask = 0xff, 640 .def = 0x0e, 641 }, 642 }, 643 }, { 644 .id = 0x33, 645 .name = "fdcdwr", 646 .swgroup = TEGRA_SWGROUP_NV, 647 .regs = { 648 .smmu = { 649 .reg = 0x22c, 650 .bit = 19, 651 }, 652 .la = { 653 .reg = 0x338, 654 .shift = 16, 655 .mask = 0xff, 656 .def = 0x10, 657 }, 658 }, 659 }, { 660 .id = 0x34, 661 .name = "fdcdwr2", 662 .swgroup = TEGRA_SWGROUP_NV, 663 .regs = { 664 .smmu = { 665 .reg = 0x22c, 666 .bit = 20, 667 }, 668 .la = { 669 .reg = 0x340, 670 .shift = 0, 671 .mask = 0xff, 672 .def = 0x10, 673 }, 674 }, 675 }, { 676 .id = 0x35, 677 .name = "hdaw", 678 .swgroup = TEGRA_SWGROUP_HDA, 679 .regs = { 680 .smmu = { 681 .reg = 0x22c, 682 .bit = 21, 683 }, 684 .la = { 685 .reg = 0x318, 686 .shift = 16, 687 .mask = 0xff, 688 .def = 0xff, 689 }, 690 }, 691 }, { 692 .id = 0x36, 693 .name = "host1xw", 694 .swgroup = TEGRA_SWGROUP_HC, 695 .regs = { 696 .smmu = { 697 .reg = 0x22c, 698 .bit = 22, 699 }, 700 .la = { 701 .reg = 0x314, 702 .shift = 0, 703 .mask = 0xff, 704 .def = 0x25, 705 }, 706 }, 707 }, { 708 .id = 0x37, 709 .name = "ispw", 710 .swgroup = TEGRA_SWGROUP_ISP, 711 .regs = { 712 .smmu = { 713 .reg = 0x22c, 714 .bit = 23, 715 }, 716 .la = { 717 .reg = 0x31c, 718 .shift = 0, 719 .mask = 0xff, 720 .def = 0xff, 721 }, 722 }, 723 }, { 724 .id = 0x38, 725 .name = "mpcorelpw", 726 .swgroup = TEGRA_SWGROUP_MPCORELP, 727 .regs = { 728 .la = { 729 .reg = 0x324, 730 .shift = 16, 731 .mask = 0xff, 732 .def = 0x80, 733 }, 734 }, 735 }, { 736 .id = 0x39, 737 .name = "mpcorew", 738 .swgroup = TEGRA_SWGROUP_MPCORE, 739 .regs = { 740 .la = { 741 .reg = 0x320, 742 .shift = 16, 743 .mask = 0xff, 744 .def = 0x0e, 745 }, 746 }, 747 }, { 748 .id = 0x3b, 749 .name = "ppcsahbdmaw", 750 .swgroup = TEGRA_SWGROUP_PPCS, 751 .regs = { 752 .smmu = { 753 .reg = 0x22c, 754 .bit = 27, 755 }, 756 .la = { 757 .reg = 0x348, 758 .shift = 0, 759 .mask = 0xff, 760 .def = 0xa5, 761 }, 762 }, 763 }, { 764 .id = 0x3c, 765 .name = "ppcsahbslvw", 766 .swgroup = TEGRA_SWGROUP_PPCS, 767 .regs = { 768 .smmu = { 769 .reg = 0x22c, 770 .bit = 28, 771 }, 772 .la = { 773 .reg = 0x348, 774 .shift = 16, 775 .mask = 0xff, 776 .def = 0xe8, 777 }, 778 }, 779 }, { 780 .id = 0x3e, 781 .name = "vdebsevw", 782 .swgroup = TEGRA_SWGROUP_VDE, 783 .regs = { 784 .smmu = { 785 .reg = 0x22c, 786 .bit = 30, 787 }, 788 .la = { 789 .reg = 0x35c, 790 .shift = 0, 791 .mask = 0xff, 792 .def = 0xff, 793 }, 794 }, 795 }, { 796 .id = 0x3f, 797 .name = "vdedbgw", 798 .swgroup = TEGRA_SWGROUP_VDE, 799 .regs = { 800 .smmu = { 801 .reg = 0x22c, 802 .bit = 31, 803 }, 804 .la = { 805 .reg = 0x35c, 806 .shift = 16, 807 .mask = 0xff, 808 .def = 0xff, 809 }, 810 }, 811 }, { 812 .id = 0x40, 813 .name = "vdembew", 814 .swgroup = TEGRA_SWGROUP_VDE, 815 .regs = { 816 .smmu = { 817 .reg = 0x230, 818 .bit = 0, 819 }, 820 .la = { 821 .reg = 0x360, 822 .shift = 0, 823 .mask = 0xff, 824 .def = 0x89, 825 }, 826 }, 827 }, { 828 .id = 0x41, 829 .name = "vdetpmw", 830 .swgroup = TEGRA_SWGROUP_VDE, 831 .regs = { 832 .smmu = { 833 .reg = 0x230, 834 .bit = 1, 835 }, 836 .la = { 837 .reg = 0x360, 838 .shift = 16, 839 .mask = 0xff, 840 .def = 0x59, 841 }, 842 }, 843 }, { 844 .id = 0x4a, 845 .name = "xusb_hostr", 846 .swgroup = TEGRA_SWGROUP_XUSB_HOST, 847 .regs = { 848 .smmu = { 849 .reg = 0x230, 850 .bit = 10, 851 }, 852 .la = { 853 .reg = 0x37c, 854 .shift = 0, 855 .mask = 0xff, 856 .def = 0xa5, 857 }, 858 }, 859 }, { 860 .id = 0x4b, 861 .name = "xusb_hostw", 862 .swgroup = TEGRA_SWGROUP_XUSB_HOST, 863 .regs = { 864 .smmu = { 865 .reg = 0x230, 866 .bit = 11, 867 }, 868 .la = { 869 .reg = 0x37c, 870 .shift = 16, 871 .mask = 0xff, 872 .def = 0xa5, 873 }, 874 }, 875 }, { 876 .id = 0x4c, 877 .name = "xusb_devr", 878 .swgroup = TEGRA_SWGROUP_XUSB_DEV, 879 .regs = { 880 .smmu = { 881 .reg = 0x230, 882 .bit = 12, 883 }, 884 .la = { 885 .reg = 0x380, 886 .shift = 0, 887 .mask = 0xff, 888 .def = 0xa5, 889 }, 890 }, 891 }, { 892 .id = 0x4d, 893 .name = "xusb_devw", 894 .swgroup = TEGRA_SWGROUP_XUSB_DEV, 895 .regs = { 896 .smmu = { 897 .reg = 0x230, 898 .bit = 13, 899 }, 900 .la = { 901 .reg = 0x380, 902 .shift = 16, 903 .mask = 0xff, 904 .def = 0xa5, 905 }, 906 }, 907 }, { 908 .id = 0x4e, 909 .name = "fdcdwr3", 910 .swgroup = TEGRA_SWGROUP_NV, 911 .regs = { 912 .smmu = { 913 .reg = 0x230, 914 .bit = 14, 915 }, 916 .la = { 917 .reg = 0x388, 918 .shift = 0, 919 .mask = 0xff, 920 .def = 0x10, 921 }, 922 }, 923 }, { 924 .id = 0x4f, 925 .name = "fdcdrd3", 926 .swgroup = TEGRA_SWGROUP_NV, 927 .regs = { 928 .smmu = { 929 .reg = 0x230, 930 .bit = 15, 931 }, 932 .la = { 933 .reg = 0x384, 934 .shift = 0, 935 .mask = 0xff, 936 .def = 0x0c, 937 }, 938 }, 939 }, { 940 .id = 0x50, 941 .name = "fdcwr4", 942 .swgroup = TEGRA_SWGROUP_NV, 943 .regs = { 944 .smmu = { 945 .reg = 0x230, 946 .bit = 16, 947 }, 948 .la = { 949 .reg = 0x388, 950 .shift = 16, 951 .mask = 0xff, 952 .def = 0x10, 953 }, 954 }, 955 }, { 956 .id = 0x51, 957 .name = "fdcrd4", 958 .swgroup = TEGRA_SWGROUP_NV, 959 .regs = { 960 .smmu = { 961 .reg = 0x230, 962 .bit = 17, 963 }, 964 .la = { 965 .reg = 0x384, 966 .shift = 16, 967 .mask = 0xff, 968 .def = 0x0c, 969 }, 970 }, 971 }, { 972 .id = 0x52, 973 .name = "emucifr", 974 .swgroup = TEGRA_SWGROUP_EMUCIF, 975 .regs = { 976 .la = { 977 .reg = 0x38c, 978 .shift = 0, 979 .mask = 0xff, 980 .def = 0x04, 981 }, 982 }, 983 }, { 984 .id = 0x53, 985 .name = "emucifw", 986 .swgroup = TEGRA_SWGROUP_EMUCIF, 987 .regs = { 988 .la = { 989 .reg = 0x38c, 990 .shift = 16, 991 .mask = 0xff, 992 .def = 0x0e, 993 }, 994 }, 995 }, { 996 .id = 0x54, 997 .name = "tsecsrd", 998 .swgroup = TEGRA_SWGROUP_TSEC, 999 .regs = { 1000 .smmu = { 1001 .reg = 0x230, 1002 .bit = 20, 1003 }, 1004 .la = { 1005 .reg = 0x390, 1006 .shift = 0, 1007 .mask = 0xff, 1008 .def = 0x50, 1009 }, 1010 }, 1011 }, { 1012 .id = 0x55, 1013 .name = "tsecswr", 1014 .swgroup = TEGRA_SWGROUP_TSEC, 1015 .regs = { 1016 .smmu = { 1017 .reg = 0x230, 1018 .bit = 21, 1019 }, 1020 .la = { 1021 .reg = 0x390, 1022 .shift = 16, 1023 .mask = 0xff, 1024 .def = 0x50, 1025 }, 1026 }, 1027 }, 1028 }; 1029 1030 static const struct tegra_smmu_swgroup tegra114_swgroups[] = { 1031 { .name = "dc", .swgroup = TEGRA_SWGROUP_DC, .reg = 0x240 }, 1032 { .name = "dcb", .swgroup = TEGRA_SWGROUP_DCB, .reg = 0x244 }, 1033 { .name = "epp", .swgroup = TEGRA_SWGROUP_EPP, .reg = 0x248 }, 1034 { .name = "g2", .swgroup = TEGRA_SWGROUP_G2, .reg = 0x24c }, 1035 { .name = "avpc", .swgroup = TEGRA_SWGROUP_AVPC, .reg = 0x23c }, 1036 { .name = "nv", .swgroup = TEGRA_SWGROUP_NV, .reg = 0x268 }, 1037 { .name = "hda", .swgroup = TEGRA_SWGROUP_HDA, .reg = 0x254 }, 1038 { .name = "hc", .swgroup = TEGRA_SWGROUP_HC, .reg = 0x250 }, 1039 { .name = "msenc", .swgroup = TEGRA_SWGROUP_MSENC, .reg = 0x264 }, 1040 { .name = "ppcs", .swgroup = TEGRA_SWGROUP_PPCS, .reg = 0x270 }, 1041 { .name = "vde", .swgroup = TEGRA_SWGROUP_VDE, .reg = 0x27c }, 1042 { .name = "vi", .swgroup = TEGRA_SWGROUP_VI, .reg = 0x280 }, 1043 { .name = "isp", .swgroup = TEGRA_SWGROUP_ISP, .reg = 0x258 }, 1044 { .name = "xusb_host", .swgroup = TEGRA_SWGROUP_XUSB_HOST, .reg = 0x288 }, 1045 { .name = "xusb_dev", .swgroup = TEGRA_SWGROUP_XUSB_DEV, .reg = 0x28c }, 1046 { .name = "tsec", .swgroup = TEGRA_SWGROUP_TSEC, .reg = 0x294 }, 1047 }; 1048 1049 static const unsigned int tegra114_group_drm[] = { 1050 TEGRA_SWGROUP_DC, 1051 TEGRA_SWGROUP_DCB, 1052 TEGRA_SWGROUP_G2, 1053 TEGRA_SWGROUP_NV, 1054 }; 1055 1056 static const struct tegra_smmu_group_soc tegra114_groups[] = { 1057 { 1058 .name = "drm", 1059 .swgroups = tegra114_group_drm, 1060 .num_swgroups = ARRAY_SIZE(tegra114_group_drm), 1061 }, 1062 }; 1063 1064 static const struct tegra_smmu_soc tegra114_smmu_soc = { 1065 .clients = tegra114_mc_clients, 1066 .num_clients = ARRAY_SIZE(tegra114_mc_clients), 1067 .swgroups = tegra114_swgroups, 1068 .num_swgroups = ARRAY_SIZE(tegra114_swgroups), 1069 .groups = tegra114_groups, 1070 .num_groups = ARRAY_SIZE(tegra114_groups), 1071 .supports_round_robin_arbitration = false, 1072 .supports_request_limit = false, 1073 .num_tlb_lines = 32, 1074 .num_asids = 4, 1075 }; 1076 1077 #define TEGRA114_MC_RESET(_name, _control, _status, _bit) \ 1078 { \ 1079 .name = #_name, \ 1080 .id = TEGRA114_MC_RESET_##_name, \ 1081 .control = _control, \ 1082 .status = _status, \ 1083 .bit = _bit, \ 1084 } 1085 1086 static const struct tegra_mc_reset tegra114_mc_resets[] = { 1087 TEGRA114_MC_RESET(AVPC, 0x200, 0x204, 1), 1088 TEGRA114_MC_RESET(DC, 0x200, 0x204, 2), 1089 TEGRA114_MC_RESET(DCB, 0x200, 0x204, 3), 1090 TEGRA114_MC_RESET(EPP, 0x200, 0x204, 4), 1091 TEGRA114_MC_RESET(2D, 0x200, 0x204, 5), 1092 TEGRA114_MC_RESET(HC, 0x200, 0x204, 6), 1093 TEGRA114_MC_RESET(HDA, 0x200, 0x204, 7), 1094 TEGRA114_MC_RESET(ISP, 0x200, 0x204, 8), 1095 TEGRA114_MC_RESET(MPCORE, 0x200, 0x204, 9), 1096 TEGRA114_MC_RESET(MPCORELP, 0x200, 0x204, 10), 1097 TEGRA114_MC_RESET(MPE, 0x200, 0x204, 11), 1098 TEGRA114_MC_RESET(3D, 0x200, 0x204, 12), 1099 TEGRA114_MC_RESET(3D2, 0x200, 0x204, 13), 1100 TEGRA114_MC_RESET(PPCS, 0x200, 0x204, 14), 1101 TEGRA114_MC_RESET(VDE, 0x200, 0x204, 16), 1102 TEGRA114_MC_RESET(VI, 0x200, 0x204, 17), 1103 }; 1104 1105 static void tegra114_mc_tune_client_latency(struct tegra_mc *mc, 1106 const struct tegra_mc_client *client, 1107 unsigned int bandwidth_mbytes_sec) 1108 { 1109 u32 arb_tolerance_compensation_nsec, arb_tolerance_compensation_div; 1110 unsigned int fifo_size = client->fifo_size; 1111 u32 arb_nsec, la_ticks, value; 1112 1113 /* see 20.3.1.1 Client Configuration in Tegra4 TRM v01p */ 1114 if (bandwidth_mbytes_sec) 1115 arb_nsec = fifo_size * NSEC_PER_USEC / bandwidth_mbytes_sec; 1116 else 1117 arb_nsec = U32_MAX; 1118 1119 /* 1120 * Latency allowness should be set with consideration for the module's 1121 * latency tolerance and internal buffering capabilities. 1122 * 1123 * Display memory clients use isochronous transfers and have very low 1124 * tolerance to a belated transfers. Hence we need to compensate the 1125 * memory arbitration imperfection for them in order to prevent FIFO 1126 * underflow condition when memory bus is busy. 1127 * 1128 * VI clients also need a stronger compensation. 1129 */ 1130 switch (client->swgroup) { 1131 case TEGRA_SWGROUP_MPCORE: 1132 case TEGRA_SWGROUP_PTC: 1133 /* 1134 * We always want lower latency for these clients, hence 1135 * don't touch them. 1136 */ 1137 return; 1138 1139 case TEGRA_SWGROUP_DC: 1140 case TEGRA_SWGROUP_DCB: 1141 arb_tolerance_compensation_nsec = 1050; 1142 arb_tolerance_compensation_div = 2; 1143 break; 1144 1145 case TEGRA_SWGROUP_VI: 1146 arb_tolerance_compensation_nsec = 1050; 1147 arb_tolerance_compensation_div = 1; 1148 break; 1149 1150 default: 1151 arb_tolerance_compensation_nsec = 150; 1152 arb_tolerance_compensation_div = 1; 1153 break; 1154 } 1155 1156 if (arb_nsec > arb_tolerance_compensation_nsec) 1157 arb_nsec -= arb_tolerance_compensation_nsec; 1158 else 1159 arb_nsec = 0; 1160 1161 arb_nsec /= arb_tolerance_compensation_div; 1162 1163 /* 1164 * Latency allowance is a number of ticks a request from a particular 1165 * client may wait in the EMEM arbiter before it becomes a high-priority 1166 * request. 1167 */ 1168 la_ticks = arb_nsec / mc->tick; 1169 la_ticks = min(la_ticks, client->regs.la.mask); 1170 1171 value = mc_readl(mc, client->regs.la.reg); 1172 value &= ~(client->regs.la.mask << client->regs.la.shift); 1173 value |= la_ticks << client->regs.la.shift; 1174 mc_writel(mc, value, client->regs.la.reg); 1175 } 1176 1177 static int tegra114_mc_icc_set(struct icc_node *src, struct icc_node *dst) 1178 { 1179 struct tegra_mc *mc = icc_provider_to_tegra_mc(src->provider); 1180 const struct tegra_mc_client *client = &mc->soc->clients[src->id]; 1181 u64 peak_bandwidth = icc_units_to_bps(src->peak_bw); 1182 1183 /* 1184 * Skip pre-initialization that is done by icc_node_add(), which sets 1185 * bandwidth to maximum for all clients before drivers are loaded. 1186 * 1187 * This doesn't make sense for us because we don't have drivers for all 1188 * clients and it's okay to keep configuration left from bootloader 1189 * during boot, at least for today. 1190 */ 1191 if (src == dst) 1192 return 0; 1193 1194 /* convert bytes/sec to megabytes/sec */ 1195 do_div(peak_bandwidth, 1000000); 1196 1197 tegra114_mc_tune_client_latency(mc, client, peak_bandwidth); 1198 1199 return 0; 1200 } 1201 1202 static int tegra114_mc_icc_aggreate(struct icc_node *node, u32 tag, u32 avg_bw, 1203 u32 peak_bw, u32 *agg_avg, u32 *agg_peak) 1204 { 1205 /* 1206 * ISO clients need to reserve extra bandwidth up-front because 1207 * there could be high bandwidth pressure during initial filling 1208 * of the client's FIFO buffers. Secondly, we need to take into 1209 * account impurities of the memory subsystem. 1210 */ 1211 if (tag & TEGRA_MC_ICC_TAG_ISO) 1212 peak_bw = tegra_mc_scale_percents(peak_bw, 400); 1213 1214 *agg_avg += avg_bw; 1215 *agg_peak = max(*agg_peak, peak_bw); 1216 1217 return 0; 1218 } 1219 1220 static struct icc_node_data * 1221 tegra114_mc_of_icc_xlate_extended(const struct of_phandle_args *spec, void *data) 1222 { 1223 struct tegra_mc *mc = icc_provider_to_tegra_mc(data); 1224 const struct tegra_mc_client *client; 1225 unsigned int i, idx = spec->args[0]; 1226 struct icc_node_data *ndata; 1227 struct icc_node *node; 1228 1229 list_for_each_entry(node, &mc->provider.nodes, node_list) { 1230 if (node->id != idx) 1231 continue; 1232 1233 ndata = kzalloc_obj(*ndata); 1234 if (!ndata) 1235 return ERR_PTR(-ENOMEM); 1236 1237 client = &mc->soc->clients[idx]; 1238 ndata->node = node; 1239 1240 switch (client->swgroup) { 1241 case TEGRA_SWGROUP_DC: 1242 case TEGRA_SWGROUP_DCB: 1243 case TEGRA_SWGROUP_PTC: 1244 case TEGRA_SWGROUP_VI: 1245 /* these clients are isochronous by default */ 1246 ndata->tag = TEGRA_MC_ICC_TAG_ISO; 1247 break; 1248 1249 default: 1250 ndata->tag = TEGRA_MC_ICC_TAG_DEFAULT; 1251 break; 1252 } 1253 1254 return ndata; 1255 } 1256 1257 for (i = 0; i < mc->soc->num_clients; i++) { 1258 if (mc->soc->clients[i].id == idx) 1259 return ERR_PTR(-EPROBE_DEFER); 1260 } 1261 1262 dev_err(mc->dev, "invalid ICC client ID %u\n", idx); 1263 1264 return ERR_PTR(-EINVAL); 1265 } 1266 1267 static const struct tegra_mc_icc_ops tegra114_mc_icc_ops = { 1268 .xlate_extended = tegra114_mc_of_icc_xlate_extended, 1269 .aggregate = tegra114_mc_icc_aggreate, 1270 .set = tegra114_mc_icc_set, 1271 }; 1272 1273 static const unsigned long tegra114_mc_emem_regs[] = { 1274 MC_EMEM_ARB_CFG, 1275 MC_EMEM_ARB_OUTSTANDING_REQ, 1276 MC_EMEM_ARB_TIMING_RCD, 1277 MC_EMEM_ARB_TIMING_RP, 1278 MC_EMEM_ARB_TIMING_RC, 1279 MC_EMEM_ARB_TIMING_RAS, 1280 MC_EMEM_ARB_TIMING_FAW, 1281 MC_EMEM_ARB_TIMING_RRD, 1282 MC_EMEM_ARB_TIMING_RAP2PRE, 1283 MC_EMEM_ARB_TIMING_WAP2PRE, 1284 MC_EMEM_ARB_TIMING_R2R, 1285 MC_EMEM_ARB_TIMING_W2W, 1286 MC_EMEM_ARB_TIMING_R2W, 1287 MC_EMEM_ARB_TIMING_W2R, 1288 MC_EMEM_ARB_DA_TURNS, 1289 MC_EMEM_ARB_DA_COVERS, 1290 MC_EMEM_ARB_MISC0, 1291 MC_EMEM_ARB_RING1_THROTTLE, 1292 }; 1293 1294 static const struct tegra_mc_intmask tegra114_mc_intmasks[] = { 1295 { 1296 .reg = MC_INTMASK, 1297 .mask = MC_INT_INVALID_SMMU_PAGE | MC_INT_SECURITY_VIOLATION | 1298 MC_INT_DECERR_EMEM, 1299 }, 1300 }; 1301 1302 const struct tegra_mc_soc tegra114_mc_soc = { 1303 .clients = tegra114_mc_clients, 1304 .num_clients = ARRAY_SIZE(tegra114_mc_clients), 1305 .num_address_bits = 32, 1306 .atom_size = 32, 1307 .client_id_mask = 0x7f, 1308 .smmu = &tegra114_smmu_soc, 1309 .emem_regs = tegra114_mc_emem_regs, 1310 .num_emem_regs = ARRAY_SIZE(tegra114_mc_emem_regs), 1311 .intmasks = tegra114_mc_intmasks, 1312 .num_intmasks = ARRAY_SIZE(tegra114_mc_intmasks), 1313 .reset_ops = &tegra_mc_reset_ops_common, 1314 .resets = tegra114_mc_resets, 1315 .num_resets = ARRAY_SIZE(tegra114_mc_resets), 1316 .icc_ops = &tegra114_mc_icc_ops, 1317 .ops = &tegra30_mc_ops, 1318 .regs = &tegra20_mc_regs, 1319 .handle_irq = tegra30_mc_irq_handlers, 1320 .num_interrupts = ARRAY_SIZE(tegra30_mc_irq_handlers), 1321 .mc_err_status_type_mask = (0x7 << 28), 1322 }; 1323