0001
0002
0003
0004
0005
0006 #include <linux/of.h>
0007 #include <linux/of_device.h>
0008 #include <linux/slab.h>
0009
0010 #include <dt-bindings/memory/tegra30-mc.h>
0011
0012 #include "mc.h"
0013
0014 static const unsigned long tegra30_mc_emem_regs[] = {
0015 MC_EMEM_ARB_CFG,
0016 MC_EMEM_ARB_OUTSTANDING_REQ,
0017 MC_EMEM_ARB_TIMING_RCD,
0018 MC_EMEM_ARB_TIMING_RP,
0019 MC_EMEM_ARB_TIMING_RC,
0020 MC_EMEM_ARB_TIMING_RAS,
0021 MC_EMEM_ARB_TIMING_FAW,
0022 MC_EMEM_ARB_TIMING_RRD,
0023 MC_EMEM_ARB_TIMING_RAP2PRE,
0024 MC_EMEM_ARB_TIMING_WAP2PRE,
0025 MC_EMEM_ARB_TIMING_R2R,
0026 MC_EMEM_ARB_TIMING_W2W,
0027 MC_EMEM_ARB_TIMING_R2W,
0028 MC_EMEM_ARB_TIMING_W2R,
0029 MC_EMEM_ARB_DA_TURNS,
0030 MC_EMEM_ARB_DA_COVERS,
0031 MC_EMEM_ARB_MISC0,
0032 MC_EMEM_ARB_RING1_THROTTLE,
0033 };
0034
0035 static const struct tegra_mc_client tegra30_mc_clients[] = {
0036 {
0037 .id = 0x00,
0038 .name = "ptcr",
0039 .swgroup = TEGRA_SWGROUP_PTC,
0040 .regs = {
0041 .la = {
0042 .reg = 0x34c,
0043 .shift = 0,
0044 .mask = 0xff,
0045 .def = 0x0,
0046 },
0047 },
0048 .fifo_size = 16 * 2,
0049 }, {
0050 .id = 0x01,
0051 .name = "display0a",
0052 .swgroup = TEGRA_SWGROUP_DC,
0053 .regs = {
0054 .smmu = {
0055 .reg = 0x228,
0056 .bit = 1,
0057 },
0058 .la = {
0059 .reg = 0x2e8,
0060 .shift = 0,
0061 .mask = 0xff,
0062 .def = 0x4e,
0063 },
0064 },
0065 .fifo_size = 16 * 128,
0066 }, {
0067 .id = 0x02,
0068 .name = "display0ab",
0069 .swgroup = TEGRA_SWGROUP_DCB,
0070 .regs = {
0071 .smmu = {
0072 .reg = 0x228,
0073 .bit = 2,
0074 },
0075 .la = {
0076 .reg = 0x2f4,
0077 .shift = 0,
0078 .mask = 0xff,
0079 .def = 0x4e,
0080 },
0081 },
0082 .fifo_size = 16 * 128,
0083 }, {
0084 .id = 0x03,
0085 .name = "display0b",
0086 .swgroup = TEGRA_SWGROUP_DC,
0087 .regs = {
0088 .smmu = {
0089 .reg = 0x228,
0090 .bit = 3,
0091 },
0092 .la = {
0093 .reg = 0x2e8,
0094 .shift = 16,
0095 .mask = 0xff,
0096 .def = 0x4e,
0097 },
0098 },
0099 .fifo_size = 16 * 64,
0100 }, {
0101 .id = 0x04,
0102 .name = "display0bb",
0103 .swgroup = TEGRA_SWGROUP_DCB,
0104 .regs = {
0105 .smmu = {
0106 .reg = 0x228,
0107 .bit = 4,
0108 },
0109 .la = {
0110 .reg = 0x2f4,
0111 .shift = 16,
0112 .mask = 0xff,
0113 .def = 0x4e,
0114 },
0115 },
0116 .fifo_size = 16 * 64,
0117 }, {
0118 .id = 0x05,
0119 .name = "display0c",
0120 .swgroup = TEGRA_SWGROUP_DC,
0121 .regs = {
0122 .smmu = {
0123 .reg = 0x228,
0124 .bit = 5,
0125 },
0126 .la = {
0127 .reg = 0x2ec,
0128 .shift = 0,
0129 .mask = 0xff,
0130 .def = 0x4e,
0131 },
0132 },
0133 .fifo_size = 16 * 128,
0134 }, {
0135 .id = 0x06,
0136 .name = "display0cb",
0137 .swgroup = TEGRA_SWGROUP_DCB,
0138 .regs = {
0139 .smmu = {
0140 .reg = 0x228,
0141 .bit = 6,
0142 },
0143 .la = {
0144 .reg = 0x2f8,
0145 .shift = 0,
0146 .mask = 0xff,
0147 .def = 0x4e,
0148 },
0149 },
0150 .fifo_size = 16 * 128,
0151 }, {
0152 .id = 0x07,
0153 .name = "display1b",
0154 .swgroup = TEGRA_SWGROUP_DC,
0155 .regs = {
0156 .smmu = {
0157 .reg = 0x228,
0158 .bit = 7,
0159 },
0160 .la = {
0161 .reg = 0x2ec,
0162 .shift = 16,
0163 .mask = 0xff,
0164 .def = 0x4e,
0165 },
0166 },
0167 .fifo_size = 16 * 64,
0168 }, {
0169 .id = 0x08,
0170 .name = "display1bb",
0171 .swgroup = TEGRA_SWGROUP_DCB,
0172 .regs = {
0173 .smmu = {
0174 .reg = 0x228,
0175 .bit = 8,
0176 },
0177 .la = {
0178 .reg = 0x2f8,
0179 .shift = 16,
0180 .mask = 0xff,
0181 .def = 0x4e,
0182 },
0183 },
0184 .fifo_size = 16 * 64,
0185 }, {
0186 .id = 0x09,
0187 .name = "eppup",
0188 .swgroup = TEGRA_SWGROUP_EPP,
0189 .regs = {
0190 .smmu = {
0191 .reg = 0x228,
0192 .bit = 9,
0193 },
0194 .la = {
0195 .reg = 0x300,
0196 .shift = 0,
0197 .mask = 0xff,
0198 .def = 0x17,
0199 },
0200 },
0201 .fifo_size = 16 * 8,
0202 }, {
0203 .id = 0x0a,
0204 .name = "g2pr",
0205 .swgroup = TEGRA_SWGROUP_G2,
0206 .regs = {
0207 .smmu = {
0208 .reg = 0x228,
0209 .bit = 10,
0210 },
0211 .la = {
0212 .reg = 0x308,
0213 .shift = 0,
0214 .mask = 0xff,
0215 .def = 0x09,
0216 },
0217 },
0218 .fifo_size = 16 * 64,
0219 }, {
0220 .id = 0x0b,
0221 .name = "g2sr",
0222 .swgroup = TEGRA_SWGROUP_G2,
0223 .regs = {
0224 .smmu = {
0225 .reg = 0x228,
0226 .bit = 11,
0227 },
0228 .la = {
0229 .reg = 0x308,
0230 .shift = 16,
0231 .mask = 0xff,
0232 .def = 0x09,
0233 },
0234 },
0235 .fifo_size = 16 * 64,
0236 }, {
0237 .id = 0x0c,
0238 .name = "mpeunifbr",
0239 .swgroup = TEGRA_SWGROUP_MPE,
0240 .regs = {
0241 .smmu = {
0242 .reg = 0x228,
0243 .bit = 12,
0244 },
0245 .la = {
0246 .reg = 0x328,
0247 .shift = 0,
0248 .mask = 0xff,
0249 .def = 0x50,
0250 },
0251 },
0252 .fifo_size = 16 * 8,
0253 }, {
0254 .id = 0x0d,
0255 .name = "viruv",
0256 .swgroup = TEGRA_SWGROUP_VI,
0257 .regs = {
0258 .smmu = {
0259 .reg = 0x228,
0260 .bit = 13,
0261 },
0262 .la = {
0263 .reg = 0x364,
0264 .shift = 0,
0265 .mask = 0xff,
0266 .def = 0x2c,
0267 },
0268 },
0269 .fifo_size = 16 * 8,
0270 }, {
0271 .id = 0x0e,
0272 .name = "afir",
0273 .swgroup = TEGRA_SWGROUP_AFI,
0274 .regs = {
0275 .smmu = {
0276 .reg = 0x228,
0277 .bit = 14,
0278 },
0279 .la = {
0280 .reg = 0x2e0,
0281 .shift = 0,
0282 .mask = 0xff,
0283 .def = 0x10,
0284 },
0285 },
0286 .fifo_size = 16 * 32,
0287 }, {
0288 .id = 0x0f,
0289 .name = "avpcarm7r",
0290 .swgroup = TEGRA_SWGROUP_AVPC,
0291 .regs = {
0292 .smmu = {
0293 .reg = 0x228,
0294 .bit = 15,
0295 },
0296 .la = {
0297 .reg = 0x2e4,
0298 .shift = 0,
0299 .mask = 0xff,
0300 .def = 0x04,
0301 },
0302 },
0303 .fifo_size = 16 * 2,
0304 }, {
0305 .id = 0x10,
0306 .name = "displayhc",
0307 .swgroup = TEGRA_SWGROUP_DC,
0308 .regs = {
0309 .smmu = {
0310 .reg = 0x228,
0311 .bit = 16,
0312 },
0313 .la = {
0314 .reg = 0x2f0,
0315 .shift = 0,
0316 .mask = 0xff,
0317 .def = 0xff,
0318 },
0319 },
0320 .fifo_size = 16 * 2,
0321 }, {
0322 .id = 0x11,
0323 .name = "displayhcb",
0324 .swgroup = TEGRA_SWGROUP_DCB,
0325 .regs = {
0326 .smmu = {
0327 .reg = 0x228,
0328 .bit = 17,
0329 },
0330 .la = {
0331 .reg = 0x2fc,
0332 .shift = 0,
0333 .mask = 0xff,
0334 .def = 0xff,
0335 },
0336 },
0337 .fifo_size = 16 * 2,
0338 }, {
0339 .id = 0x12,
0340 .name = "fdcdrd",
0341 .swgroup = TEGRA_SWGROUP_NV,
0342 .regs = {
0343 .smmu = {
0344 .reg = 0x228,
0345 .bit = 18,
0346 },
0347 .la = {
0348 .reg = 0x334,
0349 .shift = 0,
0350 .mask = 0xff,
0351 .def = 0x0a,
0352 },
0353 },
0354 .fifo_size = 16 * 48,
0355 }, {
0356 .id = 0x13,
0357 .name = "fdcdrd2",
0358 .swgroup = TEGRA_SWGROUP_NV2,
0359 .regs = {
0360 .smmu = {
0361 .reg = 0x228,
0362 .bit = 19,
0363 },
0364 .la = {
0365 .reg = 0x33c,
0366 .shift = 0,
0367 .mask = 0xff,
0368 .def = 0x0a,
0369 },
0370 },
0371 .fifo_size = 16 * 48,
0372 }, {
0373 .id = 0x14,
0374 .name = "g2dr",
0375 .swgroup = TEGRA_SWGROUP_G2,
0376 .regs = {
0377 .smmu = {
0378 .reg = 0x228,
0379 .bit = 20,
0380 },
0381 .la = {
0382 .reg = 0x30c,
0383 .shift = 0,
0384 .mask = 0xff,
0385 .def = 0x0a,
0386 },
0387 },
0388 .fifo_size = 16 * 48,
0389 }, {
0390 .id = 0x15,
0391 .name = "hdar",
0392 .swgroup = TEGRA_SWGROUP_HDA,
0393 .regs = {
0394 .smmu = {
0395 .reg = 0x228,
0396 .bit = 21,
0397 },
0398 .la = {
0399 .reg = 0x318,
0400 .shift = 0,
0401 .mask = 0xff,
0402 .def = 0xff,
0403 },
0404 },
0405 .fifo_size = 16 * 16,
0406 }, {
0407 .id = 0x16,
0408 .name = "host1xdmar",
0409 .swgroup = TEGRA_SWGROUP_HC,
0410 .regs = {
0411 .smmu = {
0412 .reg = 0x228,
0413 .bit = 22,
0414 },
0415 .la = {
0416 .reg = 0x310,
0417 .shift = 0,
0418 .mask = 0xff,
0419 .def = 0x05,
0420 },
0421 },
0422 .fifo_size = 16 * 16,
0423 }, {
0424 .id = 0x17,
0425 .name = "host1xr",
0426 .swgroup = TEGRA_SWGROUP_HC,
0427 .regs = {
0428 .smmu = {
0429 .reg = 0x228,
0430 .bit = 23,
0431 },
0432 .la = {
0433 .reg = 0x310,
0434 .shift = 16,
0435 .mask = 0xff,
0436 .def = 0x50,
0437 },
0438 },
0439 .fifo_size = 16 * 8,
0440 }, {
0441 .id = 0x18,
0442 .name = "idxsrd",
0443 .swgroup = TEGRA_SWGROUP_NV,
0444 .regs = {
0445 .smmu = {
0446 .reg = 0x228,
0447 .bit = 24,
0448 },
0449 .la = {
0450 .reg = 0x334,
0451 .shift = 16,
0452 .mask = 0xff,
0453 .def = 0x13,
0454 },
0455 },
0456 .fifo_size = 16 * 64,
0457 }, {
0458 .id = 0x19,
0459 .name = "idxsrd2",
0460 .swgroup = TEGRA_SWGROUP_NV2,
0461 .regs = {
0462 .smmu = {
0463 .reg = 0x228,
0464 .bit = 25,
0465 },
0466 .la = {
0467 .reg = 0x33c,
0468 .shift = 16,
0469 .mask = 0xff,
0470 .def = 0x13,
0471 },
0472 },
0473 .fifo_size = 16 * 64,
0474 }, {
0475 .id = 0x1a,
0476 .name = "mpe_ipred",
0477 .swgroup = TEGRA_SWGROUP_MPE,
0478 .regs = {
0479 .smmu = {
0480 .reg = 0x228,
0481 .bit = 26,
0482 },
0483 .la = {
0484 .reg = 0x328,
0485 .shift = 16,
0486 .mask = 0xff,
0487 .def = 0x80,
0488 },
0489 },
0490 .fifo_size = 16 * 2,
0491 }, {
0492 .id = 0x1b,
0493 .name = "mpeamemrd",
0494 .swgroup = TEGRA_SWGROUP_MPE,
0495 .regs = {
0496 .smmu = {
0497 .reg = 0x228,
0498 .bit = 27,
0499 },
0500 .la = {
0501 .reg = 0x32c,
0502 .shift = 0,
0503 .mask = 0xff,
0504 .def = 0x42,
0505 },
0506 },
0507 .fifo_size = 16 * 64,
0508 }, {
0509 .id = 0x1c,
0510 .name = "mpecsrd",
0511 .swgroup = TEGRA_SWGROUP_MPE,
0512 .regs = {
0513 .smmu = {
0514 .reg = 0x228,
0515 .bit = 28,
0516 },
0517 .la = {
0518 .reg = 0x32c,
0519 .shift = 16,
0520 .mask = 0xff,
0521 .def = 0xff,
0522 },
0523 },
0524 .fifo_size = 16 * 8,
0525 }, {
0526 .id = 0x1d,
0527 .name = "ppcsahbdmar",
0528 .swgroup = TEGRA_SWGROUP_PPCS,
0529 .regs = {
0530 .smmu = {
0531 .reg = 0x228,
0532 .bit = 29,
0533 },
0534 .la = {
0535 .reg = 0x344,
0536 .shift = 0,
0537 .mask = 0xff,
0538 .def = 0x10,
0539 },
0540 },
0541 .fifo_size = 16 * 2,
0542 }, {
0543 .id = 0x1e,
0544 .name = "ppcsahbslvr",
0545 .swgroup = TEGRA_SWGROUP_PPCS,
0546 .regs = {
0547 .smmu = {
0548 .reg = 0x228,
0549 .bit = 30,
0550 },
0551 .la = {
0552 .reg = 0x344,
0553 .shift = 16,
0554 .mask = 0xff,
0555 .def = 0x12,
0556 },
0557 },
0558 .fifo_size = 16 * 8,
0559 }, {
0560 .id = 0x1f,
0561 .name = "satar",
0562 .swgroup = TEGRA_SWGROUP_SATA,
0563 .regs = {
0564 .smmu = {
0565 .reg = 0x228,
0566 .bit = 31,
0567 },
0568 .la = {
0569 .reg = 0x350,
0570 .shift = 0,
0571 .mask = 0xff,
0572 .def = 0x33,
0573 },
0574 },
0575 .fifo_size = 16 * 32,
0576 }, {
0577 .id = 0x20,
0578 .name = "texsrd",
0579 .swgroup = TEGRA_SWGROUP_NV,
0580 .regs = {
0581 .smmu = {
0582 .reg = 0x22c,
0583 .bit = 0,
0584 },
0585 .la = {
0586 .reg = 0x338,
0587 .shift = 0,
0588 .mask = 0xff,
0589 .def = 0x13,
0590 },
0591 },
0592 .fifo_size = 16 * 64,
0593 }, {
0594 .id = 0x21,
0595 .name = "texsrd2",
0596 .swgroup = TEGRA_SWGROUP_NV2,
0597 .regs = {
0598 .smmu = {
0599 .reg = 0x22c,
0600 .bit = 1,
0601 },
0602 .la = {
0603 .reg = 0x340,
0604 .shift = 0,
0605 .mask = 0xff,
0606 .def = 0x13,
0607 },
0608 },
0609 .fifo_size = 16 * 64,
0610 }, {
0611 .id = 0x22,
0612 .name = "vdebsevr",
0613 .swgroup = TEGRA_SWGROUP_VDE,
0614 .regs = {
0615 .smmu = {
0616 .reg = 0x22c,
0617 .bit = 2,
0618 },
0619 .la = {
0620 .reg = 0x354,
0621 .shift = 0,
0622 .mask = 0xff,
0623 .def = 0xff,
0624 },
0625 },
0626 .fifo_size = 16 * 8,
0627 }, {
0628 .id = 0x23,
0629 .name = "vdember",
0630 .swgroup = TEGRA_SWGROUP_VDE,
0631 .regs = {
0632 .smmu = {
0633 .reg = 0x22c,
0634 .bit = 3,
0635 },
0636 .la = {
0637 .reg = 0x354,
0638 .shift = 16,
0639 .mask = 0xff,
0640 .def = 0xd0,
0641 },
0642 },
0643 .fifo_size = 16 * 4,
0644 }, {
0645 .id = 0x24,
0646 .name = "vdemcer",
0647 .swgroup = TEGRA_SWGROUP_VDE,
0648 .regs = {
0649 .smmu = {
0650 .reg = 0x22c,
0651 .bit = 4,
0652 },
0653 .la = {
0654 .reg = 0x358,
0655 .shift = 0,
0656 .mask = 0xff,
0657 .def = 0x2a,
0658 },
0659 },
0660 .fifo_size = 16 * 16,
0661 }, {
0662 .id = 0x25,
0663 .name = "vdetper",
0664 .swgroup = TEGRA_SWGROUP_VDE,
0665 .regs = {
0666 .smmu = {
0667 .reg = 0x22c,
0668 .bit = 5,
0669 },
0670 .la = {
0671 .reg = 0x358,
0672 .shift = 16,
0673 .mask = 0xff,
0674 .def = 0x74,
0675 },
0676 },
0677 .fifo_size = 16 * 16,
0678 }, {
0679 .id = 0x26,
0680 .name = "mpcorelpr",
0681 .swgroup = TEGRA_SWGROUP_MPCORELP,
0682 .regs = {
0683 .la = {
0684 .reg = 0x324,
0685 .shift = 0,
0686 .mask = 0xff,
0687 .def = 0x04,
0688 },
0689 },
0690 .fifo_size = 16 * 14,
0691 }, {
0692 .id = 0x27,
0693 .name = "mpcorer",
0694 .swgroup = TEGRA_SWGROUP_MPCORE,
0695 .regs = {
0696 .la = {
0697 .reg = 0x320,
0698 .shift = 0,
0699 .mask = 0xff,
0700 .def = 0x04,
0701 },
0702 },
0703 .fifo_size = 16 * 14,
0704 }, {
0705 .id = 0x28,
0706 .name = "eppu",
0707 .swgroup = TEGRA_SWGROUP_EPP,
0708 .regs = {
0709 .smmu = {
0710 .reg = 0x22c,
0711 .bit = 8,
0712 },
0713 .la = {
0714 .reg = 0x300,
0715 .shift = 16,
0716 .mask = 0xff,
0717 .def = 0x6c,
0718 },
0719 },
0720 .fifo_size = 16 * 64,
0721 }, {
0722 .id = 0x29,
0723 .name = "eppv",
0724 .swgroup = TEGRA_SWGROUP_EPP,
0725 .regs = {
0726 .smmu = {
0727 .reg = 0x22c,
0728 .bit = 9,
0729 },
0730 .la = {
0731 .reg = 0x304,
0732 .shift = 0,
0733 .mask = 0xff,
0734 .def = 0x6c,
0735 },
0736 },
0737 .fifo_size = 16 * 64,
0738 }, {
0739 .id = 0x2a,
0740 .name = "eppy",
0741 .swgroup = TEGRA_SWGROUP_EPP,
0742 .regs = {
0743 .smmu = {
0744 .reg = 0x22c,
0745 .bit = 10,
0746 },
0747 .la = {
0748 .reg = 0x304,
0749 .shift = 16,
0750 .mask = 0xff,
0751 .def = 0x6c,
0752 },
0753 },
0754 .fifo_size = 16 * 64,
0755 }, {
0756 .id = 0x2b,
0757 .name = "mpeunifbw",
0758 .swgroup = TEGRA_SWGROUP_MPE,
0759 .regs = {
0760 .smmu = {
0761 .reg = 0x22c,
0762 .bit = 11,
0763 },
0764 .la = {
0765 .reg = 0x330,
0766 .shift = 0,
0767 .mask = 0xff,
0768 .def = 0x13,
0769 },
0770 },
0771 .fifo_size = 16 * 8,
0772 }, {
0773 .id = 0x2c,
0774 .name = "viwsb",
0775 .swgroup = TEGRA_SWGROUP_VI,
0776 .regs = {
0777 .smmu = {
0778 .reg = 0x22c,
0779 .bit = 12,
0780 },
0781 .la = {
0782 .reg = 0x364,
0783 .shift = 16,
0784 .mask = 0xff,
0785 .def = 0x12,
0786 },
0787 },
0788 .fifo_size = 16 * 64,
0789 }, {
0790 .id = 0x2d,
0791 .name = "viwu",
0792 .swgroup = TEGRA_SWGROUP_VI,
0793 .regs = {
0794 .smmu = {
0795 .reg = 0x22c,
0796 .bit = 13,
0797 },
0798 .la = {
0799 .reg = 0x368,
0800 .shift = 0,
0801 .mask = 0xff,
0802 .def = 0xb2,
0803 },
0804 },
0805 .fifo_size = 16 * 64,
0806 }, {
0807 .id = 0x2e,
0808 .name = "viwv",
0809 .swgroup = TEGRA_SWGROUP_VI,
0810 .regs = {
0811 .smmu = {
0812 .reg = 0x22c,
0813 .bit = 14,
0814 },
0815 .la = {
0816 .reg = 0x368,
0817 .shift = 16,
0818 .mask = 0xff,
0819 .def = 0xb2,
0820 },
0821 },
0822 .fifo_size = 16 * 64,
0823 }, {
0824 .id = 0x2f,
0825 .name = "viwy",
0826 .swgroup = TEGRA_SWGROUP_VI,
0827 .regs = {
0828 .smmu = {
0829 .reg = 0x22c,
0830 .bit = 15,
0831 },
0832 .la = {
0833 .reg = 0x36c,
0834 .shift = 0,
0835 .mask = 0xff,
0836 .def = 0x12,
0837 },
0838 },
0839 .fifo_size = 16 * 64,
0840 }, {
0841 .id = 0x30,
0842 .name = "g2dw",
0843 .swgroup = TEGRA_SWGROUP_G2,
0844 .regs = {
0845 .smmu = {
0846 .reg = 0x22c,
0847 .bit = 16,
0848 },
0849 .la = {
0850 .reg = 0x30c,
0851 .shift = 16,
0852 .mask = 0xff,
0853 .def = 0x9,
0854 },
0855 },
0856 .fifo_size = 16 * 128,
0857 }, {
0858 .id = 0x31,
0859 .name = "afiw",
0860 .swgroup = TEGRA_SWGROUP_AFI,
0861 .regs = {
0862 .smmu = {
0863 .reg = 0x22c,
0864 .bit = 17,
0865 },
0866 .la = {
0867 .reg = 0x2e0,
0868 .shift = 16,
0869 .mask = 0xff,
0870 .def = 0x0c,
0871 },
0872 },
0873 .fifo_size = 16 * 32,
0874 }, {
0875 .id = 0x32,
0876 .name = "avpcarm7w",
0877 .swgroup = TEGRA_SWGROUP_AVPC,
0878 .regs = {
0879 .smmu = {
0880 .reg = 0x22c,
0881 .bit = 18,
0882 },
0883 .la = {
0884 .reg = 0x2e4,
0885 .shift = 16,
0886 .mask = 0xff,
0887 .def = 0x0e,
0888 },
0889 },
0890 .fifo_size = 16 * 2,
0891 }, {
0892 .id = 0x33,
0893 .name = "fdcdwr",
0894 .swgroup = TEGRA_SWGROUP_NV,
0895 .regs = {
0896 .smmu = {
0897 .reg = 0x22c,
0898 .bit = 19,
0899 },
0900 .la = {
0901 .reg = 0x338,
0902 .shift = 16,
0903 .mask = 0xff,
0904 .def = 0x0a,
0905 },
0906 },
0907 .fifo_size = 16 * 48,
0908 }, {
0909 .id = 0x34,
0910 .name = "fdcdwr2",
0911 .swgroup = TEGRA_SWGROUP_NV2,
0912 .regs = {
0913 .smmu = {
0914 .reg = 0x22c,
0915 .bit = 20,
0916 },
0917 .la = {
0918 .reg = 0x340,
0919 .shift = 16,
0920 .mask = 0xff,
0921 .def = 0x0a,
0922 },
0923 },
0924 .fifo_size = 16 * 48,
0925 }, {
0926 .id = 0x35,
0927 .name = "hdaw",
0928 .swgroup = TEGRA_SWGROUP_HDA,
0929 .regs = {
0930 .smmu = {
0931 .reg = 0x22c,
0932 .bit = 21,
0933 },
0934 .la = {
0935 .reg = 0x318,
0936 .shift = 16,
0937 .mask = 0xff,
0938 .def = 0xff,
0939 },
0940 },
0941 .fifo_size = 16 * 16,
0942 }, {
0943 .id = 0x36,
0944 .name = "host1xw",
0945 .swgroup = TEGRA_SWGROUP_HC,
0946 .regs = {
0947 .smmu = {
0948 .reg = 0x22c,
0949 .bit = 22,
0950 },
0951 .la = {
0952 .reg = 0x314,
0953 .shift = 0,
0954 .mask = 0xff,
0955 .def = 0x10,
0956 },
0957 },
0958 .fifo_size = 16 * 32,
0959 }, {
0960 .id = 0x37,
0961 .name = "ispw",
0962 .swgroup = TEGRA_SWGROUP_ISP,
0963 .regs = {
0964 .smmu = {
0965 .reg = 0x22c,
0966 .bit = 23,
0967 },
0968 .la = {
0969 .reg = 0x31c,
0970 .shift = 0,
0971 .mask = 0xff,
0972 .def = 0xff,
0973 },
0974 },
0975 .fifo_size = 16 * 64,
0976 }, {
0977 .id = 0x38,
0978 .name = "mpcorelpw",
0979 .swgroup = TEGRA_SWGROUP_MPCORELP,
0980 .regs = {
0981 .la = {
0982 .reg = 0x324,
0983 .shift = 16,
0984 .mask = 0xff,
0985 .def = 0x0e,
0986 },
0987 },
0988 .fifo_size = 16 * 24,
0989 }, {
0990 .id = 0x39,
0991 .name = "mpcorew",
0992 .swgroup = TEGRA_SWGROUP_MPCORE,
0993 .regs = {
0994 .la = {
0995 .reg = 0x320,
0996 .shift = 16,
0997 .mask = 0xff,
0998 .def = 0x0e,
0999 },
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
1141 static 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
1160 static 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
1168 static 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
1176 static 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
1198 static 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
1219 static 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
1228 if (bandwidth_mbytes_sec)
1229 arb_nsec = fifo_size * NSEC_PER_USEC / bandwidth_mbytes_sec;
1230 else
1231 arb_nsec = U32_MAX;
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244 switch (client->swgroup) {
1245 case TEGRA_SWGROUP_MPCORE:
1246 case TEGRA_SWGROUP_PTC:
1247
1248
1249
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 else
1273 arb_nsec = 0;
1274
1275 arb_nsec /= arb_tolerance_compensation_div;
1276
1277
1278
1279
1280
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
1291 static 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
1299
1300
1301
1302
1303
1304
1305 if (src == dst)
1306 return 0;
1307
1308
1309 do_div(peak_bandwidth, 1000000);
1310
1311 tegra30_mc_tune_client_latency(mc, client, peak_bandwidth);
1312
1313 return 0;
1314 }
1315
1316 static 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
1321
1322
1323
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
1334 static struct icc_node_data *
1335 tegra30_mc_of_icc_xlate_extended(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
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
1381 static 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
1387 const 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 };