mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1271 lines
23 KiB
1271 lines
23 KiB
// SPDX-License-Identifier: GPL-2.0-only |
|
/* |
|
* Copyright (C) 2014 NVIDIA CORPORATION. All rights reserved. |
|
*/ |
|
|
|
#include <linux/of.h> |
|
#include <linux/of_device.h> |
|
#include <linux/slab.h> |
|
|
|
#include <dt-bindings/memory/tegra30-mc.h> |
|
|
|
#include "mc.h" |
|
|
|
static const unsigned long tegra30_mc_emem_regs[] = { |
|
MC_EMEM_ARB_CFG, |
|
MC_EMEM_ARB_OUTSTANDING_REQ, |
|
MC_EMEM_ARB_TIMING_RCD, |
|
MC_EMEM_ARB_TIMING_RP, |
|
MC_EMEM_ARB_TIMING_RC, |
|
MC_EMEM_ARB_TIMING_RAS, |
|
MC_EMEM_ARB_TIMING_FAW, |
|
MC_EMEM_ARB_TIMING_RRD, |
|
MC_EMEM_ARB_TIMING_RAP2PRE, |
|
MC_EMEM_ARB_TIMING_WAP2PRE, |
|
MC_EMEM_ARB_TIMING_R2R, |
|
MC_EMEM_ARB_TIMING_W2W, |
|
MC_EMEM_ARB_TIMING_R2W, |
|
MC_EMEM_ARB_TIMING_W2R, |
|
MC_EMEM_ARB_DA_TURNS, |
|
MC_EMEM_ARB_DA_COVERS, |
|
MC_EMEM_ARB_MISC0, |
|
MC_EMEM_ARB_RING1_THROTTLE, |
|
}; |
|
|
|
static const struct tegra_mc_client tegra30_mc_clients[] = { |
|
{ |
|
.id = 0x00, |
|
.name = "ptcr", |
|
.swgroup = TEGRA_SWGROUP_PTC, |
|
.la = { |
|
.reg = 0x34c, |
|
.shift = 0, |
|
.mask = 0xff, |
|
.def = 0x0, |
|
}, |
|
.fifo_size = 16 * 2, |
|
}, { |
|
.id = 0x01, |
|
.name = "display0a", |
|
.swgroup = TEGRA_SWGROUP_DC, |
|
.smmu = { |
|
.reg = 0x228, |
|
.bit = 1, |
|
}, |
|
.la = { |
|
.reg = 0x2e8, |
|
.shift = 0, |
|
.mask = 0xff, |
|
.def = 0x4e, |
|
}, |
|
.fifo_size = 16 * 128, |
|
}, { |
|
.id = 0x02, |
|
.name = "display0ab", |
|
.swgroup = TEGRA_SWGROUP_DCB, |
|
.smmu = { |
|
.reg = 0x228, |
|
.bit = 2, |
|
}, |
|
.la = { |
|
.reg = 0x2f4, |
|
.shift = 0, |
|
.mask = 0xff, |
|
.def = 0x4e, |
|
}, |
|
.fifo_size = 16 * 128, |
|
}, { |
|
.id = 0x03, |
|
.name = "display0b", |
|
.swgroup = TEGRA_SWGROUP_DC, |
|
.smmu = { |
|
.reg = 0x228, |
|
.bit = 3, |
|
}, |
|
.la = { |
|
.reg = 0x2e8, |
|
.shift = 16, |
|
.mask = 0xff, |
|
.def = 0x4e, |
|
}, |
|
.fifo_size = 16 * 64, |
|
}, { |
|
.id = 0x04, |
|
.name = "display0bb", |
|
.swgroup = TEGRA_SWGROUP_DCB, |
|
.smmu = { |
|
.reg = 0x228, |
|
.bit = 4, |
|
}, |
|
.la = { |
|
.reg = 0x2f4, |
|
.shift = 16, |
|
.mask = 0xff, |
|
.def = 0x4e, |
|
}, |
|
.fifo_size = 16 * 64, |
|
}, { |
|
.id = 0x05, |
|
.name = "display0c", |
|
.swgroup = TEGRA_SWGROUP_DC, |
|
.smmu = { |
|
.reg = 0x228, |
|
.bit = 5, |
|
}, |
|
.la = { |
|
.reg = 0x2ec, |
|
.shift = 0, |
|
.mask = 0xff, |
|
.def = 0x4e, |
|
}, |
|
.fifo_size = 16 * 128, |
|
}, { |
|
.id = 0x06, |
|
.name = "display0cb", |
|
.swgroup = TEGRA_SWGROUP_DCB, |
|
.smmu = { |
|
.reg = 0x228, |
|
.bit = 6, |
|
}, |
|
.la = { |
|
.reg = 0x2f8, |
|
.shift = 0, |
|
.mask = 0xff, |
|
.def = 0x4e, |
|
}, |
|
.fifo_size = 16 * 128, |
|
}, { |
|
.id = 0x07, |
|
.name = "display1b", |
|
.swgroup = TEGRA_SWGROUP_DC, |
|
.smmu = { |
|
.reg = 0x228, |
|
.bit = 7, |
|
}, |
|
.la = { |
|
.reg = 0x2ec, |
|
.shift = 16, |
|
.mask = 0xff, |
|
.def = 0x4e, |
|
}, |
|
.fifo_size = 16 * 64, |
|
}, { |
|
.id = 0x08, |
|
.name = "display1bb", |
|
.swgroup = TEGRA_SWGROUP_DCB, |
|
.smmu = { |
|
.reg = 0x228, |
|
.bit = 8, |
|
}, |
|
.la = { |
|
.reg = 0x2f8, |
|
.shift = 16, |
|
.mask = 0xff, |
|
.def = 0x4e, |
|
}, |
|
.fifo_size = 16 * 64, |
|
}, { |
|
.id = 0x09, |
|
.name = "eppup", |
|
.swgroup = TEGRA_SWGROUP_EPP, |
|
.smmu = { |
|
.reg = 0x228, |
|
.bit = 9, |
|
}, |
|
.la = { |
|
.reg = 0x300, |
|
.shift = 0, |
|
.mask = 0xff, |
|
.def = 0x17, |
|
}, |
|
.fifo_size = 16 * 8, |
|
}, { |
|
.id = 0x0a, |
|
.name = "g2pr", |
|
.swgroup = TEGRA_SWGROUP_G2, |
|
.smmu = { |
|
.reg = 0x228, |
|
.bit = 10, |
|
}, |
|
.la = { |
|
.reg = 0x308, |
|
.shift = 0, |
|
.mask = 0xff, |
|
.def = 0x09, |
|
}, |
|
.fifo_size = 16 * 64, |
|
}, { |
|
.id = 0x0b, |
|
.name = "g2sr", |
|
.swgroup = TEGRA_SWGROUP_G2, |
|
.smmu = { |
|
.reg = 0x228, |
|
.bit = 11, |
|
}, |
|
.la = { |
|
.reg = 0x308, |
|
.shift = 16, |
|
.mask = 0xff, |
|
.def = 0x09, |
|
}, |
|
.fifo_size = 16 * 64, |
|
}, { |
|
.id = 0x0c, |
|
.name = "mpeunifbr", |
|
.swgroup = TEGRA_SWGROUP_MPE, |
|
.smmu = { |
|
.reg = 0x228, |
|
.bit = 12, |
|
}, |
|
.la = { |
|
.reg = 0x328, |
|
.shift = 0, |
|
.mask = 0xff, |
|
.def = 0x50, |
|
}, |
|
.fifo_size = 16 * 8, |
|
}, { |
|
.id = 0x0d, |
|
.name = "viruv", |
|
.swgroup = TEGRA_SWGROUP_VI, |
|
.smmu = { |
|
.reg = 0x228, |
|
.bit = 13, |
|
}, |
|
.la = { |
|
.reg = 0x364, |
|
.shift = 0, |
|
.mask = 0xff, |
|
.def = 0x2c, |
|
}, |
|
.fifo_size = 16 * 8, |
|
}, { |
|
.id = 0x0e, |
|
.name = "afir", |
|
.swgroup = TEGRA_SWGROUP_AFI, |
|
.smmu = { |
|
.reg = 0x228, |
|
.bit = 14, |
|
}, |
|
.la = { |
|
.reg = 0x2e0, |
|
.shift = 0, |
|
.mask = 0xff, |
|
.def = 0x10, |
|
}, |
|
.fifo_size = 16 * 32, |
|
}, { |
|
.id = 0x0f, |
|
.name = "avpcarm7r", |
|
.swgroup = TEGRA_SWGROUP_AVPC, |
|
.smmu = { |
|
.reg = 0x228, |
|
.bit = 15, |
|
}, |
|
.la = { |
|
.reg = 0x2e4, |
|
.shift = 0, |
|
.mask = 0xff, |
|
.def = 0x04, |
|
}, |
|
.fifo_size = 16 * 2, |
|
}, { |
|
.id = 0x10, |
|
.name = "displayhc", |
|
.swgroup = TEGRA_SWGROUP_DC, |
|
.smmu = { |
|
.reg = 0x228, |
|
.bit = 16, |
|
}, |
|
.la = { |
|
.reg = 0x2f0, |
|
.shift = 0, |
|
.mask = 0xff, |
|
.def = 0xff, |
|
}, |
|
.fifo_size = 16 * 2, |
|
}, { |
|
.id = 0x11, |
|
.name = "displayhcb", |
|
.swgroup = TEGRA_SWGROUP_DCB, |
|
.smmu = { |
|
.reg = 0x228, |
|
.bit = 17, |
|
}, |
|
.la = { |
|
.reg = 0x2fc, |
|
.shift = 0, |
|
.mask = 0xff, |
|
.def = 0xff, |
|
}, |
|
.fifo_size = 16 * 2, |
|
}, { |
|
.id = 0x12, |
|
.name = "fdcdrd", |
|
.swgroup = TEGRA_SWGROUP_NV, |
|
.smmu = { |
|
.reg = 0x228, |
|
.bit = 18, |
|
}, |
|
.la = { |
|
.reg = 0x334, |
|
.shift = 0, |
|
.mask = 0xff, |
|
.def = 0x0a, |
|
}, |
|
.fifo_size = 16 * 48, |
|
}, { |
|
.id = 0x13, |
|
.name = "fdcdrd2", |
|
.swgroup = TEGRA_SWGROUP_NV2, |
|
.smmu = { |
|
.reg = 0x228, |
|
.bit = 19, |
|
}, |
|
.la = { |
|
.reg = 0x33c, |
|
.shift = 0, |
|
.mask = 0xff, |
|
.def = 0x0a, |
|
}, |
|
.fifo_size = 16 * 48, |
|
}, { |
|
.id = 0x14, |
|
.name = "g2dr", |
|
.swgroup = TEGRA_SWGROUP_G2, |
|
.smmu = { |
|
.reg = 0x228, |
|
.bit = 20, |
|
}, |
|
.la = { |
|
.reg = 0x30c, |
|
.shift = 0, |
|
.mask = 0xff, |
|
.def = 0x0a, |
|
}, |
|
.fifo_size = 16 * 48, |
|
}, { |
|
.id = 0x15, |
|
.name = "hdar", |
|
.swgroup = TEGRA_SWGROUP_HDA, |
|
.smmu = { |
|
.reg = 0x228, |
|
.bit = 21, |
|
}, |
|
.la = { |
|
.reg = 0x318, |
|
.shift = 0, |
|
.mask = 0xff, |
|
.def = 0xff, |
|
}, |
|
.fifo_size = 16 * 16, |
|
}, { |
|
.id = 0x16, |
|
.name = "host1xdmar", |
|
.swgroup = TEGRA_SWGROUP_HC, |
|
.smmu = { |
|
.reg = 0x228, |
|
.bit = 22, |
|
}, |
|
.la = { |
|
.reg = 0x310, |
|
.shift = 0, |
|
.mask = 0xff, |
|
.def = 0x05, |
|
}, |
|
.fifo_size = 16 * 16, |
|
}, { |
|
.id = 0x17, |
|
.name = "host1xr", |
|
.swgroup = TEGRA_SWGROUP_HC, |
|
.smmu = { |
|
.reg = 0x228, |
|
.bit = 23, |
|
}, |
|
.la = { |
|
.reg = 0x310, |
|
.shift = 16, |
|
.mask = 0xff, |
|
.def = 0x50, |
|
}, |
|
.fifo_size = 16 * 8, |
|
}, { |
|
.id = 0x18, |
|
.name = "idxsrd", |
|
.swgroup = TEGRA_SWGROUP_NV, |
|
.smmu = { |
|
.reg = 0x228, |
|
.bit = 24, |
|
}, |
|
.la = { |
|
.reg = 0x334, |
|
.shift = 16, |
|
.mask = 0xff, |
|
.def = 0x13, |
|
}, |
|
.fifo_size = 16 * 64, |
|
}, { |
|
.id = 0x19, |
|
.name = "idxsrd2", |
|
.swgroup = TEGRA_SWGROUP_NV2, |
|
.smmu = { |
|
.reg = 0x228, |
|
.bit = 25, |
|
}, |
|
.la = { |
|
.reg = 0x33c, |
|
.shift = 16, |
|
.mask = 0xff, |
|
.def = 0x13, |
|
}, |
|
.fifo_size = 16 * 64, |
|
}, { |
|
.id = 0x1a, |
|
.name = "mpe_ipred", |
|
.swgroup = TEGRA_SWGROUP_MPE, |
|
.smmu = { |
|
.reg = 0x228, |
|
.bit = 26, |
|
}, |
|
.la = { |
|
.reg = 0x328, |
|
.shift = 16, |
|
.mask = 0xff, |
|
.def = 0x80, |
|
}, |
|
.fifo_size = 16 * 2, |
|
}, { |
|
.id = 0x1b, |
|
.name = "mpeamemrd", |
|
.swgroup = TEGRA_SWGROUP_MPE, |
|
.smmu = { |
|
.reg = 0x228, |
|
.bit = 27, |
|
}, |
|
.la = { |
|
.reg = 0x32c, |
|
.shift = 0, |
|
.mask = 0xff, |
|
.def = 0x42, |
|
}, |
|
.fifo_size = 16 * 64, |
|
}, { |
|
.id = 0x1c, |
|
.name = "mpecsrd", |
|
.swgroup = TEGRA_SWGROUP_MPE, |
|
.smmu = { |
|
.reg = 0x228, |
|
.bit = 28, |
|
}, |
|
.la = { |
|
.reg = 0x32c, |
|
.shift = 16, |
|
.mask = 0xff, |
|
.def = 0xff, |
|
}, |
|
.fifo_size = 16 * 8, |
|
}, { |
|
.id = 0x1d, |
|
.name = "ppcsahbdmar", |
|
.swgroup = TEGRA_SWGROUP_PPCS, |
|
.smmu = { |
|
.reg = 0x228, |
|
.bit = 29, |
|
}, |
|
.la = { |
|
.reg = 0x344, |
|
.shift = 0, |
|
.mask = 0xff, |
|
.def = 0x10, |
|
}, |
|
.fifo_size = 16 * 2, |
|
}, { |
|
.id = 0x1e, |
|
.name = "ppcsahbslvr", |
|
.swgroup = TEGRA_SWGROUP_PPCS, |
|
.smmu = { |
|
.reg = 0x228, |
|
.bit = 30, |
|
}, |
|
.la = { |
|
.reg = 0x344, |
|
.shift = 16, |
|
.mask = 0xff, |
|
.def = 0x12, |
|
}, |
|
.fifo_size = 16 * 8, |
|
}, { |
|
.id = 0x1f, |
|
.name = "satar", |
|
.swgroup = TEGRA_SWGROUP_SATA, |
|
.smmu = { |
|
.reg = 0x228, |
|
.bit = 31, |
|
}, |
|
.la = { |
|
.reg = 0x350, |
|
.shift = 0, |
|
.mask = 0xff, |
|
.def = 0x33, |
|
}, |
|
.fifo_size = 16 * 32, |
|
}, { |
|
.id = 0x20, |
|
.name = "texsrd", |
|
.swgroup = TEGRA_SWGROUP_NV, |
|
.smmu = { |
|
.reg = 0x22c, |
|
.bit = 0, |
|
}, |
|
.la = { |
|
.reg = 0x338, |
|
.shift = 0, |
|
.mask = 0xff, |
|
.def = 0x13, |
|
}, |
|
.fifo_size = 16 * 64, |
|
}, { |
|
.id = 0x21, |
|
.name = "texsrd2", |
|
.swgroup = TEGRA_SWGROUP_NV2, |
|
.smmu = { |
|
.reg = 0x22c, |
|
.bit = 1, |
|
}, |
|
.la = { |
|
.reg = 0x340, |
|
.shift = 0, |
|
.mask = 0xff, |
|
.def = 0x13, |
|
}, |
|
.fifo_size = 16 * 64, |
|
}, { |
|
.id = 0x22, |
|
.name = "vdebsevr", |
|
.swgroup = TEGRA_SWGROUP_VDE, |
|
.smmu = { |
|
.reg = 0x22c, |
|
.bit = 2, |
|
}, |
|
.la = { |
|
.reg = 0x354, |
|
.shift = 0, |
|
.mask = 0xff, |
|
.def = 0xff, |
|
}, |
|
.fifo_size = 16 * 8, |
|
}, { |
|
.id = 0x23, |
|
.name = "vdember", |
|
.swgroup = TEGRA_SWGROUP_VDE, |
|
.smmu = { |
|
.reg = 0x22c, |
|
.bit = 3, |
|
}, |
|
.la = { |
|
.reg = 0x354, |
|
.shift = 16, |
|
.mask = 0xff, |
|
.def = 0xd0, |
|
}, |
|
.fifo_size = 16 * 4, |
|
}, { |
|
.id = 0x24, |
|
.name = "vdemcer", |
|
.swgroup = TEGRA_SWGROUP_VDE, |
|
.smmu = { |
|
.reg = 0x22c, |
|
.bit = 4, |
|
}, |
|
.la = { |
|
.reg = 0x358, |
|
.shift = 0, |
|
.mask = 0xff, |
|
.def = 0x2a, |
|
}, |
|
.fifo_size = 16 * 16, |
|
}, { |
|
.id = 0x25, |
|
.name = "vdetper", |
|
.swgroup = TEGRA_SWGROUP_VDE, |
|
.smmu = { |
|
.reg = 0x22c, |
|
.bit = 5, |
|
}, |
|
.la = { |
|
.reg = 0x358, |
|
.shift = 16, |
|
.mask = 0xff, |
|
.def = 0x74, |
|
}, |
|
.fifo_size = 16 * 16, |
|
}, { |
|
.id = 0x26, |
|
.name = "mpcorelpr", |
|
.swgroup = TEGRA_SWGROUP_MPCORELP, |
|
.la = { |
|
.reg = 0x324, |
|
.shift = 0, |
|
.mask = 0xff, |
|
.def = 0x04, |
|
}, |
|
.fifo_size = 16 * 14, |
|
}, { |
|
.id = 0x27, |
|
.name = "mpcorer", |
|
.swgroup = TEGRA_SWGROUP_MPCORE, |
|
.la = { |
|
.reg = 0x320, |
|
.shift = 0, |
|
.mask = 0xff, |
|
.def = 0x04, |
|
}, |
|
.fifo_size = 16 * 14, |
|
}, { |
|
.id = 0x28, |
|
.name = "eppu", |
|
.swgroup = TEGRA_SWGROUP_EPP, |
|
.smmu = { |
|
.reg = 0x22c, |
|
.bit = 8, |
|
}, |
|
.la = { |
|
.reg = 0x300, |
|
.shift = 16, |
|
.mask = 0xff, |
|
.def = 0x6c, |
|
}, |
|
.fifo_size = 16 * 64, |
|
}, { |
|
.id = 0x29, |
|
.name = "eppv", |
|
.swgroup = TEGRA_SWGROUP_EPP, |
|
.smmu = { |
|
.reg = 0x22c, |
|
.bit = 9, |
|
}, |
|
.la = { |
|
.reg = 0x304, |
|
.shift = 0, |
|
.mask = 0xff, |
|
.def = 0x6c, |
|
}, |
|
.fifo_size = 16 * 64, |
|
}, { |
|
.id = 0x2a, |
|
.name = "eppy", |
|
.swgroup = TEGRA_SWGROUP_EPP, |
|
.smmu = { |
|
.reg = 0x22c, |
|
.bit = 10, |
|
}, |
|
.la = { |
|
.reg = 0x304, |
|
.shift = 16, |
|
.mask = 0xff, |
|
.def = 0x6c, |
|
}, |
|
.fifo_size = 16 * 64, |
|
}, { |
|
.id = 0x2b, |
|
.name = "mpeunifbw", |
|
.swgroup = TEGRA_SWGROUP_MPE, |
|
.smmu = { |
|
.reg = 0x22c, |
|
.bit = 11, |
|
}, |
|
.la = { |
|
.reg = 0x330, |
|
.shift = 0, |
|
.mask = 0xff, |
|
.def = 0x13, |
|
}, |
|
.fifo_size = 16 * 8, |
|
}, { |
|
.id = 0x2c, |
|
.name = "viwsb", |
|
.swgroup = TEGRA_SWGROUP_VI, |
|
.smmu = { |
|
.reg = 0x22c, |
|
.bit = 12, |
|
}, |
|
.la = { |
|
.reg = 0x364, |
|
.shift = 16, |
|
.mask = 0xff, |
|
.def = 0x12, |
|
}, |
|
.fifo_size = 16 * 64, |
|
}, { |
|
.id = 0x2d, |
|
.name = "viwu", |
|
.swgroup = TEGRA_SWGROUP_VI, |
|
.smmu = { |
|
.reg = 0x22c, |
|
.bit = 13, |
|
}, |
|
.la = { |
|
.reg = 0x368, |
|
.shift = 0, |
|
.mask = 0xff, |
|
.def = 0xb2, |
|
}, |
|
.fifo_size = 16 * 64, |
|
}, { |
|
.id = 0x2e, |
|
.name = "viwv", |
|
.swgroup = TEGRA_SWGROUP_VI, |
|
.smmu = { |
|
.reg = 0x22c, |
|
.bit = 14, |
|
}, |
|
.la = { |
|
.reg = 0x368, |
|
.shift = 16, |
|
.mask = 0xff, |
|
.def = 0xb2, |
|
}, |
|
.fifo_size = 16 * 64, |
|
}, { |
|
.id = 0x2f, |
|
.name = "viwy", |
|
.swgroup = TEGRA_SWGROUP_VI, |
|
.smmu = { |
|
.reg = 0x22c, |
|
.bit = 15, |
|
}, |
|
.la = { |
|
.reg = 0x36c, |
|
.shift = 0, |
|
.mask = 0xff, |
|
.def = 0x12, |
|
}, |
|
.fifo_size = 16 * 64, |
|
}, { |
|
.id = 0x30, |
|
.name = "g2dw", |
|
.swgroup = TEGRA_SWGROUP_G2, |
|
.smmu = { |
|
.reg = 0x22c, |
|
.bit = 16, |
|
}, |
|
.la = { |
|
.reg = 0x30c, |
|
.shift = 16, |
|
.mask = 0xff, |
|
.def = 0x9, |
|
}, |
|
.fifo_size = 16 * 128, |
|
}, { |
|
.id = 0x31, |
|
.name = "afiw", |
|
.swgroup = TEGRA_SWGROUP_AFI, |
|
.smmu = { |
|
.reg = 0x22c, |
|
.bit = 17, |
|
}, |
|
.la = { |
|
.reg = 0x2e0, |
|
.shift = 16, |
|
.mask = 0xff, |
|
.def = 0x0c, |
|
}, |
|
.fifo_size = 16 * 32, |
|
}, { |
|
.id = 0x32, |
|
.name = "avpcarm7w", |
|
.swgroup = TEGRA_SWGROUP_AVPC, |
|
.smmu = { |
|
.reg = 0x22c, |
|
.bit = 18, |
|
}, |
|
.la = { |
|
.reg = 0x2e4, |
|
.shift = 16, |
|
.mask = 0xff, |
|
.def = 0x0e, |
|
}, |
|
.fifo_size = 16 * 2, |
|
}, { |
|
.id = 0x33, |
|
.name = "fdcdwr", |
|
.swgroup = TEGRA_SWGROUP_NV, |
|
.smmu = { |
|
.reg = 0x22c, |
|
.bit = 19, |
|
}, |
|
.la = { |
|
.reg = 0x338, |
|
.shift = 16, |
|
.mask = 0xff, |
|
.def = 0x0a, |
|
}, |
|
.fifo_size = 16 * 48, |
|
}, { |
|
.id = 0x34, |
|
.name = "fdcdwr2", |
|
.swgroup = TEGRA_SWGROUP_NV2, |
|
.smmu = { |
|
.reg = 0x22c, |
|
.bit = 20, |
|
}, |
|
.la = { |
|
.reg = 0x340, |
|
.shift = 16, |
|
.mask = 0xff, |
|
.def = 0x0a, |
|
}, |
|
.fifo_size = 16 * 48, |
|
}, { |
|
.id = 0x35, |
|
.name = "hdaw", |
|
.swgroup = TEGRA_SWGROUP_HDA, |
|
.smmu = { |
|
.reg = 0x22c, |
|
.bit = 21, |
|
}, |
|
.la = { |
|
.reg = 0x318, |
|
.shift = 16, |
|
.mask = 0xff, |
|
.def = 0xff, |
|
}, |
|
.fifo_size = 16 * 16, |
|
}, { |
|
.id = 0x36, |
|
.name = "host1xw", |
|
.swgroup = TEGRA_SWGROUP_HC, |
|
.smmu = { |
|
.reg = 0x22c, |
|
.bit = 22, |
|
}, |
|
.la = { |
|
.reg = 0x314, |
|
.shift = 0, |
|
.mask = 0xff, |
|
.def = 0x10, |
|
}, |
|
.fifo_size = 16 * 32, |
|
}, { |
|
.id = 0x37, |
|
.name = "ispw", |
|
.swgroup = TEGRA_SWGROUP_ISP, |
|
.smmu = { |
|
.reg = 0x22c, |
|
.bit = 23, |
|
}, |
|
.la = { |
|
.reg = 0x31c, |
|
.shift = 0, |
|
.mask = 0xff, |
|
.def = 0xff, |
|
}, |
|
.fifo_size = 16 * 64, |
|
}, { |
|
.id = 0x38, |
|
.name = "mpcorelpw", |
|
.swgroup = TEGRA_SWGROUP_MPCORELP, |
|
.la = { |
|
.reg = 0x324, |
|
.shift = 16, |
|
.mask = 0xff, |
|
.def = 0x0e, |
|
}, |
|
.fifo_size = 16 * 24, |
|
}, { |
|
.id = 0x39, |
|
.name = "mpcorew", |
|
.swgroup = TEGRA_SWGROUP_MPCORE, |
|
.la = { |
|
.reg = 0x320, |
|
.shift = 16, |
|
.mask = 0xff, |
|
.def = 0x0e, |
|
}, |
|
.fifo_size = 16 * 24, |
|
}, { |
|
.id = 0x3a, |
|
.name = "mpecswr", |
|
.swgroup = TEGRA_SWGROUP_MPE, |
|
.smmu = { |
|
.reg = 0x22c, |
|
.bit = 26, |
|
}, |
|
.la = { |
|
.reg = 0x330, |
|
.shift = 16, |
|
.mask = 0xff, |
|
.def = 0xff, |
|
}, |
|
.fifo_size = 16 * 8, |
|
}, { |
|
.id = 0x3b, |
|
.name = "ppcsahbdmaw", |
|
.swgroup = TEGRA_SWGROUP_PPCS, |
|
.smmu = { |
|
.reg = 0x22c, |
|
.bit = 27, |
|
}, |
|
.la = { |
|
.reg = 0x348, |
|
.shift = 0, |
|
.mask = 0xff, |
|
.def = 0x10, |
|
}, |
|
.fifo_size = 16 * 2, |
|
}, { |
|
.id = 0x3c, |
|
.name = "ppcsahbslvw", |
|
.swgroup = TEGRA_SWGROUP_PPCS, |
|
.smmu = { |
|
.reg = 0x22c, |
|
.bit = 28, |
|
}, |
|
.la = { |
|
.reg = 0x348, |
|
.shift = 16, |
|
.mask = 0xff, |
|
.def = 0x06, |
|
}, |
|
.fifo_size = 16 * 4, |
|
}, { |
|
.id = 0x3d, |
|
.name = "sataw", |
|
.swgroup = TEGRA_SWGROUP_SATA, |
|
.smmu = { |
|
.reg = 0x22c, |
|
.bit = 29, |
|
}, |
|
.la = { |
|
.reg = 0x350, |
|
.shift = 16, |
|
.mask = 0xff, |
|
.def = 0x33, |
|
}, |
|
.fifo_size = 16 * 32, |
|
}, { |
|
.id = 0x3e, |
|
.name = "vdebsevw", |
|
.swgroup = TEGRA_SWGROUP_VDE, |
|
.smmu = { |
|
.reg = 0x22c, |
|
.bit = 30, |
|
}, |
|
.la = { |
|
.reg = 0x35c, |
|
.shift = 0, |
|
.mask = 0xff, |
|
.def = 0xff, |
|
}, |
|
.fifo_size = 16 * 4, |
|
}, { |
|
.id = 0x3f, |
|
.name = "vdedbgw", |
|
.swgroup = TEGRA_SWGROUP_VDE, |
|
.smmu = { |
|
.reg = 0x22c, |
|
.bit = 31, |
|
}, |
|
.la = { |
|
.reg = 0x35c, |
|
.shift = 16, |
|
.mask = 0xff, |
|
.def = 0xff, |
|
}, |
|
.fifo_size = 16 * 16, |
|
}, { |
|
.id = 0x40, |
|
.name = "vdembew", |
|
.swgroup = TEGRA_SWGROUP_VDE, |
|
.smmu = { |
|
.reg = 0x230, |
|
.bit = 0, |
|
}, |
|
.la = { |
|
.reg = 0x360, |
|
.shift = 0, |
|
.mask = 0xff, |
|
.def = 0x42, |
|
}, |
|
.fifo_size = 16 * 2, |
|
}, { |
|
.id = 0x41, |
|
.name = "vdetpmw", |
|
.swgroup = TEGRA_SWGROUP_VDE, |
|
.smmu = { |
|
.reg = 0x230, |
|
.bit = 1, |
|
}, |
|
.la = { |
|
.reg = 0x360, |
|
.shift = 16, |
|
.mask = 0xff, |
|
.def = 0x2a, |
|
}, |
|
.fifo_size = 16 * 16, |
|
}, |
|
}; |
|
|
|
static const struct tegra_smmu_swgroup tegra30_swgroups[] = { |
|
{ .name = "dc", .swgroup = TEGRA_SWGROUP_DC, .reg = 0x240 }, |
|
{ .name = "dcb", .swgroup = TEGRA_SWGROUP_DCB, .reg = 0x244 }, |
|
{ .name = "epp", .swgroup = TEGRA_SWGROUP_EPP, .reg = 0x248 }, |
|
{ .name = "g2", .swgroup = TEGRA_SWGROUP_G2, .reg = 0x24c }, |
|
{ .name = "mpe", .swgroup = TEGRA_SWGROUP_MPE, .reg = 0x264 }, |
|
{ .name = "vi", .swgroup = TEGRA_SWGROUP_VI, .reg = 0x280 }, |
|
{ .name = "afi", .swgroup = TEGRA_SWGROUP_AFI, .reg = 0x238 }, |
|
{ .name = "avpc", .swgroup = TEGRA_SWGROUP_AVPC, .reg = 0x23c }, |
|
{ .name = "nv", .swgroup = TEGRA_SWGROUP_NV, .reg = 0x268 }, |
|
{ .name = "nv2", .swgroup = TEGRA_SWGROUP_NV2, .reg = 0x26c }, |
|
{ .name = "hda", .swgroup = TEGRA_SWGROUP_HDA, .reg = 0x254 }, |
|
{ .name = "hc", .swgroup = TEGRA_SWGROUP_HC, .reg = 0x250 }, |
|
{ .name = "ppcs", .swgroup = TEGRA_SWGROUP_PPCS, .reg = 0x270 }, |
|
{ .name = "sata", .swgroup = TEGRA_SWGROUP_SATA, .reg = 0x278 }, |
|
{ .name = "vde", .swgroup = TEGRA_SWGROUP_VDE, .reg = 0x27c }, |
|
{ .name = "isp", .swgroup = TEGRA_SWGROUP_ISP, .reg = 0x258 }, |
|
}; |
|
|
|
static const unsigned int tegra30_group_drm[] = { |
|
TEGRA_SWGROUP_DC, |
|
TEGRA_SWGROUP_DCB, |
|
TEGRA_SWGROUP_G2, |
|
TEGRA_SWGROUP_NV, |
|
TEGRA_SWGROUP_NV2, |
|
}; |
|
|
|
static const struct tegra_smmu_group_soc tegra30_groups[] = { |
|
{ |
|
.name = "drm", |
|
.swgroups = tegra30_group_drm, |
|
.num_swgroups = ARRAY_SIZE(tegra30_group_drm), |
|
}, |
|
}; |
|
|
|
static const struct tegra_smmu_soc tegra30_smmu_soc = { |
|
.clients = tegra30_mc_clients, |
|
.num_clients = ARRAY_SIZE(tegra30_mc_clients), |
|
.swgroups = tegra30_swgroups, |
|
.num_swgroups = ARRAY_SIZE(tegra30_swgroups), |
|
.groups = tegra30_groups, |
|
.num_groups = ARRAY_SIZE(tegra30_groups), |
|
.supports_round_robin_arbitration = false, |
|
.supports_request_limit = false, |
|
.num_tlb_lines = 16, |
|
.num_asids = 4, |
|
}; |
|
|
|
#define TEGRA30_MC_RESET(_name, _control, _status, _bit) \ |
|
{ \ |
|
.name = #_name, \ |
|
.id = TEGRA30_MC_RESET_##_name, \ |
|
.control = _control, \ |
|
.status = _status, \ |
|
.bit = _bit, \ |
|
} |
|
|
|
static const struct tegra_mc_reset tegra30_mc_resets[] = { |
|
TEGRA30_MC_RESET(AFI, 0x200, 0x204, 0), |
|
TEGRA30_MC_RESET(AVPC, 0x200, 0x204, 1), |
|
TEGRA30_MC_RESET(DC, 0x200, 0x204, 2), |
|
TEGRA30_MC_RESET(DCB, 0x200, 0x204, 3), |
|
TEGRA30_MC_RESET(EPP, 0x200, 0x204, 4), |
|
TEGRA30_MC_RESET(2D, 0x200, 0x204, 5), |
|
TEGRA30_MC_RESET(HC, 0x200, 0x204, 6), |
|
TEGRA30_MC_RESET(HDA, 0x200, 0x204, 7), |
|
TEGRA30_MC_RESET(ISP, 0x200, 0x204, 8), |
|
TEGRA30_MC_RESET(MPCORE, 0x200, 0x204, 9), |
|
TEGRA30_MC_RESET(MPCORELP, 0x200, 0x204, 10), |
|
TEGRA30_MC_RESET(MPE, 0x200, 0x204, 11), |
|
TEGRA30_MC_RESET(3D, 0x200, 0x204, 12), |
|
TEGRA30_MC_RESET(3D2, 0x200, 0x204, 13), |
|
TEGRA30_MC_RESET(PPCS, 0x200, 0x204, 14), |
|
TEGRA30_MC_RESET(SATA, 0x200, 0x204, 15), |
|
TEGRA30_MC_RESET(VDE, 0x200, 0x204, 16), |
|
TEGRA30_MC_RESET(VI, 0x200, 0x204, 17), |
|
}; |
|
|
|
static void tegra30_mc_tune_client_latency(struct tegra_mc *mc, |
|
const struct tegra_mc_client *client, |
|
unsigned int bandwidth_mbytes_sec) |
|
{ |
|
u32 arb_tolerance_compensation_nsec, arb_tolerance_compensation_div; |
|
const struct tegra_mc_la *la = &client->la; |
|
unsigned int fifo_size = client->fifo_size; |
|
u32 arb_nsec, la_ticks, value; |
|
|
|
/* see 18.4.1 Client Configuration in Tegra3 TRM v03p */ |
|
if (bandwidth_mbytes_sec) |
|
arb_nsec = fifo_size * NSEC_PER_USEC / bandwidth_mbytes_sec; |
|
else |
|
arb_nsec = U32_MAX; |
|
|
|
/* |
|
* Latency allowness should be set with consideration for the module's |
|
* latency tolerance and internal buffering capabilities. |
|
* |
|
* Display memory clients use isochronous transfers and have very low |
|
* tolerance to a belated transfers. Hence we need to compensate the |
|
* memory arbitration imperfection for them in order to prevent FIFO |
|
* underflow condition when memory bus is busy. |
|
* |
|
* VI clients also need a stronger compensation. |
|
*/ |
|
switch (client->swgroup) { |
|
case TEGRA_SWGROUP_MPCORE: |
|
case TEGRA_SWGROUP_PTC: |
|
/* |
|
* We always want lower latency for these clients, hence |
|
* don't touch them. |
|
*/ |
|
return; |
|
|
|
case TEGRA_SWGROUP_DC: |
|
case TEGRA_SWGROUP_DCB: |
|
arb_tolerance_compensation_nsec = 1050; |
|
arb_tolerance_compensation_div = 2; |
|
break; |
|
|
|
case TEGRA_SWGROUP_VI: |
|
arb_tolerance_compensation_nsec = 1050; |
|
arb_tolerance_compensation_div = 1; |
|
break; |
|
|
|
default: |
|
arb_tolerance_compensation_nsec = 150; |
|
arb_tolerance_compensation_div = 1; |
|
break; |
|
} |
|
|
|
if (arb_nsec > arb_tolerance_compensation_nsec) |
|
arb_nsec -= arb_tolerance_compensation_nsec; |
|
else |
|
arb_nsec = 0; |
|
|
|
arb_nsec /= arb_tolerance_compensation_div; |
|
|
|
/* |
|
* Latency allowance is a number of ticks a request from a particular |
|
* client may wait in the EMEM arbiter before it becomes a high-priority |
|
* request. |
|
*/ |
|
la_ticks = arb_nsec / mc->tick; |
|
la_ticks = min(la_ticks, la->mask); |
|
|
|
value = mc_readl(mc, la->reg); |
|
value &= ~(la->mask << la->shift); |
|
value |= la_ticks << la->shift; |
|
mc_writel(mc, value, la->reg); |
|
} |
|
|
|
static int tegra30_mc_icc_set(struct icc_node *src, struct icc_node *dst) |
|
{ |
|
struct tegra_mc *mc = icc_provider_to_tegra_mc(src->provider); |
|
const struct tegra_mc_client *client = &mc->soc->clients[src->id]; |
|
u64 peak_bandwidth = icc_units_to_bps(src->peak_bw); |
|
|
|
/* |
|
* Skip pre-initialization that is done by icc_node_add(), which sets |
|
* bandwidth to maximum for all clients before drivers are loaded. |
|
* |
|
* This doesn't make sense for us because we don't have drivers for all |
|
* clients and it's okay to keep configuration left from bootloader |
|
* during boot, at least for today. |
|
*/ |
|
if (src == dst) |
|
return 0; |
|
|
|
/* convert bytes/sec to megabytes/sec */ |
|
do_div(peak_bandwidth, 1000000); |
|
|
|
tegra30_mc_tune_client_latency(mc, client, peak_bandwidth); |
|
|
|
return 0; |
|
} |
|
|
|
static int tegra30_mc_icc_aggreate(struct icc_node *node, u32 tag, u32 avg_bw, |
|
u32 peak_bw, u32 *agg_avg, u32 *agg_peak) |
|
{ |
|
/* |
|
* ISO clients need to reserve extra bandwidth up-front because |
|
* there could be high bandwidth pressure during initial filling |
|
* of the client's FIFO buffers. Secondly, we need to take into |
|
* account impurities of the memory subsystem. |
|
*/ |
|
if (tag & TEGRA_MC_ICC_TAG_ISO) |
|
peak_bw = tegra_mc_scale_percents(peak_bw, 400); |
|
|
|
*agg_avg += avg_bw; |
|
*agg_peak = max(*agg_peak, peak_bw); |
|
|
|
return 0; |
|
} |
|
|
|
static struct icc_node_data * |
|
tegra30_mc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data) |
|
{ |
|
struct tegra_mc *mc = icc_provider_to_tegra_mc(data); |
|
const struct tegra_mc_client *client; |
|
unsigned int i, idx = spec->args[0]; |
|
struct icc_node_data *ndata; |
|
struct icc_node *node; |
|
|
|
list_for_each_entry(node, &mc->provider.nodes, node_list) { |
|
if (node->id != idx) |
|
continue; |
|
|
|
ndata = kzalloc(sizeof(*ndata), GFP_KERNEL); |
|
if (!ndata) |
|
return ERR_PTR(-ENOMEM); |
|
|
|
client = &mc->soc->clients[idx]; |
|
ndata->node = node; |
|
|
|
switch (client->swgroup) { |
|
case TEGRA_SWGROUP_DC: |
|
case TEGRA_SWGROUP_DCB: |
|
case TEGRA_SWGROUP_PTC: |
|
case TEGRA_SWGROUP_VI: |
|
/* these clients are isochronous by default */ |
|
ndata->tag = TEGRA_MC_ICC_TAG_ISO; |
|
break; |
|
|
|
default: |
|
ndata->tag = TEGRA_MC_ICC_TAG_DEFAULT; |
|
break; |
|
} |
|
|
|
return ndata; |
|
} |
|
|
|
for (i = 0; i < mc->soc->num_clients; i++) { |
|
if (mc->soc->clients[i].id == idx) |
|
return ERR_PTR(-EPROBE_DEFER); |
|
} |
|
|
|
dev_err(mc->dev, "invalid ICC client ID %u\n", idx); |
|
|
|
return ERR_PTR(-EINVAL); |
|
} |
|
|
|
static const struct tegra_mc_icc_ops tegra30_mc_icc_ops = { |
|
.xlate_extended = tegra30_mc_of_icc_xlate_extended, |
|
.aggregate = tegra30_mc_icc_aggreate, |
|
.set = tegra30_mc_icc_set, |
|
}; |
|
|
|
const struct tegra_mc_soc tegra30_mc_soc = { |
|
.clients = tegra30_mc_clients, |
|
.num_clients = ARRAY_SIZE(tegra30_mc_clients), |
|
.num_address_bits = 32, |
|
.atom_size = 16, |
|
.client_id_mask = 0x7f, |
|
.smmu = &tegra30_smmu_soc, |
|
.emem_regs = tegra30_mc_emem_regs, |
|
.num_emem_regs = ARRAY_SIZE(tegra30_mc_emem_regs), |
|
.intmask = MC_INT_INVALID_SMMU_PAGE | MC_INT_SECURITY_VIOLATION | |
|
MC_INT_DECERR_EMEM, |
|
.reset_ops = &tegra_mc_reset_ops_common, |
|
.resets = tegra30_mc_resets, |
|
.num_resets = ARRAY_SIZE(tegra30_mc_resets), |
|
.icc_ops = &tegra30_mc_icc_ops, |
|
};
|
|
|