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