cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

tegra30.c (25398B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (C) 2014 NVIDIA CORPORATION.  All rights reserved.
      4 */
      5
      6#include <linux/of.h>
      7#include <linux/of_device.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	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
   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 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
   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 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
   1334static struct icc_node_data *
   1335tegra30_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
   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};