Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2014 NVIDIA CORPORATION.  All rights reserved.
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     /* 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     else
1231         arb_nsec = U32_MAX;
1232 
1233     /*
1234      * Latency allowness should be set with consideration for the module's
1235      * latency tolerance and internal buffering capabilities.
1236      *
1237      * Display memory clients use isochronous transfers and have very low
1238      * tolerance to a belated transfers. Hence we need to compensate the
1239      * memory arbitration imperfection for them in order to prevent FIFO
1240      * 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, hence
1249          * 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     else
1273         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 particular
1279      * client may wait in the EMEM arbiter before it becomes a high-priority
1280      * 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 
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      * Skip pre-initialization that is done by icc_node_add(), which sets
1299      * 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 all
1302      * clients and it's okay to keep configuration left from bootloader
1303      * 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 
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      * ISO clients need to reserve extra bandwidth up-front because
1321      * there could be high bandwidth pressure during initial filling
1322      * of the client's FIFO buffers.  Secondly, we need to take into
1323      * 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 
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             /* 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 
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 };