mirror of
https://github.com/torvalds/linux.git
synced 2024-11-08 21:21:47 +00:00
Merge branch 'for-3.19/iommu' into for-3.19/dt
This commit is contained in:
commit
f538c50930
@ -0,0 +1,36 @@
|
||||
NVIDIA Tegra Memory Controller device tree bindings
|
||||
===================================================
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "nvidia,tegra<chip>-mc"
|
||||
- reg: Physical base address and length of the controller's registers.
|
||||
- clocks: Must contain an entry for each entry in clock-names.
|
||||
See ../clocks/clock-bindings.txt for details.
|
||||
- clock-names: Must include the following entries:
|
||||
- mc: the module's clock input
|
||||
- interrupts: The interrupt outputs from the controller.
|
||||
- #iommu-cells: Should be 1. The single cell of the IOMMU specifier defines
|
||||
the SWGROUP of the master.
|
||||
|
||||
This device implements an IOMMU that complies with the generic IOMMU binding.
|
||||
See ../iommu/iommu.txt for details.
|
||||
|
||||
Example:
|
||||
--------
|
||||
|
||||
mc: memory-controller@0,70019000 {
|
||||
compatible = "nvidia,tegra124-mc";
|
||||
reg = <0x0 0x70019000 0x0 0x1000>;
|
||||
clocks = <&tegra_car TEGRA124_CLK_MC>;
|
||||
clock-names = "mc";
|
||||
|
||||
interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
|
||||
|
||||
#iommu-cells = <1>;
|
||||
};
|
||||
|
||||
sdhci@0,700b0000 {
|
||||
compatible = "nvidia,tegra124-sdhci";
|
||||
...
|
||||
iommus = <&mc TEGRA_SWGROUP_SDMMC1A>;
|
||||
};
|
@ -1259,9 +1259,6 @@ source "arch/arm/common/Kconfig"
|
||||
|
||||
menu "Bus support"
|
||||
|
||||
config ARM_AMBA
|
||||
bool
|
||||
|
||||
config ISA
|
||||
bool
|
||||
help
|
||||
|
@ -2,6 +2,7 @@ menuconfig ARCH_TEGRA
|
||||
bool "NVIDIA Tegra" if ARCH_MULTI_V7
|
||||
select ARCH_REQUIRE_GPIOLIB
|
||||
select ARCH_SUPPORTS_TRUSTED_FOUNDATIONS
|
||||
select ARM_AMBA
|
||||
select ARM_GIC
|
||||
select CLKSRC_MMIO
|
||||
select HAVE_ARM_SCU if SMP
|
||||
@ -59,12 +60,4 @@ config ARCH_TEGRA_124_SOC
|
||||
Support for NVIDIA Tegra T124 processor family, based on the
|
||||
ARM CortexA15MP CPU
|
||||
|
||||
config TEGRA_AHB
|
||||
bool "Enable AHB driver for NVIDIA Tegra SoCs"
|
||||
default y
|
||||
help
|
||||
Adds AHB configuration functionality for NVIDIA Tegra SoCs,
|
||||
which controls AHB bus master arbitration and some
|
||||
performance parameters(priority, prefech size).
|
||||
|
||||
endif
|
||||
|
@ -166,9 +166,6 @@ endmenu
|
||||
|
||||
menu "Bus support"
|
||||
|
||||
config ARM_AMBA
|
||||
bool
|
||||
|
||||
config PCI
|
||||
bool "PCI support"
|
||||
help
|
||||
|
@ -137,13 +137,16 @@ static inline void set_iommu_table_base_and_group(struct device *dev,
|
||||
iommu_add_device(dev);
|
||||
}
|
||||
|
||||
extern int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
|
||||
struct scatterlist *sglist, int nelems,
|
||||
unsigned long mask, enum dma_data_direction direction,
|
||||
struct dma_attrs *attrs);
|
||||
extern void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist,
|
||||
int nelems, enum dma_data_direction direction,
|
||||
struct dma_attrs *attrs);
|
||||
extern int ppc_iommu_map_sg(struct device *dev, struct iommu_table *tbl,
|
||||
struct scatterlist *sglist, int nelems,
|
||||
unsigned long mask,
|
||||
enum dma_data_direction direction,
|
||||
struct dma_attrs *attrs);
|
||||
extern void ppc_iommu_unmap_sg(struct iommu_table *tbl,
|
||||
struct scatterlist *sglist,
|
||||
int nelems,
|
||||
enum dma_data_direction direction,
|
||||
struct dma_attrs *attrs);
|
||||
|
||||
extern void *iommu_alloc_coherent(struct device *dev, struct iommu_table *tbl,
|
||||
size_t size, dma_addr_t *dma_handle,
|
||||
|
@ -60,16 +60,16 @@ static int dma_iommu_map_sg(struct device *dev, struct scatterlist *sglist,
|
||||
int nelems, enum dma_data_direction direction,
|
||||
struct dma_attrs *attrs)
|
||||
{
|
||||
return iommu_map_sg(dev, get_iommu_table_base(dev), sglist, nelems,
|
||||
device_to_mask(dev), direction, attrs);
|
||||
return ppc_iommu_map_sg(dev, get_iommu_table_base(dev), sglist, nelems,
|
||||
device_to_mask(dev), direction, attrs);
|
||||
}
|
||||
|
||||
static void dma_iommu_unmap_sg(struct device *dev, struct scatterlist *sglist,
|
||||
int nelems, enum dma_data_direction direction,
|
||||
struct dma_attrs *attrs)
|
||||
{
|
||||
iommu_unmap_sg(get_iommu_table_base(dev), sglist, nelems, direction,
|
||||
attrs);
|
||||
ppc_iommu_unmap_sg(get_iommu_table_base(dev), sglist, nelems,
|
||||
direction, attrs);
|
||||
}
|
||||
|
||||
/* We support DMA to/from any memory page via the iommu */
|
||||
|
@ -428,10 +428,10 @@ static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
|
||||
ppc_md.tce_flush(tbl);
|
||||
}
|
||||
|
||||
int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
|
||||
struct scatterlist *sglist, int nelems,
|
||||
unsigned long mask, enum dma_data_direction direction,
|
||||
struct dma_attrs *attrs)
|
||||
int ppc_iommu_map_sg(struct device *dev, struct iommu_table *tbl,
|
||||
struct scatterlist *sglist, int nelems,
|
||||
unsigned long mask, enum dma_data_direction direction,
|
||||
struct dma_attrs *attrs)
|
||||
{
|
||||
dma_addr_t dma_next = 0, dma_addr;
|
||||
struct scatterlist *s, *outs, *segstart;
|
||||
@ -539,7 +539,7 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
|
||||
|
||||
DBG("mapped %d elements:\n", outcount);
|
||||
|
||||
/* For the sake of iommu_unmap_sg, we clear out the length in the
|
||||
/* For the sake of ppc_iommu_unmap_sg, we clear out the length in the
|
||||
* next entry of the sglist if we didn't fill the list completely
|
||||
*/
|
||||
if (outcount < incount) {
|
||||
@ -572,9 +572,9 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
|
||||
}
|
||||
|
||||
|
||||
void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist,
|
||||
int nelems, enum dma_data_direction direction,
|
||||
struct dma_attrs *attrs)
|
||||
void ppc_iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist,
|
||||
int nelems, enum dma_data_direction direction,
|
||||
struct dma_attrs *attrs)
|
||||
{
|
||||
struct scatterlist *sg;
|
||||
|
||||
|
@ -621,8 +621,9 @@ static int dma_fixed_map_sg(struct device *dev, struct scatterlist *sg,
|
||||
if (iommu_fixed_is_weak == dma_get_attr(DMA_ATTR_WEAK_ORDERING, attrs))
|
||||
return dma_direct_ops.map_sg(dev, sg, nents, direction, attrs);
|
||||
else
|
||||
return iommu_map_sg(dev, cell_get_iommu_table(dev), sg, nents,
|
||||
device_to_mask(dev), direction, attrs);
|
||||
return ppc_iommu_map_sg(dev, cell_get_iommu_table(dev), sg,
|
||||
nents, device_to_mask(dev),
|
||||
direction, attrs);
|
||||
}
|
||||
|
||||
static void dma_fixed_unmap_sg(struct device *dev, struct scatterlist *sg,
|
||||
@ -632,8 +633,8 @@ static void dma_fixed_unmap_sg(struct device *dev, struct scatterlist *sg,
|
||||
if (iommu_fixed_is_weak == dma_get_attr(DMA_ATTR_WEAK_ORDERING, attrs))
|
||||
dma_direct_ops.unmap_sg(dev, sg, nents, direction, attrs);
|
||||
else
|
||||
iommu_unmap_sg(cell_get_iommu_table(dev), sg, nents, direction,
|
||||
attrs);
|
||||
ppc_iommu_unmap_sg(cell_get_iommu_table(dev), sg, nents,
|
||||
direction, attrs);
|
||||
}
|
||||
|
||||
static int dma_fixed_dma_supported(struct device *dev, u64 mask)
|
||||
|
@ -1,5 +1,7 @@
|
||||
menu "Device Drivers"
|
||||
|
||||
source "drivers/amba/Kconfig"
|
||||
|
||||
source "drivers/base/Kconfig"
|
||||
|
||||
source "drivers/bus/Kconfig"
|
||||
|
14
drivers/amba/Kconfig
Normal file
14
drivers/amba/Kconfig
Normal file
@ -0,0 +1,14 @@
|
||||
config ARM_AMBA
|
||||
bool
|
||||
|
||||
if ARM_AMBA
|
||||
|
||||
config TEGRA_AHB
|
||||
bool "Enable AHB driver for NVIDIA Tegra SoCs"
|
||||
default y if ARCH_TEGRA
|
||||
help
|
||||
Adds AHB configuration functionality for NVIDIA Tegra SoCs,
|
||||
which controls AHB bus master arbitration and some performance
|
||||
parameters (priority, prefetch size).
|
||||
|
||||
endif
|
@ -185,3 +185,16 @@ struct clk *tegra_clk_register_divider(const char *name,
|
||||
|
||||
return clk;
|
||||
}
|
||||
|
||||
static const struct clk_div_table mc_div_table[] = {
|
||||
{ .val = 0, .div = 2 },
|
||||
{ .val = 1, .div = 1 },
|
||||
{ .val = 0, .div = 0 },
|
||||
};
|
||||
|
||||
struct clk *tegra_clk_register_mc(const char *name, const char *parent_name,
|
||||
void __iomem *reg, spinlock_t *lock)
|
||||
{
|
||||
return clk_register_divider_table(NULL, name, parent_name, 0, reg,
|
||||
16, 1, 0, mc_div_table, lock);
|
||||
}
|
||||
|
@ -173,6 +173,7 @@ static DEFINE_SPINLOCK(pll_d_lock);
|
||||
static DEFINE_SPINLOCK(pll_d2_lock);
|
||||
static DEFINE_SPINLOCK(pll_u_lock);
|
||||
static DEFINE_SPINLOCK(pll_re_lock);
|
||||
static DEFINE_SPINLOCK(emc_lock);
|
||||
|
||||
static struct div_nmp pllxc_nmp = {
|
||||
.divm_shift = 0,
|
||||
@ -1228,7 +1229,11 @@ static __init void tegra114_periph_clk_init(void __iomem *clk_base,
|
||||
ARRAY_SIZE(mux_pllmcp_clkm),
|
||||
CLK_SET_RATE_NO_REPARENT,
|
||||
clk_base + CLK_SOURCE_EMC,
|
||||
29, 3, 0, NULL);
|
||||
29, 3, 0, &emc_lock);
|
||||
|
||||
clk = tegra_clk_register_mc("mc", "emc_mux", clk_base + CLK_SOURCE_EMC,
|
||||
&emc_lock);
|
||||
clks[TEGRA114_CLK_MC] = clk;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) {
|
||||
data = &tegra_periph_clk_list[i];
|
||||
|
@ -132,6 +132,7 @@ static DEFINE_SPINLOCK(pll_d2_lock);
|
||||
static DEFINE_SPINLOCK(pll_e_lock);
|
||||
static DEFINE_SPINLOCK(pll_re_lock);
|
||||
static DEFINE_SPINLOCK(pll_u_lock);
|
||||
static DEFINE_SPINLOCK(emc_lock);
|
||||
|
||||
/* possible OSC frequencies in Hz */
|
||||
static unsigned long tegra124_input_freq[] = {
|
||||
@ -1127,7 +1128,11 @@ static __init void tegra124_periph_clk_init(void __iomem *clk_base,
|
||||
clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm,
|
||||
ARRAY_SIZE(mux_pllmcp_clkm), 0,
|
||||
clk_base + CLK_SOURCE_EMC,
|
||||
29, 3, 0, NULL);
|
||||
29, 3, 0, &emc_lock);
|
||||
|
||||
clk = tegra_clk_register_mc("mc", "emc_mux", clk_base + CLK_SOURCE_EMC,
|
||||
&emc_lock);
|
||||
clks[TEGRA124_CLK_MC] = clk;
|
||||
|
||||
/* cml0 */
|
||||
clk = clk_register_gate(NULL, "cml0", "pll_e", 0, clk_base + PLLE_AUX,
|
||||
|
@ -140,6 +140,8 @@ static struct cpu_clk_suspend_context {
|
||||
static void __iomem *clk_base;
|
||||
static void __iomem *pmc_base;
|
||||
|
||||
static DEFINE_SPINLOCK(emc_lock);
|
||||
|
||||
#define TEGRA_INIT_DATA_MUX(_name, _parents, _offset, \
|
||||
_clk_num, _gate_flags, _clk_id) \
|
||||
TEGRA_INIT_DATA(_name, NULL, NULL, _parents, _offset, \
|
||||
@ -819,11 +821,15 @@ static void __init tegra20_periph_clk_init(void)
|
||||
ARRAY_SIZE(mux_pllmcp_clkm),
|
||||
CLK_SET_RATE_NO_REPARENT,
|
||||
clk_base + CLK_SOURCE_EMC,
|
||||
30, 2, 0, NULL);
|
||||
30, 2, 0, &emc_lock);
|
||||
clk = tegra_clk_register_periph_gate("emc", "emc_mux", 0, clk_base, 0,
|
||||
57, periph_clk_enb_refcnt);
|
||||
clks[TEGRA20_CLK_EMC] = clk;
|
||||
|
||||
clk = tegra_clk_register_mc("mc", "emc_mux", clk_base + CLK_SOURCE_EMC,
|
||||
&emc_lock);
|
||||
clks[TEGRA20_CLK_MC] = clk;
|
||||
|
||||
/* dsi */
|
||||
clk = tegra_clk_register_periph_gate("dsi", "pll_d", 0, clk_base, 0,
|
||||
48, periph_clk_enb_refcnt);
|
||||
|
@ -177,6 +177,7 @@ static unsigned long input_freq;
|
||||
|
||||
static DEFINE_SPINLOCK(cml_lock);
|
||||
static DEFINE_SPINLOCK(pll_d_lock);
|
||||
static DEFINE_SPINLOCK(emc_lock);
|
||||
|
||||
#define TEGRA_INIT_DATA_MUX(_name, _parents, _offset, \
|
||||
_clk_num, _gate_flags, _clk_id) \
|
||||
@ -1157,11 +1158,15 @@ static void __init tegra30_periph_clk_init(void)
|
||||
ARRAY_SIZE(mux_pllmcp_clkm),
|
||||
CLK_SET_RATE_NO_REPARENT,
|
||||
clk_base + CLK_SOURCE_EMC,
|
||||
30, 2, 0, NULL);
|
||||
30, 2, 0, &emc_lock);
|
||||
clk = tegra_clk_register_periph_gate("emc", "emc_mux", 0, clk_base, 0,
|
||||
57, periph_clk_enb_refcnt);
|
||||
clks[TEGRA30_CLK_EMC] = clk;
|
||||
|
||||
clk = tegra_clk_register_mc("mc", "emc_mux", clk_base + CLK_SOURCE_EMC,
|
||||
&emc_lock);
|
||||
clks[TEGRA30_CLK_MC] = clk;
|
||||
|
||||
/* cml0 */
|
||||
clk = clk_register_gate(NULL, "cml0", "pll_e", 0, clk_base + PLLE_AUX,
|
||||
0, 0, &cml_lock);
|
||||
|
@ -86,6 +86,8 @@ struct clk *tegra_clk_register_divider(const char *name,
|
||||
const char *parent_name, void __iomem *reg,
|
||||
unsigned long flags, u8 clk_divider_flags, u8 shift, u8 width,
|
||||
u8 frac_width, spinlock_t *lock);
|
||||
struct clk *tegra_clk_register_mc(const char *name, const char *parent_name,
|
||||
void __iomem *reg, spinlock_t *lock);
|
||||
|
||||
/*
|
||||
* Tegra PLL:
|
||||
|
@ -163,14 +163,14 @@ config TEGRA_IOMMU_GART
|
||||
hardware included on Tegra SoCs.
|
||||
|
||||
config TEGRA_IOMMU_SMMU
|
||||
bool "Tegra SMMU IOMMU Support"
|
||||
depends on ARCH_TEGRA && TEGRA_AHB
|
||||
bool "NVIDIA Tegra SMMU Support"
|
||||
depends on ARCH_TEGRA
|
||||
depends on TEGRA_AHB
|
||||
depends on TEGRA_MC
|
||||
select IOMMU_API
|
||||
help
|
||||
Enables support for remapping discontiguous physical memory
|
||||
shared with the operating system into contiguous I/O virtual
|
||||
space through the SMMU (System Memory Management Unit)
|
||||
hardware included on Tegra SoCs.
|
||||
This driver supports the IOMMU hardware (SMMU) found on NVIDIA Tegra
|
||||
SoCs (Tegra30 up to Tegra124).
|
||||
|
||||
config EXYNOS_IOMMU
|
||||
bool "Exynos IOMMU Support"
|
||||
|
@ -3424,6 +3424,7 @@ static const struct iommu_ops amd_iommu_ops = {
|
||||
.detach_dev = amd_iommu_detach_device,
|
||||
.map = amd_iommu_map,
|
||||
.unmap = amd_iommu_unmap,
|
||||
.map_sg = default_iommu_map_sg,
|
||||
.iova_to_phys = amd_iommu_iova_to_phys,
|
||||
.pgsize_bitmap = AMD_IOMMU_PGSIZES,
|
||||
};
|
||||
|
@ -1652,6 +1652,7 @@ static const struct iommu_ops arm_smmu_ops = {
|
||||
.detach_dev = arm_smmu_detach_dev,
|
||||
.map = arm_smmu_map,
|
||||
.unmap = arm_smmu_unmap,
|
||||
.map_sg = default_iommu_map_sg,
|
||||
.iova_to_phys = arm_smmu_iova_to_phys,
|
||||
.add_device = arm_smmu_add_device,
|
||||
.remove_device = arm_smmu_remove_device,
|
||||
|
@ -1178,6 +1178,7 @@ static const struct iommu_ops exynos_iommu_ops = {
|
||||
.detach_dev = exynos_iommu_detach_device,
|
||||
.map = exynos_iommu_map,
|
||||
.unmap = exynos_iommu_unmap,
|
||||
.map_sg = default_iommu_map_sg,
|
||||
.iova_to_phys = exynos_iommu_iova_to_phys,
|
||||
.add_device = exynos_iommu_add_device,
|
||||
.remove_device = exynos_iommu_remove_device,
|
||||
|
@ -4467,6 +4467,7 @@ static const struct iommu_ops intel_iommu_ops = {
|
||||
.detach_dev = intel_iommu_detach_device,
|
||||
.map = intel_iommu_map,
|
||||
.unmap = intel_iommu_unmap,
|
||||
.map_sg = default_iommu_map_sg,
|
||||
.iova_to_phys = intel_iommu_iova_to_phys,
|
||||
.add_device = intel_iommu_add_device,
|
||||
.remove_device = intel_iommu_remove_device,
|
||||
|
@ -818,7 +818,15 @@ static int iommu_bus_init(struct bus_type *bus, const struct iommu_ops *ops)
|
||||
kfree(nb);
|
||||
return err;
|
||||
}
|
||||
return bus_for_each_dev(bus, NULL, &cb, add_iommu_group);
|
||||
|
||||
err = bus_for_each_dev(bus, NULL, &cb, add_iommu_group);
|
||||
if (err) {
|
||||
bus_unregister_notifier(bus, nb);
|
||||
kfree(nb);
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -836,13 +844,19 @@ static int iommu_bus_init(struct bus_type *bus, const struct iommu_ops *ops)
|
||||
*/
|
||||
int bus_set_iommu(struct bus_type *bus, const struct iommu_ops *ops)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (bus->iommu_ops != NULL)
|
||||
return -EBUSY;
|
||||
|
||||
bus->iommu_ops = ops;
|
||||
|
||||
/* Do IOMMU specific setup for this bus-type */
|
||||
return iommu_bus_init(bus, ops);
|
||||
err = iommu_bus_init(bus, ops);
|
||||
if (err)
|
||||
bus->iommu_ops = NULL;
|
||||
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(bus_set_iommu);
|
||||
|
||||
@ -1124,6 +1138,38 @@ size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(iommu_unmap);
|
||||
|
||||
size_t default_iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
|
||||
struct scatterlist *sg, unsigned int nents, int prot)
|
||||
{
|
||||
struct scatterlist *s;
|
||||
size_t mapped = 0;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
for_each_sg(sg, s, nents, i) {
|
||||
phys_addr_t phys = page_to_phys(sg_page(s));
|
||||
|
||||
/* We are mapping on page boundarys, so offset must be 0 */
|
||||
if (s->offset)
|
||||
goto out_err;
|
||||
|
||||
ret = iommu_map(domain, iova + mapped, phys, s->length, prot);
|
||||
if (ret)
|
||||
goto out_err;
|
||||
|
||||
mapped += s->length;
|
||||
}
|
||||
|
||||
return mapped;
|
||||
|
||||
out_err:
|
||||
/* undo mappings already done */
|
||||
iommu_unmap(domain, iova, mapped);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(default_iommu_map_sg);
|
||||
|
||||
int iommu_domain_window_enable(struct iommu_domain *domain, u32 wnd_nr,
|
||||
phys_addr_t paddr, u64 size, int prot)
|
||||
|
@ -1127,6 +1127,7 @@ static const struct iommu_ops ipmmu_ops = {
|
||||
.detach_dev = ipmmu_detach_device,
|
||||
.map = ipmmu_map,
|
||||
.unmap = ipmmu_unmap,
|
||||
.map_sg = default_iommu_map_sg,
|
||||
.iova_to_phys = ipmmu_iova_to_phys,
|
||||
.add_device = ipmmu_add_device,
|
||||
.remove_device = ipmmu_remove_device,
|
||||
|
@ -681,6 +681,7 @@ static const struct iommu_ops msm_iommu_ops = {
|
||||
.detach_dev = msm_iommu_detach_dev,
|
||||
.map = msm_iommu_map,
|
||||
.unmap = msm_iommu_unmap,
|
||||
.map_sg = default_iommu_map_sg,
|
||||
.iova_to_phys = msm_iommu_iova_to_phys,
|
||||
.pgsize_bitmap = MSM_IOMMU_PGSIZES,
|
||||
};
|
||||
|
@ -1288,6 +1288,7 @@ static const struct iommu_ops omap_iommu_ops = {
|
||||
.detach_dev = omap_iommu_detach_dev,
|
||||
.map = omap_iommu_map,
|
||||
.unmap = omap_iommu_unmap,
|
||||
.map_sg = default_iommu_map_sg,
|
||||
.iova_to_phys = omap_iommu_iova_to_phys,
|
||||
.add_device = omap_iommu_add_device,
|
||||
.remove_device = omap_iommu_remove_device,
|
||||
|
@ -361,6 +361,7 @@ static const struct iommu_ops shmobile_iommu_ops = {
|
||||
.detach_dev = shmobile_iommu_detach_device,
|
||||
.map = shmobile_iommu_map,
|
||||
.unmap = shmobile_iommu_unmap,
|
||||
.map_sg = default_iommu_map_sg,
|
||||
.iova_to_phys = shmobile_iommu_iova_to_phys,
|
||||
.add_device = shmobile_iommu_add_device,
|
||||
.pgsize_bitmap = SZ_1M | SZ_64K | SZ_4K,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -61,16 +61,6 @@ config TEGRA20_MC
|
||||
analysis, especially for IOMMU/GART(Graphics Address
|
||||
Relocation Table) module.
|
||||
|
||||
config TEGRA30_MC
|
||||
bool "Tegra30 Memory Controller(MC) driver"
|
||||
default y
|
||||
depends on ARCH_TEGRA_3x_SOC
|
||||
help
|
||||
This driver is for the Memory Controller(MC) module available
|
||||
in Tegra30 SoCs, mainly for a address translation fault
|
||||
analysis, especially for IOMMU/SMMU(System Memory Management
|
||||
Unit) module.
|
||||
|
||||
config FSL_CORENET_CF
|
||||
tristate "Freescale CoreNet Error Reporting"
|
||||
depends on FSL_SOC_BOOKE
|
||||
@ -85,4 +75,6 @@ config FSL_IFC
|
||||
bool
|
||||
depends on FSL_SOC
|
||||
|
||||
source "drivers/memory/tegra/Kconfig"
|
||||
|
||||
endif
|
||||
|
@ -12,4 +12,5 @@ obj-$(CONFIG_FSL_CORENET_CF) += fsl-corenet-cf.o
|
||||
obj-$(CONFIG_FSL_IFC) += fsl_ifc.o
|
||||
obj-$(CONFIG_MVEBU_DEVBUS) += mvebu-devbus.o
|
||||
obj-$(CONFIG_TEGRA20_MC) += tegra20-mc.o
|
||||
obj-$(CONFIG_TEGRA30_MC) += tegra30-mc.o
|
||||
|
||||
obj-$(CONFIG_TEGRA_MC) += tegra/
|
||||
|
7
drivers/memory/tegra/Kconfig
Normal file
7
drivers/memory/tegra/Kconfig
Normal file
@ -0,0 +1,7 @@
|
||||
config TEGRA_MC
|
||||
bool "NVIDIA Tegra Memory Controller support"
|
||||
default y
|
||||
depends on ARCH_TEGRA
|
||||
help
|
||||
This driver supports the Memory Controller (MC) hardware found on
|
||||
NVIDIA Tegra SoCs.
|
7
drivers/memory/tegra/Makefile
Normal file
7
drivers/memory/tegra/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
tegra-mc-y := mc.o
|
||||
|
||||
tegra-mc-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra30.o
|
||||
tegra-mc-$(CONFIG_ARCH_TEGRA_114_SOC) += tegra114.o
|
||||
tegra-mc-$(CONFIG_ARCH_TEGRA_124_SOC) += tegra124.o
|
||||
|
||||
obj-$(CONFIG_TEGRA_MC) += tegra-mc.o
|
301
drivers/memory/tegra/mc.c
Normal file
301
drivers/memory/tegra/mc.c
Normal file
@ -0,0 +1,301 @@
|
||||
/*
|
||||
* Copyright (C) 2014 NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "mc.h"
|
||||
|
||||
#define MC_INTSTATUS 0x000
|
||||
#define MC_INT_DECERR_MTS (1 << 16)
|
||||
#define MC_INT_SECERR_SEC (1 << 13)
|
||||
#define MC_INT_DECERR_VPR (1 << 12)
|
||||
#define MC_INT_INVALID_APB_ASID_UPDATE (1 << 11)
|
||||
#define MC_INT_INVALID_SMMU_PAGE (1 << 10)
|
||||
#define MC_INT_ARBITRATION_EMEM (1 << 9)
|
||||
#define MC_INT_SECURITY_VIOLATION (1 << 8)
|
||||
#define MC_INT_DECERR_EMEM (1 << 6)
|
||||
|
||||
#define MC_INTMASK 0x004
|
||||
|
||||
#define MC_ERR_STATUS 0x08
|
||||
#define MC_ERR_STATUS_TYPE_SHIFT 28
|
||||
#define MC_ERR_STATUS_TYPE_INVALID_SMMU_PAGE (6 << MC_ERR_STATUS_TYPE_SHIFT)
|
||||
#define MC_ERR_STATUS_TYPE_MASK (0x7 << MC_ERR_STATUS_TYPE_SHIFT)
|
||||
#define MC_ERR_STATUS_READABLE (1 << 27)
|
||||
#define MC_ERR_STATUS_WRITABLE (1 << 26)
|
||||
#define MC_ERR_STATUS_NONSECURE (1 << 25)
|
||||
#define MC_ERR_STATUS_ADR_HI_SHIFT 20
|
||||
#define MC_ERR_STATUS_ADR_HI_MASK 0x3
|
||||
#define MC_ERR_STATUS_SECURITY (1 << 17)
|
||||
#define MC_ERR_STATUS_RW (1 << 16)
|
||||
#define MC_ERR_STATUS_CLIENT_MASK 0x7f
|
||||
|
||||
#define MC_ERR_ADR 0x0c
|
||||
|
||||
#define MC_EMEM_ARB_CFG 0x90
|
||||
#define MC_EMEM_ARB_CFG_CYCLES_PER_UPDATE(x) (((x) & 0x1ff) << 0)
|
||||
#define MC_EMEM_ARB_CFG_CYCLES_PER_UPDATE_MASK 0x1ff
|
||||
#define MC_EMEM_ARB_MISC0 0xd8
|
||||
|
||||
static const struct of_device_id tegra_mc_of_match[] = {
|
||||
#ifdef CONFIG_ARCH_TEGRA_3x_SOC
|
||||
{ .compatible = "nvidia,tegra30-mc", .data = &tegra30_mc_soc },
|
||||
#endif
|
||||
#ifdef CONFIG_ARCH_TEGRA_114_SOC
|
||||
{ .compatible = "nvidia,tegra114-mc", .data = &tegra114_mc_soc },
|
||||
#endif
|
||||
#ifdef CONFIG_ARCH_TEGRA_124_SOC
|
||||
{ .compatible = "nvidia,tegra124-mc", .data = &tegra124_mc_soc },
|
||||
#endif
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, tegra_mc_of_match);
|
||||
|
||||
static int tegra_mc_setup_latency_allowance(struct tegra_mc *mc)
|
||||
{
|
||||
unsigned long long tick;
|
||||
unsigned int i;
|
||||
u32 value;
|
||||
|
||||
/* compute the number of MC clock cycles per tick */
|
||||
tick = mc->tick * clk_get_rate(mc->clk);
|
||||
do_div(tick, NSEC_PER_SEC);
|
||||
|
||||
value = readl(mc->regs + MC_EMEM_ARB_CFG);
|
||||
value &= ~MC_EMEM_ARB_CFG_CYCLES_PER_UPDATE_MASK;
|
||||
value |= MC_EMEM_ARB_CFG_CYCLES_PER_UPDATE(tick);
|
||||
writel(value, mc->regs + MC_EMEM_ARB_CFG);
|
||||
|
||||
/* write latency allowance defaults */
|
||||
for (i = 0; i < mc->soc->num_clients; i++) {
|
||||
const struct tegra_mc_la *la = &mc->soc->clients[i].la;
|
||||
u32 value;
|
||||
|
||||
value = readl(mc->regs + la->reg);
|
||||
value &= ~(la->mask << la->shift);
|
||||
value |= (la->def & la->mask) << la->shift;
|
||||
writel(value, mc->regs + la->reg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *const status_names[32] = {
|
||||
[ 1] = "External interrupt",
|
||||
[ 6] = "EMEM address decode error",
|
||||
[ 8] = "Security violation",
|
||||
[ 9] = "EMEM arbitration error",
|
||||
[10] = "Page fault",
|
||||
[11] = "Invalid APB ASID update",
|
||||
[12] = "VPR violation",
|
||||
[13] = "Secure carveout violation",
|
||||
[16] = "MTS carveout violation",
|
||||
};
|
||||
|
||||
static const char *const error_names[8] = {
|
||||
[2] = "EMEM decode error",
|
||||
[3] = "TrustZone violation",
|
||||
[4] = "Carveout violation",
|
||||
[6] = "SMMU translation error",
|
||||
};
|
||||
|
||||
static irqreturn_t tegra_mc_irq(int irq, void *data)
|
||||
{
|
||||
struct tegra_mc *mc = data;
|
||||
unsigned long status, mask;
|
||||
unsigned int bit;
|
||||
|
||||
/* mask all interrupts to avoid flooding */
|
||||
status = mc_readl(mc, MC_INTSTATUS);
|
||||
mask = mc_readl(mc, MC_INTMASK);
|
||||
|
||||
for_each_set_bit(bit, &status, 32) {
|
||||
const char *error = status_names[bit] ?: "unknown";
|
||||
const char *client = "unknown", *desc;
|
||||
const char *direction, *secure;
|
||||
phys_addr_t addr = 0;
|
||||
unsigned int i;
|
||||
char perm[7];
|
||||
u8 id, type;
|
||||
u32 value;
|
||||
|
||||
value = mc_readl(mc, MC_ERR_STATUS);
|
||||
|
||||
#ifdef CONFIG_PHYS_ADDR_T_64BIT
|
||||
if (mc->soc->num_address_bits > 32) {
|
||||
addr = ((value >> MC_ERR_STATUS_ADR_HI_SHIFT) &
|
||||
MC_ERR_STATUS_ADR_HI_MASK);
|
||||
addr <<= 32;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (value & MC_ERR_STATUS_RW)
|
||||
direction = "write";
|
||||
else
|
||||
direction = "read";
|
||||
|
||||
if (value & MC_ERR_STATUS_SECURITY)
|
||||
secure = "secure ";
|
||||
else
|
||||
secure = "";
|
||||
|
||||
id = value & MC_ERR_STATUS_CLIENT_MASK;
|
||||
|
||||
for (i = 0; i < mc->soc->num_clients; i++) {
|
||||
if (mc->soc->clients[i].id == id) {
|
||||
client = mc->soc->clients[i].name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
type = (value & MC_ERR_STATUS_TYPE_MASK) >>
|
||||
MC_ERR_STATUS_TYPE_SHIFT;
|
||||
desc = error_names[type];
|
||||
|
||||
switch (value & MC_ERR_STATUS_TYPE_MASK) {
|
||||
case MC_ERR_STATUS_TYPE_INVALID_SMMU_PAGE:
|
||||
perm[0] = ' ';
|
||||
perm[1] = '[';
|
||||
|
||||
if (value & MC_ERR_STATUS_READABLE)
|
||||
perm[2] = 'R';
|
||||
else
|
||||
perm[2] = '-';
|
||||
|
||||
if (value & MC_ERR_STATUS_WRITABLE)
|
||||
perm[3] = 'W';
|
||||
else
|
||||
perm[3] = '-';
|
||||
|
||||
if (value & MC_ERR_STATUS_NONSECURE)
|
||||
perm[4] = '-';
|
||||
else
|
||||
perm[4] = 'S';
|
||||
|
||||
perm[5] = ']';
|
||||
perm[6] = '\0';
|
||||
break;
|
||||
|
||||
default:
|
||||
perm[0] = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
value = mc_readl(mc, MC_ERR_ADR);
|
||||
addr |= value;
|
||||
|
||||
dev_err_ratelimited(mc->dev, "%s: %s%s @%pa: %s (%s%s)\n",
|
||||
client, secure, direction, &addr, error,
|
||||
desc, perm);
|
||||
}
|
||||
|
||||
/* clear interrupts */
|
||||
mc_writel(mc, status, MC_INTSTATUS);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int tegra_mc_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct of_device_id *match;
|
||||
struct resource *res;
|
||||
struct tegra_mc *mc;
|
||||
u32 value;
|
||||
int err;
|
||||
|
||||
match = of_match_node(tegra_mc_of_match, pdev->dev.of_node);
|
||||
if (!match)
|
||||
return -ENODEV;
|
||||
|
||||
mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL);
|
||||
if (!mc)
|
||||
return -ENOMEM;
|
||||
|
||||
platform_set_drvdata(pdev, mc);
|
||||
mc->soc = match->data;
|
||||
mc->dev = &pdev->dev;
|
||||
|
||||
/* length of MC tick in nanoseconds */
|
||||
mc->tick = 30;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
mc->regs = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(mc->regs))
|
||||
return PTR_ERR(mc->regs);
|
||||
|
||||
mc->clk = devm_clk_get(&pdev->dev, "mc");
|
||||
if (IS_ERR(mc->clk)) {
|
||||
dev_err(&pdev->dev, "failed to get MC clock: %ld\n",
|
||||
PTR_ERR(mc->clk));
|
||||
return PTR_ERR(mc->clk);
|
||||
}
|
||||
|
||||
err = tegra_mc_setup_latency_allowance(mc);
|
||||
if (err < 0) {
|
||||
dev_err(&pdev->dev, "failed to setup latency allowance: %d\n",
|
||||
err);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_TEGRA_IOMMU_SMMU)) {
|
||||
mc->smmu = tegra_smmu_probe(&pdev->dev, mc->soc->smmu, mc);
|
||||
if (IS_ERR(mc->smmu)) {
|
||||
dev_err(&pdev->dev, "failed to probe SMMU: %ld\n",
|
||||
PTR_ERR(mc->smmu));
|
||||
return PTR_ERR(mc->smmu);
|
||||
}
|
||||
}
|
||||
|
||||
mc->irq = platform_get_irq(pdev, 0);
|
||||
if (mc->irq < 0) {
|
||||
dev_err(&pdev->dev, "interrupt not specified\n");
|
||||
return mc->irq;
|
||||
}
|
||||
|
||||
err = devm_request_irq(&pdev->dev, mc->irq, tegra_mc_irq, IRQF_SHARED,
|
||||
dev_name(&pdev->dev), mc);
|
||||
if (err < 0) {
|
||||
dev_err(&pdev->dev, "failed to request IRQ#%u: %d\n", mc->irq,
|
||||
err);
|
||||
return err;
|
||||
}
|
||||
|
||||
value = MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
|
||||
MC_INT_INVALID_APB_ASID_UPDATE | MC_INT_INVALID_SMMU_PAGE |
|
||||
MC_INT_ARBITRATION_EMEM | MC_INT_SECURITY_VIOLATION |
|
||||
MC_INT_DECERR_EMEM;
|
||||
mc_writel(mc, value, MC_INTMASK);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver tegra_mc_driver = {
|
||||
.driver = {
|
||||
.name = "tegra-mc",
|
||||
.of_match_table = tegra_mc_of_match,
|
||||
.suppress_bind_attrs = true,
|
||||
},
|
||||
.prevent_deferred_probe = true,
|
||||
.probe = tegra_mc_probe,
|
||||
};
|
||||
|
||||
static int tegra_mc_init(void)
|
||||
{
|
||||
return platform_driver_register(&tegra_mc_driver);
|
||||
}
|
||||
arch_initcall(tegra_mc_init);
|
||||
|
||||
MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>");
|
||||
MODULE_DESCRIPTION("NVIDIA Tegra Memory Controller driver");
|
||||
MODULE_LICENSE("GPL v2");
|
40
drivers/memory/tegra/mc.h
Normal file
40
drivers/memory/tegra/mc.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2014 NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef MEMORY_TEGRA_MC_H
|
||||
#define MEMORY_TEGRA_MC_H
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <soc/tegra/mc.h>
|
||||
|
||||
static inline u32 mc_readl(struct tegra_mc *mc, unsigned long offset)
|
||||
{
|
||||
return readl(mc->regs + offset);
|
||||
}
|
||||
|
||||
static inline void mc_writel(struct tegra_mc *mc, u32 value,
|
||||
unsigned long offset)
|
||||
{
|
||||
writel(value, mc->regs + offset);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARCH_TEGRA_3x_SOC
|
||||
extern const struct tegra_mc_soc tegra30_mc_soc;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_TEGRA_114_SOC
|
||||
extern const struct tegra_mc_soc tegra114_mc_soc;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_TEGRA_124_SOC
|
||||
extern const struct tegra_mc_soc tegra124_mc_soc;
|
||||
#endif
|
||||
|
||||
#endif /* MEMORY_TEGRA_MC_H */
|
948
drivers/memory/tegra/tegra114.c
Normal file
948
drivers/memory/tegra/tegra114.c
Normal file
@ -0,0 +1,948 @@
|
||||
/*
|
||||
* Copyright (C) 2014 NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/of.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
|
||||
#include <dt-bindings/memory/tegra114-mc.h>
|
||||
|
||||
#include "mc.h"
|
||||
|
||||
static const struct tegra_mc_client tegra114_mc_clients[] = {
|
||||
{
|
||||
.id = 0x00,
|
||||
.name = "ptcr",
|
||||
.swgroup = TEGRA_SWGROUP_PTC,
|
||||
}, {
|
||||
.id = 0x01,
|
||||
.name = "display0a",
|
||||
.swgroup = TEGRA_SWGROUP_DC,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 1,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x2e8,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x4e,
|
||||
},
|
||||
}, {
|
||||
.id = 0x02,
|
||||
.name = "display0ab",
|
||||
.swgroup = TEGRA_SWGROUP_DCB,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 2,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x2f4,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x4e,
|
||||
},
|
||||
}, {
|
||||
.id = 0x03,
|
||||
.name = "display0b",
|
||||
.swgroup = TEGRA_SWGROUP_DC,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 3,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x2e8,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x4e,
|
||||
},
|
||||
}, {
|
||||
.id = 0x04,
|
||||
.name = "display0bb",
|
||||
.swgroup = TEGRA_SWGROUP_DCB,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 4,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x2f4,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x4e,
|
||||
},
|
||||
}, {
|
||||
.id = 0x05,
|
||||
.name = "display0c",
|
||||
.swgroup = TEGRA_SWGROUP_DC,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 5,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x2ec,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x4e,
|
||||
},
|
||||
}, {
|
||||
.id = 0x06,
|
||||
.name = "display0cb",
|
||||
.swgroup = TEGRA_SWGROUP_DCB,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 6,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x2f8,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x4e,
|
||||
},
|
||||
}, {
|
||||
.id = 0x09,
|
||||
.name = "eppup",
|
||||
.swgroup = TEGRA_SWGROUP_EPP,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 9,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x300,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x33,
|
||||
},
|
||||
}, {
|
||||
.id = 0x0a,
|
||||
.name = "g2pr",
|
||||
.swgroup = TEGRA_SWGROUP_G2,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 10,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x308,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x09,
|
||||
},
|
||||
}, {
|
||||
.id = 0x0b,
|
||||
.name = "g2sr",
|
||||
.swgroup = TEGRA_SWGROUP_G2,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 11,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x308,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x09,
|
||||
},
|
||||
}, {
|
||||
.id = 0x0f,
|
||||
.name = "avpcarm7r",
|
||||
.swgroup = TEGRA_SWGROUP_AVPC,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 15,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x2e4,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x04,
|
||||
},
|
||||
}, {
|
||||
.id = 0x10,
|
||||
.name = "displayhc",
|
||||
.swgroup = TEGRA_SWGROUP_DC,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 16,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x2f0,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x68,
|
||||
},
|
||||
}, {
|
||||
.id = 0x11,
|
||||
.name = "displayhcb",
|
||||
.swgroup = TEGRA_SWGROUP_DCB,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 17,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x2fc,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x68,
|
||||
},
|
||||
}, {
|
||||
.id = 0x12,
|
||||
.name = "fdcdrd",
|
||||
.swgroup = TEGRA_SWGROUP_NV,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 18,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x334,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x0c,
|
||||
},
|
||||
}, {
|
||||
.id = 0x13,
|
||||
.name = "fdcdrd2",
|
||||
.swgroup = TEGRA_SWGROUP_NV,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 19,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x33c,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x0c,
|
||||
},
|
||||
}, {
|
||||
.id = 0x14,
|
||||
.name = "g2dr",
|
||||
.swgroup = TEGRA_SWGROUP_G2,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 20,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x30c,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x0a,
|
||||
},
|
||||
}, {
|
||||
.id = 0x15,
|
||||
.name = "hdar",
|
||||
.swgroup = TEGRA_SWGROUP_HDA,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 21,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x318,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0xff,
|
||||
},
|
||||
}, {
|
||||
.id = 0x16,
|
||||
.name = "host1xdmar",
|
||||
.swgroup = TEGRA_SWGROUP_HC,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 22,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x310,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x10,
|
||||
},
|
||||
}, {
|
||||
.id = 0x17,
|
||||
.name = "host1xr",
|
||||
.swgroup = TEGRA_SWGROUP_HC,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 23,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x310,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0xa5,
|
||||
},
|
||||
}, {
|
||||
.id = 0x18,
|
||||
.name = "idxsrd",
|
||||
.swgroup = TEGRA_SWGROUP_NV,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 24,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x334,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x0b,
|
||||
},
|
||||
}, {
|
||||
.id = 0x1c,
|
||||
.name = "msencsrd",
|
||||
.swgroup = TEGRA_SWGROUP_MSENC,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 28,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x328,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x80,
|
||||
},
|
||||
}, {
|
||||
.id = 0x1d,
|
||||
.name = "ppcsahbdmar",
|
||||
.swgroup = TEGRA_SWGROUP_PPCS,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 29,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x344,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x50,
|
||||
},
|
||||
}, {
|
||||
.id = 0x1e,
|
||||
.name = "ppcsahbslvr",
|
||||
.swgroup = TEGRA_SWGROUP_PPCS,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 30,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x344,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0xe8,
|
||||
},
|
||||
}, {
|
||||
.id = 0x20,
|
||||
.name = "texl2srd",
|
||||
.swgroup = TEGRA_SWGROUP_NV,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 0,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x338,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x0c,
|
||||
},
|
||||
}, {
|
||||
.id = 0x22,
|
||||
.name = "vdebsevr",
|
||||
.swgroup = TEGRA_SWGROUP_VDE,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 2,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x354,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0xff,
|
||||
},
|
||||
}, {
|
||||
.id = 0x23,
|
||||
.name = "vdember",
|
||||
.swgroup = TEGRA_SWGROUP_VDE,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 3,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x354,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0xff,
|
||||
},
|
||||
}, {
|
||||
.id = 0x24,
|
||||
.name = "vdemcer",
|
||||
.swgroup = TEGRA_SWGROUP_VDE,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 4,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x358,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0xb8,
|
||||
},
|
||||
}, {
|
||||
.id = 0x25,
|
||||
.name = "vdetper",
|
||||
.swgroup = TEGRA_SWGROUP_VDE,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 5,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x358,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0xee,
|
||||
},
|
||||
}, {
|
||||
.id = 0x26,
|
||||
.name = "mpcorelpr",
|
||||
.swgroup = TEGRA_SWGROUP_MPCORELP,
|
||||
.la = {
|
||||
.reg = 0x324,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x04,
|
||||
},
|
||||
}, {
|
||||
.id = 0x27,
|
||||
.name = "mpcorer",
|
||||
.swgroup = TEGRA_SWGROUP_MPCORE,
|
||||
.la = {
|
||||
.reg = 0x320,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x04,
|
||||
},
|
||||
}, {
|
||||
.id = 0x28,
|
||||
.name = "eppu",
|
||||
.swgroup = TEGRA_SWGROUP_EPP,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 8,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x300,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x33,
|
||||
},
|
||||
}, {
|
||||
.id = 0x29,
|
||||
.name = "eppv",
|
||||
.swgroup = TEGRA_SWGROUP_EPP,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 9,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x304,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x6c,
|
||||
},
|
||||
}, {
|
||||
.id = 0x2a,
|
||||
.name = "eppy",
|
||||
.swgroup = TEGRA_SWGROUP_EPP,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 10,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x304,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x6c,
|
||||
},
|
||||
}, {
|
||||
.id = 0x2b,
|
||||
.name = "msencswr",
|
||||
.swgroup = TEGRA_SWGROUP_MSENC,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 11,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x328,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x80,
|
||||
},
|
||||
}, {
|
||||
.id = 0x2c,
|
||||
.name = "viwsb",
|
||||
.swgroup = TEGRA_SWGROUP_VI,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 12,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x364,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x47,
|
||||
},
|
||||
}, {
|
||||
.id = 0x2d,
|
||||
.name = "viwu",
|
||||
.swgroup = TEGRA_SWGROUP_VI,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 13,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x368,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0xff,
|
||||
},
|
||||
}, {
|
||||
.id = 0x2e,
|
||||
.name = "viwv",
|
||||
.swgroup = TEGRA_SWGROUP_VI,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 14,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x368,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0xff,
|
||||
},
|
||||
}, {
|
||||
.id = 0x2f,
|
||||
.name = "viwy",
|
||||
.swgroup = TEGRA_SWGROUP_VI,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 15,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x36c,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x47,
|
||||
},
|
||||
}, {
|
||||
.id = 0x30,
|
||||
.name = "g2dw",
|
||||
.swgroup = TEGRA_SWGROUP_G2,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 16,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x30c,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x9,
|
||||
},
|
||||
}, {
|
||||
.id = 0x32,
|
||||
.name = "avpcarm7w",
|
||||
.swgroup = TEGRA_SWGROUP_AVPC,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 18,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x2e4,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x0e,
|
||||
},
|
||||
}, {
|
||||
.id = 0x33,
|
||||
.name = "fdcdwr",
|
||||
.swgroup = TEGRA_SWGROUP_NV,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 19,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x338,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x10,
|
||||
},
|
||||
}, {
|
||||
.id = 0x34,
|
||||
.name = "fdcwr2",
|
||||
.swgroup = TEGRA_SWGROUP_NV,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 20,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x340,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x10,
|
||||
},
|
||||
}, {
|
||||
.id = 0x35,
|
||||
.name = "hdaw",
|
||||
.swgroup = TEGRA_SWGROUP_HDA,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 21,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x318,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0xff,
|
||||
},
|
||||
}, {
|
||||
.id = 0x36,
|
||||
.name = "host1xw",
|
||||
.swgroup = TEGRA_SWGROUP_HC,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 22,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x314,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x25,
|
||||
},
|
||||
}, {
|
||||
.id = 0x37,
|
||||
.name = "ispw",
|
||||
.swgroup = TEGRA_SWGROUP_ISP,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 23,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x31c,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0xff,
|
||||
},
|
||||
}, {
|
||||
.id = 0x38,
|
||||
.name = "mpcorelpw",
|
||||
.swgroup = TEGRA_SWGROUP_MPCORELP,
|
||||
.la = {
|
||||
.reg = 0x324,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x80,
|
||||
},
|
||||
}, {
|
||||
.id = 0x39,
|
||||
.name = "mpcorew",
|
||||
.swgroup = TEGRA_SWGROUP_MPCORE,
|
||||
.la = {
|
||||
.reg = 0x320,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x0e,
|
||||
},
|
||||
}, {
|
||||
.id = 0x3b,
|
||||
.name = "ppcsahbdmaw",
|
||||
.swgroup = TEGRA_SWGROUP_PPCS,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 27,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x348,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0xa5,
|
||||
},
|
||||
}, {
|
||||
.id = 0x3c,
|
||||
.name = "ppcsahbslvw",
|
||||
.swgroup = TEGRA_SWGROUP_PPCS,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 28,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x348,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0xe8,
|
||||
},
|
||||
}, {
|
||||
.id = 0x3e,
|
||||
.name = "vdebsevw",
|
||||
.swgroup = TEGRA_SWGROUP_VDE,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 30,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x35c,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0xff,
|
||||
},
|
||||
}, {
|
||||
.id = 0x3f,
|
||||
.name = "vdedbgw",
|
||||
.swgroup = TEGRA_SWGROUP_VDE,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 31,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x35c,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0xff,
|
||||
},
|
||||
}, {
|
||||
.id = 0x40,
|
||||
.name = "vdembew",
|
||||
.swgroup = TEGRA_SWGROUP_VDE,
|
||||
.smmu = {
|
||||
.reg = 0x230,
|
||||
.bit = 0,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x360,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x89,
|
||||
},
|
||||
}, {
|
||||
.id = 0x41,
|
||||
.name = "vdetpmw",
|
||||
.swgroup = TEGRA_SWGROUP_VDE,
|
||||
.smmu = {
|
||||
.reg = 0x230,
|
||||
.bit = 1,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x360,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x59,
|
||||
},
|
||||
}, {
|
||||
.id = 0x4a,
|
||||
.name = "xusb_hostr",
|
||||
.swgroup = TEGRA_SWGROUP_XUSB_HOST,
|
||||
.smmu = {
|
||||
.reg = 0x230,
|
||||
.bit = 10,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x37c,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0xa5,
|
||||
},
|
||||
}, {
|
||||
.id = 0x4b,
|
||||
.name = "xusb_hostw",
|
||||
.swgroup = TEGRA_SWGROUP_XUSB_HOST,
|
||||
.smmu = {
|
||||
.reg = 0x230,
|
||||
.bit = 11,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x37c,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0xa5,
|
||||
},
|
||||
}, {
|
||||
.id = 0x4c,
|
||||
.name = "xusb_devr",
|
||||
.swgroup = TEGRA_SWGROUP_XUSB_DEV,
|
||||
.smmu = {
|
||||
.reg = 0x230,
|
||||
.bit = 12,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x380,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0xa5,
|
||||
},
|
||||
}, {
|
||||
.id = 0x4d,
|
||||
.name = "xusb_devw",
|
||||
.swgroup = TEGRA_SWGROUP_XUSB_DEV,
|
||||
.smmu = {
|
||||
.reg = 0x230,
|
||||
.bit = 13,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x380,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0xa5,
|
||||
},
|
||||
}, {
|
||||
.id = 0x4e,
|
||||
.name = "fdcdwr3",
|
||||
.swgroup = TEGRA_SWGROUP_NV,
|
||||
.smmu = {
|
||||
.reg = 0x230,
|
||||
.bit = 14,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x388,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x10,
|
||||
},
|
||||
}, {
|
||||
.id = 0x4f,
|
||||
.name = "fdcdrd3",
|
||||
.swgroup = TEGRA_SWGROUP_NV,
|
||||
.smmu = {
|
||||
.reg = 0x230,
|
||||
.bit = 15,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x384,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x0c,
|
||||
},
|
||||
}, {
|
||||
.id = 0x50,
|
||||
.name = "fdcwr4",
|
||||
.swgroup = TEGRA_SWGROUP_NV,
|
||||
.smmu = {
|
||||
.reg = 0x230,
|
||||
.bit = 16,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x388,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x10,
|
||||
},
|
||||
}, {
|
||||
.id = 0x51,
|
||||
.name = "fdcrd4",
|
||||
.swgroup = TEGRA_SWGROUP_NV,
|
||||
.smmu = {
|
||||
.reg = 0x230,
|
||||
.bit = 17,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x384,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x0c,
|
||||
},
|
||||
}, {
|
||||
.id = 0x52,
|
||||
.name = "emucifr",
|
||||
.swgroup = TEGRA_SWGROUP_EMUCIF,
|
||||
.la = {
|
||||
.reg = 0x38c,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x04,
|
||||
},
|
||||
}, {
|
||||
.id = 0x53,
|
||||
.name = "emucifw",
|
||||
.swgroup = TEGRA_SWGROUP_EMUCIF,
|
||||
.la = {
|
||||
.reg = 0x38c,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x0e,
|
||||
},
|
||||
}, {
|
||||
.id = 0x54,
|
||||
.name = "tsecsrd",
|
||||
.swgroup = TEGRA_SWGROUP_TSEC,
|
||||
.smmu = {
|
||||
.reg = 0x230,
|
||||
.bit = 20,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x390,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x50,
|
||||
},
|
||||
}, {
|
||||
.id = 0x55,
|
||||
.name = "tsecswr",
|
||||
.swgroup = TEGRA_SWGROUP_TSEC,
|
||||
.smmu = {
|
||||
.reg = 0x230,
|
||||
.bit = 21,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x390,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x50,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static const struct tegra_smmu_swgroup tegra114_swgroups[] = {
|
||||
{ .swgroup = TEGRA_SWGROUP_DC, .reg = 0x240 },
|
||||
{ .swgroup = TEGRA_SWGROUP_DCB, .reg = 0x244 },
|
||||
{ .swgroup = TEGRA_SWGROUP_EPP, .reg = 0x248 },
|
||||
{ .swgroup = TEGRA_SWGROUP_G2, .reg = 0x24c },
|
||||
{ .swgroup = TEGRA_SWGROUP_AVPC, .reg = 0x23c },
|
||||
{ .swgroup = TEGRA_SWGROUP_NV, .reg = 0x268 },
|
||||
{ .swgroup = TEGRA_SWGROUP_HDA, .reg = 0x254 },
|
||||
{ .swgroup = TEGRA_SWGROUP_HC, .reg = 0x250 },
|
||||
{ .swgroup = TEGRA_SWGROUP_MSENC, .reg = 0x264 },
|
||||
{ .swgroup = TEGRA_SWGROUP_PPCS, .reg = 0x270 },
|
||||
{ .swgroup = TEGRA_SWGROUP_VDE, .reg = 0x27c },
|
||||
{ .swgroup = TEGRA_SWGROUP_VI, .reg = 0x280 },
|
||||
{ .swgroup = TEGRA_SWGROUP_ISP, .reg = 0x258 },
|
||||
{ .swgroup = TEGRA_SWGROUP_XUSB_HOST, .reg = 0x288 },
|
||||
{ .swgroup = TEGRA_SWGROUP_XUSB_DEV, .reg = 0x28c },
|
||||
{ .swgroup = TEGRA_SWGROUP_TSEC, .reg = 0x294 },
|
||||
};
|
||||
|
||||
static void tegra114_flush_dcache(struct page *page, unsigned long offset,
|
||||
size_t size)
|
||||
{
|
||||
phys_addr_t phys = page_to_phys(page) + offset;
|
||||
void *virt = page_address(page) + offset;
|
||||
|
||||
__cpuc_flush_dcache_area(virt, size);
|
||||
outer_flush_range(phys, phys + size);
|
||||
}
|
||||
|
||||
static const struct tegra_smmu_ops tegra114_smmu_ops = {
|
||||
.flush_dcache = tegra114_flush_dcache,
|
||||
};
|
||||
|
||||
static const struct tegra_smmu_soc tegra114_smmu_soc = {
|
||||
.clients = tegra114_mc_clients,
|
||||
.num_clients = ARRAY_SIZE(tegra114_mc_clients),
|
||||
.swgroups = tegra114_swgroups,
|
||||
.num_swgroups = ARRAY_SIZE(tegra114_swgroups),
|
||||
.supports_round_robin_arbitration = false,
|
||||
.supports_request_limit = false,
|
||||
.num_asids = 4,
|
||||
.ops = &tegra114_smmu_ops,
|
||||
};
|
||||
|
||||
const struct tegra_mc_soc tegra114_mc_soc = {
|
||||
.clients = tegra114_mc_clients,
|
||||
.num_clients = ARRAY_SIZE(tegra114_mc_clients),
|
||||
.num_address_bits = 32,
|
||||
.atom_size = 32,
|
||||
.smmu = &tegra114_smmu_soc,
|
||||
};
|
995
drivers/memory/tegra/tegra124.c
Normal file
995
drivers/memory/tegra/tegra124.c
Normal file
@ -0,0 +1,995 @@
|
||||
/*
|
||||
* Copyright (C) 2014 NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/of.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
|
||||
#include <dt-bindings/memory/tegra124-mc.h>
|
||||
|
||||
#include "mc.h"
|
||||
|
||||
static const struct tegra_mc_client tegra124_mc_clients[] = {
|
||||
{
|
||||
.id = 0x00,
|
||||
.name = "ptcr",
|
||||
.swgroup = TEGRA_SWGROUP_PTC,
|
||||
}, {
|
||||
.id = 0x01,
|
||||
.name = "display0a",
|
||||
.swgroup = TEGRA_SWGROUP_DC,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 1,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x2e8,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0xc2,
|
||||
},
|
||||
}, {
|
||||
.id = 0x02,
|
||||
.name = "display0ab",
|
||||
.swgroup = TEGRA_SWGROUP_DCB,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 2,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x2f4,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0xc6,
|
||||
},
|
||||
}, {
|
||||
.id = 0x03,
|
||||
.name = "display0b",
|
||||
.swgroup = TEGRA_SWGROUP_DC,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 3,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x2e8,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x50,
|
||||
},
|
||||
}, {
|
||||
.id = 0x04,
|
||||
.name = "display0bb",
|
||||
.swgroup = TEGRA_SWGROUP_DCB,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 4,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x2f4,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x50,
|
||||
},
|
||||
}, {
|
||||
.id = 0x05,
|
||||
.name = "display0c",
|
||||
.swgroup = TEGRA_SWGROUP_DC,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 5,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x2ec,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x50,
|
||||
},
|
||||
}, {
|
||||
.id = 0x06,
|
||||
.name = "display0cb",
|
||||
.swgroup = TEGRA_SWGROUP_DCB,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 6,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x2f8,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x50,
|
||||
},
|
||||
}, {
|
||||
.id = 0x0e,
|
||||
.name = "afir",
|
||||
.swgroup = TEGRA_SWGROUP_AFI,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 14,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x2e0,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x13,
|
||||
},
|
||||
}, {
|
||||
.id = 0x0f,
|
||||
.name = "avpcarm7r",
|
||||
.swgroup = TEGRA_SWGROUP_AVPC,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 15,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x2e4,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x04,
|
||||
},
|
||||
}, {
|
||||
.id = 0x10,
|
||||
.name = "displayhc",
|
||||
.swgroup = TEGRA_SWGROUP_DC,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 16,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x2f0,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x50,
|
||||
},
|
||||
}, {
|
||||
.id = 0x11,
|
||||
.name = "displayhcb",
|
||||
.swgroup = TEGRA_SWGROUP_DCB,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 17,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x2fc,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x50,
|
||||
},
|
||||
}, {
|
||||
.id = 0x15,
|
||||
.name = "hdar",
|
||||
.swgroup = TEGRA_SWGROUP_HDA,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 21,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x318,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x24,
|
||||
},
|
||||
}, {
|
||||
.id = 0x16,
|
||||
.name = "host1xdmar",
|
||||
.swgroup = TEGRA_SWGROUP_HC,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 22,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x310,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x1e,
|
||||
},
|
||||
}, {
|
||||
.id = 0x17,
|
||||
.name = "host1xr",
|
||||
.swgroup = TEGRA_SWGROUP_HC,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 23,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x310,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x50,
|
||||
},
|
||||
}, {
|
||||
.id = 0x1c,
|
||||
.name = "msencsrd",
|
||||
.swgroup = TEGRA_SWGROUP_MSENC,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 28,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x328,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x23,
|
||||
},
|
||||
}, {
|
||||
.id = 0x1d,
|
||||
.name = "ppcsahbdmar",
|
||||
.swgroup = TEGRA_SWGROUP_PPCS,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 29,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x344,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x49,
|
||||
},
|
||||
}, {
|
||||
.id = 0x1e,
|
||||
.name = "ppcsahbslvr",
|
||||
.swgroup = TEGRA_SWGROUP_PPCS,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 30,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x344,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x1a,
|
||||
},
|
||||
}, {
|
||||
.id = 0x1f,
|
||||
.name = "satar",
|
||||
.swgroup = TEGRA_SWGROUP_SATA,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 31,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x350,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x65,
|
||||
},
|
||||
}, {
|
||||
.id = 0x22,
|
||||
.name = "vdebsevr",
|
||||
.swgroup = TEGRA_SWGROUP_VDE,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 2,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x354,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x4f,
|
||||
},
|
||||
}, {
|
||||
.id = 0x23,
|
||||
.name = "vdember",
|
||||
.swgroup = TEGRA_SWGROUP_VDE,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 3,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x354,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x3d,
|
||||
},
|
||||
}, {
|
||||
.id = 0x24,
|
||||
.name = "vdemcer",
|
||||
.swgroup = TEGRA_SWGROUP_VDE,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 4,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x358,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x66,
|
||||
},
|
||||
}, {
|
||||
.id = 0x25,
|
||||
.name = "vdetper",
|
||||
.swgroup = TEGRA_SWGROUP_VDE,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 5,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x358,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0xa5,
|
||||
},
|
||||
}, {
|
||||
.id = 0x26,
|
||||
.name = "mpcorelpr",
|
||||
.swgroup = TEGRA_SWGROUP_MPCORELP,
|
||||
.la = {
|
||||
.reg = 0x324,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x04,
|
||||
},
|
||||
}, {
|
||||
.id = 0x27,
|
||||
.name = "mpcorer",
|
||||
.swgroup = TEGRA_SWGROUP_MPCORE,
|
||||
.la = {
|
||||
.reg = 0x320,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x04,
|
||||
},
|
||||
}, {
|
||||
.id = 0x2b,
|
||||
.name = "msencswr",
|
||||
.swgroup = TEGRA_SWGROUP_MSENC,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 11,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x328,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x80,
|
||||
},
|
||||
}, {
|
||||
.id = 0x31,
|
||||
.name = "afiw",
|
||||
.swgroup = TEGRA_SWGROUP_AFI,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 17,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x2e0,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x80,
|
||||
},
|
||||
}, {
|
||||
.id = 0x32,
|
||||
.name = "avpcarm7w",
|
||||
.swgroup = TEGRA_SWGROUP_AVPC,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 18,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x2e4,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x80,
|
||||
},
|
||||
}, {
|
||||
.id = 0x35,
|
||||
.name = "hdaw",
|
||||
.swgroup = TEGRA_SWGROUP_HDA,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 21,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x318,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x80,
|
||||
},
|
||||
}, {
|
||||
.id = 0x36,
|
||||
.name = "host1xw",
|
||||
.swgroup = TEGRA_SWGROUP_HC,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 22,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x314,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x80,
|
||||
},
|
||||
}, {
|
||||
.id = 0x38,
|
||||
.name = "mpcorelpw",
|
||||
.swgroup = TEGRA_SWGROUP_MPCORELP,
|
||||
.la = {
|
||||
.reg = 0x324,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x80,
|
||||
},
|
||||
}, {
|
||||
.id = 0x39,
|
||||
.name = "mpcorew",
|
||||
.swgroup = TEGRA_SWGROUP_MPCORE,
|
||||
.la = {
|
||||
.reg = 0x320,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x80,
|
||||
},
|
||||
}, {
|
||||
.id = 0x3b,
|
||||
.name = "ppcsahbdmaw",
|
||||
.swgroup = TEGRA_SWGROUP_PPCS,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 27,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x348,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x80,
|
||||
},
|
||||
}, {
|
||||
.id = 0x3c,
|
||||
.name = "ppcsahbslvw",
|
||||
.swgroup = TEGRA_SWGROUP_PPCS,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 28,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x348,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x80,
|
||||
},
|
||||
}, {
|
||||
.id = 0x3d,
|
||||
.name = "sataw",
|
||||
.swgroup = TEGRA_SWGROUP_SATA,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 29,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x350,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x65,
|
||||
},
|
||||
}, {
|
||||
.id = 0x3e,
|
||||
.name = "vdebsevw",
|
||||
.swgroup = TEGRA_SWGROUP_VDE,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 30,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x35c,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x80,
|
||||
},
|
||||
}, {
|
||||
.id = 0x3f,
|
||||
.name = "vdedbgw",
|
||||
.swgroup = TEGRA_SWGROUP_VDE,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 31,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x35c,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x80,
|
||||
},
|
||||
}, {
|
||||
.id = 0x40,
|
||||
.name = "vdembew",
|
||||
.swgroup = TEGRA_SWGROUP_VDE,
|
||||
.smmu = {
|
||||
.reg = 0x230,
|
||||
.bit = 0,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x360,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x80,
|
||||
},
|
||||
}, {
|
||||
.id = 0x41,
|
||||
.name = "vdetpmw",
|
||||
.swgroup = TEGRA_SWGROUP_VDE,
|
||||
.smmu = {
|
||||
.reg = 0x230,
|
||||
.bit = 1,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x360,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x80,
|
||||
},
|
||||
}, {
|
||||
.id = 0x44,
|
||||
.name = "ispra",
|
||||
.swgroup = TEGRA_SWGROUP_ISP2,
|
||||
.smmu = {
|
||||
.reg = 0x230,
|
||||
.bit = 4,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x370,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x18,
|
||||
},
|
||||
}, {
|
||||
.id = 0x46,
|
||||
.name = "ispwa",
|
||||
.swgroup = TEGRA_SWGROUP_ISP2,
|
||||
.smmu = {
|
||||
.reg = 0x230,
|
||||
.bit = 6,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x374,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x80,
|
||||
},
|
||||
}, {
|
||||
.id = 0x47,
|
||||
.name = "ispwb",
|
||||
.swgroup = TEGRA_SWGROUP_ISP2,
|
||||
.smmu = {
|
||||
.reg = 0x230,
|
||||
.bit = 7,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x374,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x80,
|
||||
},
|
||||
}, {
|
||||
.id = 0x4a,
|
||||
.name = "xusb_hostr",
|
||||
.swgroup = TEGRA_SWGROUP_XUSB_HOST,
|
||||
.smmu = {
|
||||
.reg = 0x230,
|
||||
.bit = 10,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x37c,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x39,
|
||||
},
|
||||
}, {
|
||||
.id = 0x4b,
|
||||
.name = "xusb_hostw",
|
||||
.swgroup = TEGRA_SWGROUP_XUSB_HOST,
|
||||
.smmu = {
|
||||
.reg = 0x230,
|
||||
.bit = 11,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x37c,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x80,
|
||||
},
|
||||
}, {
|
||||
.id = 0x4c,
|
||||
.name = "xusb_devr",
|
||||
.swgroup = TEGRA_SWGROUP_XUSB_DEV,
|
||||
.smmu = {
|
||||
.reg = 0x230,
|
||||
.bit = 12,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x380,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x39,
|
||||
},
|
||||
}, {
|
||||
.id = 0x4d,
|
||||
.name = "xusb_devw",
|
||||
.swgroup = TEGRA_SWGROUP_XUSB_DEV,
|
||||
.smmu = {
|
||||
.reg = 0x230,
|
||||
.bit = 13,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x380,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x80,
|
||||
},
|
||||
}, {
|
||||
.id = 0x4e,
|
||||
.name = "isprab",
|
||||
.swgroup = TEGRA_SWGROUP_ISP2B,
|
||||
.smmu = {
|
||||
.reg = 0x230,
|
||||
.bit = 14,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x384,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x18,
|
||||
},
|
||||
}, {
|
||||
.id = 0x50,
|
||||
.name = "ispwab",
|
||||
.swgroup = TEGRA_SWGROUP_ISP2B,
|
||||
.smmu = {
|
||||
.reg = 0x230,
|
||||
.bit = 16,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x388,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x80,
|
||||
},
|
||||
}, {
|
||||
.id = 0x51,
|
||||
.name = "ispwbb",
|
||||
.swgroup = TEGRA_SWGROUP_ISP2B,
|
||||
.smmu = {
|
||||
.reg = 0x230,
|
||||
.bit = 17,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x388,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x80,
|
||||
},
|
||||
}, {
|
||||
.id = 0x54,
|
||||
.name = "tsecsrd",
|
||||
.swgroup = TEGRA_SWGROUP_TSEC,
|
||||
.smmu = {
|
||||
.reg = 0x230,
|
||||
.bit = 20,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x390,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x9b,
|
||||
},
|
||||
}, {
|
||||
.id = 0x55,
|
||||
.name = "tsecswr",
|
||||
.swgroup = TEGRA_SWGROUP_TSEC,
|
||||
.smmu = {
|
||||
.reg = 0x230,
|
||||
.bit = 21,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x390,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x80,
|
||||
},
|
||||
}, {
|
||||
.id = 0x56,
|
||||
.name = "a9avpscr",
|
||||
.swgroup = TEGRA_SWGROUP_A9AVP,
|
||||
.smmu = {
|
||||
.reg = 0x230,
|
||||
.bit = 22,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x3a4,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x04,
|
||||
},
|
||||
}, {
|
||||
.id = 0x57,
|
||||
.name = "a9avpscw",
|
||||
.swgroup = TEGRA_SWGROUP_A9AVP,
|
||||
.smmu = {
|
||||
.reg = 0x230,
|
||||
.bit = 23,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x3a4,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x80,
|
||||
},
|
||||
}, {
|
||||
.id = 0x58,
|
||||
.name = "gpusrd",
|
||||
.swgroup = TEGRA_SWGROUP_GPU,
|
||||
.smmu = {
|
||||
/* read-only */
|
||||
.reg = 0x230,
|
||||
.bit = 24,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x3c8,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x1a,
|
||||
},
|
||||
}, {
|
||||
.id = 0x59,
|
||||
.name = "gpuswr",
|
||||
.swgroup = TEGRA_SWGROUP_GPU,
|
||||
.smmu = {
|
||||
/* read-only */
|
||||
.reg = 0x230,
|
||||
.bit = 25,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x3c8,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x80,
|
||||
},
|
||||
}, {
|
||||
.id = 0x5a,
|
||||
.name = "displayt",
|
||||
.swgroup = TEGRA_SWGROUP_DC,
|
||||
.smmu = {
|
||||
.reg = 0x230,
|
||||
.bit = 26,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x2f0,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x50,
|
||||
},
|
||||
}, {
|
||||
.id = 0x60,
|
||||
.name = "sdmmcra",
|
||||
.swgroup = TEGRA_SWGROUP_SDMMC1A,
|
||||
.smmu = {
|
||||
.reg = 0x234,
|
||||
.bit = 0,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x3b8,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x49,
|
||||
},
|
||||
}, {
|
||||
.id = 0x61,
|
||||
.name = "sdmmcraa",
|
||||
.swgroup = TEGRA_SWGROUP_SDMMC2A,
|
||||
.smmu = {
|
||||
.reg = 0x234,
|
||||
.bit = 1,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x3bc,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x49,
|
||||
},
|
||||
}, {
|
||||
.id = 0x62,
|
||||
.name = "sdmmcr",
|
||||
.swgroup = TEGRA_SWGROUP_SDMMC3A,
|
||||
.smmu = {
|
||||
.reg = 0x234,
|
||||
.bit = 2,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x3c0,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x49,
|
||||
},
|
||||
}, {
|
||||
.id = 0x63,
|
||||
.swgroup = TEGRA_SWGROUP_SDMMC4A,
|
||||
.name = "sdmmcrab",
|
||||
.smmu = {
|
||||
.reg = 0x234,
|
||||
.bit = 3,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x3c4,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x49,
|
||||
},
|
||||
}, {
|
||||
.id = 0x64,
|
||||
.name = "sdmmcwa",
|
||||
.swgroup = TEGRA_SWGROUP_SDMMC1A,
|
||||
.smmu = {
|
||||
.reg = 0x234,
|
||||
.bit = 4,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x3b8,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x80,
|
||||
},
|
||||
}, {
|
||||
.id = 0x65,
|
||||
.name = "sdmmcwaa",
|
||||
.swgroup = TEGRA_SWGROUP_SDMMC2A,
|
||||
.smmu = {
|
||||
.reg = 0x234,
|
||||
.bit = 5,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x3bc,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x80,
|
||||
},
|
||||
}, {
|
||||
.id = 0x66,
|
||||
.name = "sdmmcw",
|
||||
.swgroup = TEGRA_SWGROUP_SDMMC3A,
|
||||
.smmu = {
|
||||
.reg = 0x234,
|
||||
.bit = 6,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x3c0,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x80,
|
||||
},
|
||||
}, {
|
||||
.id = 0x67,
|
||||
.name = "sdmmcwab",
|
||||
.swgroup = TEGRA_SWGROUP_SDMMC4A,
|
||||
.smmu = {
|
||||
.reg = 0x234,
|
||||
.bit = 7,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x3c4,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x80,
|
||||
},
|
||||
}, {
|
||||
.id = 0x6c,
|
||||
.name = "vicsrd",
|
||||
.swgroup = TEGRA_SWGROUP_VIC,
|
||||
.smmu = {
|
||||
.reg = 0x234,
|
||||
.bit = 12,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x394,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x1a,
|
||||
},
|
||||
}, {
|
||||
.id = 0x6d,
|
||||
.name = "vicswr",
|
||||
.swgroup = TEGRA_SWGROUP_VIC,
|
||||
.smmu = {
|
||||
.reg = 0x234,
|
||||
.bit = 13,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x394,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x80,
|
||||
},
|
||||
}, {
|
||||
.id = 0x72,
|
||||
.name = "viw",
|
||||
.swgroup = TEGRA_SWGROUP_VI,
|
||||
.smmu = {
|
||||
.reg = 0x234,
|
||||
.bit = 18,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x398,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x80,
|
||||
},
|
||||
}, {
|
||||
.id = 0x73,
|
||||
.name = "displayd",
|
||||
.swgroup = TEGRA_SWGROUP_DC,
|
||||
.smmu = {
|
||||
.reg = 0x234,
|
||||
.bit = 19,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x3c8,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x50,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static const struct tegra_smmu_swgroup tegra124_swgroups[] = {
|
||||
{ .swgroup = TEGRA_SWGROUP_DC, .reg = 0x240 },
|
||||
{ .swgroup = TEGRA_SWGROUP_DCB, .reg = 0x244 },
|
||||
{ .swgroup = TEGRA_SWGROUP_AFI, .reg = 0x238 },
|
||||
{ .swgroup = TEGRA_SWGROUP_AVPC, .reg = 0x23c },
|
||||
{ .swgroup = TEGRA_SWGROUP_HDA, .reg = 0x254 },
|
||||
{ .swgroup = TEGRA_SWGROUP_HC, .reg = 0x250 },
|
||||
{ .swgroup = TEGRA_SWGROUP_MSENC, .reg = 0x264 },
|
||||
{ .swgroup = TEGRA_SWGROUP_PPCS, .reg = 0x270 },
|
||||
{ .swgroup = TEGRA_SWGROUP_SATA, .reg = 0x274 },
|
||||
{ .swgroup = TEGRA_SWGROUP_VDE, .reg = 0x27c },
|
||||
{ .swgroup = TEGRA_SWGROUP_ISP2, .reg = 0x258 },
|
||||
{ .swgroup = TEGRA_SWGROUP_XUSB_HOST, .reg = 0x288 },
|
||||
{ .swgroup = TEGRA_SWGROUP_XUSB_DEV, .reg = 0x28c },
|
||||
{ .swgroup = TEGRA_SWGROUP_ISP2B, .reg = 0xaa4 },
|
||||
{ .swgroup = TEGRA_SWGROUP_TSEC, .reg = 0x294 },
|
||||
{ .swgroup = TEGRA_SWGROUP_A9AVP, .reg = 0x290 },
|
||||
{ .swgroup = TEGRA_SWGROUP_GPU, .reg = 0xaac },
|
||||
{ .swgroup = TEGRA_SWGROUP_SDMMC1A, .reg = 0xa94 },
|
||||
{ .swgroup = TEGRA_SWGROUP_SDMMC2A, .reg = 0xa98 },
|
||||
{ .swgroup = TEGRA_SWGROUP_SDMMC3A, .reg = 0xa9c },
|
||||
{ .swgroup = TEGRA_SWGROUP_SDMMC4A, .reg = 0xaa0 },
|
||||
{ .swgroup = TEGRA_SWGROUP_VIC, .reg = 0x284 },
|
||||
{ .swgroup = TEGRA_SWGROUP_VI, .reg = 0x280 },
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ARCH_TEGRA_124_SOC
|
||||
static void tegra124_flush_dcache(struct page *page, unsigned long offset,
|
||||
size_t size)
|
||||
{
|
||||
phys_addr_t phys = page_to_phys(page) + offset;
|
||||
void *virt = page_address(page) + offset;
|
||||
|
||||
__cpuc_flush_dcache_area(virt, size);
|
||||
outer_flush_range(phys, phys + size);
|
||||
}
|
||||
|
||||
static const struct tegra_smmu_ops tegra124_smmu_ops = {
|
||||
.flush_dcache = tegra124_flush_dcache,
|
||||
};
|
||||
|
||||
static const struct tegra_smmu_soc tegra124_smmu_soc = {
|
||||
.clients = tegra124_mc_clients,
|
||||
.num_clients = ARRAY_SIZE(tegra124_mc_clients),
|
||||
.swgroups = tegra124_swgroups,
|
||||
.num_swgroups = ARRAY_SIZE(tegra124_swgroups),
|
||||
.supports_round_robin_arbitration = true,
|
||||
.supports_request_limit = true,
|
||||
.num_asids = 128,
|
||||
.ops = &tegra124_smmu_ops,
|
||||
};
|
||||
|
||||
const struct tegra_mc_soc tegra124_mc_soc = {
|
||||
.clients = tegra124_mc_clients,
|
||||
.num_clients = ARRAY_SIZE(tegra124_mc_clients),
|
||||
.num_address_bits = 34,
|
||||
.atom_size = 32,
|
||||
.smmu = &tegra124_smmu_soc,
|
||||
};
|
||||
#endif /* CONFIG_ARCH_TEGRA_124_SOC */
|
970
drivers/memory/tegra/tegra30.c
Normal file
970
drivers/memory/tegra/tegra30.c
Normal file
@ -0,0 +1,970 @@
|
||||
/*
|
||||
* Copyright (C) 2014 NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/of.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
|
||||
#include <dt-bindings/memory/tegra30-mc.h>
|
||||
|
||||
#include "mc.h"
|
||||
|
||||
static const struct tegra_mc_client tegra30_mc_clients[] = {
|
||||
{
|
||||
.id = 0x00,
|
||||
.name = "ptcr",
|
||||
.swgroup = TEGRA_SWGROUP_PTC,
|
||||
}, {
|
||||
.id = 0x01,
|
||||
.name = "display0a",
|
||||
.swgroup = TEGRA_SWGROUP_DC,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 1,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x2e8,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x4e,
|
||||
},
|
||||
}, {
|
||||
.id = 0x02,
|
||||
.name = "display0ab",
|
||||
.swgroup = TEGRA_SWGROUP_DCB,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 2,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x2f4,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x4e,
|
||||
},
|
||||
}, {
|
||||
.id = 0x03,
|
||||
.name = "display0b",
|
||||
.swgroup = TEGRA_SWGROUP_DC,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 3,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x2e8,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x4e,
|
||||
},
|
||||
}, {
|
||||
.id = 0x04,
|
||||
.name = "display0bb",
|
||||
.swgroup = TEGRA_SWGROUP_DCB,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 4,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x2f4,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x4e,
|
||||
},
|
||||
}, {
|
||||
.id = 0x05,
|
||||
.name = "display0c",
|
||||
.swgroup = TEGRA_SWGROUP_DC,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 5,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x2ec,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x4e,
|
||||
},
|
||||
}, {
|
||||
.id = 0x06,
|
||||
.name = "display0cb",
|
||||
.swgroup = TEGRA_SWGROUP_DCB,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 6,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x2f8,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x4e,
|
||||
},
|
||||
}, {
|
||||
.id = 0x07,
|
||||
.name = "display1b",
|
||||
.swgroup = TEGRA_SWGROUP_DC,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 7,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x2ec,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x4e,
|
||||
},
|
||||
}, {
|
||||
.id = 0x08,
|
||||
.name = "display1bb",
|
||||
.swgroup = TEGRA_SWGROUP_DCB,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 8,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x2f8,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x4e,
|
||||
},
|
||||
}, {
|
||||
.id = 0x09,
|
||||
.name = "eppup",
|
||||
.swgroup = TEGRA_SWGROUP_EPP,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 9,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x300,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x17,
|
||||
},
|
||||
}, {
|
||||
.id = 0x0a,
|
||||
.name = "g2pr",
|
||||
.swgroup = TEGRA_SWGROUP_G2,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 10,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x308,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x09,
|
||||
},
|
||||
}, {
|
||||
.id = 0x0b,
|
||||
.name = "g2sr",
|
||||
.swgroup = TEGRA_SWGROUP_G2,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 11,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x308,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x09,
|
||||
},
|
||||
}, {
|
||||
.id = 0x0c,
|
||||
.name = "mpeunifbr",
|
||||
.swgroup = TEGRA_SWGROUP_MPE,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 12,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x328,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x50,
|
||||
},
|
||||
}, {
|
||||
.id = 0x0d,
|
||||
.name = "viruv",
|
||||
.swgroup = TEGRA_SWGROUP_VI,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 13,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x364,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x2c,
|
||||
},
|
||||
}, {
|
||||
.id = 0x0e,
|
||||
.name = "afir",
|
||||
.swgroup = TEGRA_SWGROUP_AFI,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 14,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x2e0,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x10,
|
||||
},
|
||||
}, {
|
||||
.id = 0x0f,
|
||||
.name = "avpcarm7r",
|
||||
.swgroup = TEGRA_SWGROUP_AVPC,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 15,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x2e4,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x04,
|
||||
},
|
||||
}, {
|
||||
.id = 0x10,
|
||||
.name = "displayhc",
|
||||
.swgroup = TEGRA_SWGROUP_DC,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 16,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x2f0,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0xff,
|
||||
},
|
||||
}, {
|
||||
.id = 0x11,
|
||||
.name = "displayhcb",
|
||||
.swgroup = TEGRA_SWGROUP_DCB,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 17,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x2fc,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0xff,
|
||||
},
|
||||
}, {
|
||||
.id = 0x12,
|
||||
.name = "fdcdrd",
|
||||
.swgroup = TEGRA_SWGROUP_NV,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 18,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x334,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x0a,
|
||||
},
|
||||
}, {
|
||||
.id = 0x13,
|
||||
.name = "fdcdrd2",
|
||||
.swgroup = TEGRA_SWGROUP_NV2,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 19,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x33c,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x0a,
|
||||
},
|
||||
}, {
|
||||
.id = 0x14,
|
||||
.name = "g2dr",
|
||||
.swgroup = TEGRA_SWGROUP_G2,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 20,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x30c,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x0a,
|
||||
},
|
||||
}, {
|
||||
.id = 0x15,
|
||||
.name = "hdar",
|
||||
.swgroup = TEGRA_SWGROUP_HDA,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 21,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x318,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0xff,
|
||||
},
|
||||
}, {
|
||||
.id = 0x16,
|
||||
.name = "host1xdmar",
|
||||
.swgroup = TEGRA_SWGROUP_HC,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 22,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x310,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x05,
|
||||
},
|
||||
}, {
|
||||
.id = 0x17,
|
||||
.name = "host1xr",
|
||||
.swgroup = TEGRA_SWGROUP_HC,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 23,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x310,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x50,
|
||||
},
|
||||
}, {
|
||||
.id = 0x18,
|
||||
.name = "idxsrd",
|
||||
.swgroup = TEGRA_SWGROUP_NV,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 24,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x334,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x13,
|
||||
},
|
||||
}, {
|
||||
.id = 0x19,
|
||||
.name = "idxsrd2",
|
||||
.swgroup = TEGRA_SWGROUP_NV2,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 25,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x33c,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x13,
|
||||
},
|
||||
}, {
|
||||
.id = 0x1a,
|
||||
.name = "mpe_ipred",
|
||||
.swgroup = TEGRA_SWGROUP_MPE,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 26,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x328,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x80,
|
||||
},
|
||||
}, {
|
||||
.id = 0x1b,
|
||||
.name = "mpeamemrd",
|
||||
.swgroup = TEGRA_SWGROUP_MPE,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 27,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x32c,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x42,
|
||||
},
|
||||
}, {
|
||||
.id = 0x1c,
|
||||
.name = "mpecsrd",
|
||||
.swgroup = TEGRA_SWGROUP_MPE,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 28,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x32c,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0xff,
|
||||
},
|
||||
}, {
|
||||
.id = 0x1d,
|
||||
.name = "ppcsahbdmar",
|
||||
.swgroup = TEGRA_SWGROUP_PPCS,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 29,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x344,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x10,
|
||||
},
|
||||
}, {
|
||||
.id = 0x1e,
|
||||
.name = "ppcsahbslvr",
|
||||
.swgroup = TEGRA_SWGROUP_PPCS,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 30,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x344,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x12,
|
||||
},
|
||||
}, {
|
||||
.id = 0x1f,
|
||||
.name = "satar",
|
||||
.swgroup = TEGRA_SWGROUP_SATA,
|
||||
.smmu = {
|
||||
.reg = 0x228,
|
||||
.bit = 31,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x350,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x33,
|
||||
},
|
||||
}, {
|
||||
.id = 0x20,
|
||||
.name = "texsrd",
|
||||
.swgroup = TEGRA_SWGROUP_NV,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 0,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x338,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x13,
|
||||
},
|
||||
}, {
|
||||
.id = 0x21,
|
||||
.name = "texsrd2",
|
||||
.swgroup = TEGRA_SWGROUP_NV2,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 1,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x340,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x13,
|
||||
},
|
||||
}, {
|
||||
.id = 0x22,
|
||||
.name = "vdebsevr",
|
||||
.swgroup = TEGRA_SWGROUP_VDE,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 2,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x354,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0xff,
|
||||
},
|
||||
}, {
|
||||
.id = 0x23,
|
||||
.name = "vdember",
|
||||
.swgroup = TEGRA_SWGROUP_VDE,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 3,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x354,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0xd0,
|
||||
},
|
||||
}, {
|
||||
.id = 0x24,
|
||||
.name = "vdemcer",
|
||||
.swgroup = TEGRA_SWGROUP_VDE,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 4,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x358,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x2a,
|
||||
},
|
||||
}, {
|
||||
.id = 0x25,
|
||||
.name = "vdetper",
|
||||
.swgroup = TEGRA_SWGROUP_VDE,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 5,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x358,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x74,
|
||||
},
|
||||
}, {
|
||||
.id = 0x26,
|
||||
.name = "mpcorelpr",
|
||||
.swgroup = TEGRA_SWGROUP_MPCORELP,
|
||||
.la = {
|
||||
.reg = 0x324,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x04,
|
||||
},
|
||||
}, {
|
||||
.id = 0x27,
|
||||
.name = "mpcorer",
|
||||
.swgroup = TEGRA_SWGROUP_MPCORE,
|
||||
.la = {
|
||||
.reg = 0x320,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x04,
|
||||
},
|
||||
}, {
|
||||
.id = 0x28,
|
||||
.name = "eppu",
|
||||
.swgroup = TEGRA_SWGROUP_EPP,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 8,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x300,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x6c,
|
||||
},
|
||||
}, {
|
||||
.id = 0x29,
|
||||
.name = "eppv",
|
||||
.swgroup = TEGRA_SWGROUP_EPP,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 9,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x304,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x6c,
|
||||
},
|
||||
}, {
|
||||
.id = 0x2a,
|
||||
.name = "eppy",
|
||||
.swgroup = TEGRA_SWGROUP_EPP,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 10,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x304,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x6c,
|
||||
},
|
||||
}, {
|
||||
.id = 0x2b,
|
||||
.name = "mpeunifbw",
|
||||
.swgroup = TEGRA_SWGROUP_MPE,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 11,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x330,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x13,
|
||||
},
|
||||
}, {
|
||||
.id = 0x2c,
|
||||
.name = "viwsb",
|
||||
.swgroup = TEGRA_SWGROUP_VI,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 12,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x364,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x12,
|
||||
},
|
||||
}, {
|
||||
.id = 0x2d,
|
||||
.name = "viwu",
|
||||
.swgroup = TEGRA_SWGROUP_VI,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 13,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x368,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0xb2,
|
||||
},
|
||||
}, {
|
||||
.id = 0x2e,
|
||||
.name = "viwv",
|
||||
.swgroup = TEGRA_SWGROUP_VI,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 14,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x368,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0xb2,
|
||||
},
|
||||
}, {
|
||||
.id = 0x2f,
|
||||
.name = "viwy",
|
||||
.swgroup = TEGRA_SWGROUP_VI,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 15,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x36c,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x12,
|
||||
},
|
||||
}, {
|
||||
.id = 0x30,
|
||||
.name = "g2dw",
|
||||
.swgroup = TEGRA_SWGROUP_G2,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 16,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x30c,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x9,
|
||||
},
|
||||
}, {
|
||||
.id = 0x31,
|
||||
.name = "afiw",
|
||||
.swgroup = TEGRA_SWGROUP_AFI,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 17,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x2e0,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x0c,
|
||||
},
|
||||
}, {
|
||||
.id = 0x32,
|
||||
.name = "avpcarm7w",
|
||||
.swgroup = TEGRA_SWGROUP_AVPC,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 18,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x2e4,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x0e,
|
||||
},
|
||||
}, {
|
||||
.id = 0x33,
|
||||
.name = "fdcdwr",
|
||||
.swgroup = TEGRA_SWGROUP_NV,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 19,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x338,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x0a,
|
||||
},
|
||||
}, {
|
||||
.id = 0x34,
|
||||
.name = "fdcwr2",
|
||||
.swgroup = TEGRA_SWGROUP_NV2,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 20,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x340,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x0a,
|
||||
},
|
||||
}, {
|
||||
.id = 0x35,
|
||||
.name = "hdaw",
|
||||
.swgroup = TEGRA_SWGROUP_HDA,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 21,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x318,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0xff,
|
||||
},
|
||||
}, {
|
||||
.id = 0x36,
|
||||
.name = "host1xw",
|
||||
.swgroup = TEGRA_SWGROUP_HC,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 22,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x314,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x10,
|
||||
},
|
||||
}, {
|
||||
.id = 0x37,
|
||||
.name = "ispw",
|
||||
.swgroup = TEGRA_SWGROUP_ISP,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 23,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x31c,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0xff,
|
||||
},
|
||||
}, {
|
||||
.id = 0x38,
|
||||
.name = "mpcorelpw",
|
||||
.swgroup = TEGRA_SWGROUP_MPCORELP,
|
||||
.la = {
|
||||
.reg = 0x324,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x0e,
|
||||
},
|
||||
}, {
|
||||
.id = 0x39,
|
||||
.name = "mpcorew",
|
||||
.swgroup = TEGRA_SWGROUP_MPCORE,
|
||||
.la = {
|
||||
.reg = 0x320,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x0e,
|
||||
},
|
||||
}, {
|
||||
.id = 0x3a,
|
||||
.name = "mpecswr",
|
||||
.swgroup = TEGRA_SWGROUP_MPE,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 26,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x330,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0xff,
|
||||
},
|
||||
}, {
|
||||
.id = 0x3b,
|
||||
.name = "ppcsahbdmaw",
|
||||
.swgroup = TEGRA_SWGROUP_PPCS,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 27,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x348,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x10,
|
||||
},
|
||||
}, {
|
||||
.id = 0x3c,
|
||||
.name = "ppcsahbslvw",
|
||||
.swgroup = TEGRA_SWGROUP_PPCS,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 28,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x348,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x06,
|
||||
},
|
||||
}, {
|
||||
.id = 0x3d,
|
||||
.name = "sataw",
|
||||
.swgroup = TEGRA_SWGROUP_SATA,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 29,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x350,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x33,
|
||||
},
|
||||
}, {
|
||||
.id = 0x3e,
|
||||
.name = "vdebsevw",
|
||||
.swgroup = TEGRA_SWGROUP_VDE,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 30,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x35c,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0xff,
|
||||
},
|
||||
}, {
|
||||
.id = 0x3f,
|
||||
.name = "vdedbgw",
|
||||
.swgroup = TEGRA_SWGROUP_VDE,
|
||||
.smmu = {
|
||||
.reg = 0x22c,
|
||||
.bit = 31,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x35c,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0xff,
|
||||
},
|
||||
}, {
|
||||
.id = 0x40,
|
||||
.name = "vdembew",
|
||||
.swgroup = TEGRA_SWGROUP_VDE,
|
||||
.smmu = {
|
||||
.reg = 0x230,
|
||||
.bit = 0,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x360,
|
||||
.shift = 0,
|
||||
.mask = 0xff,
|
||||
.def = 0x42,
|
||||
},
|
||||
}, {
|
||||
.id = 0x41,
|
||||
.name = "vdetpmw",
|
||||
.swgroup = TEGRA_SWGROUP_VDE,
|
||||
.smmu = {
|
||||
.reg = 0x230,
|
||||
.bit = 1,
|
||||
},
|
||||
.la = {
|
||||
.reg = 0x360,
|
||||
.shift = 16,
|
||||
.mask = 0xff,
|
||||
.def = 0x2a,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static const struct tegra_smmu_swgroup tegra30_swgroups[] = {
|
||||
{ .swgroup = TEGRA_SWGROUP_DC, .reg = 0x240 },
|
||||
{ .swgroup = TEGRA_SWGROUP_DCB, .reg = 0x244 },
|
||||
{ .swgroup = TEGRA_SWGROUP_EPP, .reg = 0x248 },
|
||||
{ .swgroup = TEGRA_SWGROUP_G2, .reg = 0x24c },
|
||||
{ .swgroup = TEGRA_SWGROUP_MPE, .reg = 0x264 },
|
||||
{ .swgroup = TEGRA_SWGROUP_VI, .reg = 0x280 },
|
||||
{ .swgroup = TEGRA_SWGROUP_AFI, .reg = 0x238 },
|
||||
{ .swgroup = TEGRA_SWGROUP_AVPC, .reg = 0x23c },
|
||||
{ .swgroup = TEGRA_SWGROUP_NV, .reg = 0x268 },
|
||||
{ .swgroup = TEGRA_SWGROUP_NV2, .reg = 0x26c },
|
||||
{ .swgroup = TEGRA_SWGROUP_HDA, .reg = 0x254 },
|
||||
{ .swgroup = TEGRA_SWGROUP_HC, .reg = 0x250 },
|
||||
{ .swgroup = TEGRA_SWGROUP_PPCS, .reg = 0x270 },
|
||||
{ .swgroup = TEGRA_SWGROUP_SATA, .reg = 0x278 },
|
||||
{ .swgroup = TEGRA_SWGROUP_VDE, .reg = 0x27c },
|
||||
{ .swgroup = TEGRA_SWGROUP_ISP, .reg = 0x258 },
|
||||
};
|
||||
|
||||
static void tegra30_flush_dcache(struct page *page, unsigned long offset,
|
||||
size_t size)
|
||||
{
|
||||
phys_addr_t phys = page_to_phys(page) + offset;
|
||||
void *virt = page_address(page) + offset;
|
||||
|
||||
__cpuc_flush_dcache_area(virt, size);
|
||||
outer_flush_range(phys, phys + size);
|
||||
}
|
||||
|
||||
static const struct tegra_smmu_ops tegra30_smmu_ops = {
|
||||
.flush_dcache = tegra30_flush_dcache,
|
||||
};
|
||||
|
||||
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),
|
||||
.supports_round_robin_arbitration = false,
|
||||
.supports_request_limit = false,
|
||||
.num_asids = 4,
|
||||
.ops = &tegra30_smmu_ops,
|
||||
};
|
||||
|
||||
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,
|
||||
.smmu = &tegra30_smmu_soc,
|
||||
};
|
@ -1,378 +0,0 @@
|
||||
/*
|
||||
* Tegra30 Memory Controller
|
||||
*
|
||||
* Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/ratelimit.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#define DRV_NAME "tegra30-mc"
|
||||
|
||||
#define MC_INTSTATUS 0x0
|
||||
#define MC_INTMASK 0x4
|
||||
|
||||
#define MC_INT_ERR_SHIFT 6
|
||||
#define MC_INT_ERR_MASK (0x1f << MC_INT_ERR_SHIFT)
|
||||
#define MC_INT_DECERR_EMEM BIT(MC_INT_ERR_SHIFT)
|
||||
#define MC_INT_SECURITY_VIOLATION BIT(MC_INT_ERR_SHIFT + 2)
|
||||
#define MC_INT_ARBITRATION_EMEM BIT(MC_INT_ERR_SHIFT + 3)
|
||||
#define MC_INT_INVALID_SMMU_PAGE BIT(MC_INT_ERR_SHIFT + 4)
|
||||
|
||||
#define MC_ERR_STATUS 0x8
|
||||
#define MC_ERR_ADR 0xc
|
||||
|
||||
#define MC_ERR_TYPE_SHIFT 28
|
||||
#define MC_ERR_TYPE_MASK (7 << MC_ERR_TYPE_SHIFT)
|
||||
#define MC_ERR_TYPE_DECERR_EMEM 2
|
||||
#define MC_ERR_TYPE_SECURITY_TRUSTZONE 3
|
||||
#define MC_ERR_TYPE_SECURITY_CARVEOUT 4
|
||||
#define MC_ERR_TYPE_INVALID_SMMU_PAGE 6
|
||||
|
||||
#define MC_ERR_INVALID_SMMU_PAGE_SHIFT 25
|
||||
#define MC_ERR_INVALID_SMMU_PAGE_MASK (7 << MC_ERR_INVALID_SMMU_PAGE_SHIFT)
|
||||
#define MC_ERR_RW_SHIFT 16
|
||||
#define MC_ERR_RW BIT(MC_ERR_RW_SHIFT)
|
||||
#define MC_ERR_SECURITY BIT(MC_ERR_RW_SHIFT + 1)
|
||||
|
||||
#define SECURITY_VIOLATION_TYPE BIT(30) /* 0=TRUSTZONE, 1=CARVEOUT */
|
||||
|
||||
#define MC_EMEM_ARB_CFG 0x90
|
||||
#define MC_EMEM_ARB_OUTSTANDING_REQ 0x94
|
||||
#define MC_EMEM_ARB_TIMING_RCD 0x98
|
||||
#define MC_EMEM_ARB_TIMING_RP 0x9c
|
||||
#define MC_EMEM_ARB_TIMING_RC 0xa0
|
||||
#define MC_EMEM_ARB_TIMING_RAS 0xa4
|
||||
#define MC_EMEM_ARB_TIMING_FAW 0xa8
|
||||
#define MC_EMEM_ARB_TIMING_RRD 0xac
|
||||
#define MC_EMEM_ARB_TIMING_RAP2PRE 0xb0
|
||||
#define MC_EMEM_ARB_TIMING_WAP2PRE 0xb4
|
||||
#define MC_EMEM_ARB_TIMING_R2R 0xb8
|
||||
#define MC_EMEM_ARB_TIMING_W2W 0xbc
|
||||
#define MC_EMEM_ARB_TIMING_R2W 0xc0
|
||||
#define MC_EMEM_ARB_TIMING_W2R 0xc4
|
||||
|
||||
#define MC_EMEM_ARB_DA_TURNS 0xd0
|
||||
#define MC_EMEM_ARB_DA_COVERS 0xd4
|
||||
#define MC_EMEM_ARB_MISC0 0xd8
|
||||
#define MC_EMEM_ARB_MISC1 0xdc
|
||||
|
||||
#define MC_EMEM_ARB_RING3_THROTTLE 0xe4
|
||||
#define MC_EMEM_ARB_OVERRIDE 0xe8
|
||||
|
||||
#define MC_TIMING_CONTROL 0xfc
|
||||
|
||||
#define MC_CLIENT_ID_MASK 0x7f
|
||||
|
||||
#define NUM_MC_REG_BANKS 4
|
||||
|
||||
struct tegra30_mc {
|
||||
void __iomem *regs[NUM_MC_REG_BANKS];
|
||||
struct device *dev;
|
||||
u32 ctx[0];
|
||||
};
|
||||
|
||||
static inline u32 mc_readl(struct tegra30_mc *mc, u32 offs)
|
||||
{
|
||||
u32 val = 0;
|
||||
|
||||
if (offs < 0x10)
|
||||
val = readl(mc->regs[0] + offs);
|
||||
else if (offs < 0x1f0)
|
||||
val = readl(mc->regs[1] + offs - 0x3c);
|
||||
else if (offs < 0x228)
|
||||
val = readl(mc->regs[2] + offs - 0x200);
|
||||
else if (offs < 0x400)
|
||||
val = readl(mc->regs[3] + offs - 0x284);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline void mc_writel(struct tegra30_mc *mc, u32 val, u32 offs)
|
||||
{
|
||||
if (offs < 0x10)
|
||||
writel(val, mc->regs[0] + offs);
|
||||
else if (offs < 0x1f0)
|
||||
writel(val, mc->regs[1] + offs - 0x3c);
|
||||
else if (offs < 0x228)
|
||||
writel(val, mc->regs[2] + offs - 0x200);
|
||||
else if (offs < 0x400)
|
||||
writel(val, mc->regs[3] + offs - 0x284);
|
||||
}
|
||||
|
||||
static const char * const tegra30_mc_client[] = {
|
||||
"csr_ptcr",
|
||||
"cbr_display0a",
|
||||
"cbr_display0ab",
|
||||
"cbr_display0b",
|
||||
"cbr_display0bb",
|
||||
"cbr_display0c",
|
||||
"cbr_display0cb",
|
||||
"cbr_display1b",
|
||||
"cbr_display1bb",
|
||||
"cbr_eppup",
|
||||
"cbr_g2pr",
|
||||
"cbr_g2sr",
|
||||
"cbr_mpeunifbr",
|
||||
"cbr_viruv",
|
||||
"csr_afir",
|
||||
"csr_avpcarm7r",
|
||||
"csr_displayhc",
|
||||
"csr_displayhcb",
|
||||
"csr_fdcdrd",
|
||||
"csr_fdcdrd2",
|
||||
"csr_g2dr",
|
||||
"csr_hdar",
|
||||
"csr_host1xdmar",
|
||||
"csr_host1xr",
|
||||
"csr_idxsrd",
|
||||
"csr_idxsrd2",
|
||||
"csr_mpe_ipred",
|
||||
"csr_mpeamemrd",
|
||||
"csr_mpecsrd",
|
||||
"csr_ppcsahbdmar",
|
||||
"csr_ppcsahbslvr",
|
||||
"csr_satar",
|
||||
"csr_texsrd",
|
||||
"csr_texsrd2",
|
||||
"csr_vdebsevr",
|
||||
"csr_vdember",
|
||||
"csr_vdemcer",
|
||||
"csr_vdetper",
|
||||
"csr_mpcorelpr",
|
||||
"csr_mpcorer",
|
||||
"cbw_eppu",
|
||||
"cbw_eppv",
|
||||
"cbw_eppy",
|
||||
"cbw_mpeunifbw",
|
||||
"cbw_viwsb",
|
||||
"cbw_viwu",
|
||||
"cbw_viwv",
|
||||
"cbw_viwy",
|
||||
"ccw_g2dw",
|
||||
"csw_afiw",
|
||||
"csw_avpcarm7w",
|
||||
"csw_fdcdwr",
|
||||
"csw_fdcdwr2",
|
||||
"csw_hdaw",
|
||||
"csw_host1xw",
|
||||
"csw_ispw",
|
||||
"csw_mpcorelpw",
|
||||
"csw_mpcorew",
|
||||
"csw_mpecswr",
|
||||
"csw_ppcsahbdmaw",
|
||||
"csw_ppcsahbslvw",
|
||||
"csw_sataw",
|
||||
"csw_vdebsevw",
|
||||
"csw_vdedbgw",
|
||||
"csw_vdembew",
|
||||
"csw_vdetpmw",
|
||||
};
|
||||
|
||||
static void tegra30_mc_decode(struct tegra30_mc *mc, int n)
|
||||
{
|
||||
u32 err, addr;
|
||||
const char * const mc_int_err[] = {
|
||||
"MC_DECERR",
|
||||
"Unknown",
|
||||
"MC_SECURITY_ERR",
|
||||
"MC_ARBITRATION_EMEM",
|
||||
"MC_SMMU_ERR",
|
||||
};
|
||||
const char * const err_type[] = {
|
||||
"Unknown",
|
||||
"Unknown",
|
||||
"DECERR_EMEM",
|
||||
"SECURITY_TRUSTZONE",
|
||||
"SECURITY_CARVEOUT",
|
||||
"Unknown",
|
||||
"INVALID_SMMU_PAGE",
|
||||
"Unknown",
|
||||
};
|
||||
char attr[6];
|
||||
int cid, perm, type, idx;
|
||||
const char *client = "Unknown";
|
||||
|
||||
idx = n - MC_INT_ERR_SHIFT;
|
||||
if ((idx < 0) || (idx >= ARRAY_SIZE(mc_int_err)) || (idx == 1)) {
|
||||
dev_err_ratelimited(mc->dev, "Unknown interrupt status %08lx\n",
|
||||
BIT(n));
|
||||
return;
|
||||
}
|
||||
|
||||
err = mc_readl(mc, MC_ERR_STATUS);
|
||||
|
||||
type = (err & MC_ERR_TYPE_MASK) >> MC_ERR_TYPE_SHIFT;
|
||||
perm = (err & MC_ERR_INVALID_SMMU_PAGE_MASK) >>
|
||||
MC_ERR_INVALID_SMMU_PAGE_SHIFT;
|
||||
if (type == MC_ERR_TYPE_INVALID_SMMU_PAGE)
|
||||
sprintf(attr, "%c-%c-%c",
|
||||
(perm & BIT(2)) ? 'R' : '-',
|
||||
(perm & BIT(1)) ? 'W' : '-',
|
||||
(perm & BIT(0)) ? 'S' : '-');
|
||||
else
|
||||
attr[0] = '\0';
|
||||
|
||||
cid = err & MC_CLIENT_ID_MASK;
|
||||
if (cid < ARRAY_SIZE(tegra30_mc_client))
|
||||
client = tegra30_mc_client[cid];
|
||||
|
||||
addr = mc_readl(mc, MC_ERR_ADR);
|
||||
|
||||
dev_err_ratelimited(mc->dev, "%s (0x%08x): 0x%08x %s (%s %s %s %s)\n",
|
||||
mc_int_err[idx], err, addr, client,
|
||||
(err & MC_ERR_SECURITY) ? "secure" : "non-secure",
|
||||
(err & MC_ERR_RW) ? "write" : "read",
|
||||
err_type[type], attr);
|
||||
}
|
||||
|
||||
static const u32 tegra30_mc_ctx[] = {
|
||||
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_MISC1,
|
||||
MC_EMEM_ARB_RING3_THROTTLE,
|
||||
MC_EMEM_ARB_OVERRIDE,
|
||||
MC_INTMASK,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int tegra30_mc_suspend(struct device *dev)
|
||||
{
|
||||
int i;
|
||||
struct tegra30_mc *mc = dev_get_drvdata(dev);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(tegra30_mc_ctx); i++)
|
||||
mc->ctx[i] = mc_readl(mc, tegra30_mc_ctx[i]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra30_mc_resume(struct device *dev)
|
||||
{
|
||||
int i;
|
||||
struct tegra30_mc *mc = dev_get_drvdata(dev);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(tegra30_mc_ctx); i++)
|
||||
mc_writel(mc, mc->ctx[i], tegra30_mc_ctx[i]);
|
||||
|
||||
mc_writel(mc, 1, MC_TIMING_CONTROL);
|
||||
/* Read-back to ensure that write reached */
|
||||
mc_readl(mc, MC_TIMING_CONTROL);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static UNIVERSAL_DEV_PM_OPS(tegra30_mc_pm,
|
||||
tegra30_mc_suspend,
|
||||
tegra30_mc_resume, NULL);
|
||||
|
||||
static const struct of_device_id tegra30_mc_of_match[] = {
|
||||
{ .compatible = "nvidia,tegra30-mc", },
|
||||
{},
|
||||
};
|
||||
|
||||
static irqreturn_t tegra30_mc_isr(int irq, void *data)
|
||||
{
|
||||
u32 stat, mask, bit;
|
||||
struct tegra30_mc *mc = data;
|
||||
|
||||
stat = mc_readl(mc, MC_INTSTATUS);
|
||||
mask = mc_readl(mc, MC_INTMASK);
|
||||
mask &= stat;
|
||||
if (!mask)
|
||||
return IRQ_NONE;
|
||||
while ((bit = ffs(mask)) != 0) {
|
||||
tegra30_mc_decode(mc, bit - 1);
|
||||
mask &= ~BIT(bit - 1);
|
||||
}
|
||||
|
||||
mc_writel(mc, stat, MC_INTSTATUS);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int tegra30_mc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *irq;
|
||||
struct tegra30_mc *mc;
|
||||
size_t bytes;
|
||||
int err, i;
|
||||
u32 intmask;
|
||||
|
||||
bytes = sizeof(*mc) + sizeof(u32) * ARRAY_SIZE(tegra30_mc_ctx);
|
||||
mc = devm_kzalloc(&pdev->dev, bytes, GFP_KERNEL);
|
||||
if (!mc)
|
||||
return -ENOMEM;
|
||||
mc->dev = &pdev->dev;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mc->regs); i++) {
|
||||
struct resource *res;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, i);
|
||||
mc->regs[i] = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(mc->regs[i]))
|
||||
return PTR_ERR(mc->regs[i]);
|
||||
}
|
||||
|
||||
irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
if (!irq)
|
||||
return -ENODEV;
|
||||
err = devm_request_irq(&pdev->dev, irq->start, tegra30_mc_isr,
|
||||
IRQF_SHARED, dev_name(&pdev->dev), mc);
|
||||
if (err)
|
||||
return -ENODEV;
|
||||
|
||||
platform_set_drvdata(pdev, mc);
|
||||
|
||||
intmask = MC_INT_INVALID_SMMU_PAGE |
|
||||
MC_INT_DECERR_EMEM | MC_INT_SECURITY_VIOLATION;
|
||||
mc_writel(mc, intmask, MC_INTMASK);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver tegra30_mc_driver = {
|
||||
.probe = tegra30_mc_probe,
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = tegra30_mc_of_match,
|
||||
.pm = &tegra30_mc_pm,
|
||||
},
|
||||
};
|
||||
module_platform_driver(tegra30_mc_driver);
|
||||
|
||||
MODULE_AUTHOR("Hiroshi DOYU <hdoyu@nvidia.com>");
|
||||
MODULE_DESCRIPTION("Tegra30 MC driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_ALIAS("platform:" DRV_NAME);
|
@ -49,7 +49,7 @@
|
||||
#define TEGRA114_CLK_I2S0 30
|
||||
/* 31 */
|
||||
|
||||
/* 32 */
|
||||
#define TEGRA114_CLK_MC 32
|
||||
/* 33 */
|
||||
#define TEGRA114_CLK_APBDMA 34
|
||||
/* 35 */
|
||||
|
@ -48,7 +48,7 @@
|
||||
#define TEGRA124_CLK_I2S0 30
|
||||
/* 31 */
|
||||
|
||||
/* 32 */
|
||||
#define TEGRA124_CLK_MC 32
|
||||
/* 33 */
|
||||
#define TEGRA124_CLK_APBDMA 34
|
||||
/* 35 */
|
||||
|
@ -49,7 +49,7 @@
|
||||
/* 30 */
|
||||
#define TEGRA20_CLK_CACHE2 31
|
||||
|
||||
#define TEGRA20_CLK_MEM 32
|
||||
#define TEGRA20_CLK_MC 32
|
||||
#define TEGRA20_CLK_AHBDMA 33
|
||||
#define TEGRA20_CLK_APBDMA 34
|
||||
/* 35 */
|
||||
|
25
include/dt-bindings/memory/tegra114-mc.h
Normal file
25
include/dt-bindings/memory/tegra114-mc.h
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef DT_BINDINGS_MEMORY_TEGRA114_MC_H
|
||||
#define DT_BINDINGS_MEMORY_TEGRA114_MC_H
|
||||
|
||||
#define TEGRA_SWGROUP_PTC 0
|
||||
#define TEGRA_SWGROUP_DC 1
|
||||
#define TEGRA_SWGROUP_DCB 2
|
||||
#define TEGRA_SWGROUP_EPP 3
|
||||
#define TEGRA_SWGROUP_G2 4
|
||||
#define TEGRA_SWGROUP_AVPC 5
|
||||
#define TEGRA_SWGROUP_NV 6
|
||||
#define TEGRA_SWGROUP_HDA 7
|
||||
#define TEGRA_SWGROUP_HC 8
|
||||
#define TEGRA_SWGROUP_MSENC 9
|
||||
#define TEGRA_SWGROUP_PPCS 10
|
||||
#define TEGRA_SWGROUP_VDE 11
|
||||
#define TEGRA_SWGROUP_MPCORELP 12
|
||||
#define TEGRA_SWGROUP_MPCORE 13
|
||||
#define TEGRA_SWGROUP_VI 14
|
||||
#define TEGRA_SWGROUP_ISP 15
|
||||
#define TEGRA_SWGROUP_XUSB_HOST 16
|
||||
#define TEGRA_SWGROUP_XUSB_DEV 17
|
||||
#define TEGRA_SWGROUP_EMUCIF 18
|
||||
#define TEGRA_SWGROUP_TSEC 19
|
||||
|
||||
#endif
|
31
include/dt-bindings/memory/tegra124-mc.h
Normal file
31
include/dt-bindings/memory/tegra124-mc.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef DT_BINDINGS_MEMORY_TEGRA124_MC_H
|
||||
#define DT_BINDINGS_MEMORY_TEGRA124_MC_H
|
||||
|
||||
#define TEGRA_SWGROUP_PTC 0
|
||||
#define TEGRA_SWGROUP_DC 1
|
||||
#define TEGRA_SWGROUP_DCB 2
|
||||
#define TEGRA_SWGROUP_AFI 3
|
||||
#define TEGRA_SWGROUP_AVPC 4
|
||||
#define TEGRA_SWGROUP_HDA 5
|
||||
#define TEGRA_SWGROUP_HC 6
|
||||
#define TEGRA_SWGROUP_MSENC 7
|
||||
#define TEGRA_SWGROUP_PPCS 8
|
||||
#define TEGRA_SWGROUP_SATA 9
|
||||
#define TEGRA_SWGROUP_VDE 10
|
||||
#define TEGRA_SWGROUP_MPCORELP 11
|
||||
#define TEGRA_SWGROUP_MPCORE 12
|
||||
#define TEGRA_SWGROUP_ISP2 13
|
||||
#define TEGRA_SWGROUP_XUSB_HOST 14
|
||||
#define TEGRA_SWGROUP_XUSB_DEV 15
|
||||
#define TEGRA_SWGROUP_ISP2B 16
|
||||
#define TEGRA_SWGROUP_TSEC 17
|
||||
#define TEGRA_SWGROUP_A9AVP 18
|
||||
#define TEGRA_SWGROUP_GPU 19
|
||||
#define TEGRA_SWGROUP_SDMMC1A 20
|
||||
#define TEGRA_SWGROUP_SDMMC2A 21
|
||||
#define TEGRA_SWGROUP_SDMMC3A 22
|
||||
#define TEGRA_SWGROUP_SDMMC4A 23
|
||||
#define TEGRA_SWGROUP_VIC 24
|
||||
#define TEGRA_SWGROUP_VI 25
|
||||
|
||||
#endif
|
24
include/dt-bindings/memory/tegra30-mc.h
Normal file
24
include/dt-bindings/memory/tegra30-mc.h
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef DT_BINDINGS_MEMORY_TEGRA30_MC_H
|
||||
#define DT_BINDINGS_MEMORY_TEGRA30_MC_H
|
||||
|
||||
#define TEGRA_SWGROUP_PTC 0
|
||||
#define TEGRA_SWGROUP_DC 1
|
||||
#define TEGRA_SWGROUP_DCB 2
|
||||
#define TEGRA_SWGROUP_EPP 3
|
||||
#define TEGRA_SWGROUP_G2 4
|
||||
#define TEGRA_SWGROUP_MPE 5
|
||||
#define TEGRA_SWGROUP_VI 6
|
||||
#define TEGRA_SWGROUP_AFI 7
|
||||
#define TEGRA_SWGROUP_AVPC 8
|
||||
#define TEGRA_SWGROUP_NV 9
|
||||
#define TEGRA_SWGROUP_NV2 10
|
||||
#define TEGRA_SWGROUP_HDA 11
|
||||
#define TEGRA_SWGROUP_HC 12
|
||||
#define TEGRA_SWGROUP_PPCS 13
|
||||
#define TEGRA_SWGROUP_SATA 14
|
||||
#define TEGRA_SWGROUP_VDE 15
|
||||
#define TEGRA_SWGROUP_MPCORELP 16
|
||||
#define TEGRA_SWGROUP_MPCORE 17
|
||||
#define TEGRA_SWGROUP_ISP 18
|
||||
|
||||
#endif
|
@ -22,6 +22,7 @@
|
||||
#include <linux/errno.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <trace/events/iommu.h>
|
||||
|
||||
#define IOMMU_READ (1 << 0)
|
||||
@ -97,6 +98,8 @@ enum iommu_attr {
|
||||
* @detach_dev: detach device from an iommu domain
|
||||
* @map: map a physically contiguous memory region to an iommu domain
|
||||
* @unmap: unmap a physically contiguous memory region from an iommu domain
|
||||
* @map_sg: map a scatter-gather list of physically contiguous memory chunks
|
||||
* to an iommu domain
|
||||
* @iova_to_phys: translate iova to physical address
|
||||
* @add_device: add device to iommu grouping
|
||||
* @remove_device: remove device from iommu grouping
|
||||
@ -114,6 +117,8 @@ struct iommu_ops {
|
||||
phys_addr_t paddr, size_t size, int prot);
|
||||
size_t (*unmap)(struct iommu_domain *domain, unsigned long iova,
|
||||
size_t size);
|
||||
size_t (*map_sg)(struct iommu_domain *domain, unsigned long iova,
|
||||
struct scatterlist *sg, unsigned int nents, int prot);
|
||||
phys_addr_t (*iova_to_phys)(struct iommu_domain *domain, dma_addr_t iova);
|
||||
int (*add_device)(struct device *dev);
|
||||
void (*remove_device)(struct device *dev);
|
||||
@ -156,6 +161,9 @@ extern int iommu_map(struct iommu_domain *domain, unsigned long iova,
|
||||
phys_addr_t paddr, size_t size, int prot);
|
||||
extern size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova,
|
||||
size_t size);
|
||||
extern size_t default_iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
|
||||
struct scatterlist *sg,unsigned int nents,
|
||||
int prot);
|
||||
extern phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova);
|
||||
extern void iommu_set_fault_handler(struct iommu_domain *domain,
|
||||
iommu_fault_handler_t handler, void *token);
|
||||
@ -241,6 +249,13 @@ static inline int report_iommu_fault(struct iommu_domain *domain,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline size_t iommu_map_sg(struct iommu_domain *domain,
|
||||
unsigned long iova, struct scatterlist *sg,
|
||||
unsigned int nents, int prot)
|
||||
{
|
||||
return domain->ops->map_sg(domain, iova, sg, nents, prot);
|
||||
}
|
||||
|
||||
#else /* CONFIG_IOMMU_API */
|
||||
|
||||
struct iommu_ops {};
|
||||
@ -293,6 +308,13 @@ static inline int iommu_unmap(struct iommu_domain *domain, unsigned long iova,
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static inline size_t iommu_map_sg(struct iommu_domain *domain,
|
||||
unsigned long iova, struct scatterlist *sg,
|
||||
unsigned int nents, int prot)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static inline int iommu_domain_window_enable(struct iommu_domain *domain,
|
||||
u32 wnd_nr, phys_addr_t paddr,
|
||||
u64 size, int prot)
|
||||
|
107
include/soc/tegra/mc.h
Normal file
107
include/soc/tegra/mc.h
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (C) 2014 NVIDIA Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef __SOC_TEGRA_MC_H__
|
||||
#define __SOC_TEGRA_MC_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct clk;
|
||||
struct device;
|
||||
struct page;
|
||||
|
||||
struct tegra_smmu_enable {
|
||||
unsigned int reg;
|
||||
unsigned int bit;
|
||||
};
|
||||
|
||||
/* latency allowance */
|
||||
struct tegra_mc_la {
|
||||
unsigned int reg;
|
||||
unsigned int shift;
|
||||
unsigned int mask;
|
||||
unsigned int def;
|
||||
};
|
||||
|
||||
struct tegra_mc_client {
|
||||
unsigned int id;
|
||||
const char *name;
|
||||
unsigned int swgroup;
|
||||
|
||||
unsigned int fifo_size;
|
||||
|
||||
struct tegra_smmu_enable smmu;
|
||||
struct tegra_mc_la la;
|
||||
};
|
||||
|
||||
struct tegra_smmu_swgroup {
|
||||
unsigned int swgroup;
|
||||
unsigned int reg;
|
||||
};
|
||||
|
||||
struct tegra_smmu_ops {
|
||||
void (*flush_dcache)(struct page *page, unsigned long offset,
|
||||
size_t size);
|
||||
};
|
||||
|
||||
struct tegra_smmu_soc {
|
||||
const struct tegra_mc_client *clients;
|
||||
unsigned int num_clients;
|
||||
|
||||
const struct tegra_smmu_swgroup *swgroups;
|
||||
unsigned int num_swgroups;
|
||||
|
||||
bool supports_round_robin_arbitration;
|
||||
bool supports_request_limit;
|
||||
|
||||
unsigned int num_asids;
|
||||
|
||||
const struct tegra_smmu_ops *ops;
|
||||
};
|
||||
|
||||
struct tegra_mc;
|
||||
struct tegra_smmu;
|
||||
|
||||
#ifdef CONFIG_TEGRA_IOMMU_SMMU
|
||||
struct tegra_smmu *tegra_smmu_probe(struct device *dev,
|
||||
const struct tegra_smmu_soc *soc,
|
||||
struct tegra_mc *mc);
|
||||
#else
|
||||
static inline struct tegra_smmu *
|
||||
tegra_smmu_probe(struct device *dev, const struct tegra_smmu_soc *soc,
|
||||
struct tegra_mc *mc)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct tegra_mc_soc {
|
||||
const struct tegra_mc_client *clients;
|
||||
unsigned int num_clients;
|
||||
|
||||
const unsigned int *emem_regs;
|
||||
unsigned int num_emem_regs;
|
||||
|
||||
unsigned int num_address_bits;
|
||||
unsigned int atom_size;
|
||||
|
||||
const struct tegra_smmu_soc *smmu;
|
||||
};
|
||||
|
||||
struct tegra_mc {
|
||||
struct device *dev;
|
||||
struct tegra_smmu *smmu;
|
||||
void __iomem *regs;
|
||||
struct clk *clk;
|
||||
int irq;
|
||||
|
||||
const struct tegra_mc_soc *soc;
|
||||
unsigned long tick;
|
||||
};
|
||||
|
||||
#endif /* __SOC_TEGRA_MC_H__ */
|
Loading…
Reference in New Issue
Block a user