diff options
45 files changed, 4189 insertions, 1527 deletions
diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra-mc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra-mc.txt new file mode 100644 index 000000000000..f3db93c85eea --- /dev/null +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra-mc.txt @@ -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>; + }; diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 89c4b5ccc68d..77f8ca5cc3e6 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1259,9 +1259,6 @@ source "arch/arm/common/Kconfig" menu "Bus support" -config ARM_AMBA - bool - config ISA bool help diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index 095399618ca5..d0be9a1ef6b8 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -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 diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 9532f8d5857e..db1aa5446a57 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -166,9 +166,6 @@ endmenu menu "Bus support" -config ARM_AMBA - bool - config PCI bool "PCI support" help diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h index 42632c7a2a4e..9cfa3706a1b8 100644 --- a/arch/powerpc/include/asm/iommu.h +++ b/arch/powerpc/include/asm/iommu.h @@ -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, diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c index 54d0116256f7..4c68bfe4108a 100644 --- a/arch/powerpc/kernel/dma-iommu.c +++ b/arch/powerpc/kernel/dma-iommu.c @@ -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 */ diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index a10642a0d861..a83cf5ef6488 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -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; diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index 2b90ff8a93be..c7c8720aa39f 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c @@ -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) diff --git a/drivers/Kconfig b/drivers/Kconfig index 1a693d3f9d51..af02a8a8ec4a 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -1,5 +1,7 @@ menu "Device Drivers" +source "drivers/amba/Kconfig" + source "drivers/base/Kconfig" source "drivers/bus/Kconfig" diff --git a/drivers/amba/Kconfig b/drivers/amba/Kconfig new file mode 100644 index 000000000000..4a5c9d279059 --- /dev/null +++ b/drivers/amba/Kconfig @@ -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 diff --git a/drivers/clk/tegra/clk-divider.c b/drivers/clk/tegra/clk-divider.c index 290f9c1a3749..59a5714dfe18 100644 --- a/drivers/clk/tegra/clk-divider.c +++ b/drivers/clk/tegra/clk-divider.c @@ -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); +} diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index f760f31d05c4..0b03d2cf7264 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -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]; diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c index e3a85842ce0c..f5f9baca7bb6 100644 --- a/drivers/clk/tegra/clk-tegra124.c +++ b/drivers/clk/tegra/clk-tegra124.c @@ -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, diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index dace2b1b5ae6..41272dcc9e22 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -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); diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index 5bbacd01094f..4b9d8bd3d0bf 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -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); diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 16ec8d6bb87f..4e458aa8d45c 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -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: diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index dd5112265cc9..6dbfbc209491 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -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" diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 505a9adac2d5..2d84c9edf3b8 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -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, }; diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 60558f794922..e393ae01b5d2 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -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, diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index 74233186f6f7..28372b85d8da 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -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, diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index a27d6cb1a793..02cd26a17fe0 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -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, diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index ed8b04867b1f..02e4313e937c 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -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) diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c index 7dab5cbcc775..e509c58eee92 100644 --- a/drivers/iommu/ipmmu-vmsa.c +++ b/drivers/iommu/ipmmu-vmsa.c @@ -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, diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c index 6e3dcc289d59..1c7b78ecf3e3 100644 --- a/drivers/iommu/msm_iommu.c +++ b/drivers/iommu/msm_iommu.c @@ -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, }; diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c index 36278870e84a..18003c044454 100644 --- a/drivers/iommu/omap-iommu.c +++ b/drivers/iommu/omap-iommu.c @@ -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, diff --git a/drivers/iommu/shmobile-iommu.c b/drivers/iommu/shmobile-iommu.c index 1333e6fb3405..f1b00774e4de 100644 --- a/drivers/iommu/shmobile-iommu.c +++ b/drivers/iommu/shmobile-iommu.c @@ -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, diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c index 3afdf43f732a..6e134c7c227f 100644 --- a/drivers/iommu/tegra-smmu.c +++ b/drivers/iommu/tegra-smmu.c @@ -1,1295 +1,732 @@ /* - * IOMMU API for SMMU in Tegra30 + * Copyright (C) 2011-2014 NVIDIA CORPORATION. All rights reserved. * - * Copyright (c) 2011-2013, 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. + * 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. */ -#define pr_fmt(fmt) "%s(): " fmt, __func__ - #include <linux/err.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/spinlock.h> -#include <linux/slab.h> -#include <linux/vmalloc.h> -#include <linux/mm.h> -#include <linux/pagemap.h> -#include <linux/device.h> -#include <linux/sched.h> #include <linux/iommu.h> -#include <linux/io.h> +#include <linux/kernel.h> #include <linux/of.h> -#include <linux/of_iommu.h> -#include <linux/debugfs.h> -#include <linux/seq_file.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> +#include <linux/slab.h> #include <soc/tegra/ahb.h> +#include <soc/tegra/mc.h> -#include <asm/page.h> -#include <asm/cacheflush.h> - -enum smmu_hwgrp { - HWGRP_AFI, - HWGRP_AVPC, - HWGRP_DC, - HWGRP_DCB, - HWGRP_EPP, - HWGRP_G2, - HWGRP_HC, - HWGRP_HDA, - HWGRP_ISP, - HWGRP_MPE, - HWGRP_NV, - HWGRP_NV2, - HWGRP_PPCS, - HWGRP_SATA, - HWGRP_VDE, - HWGRP_VI, - - HWGRP_COUNT, - - HWGRP_END = ~0, -}; +struct tegra_smmu { + void __iomem *regs; + struct device *dev; -#define HWG_AFI (1 << HWGRP_AFI) -#define HWG_AVPC (1 << HWGRP_AVPC) -#define HWG_DC (1 << HWGRP_DC) -#define HWG_DCB (1 << HWGRP_DCB) -#define HWG_EPP (1 << HWGRP_EPP) -#define HWG_G2 (1 << HWGRP_G2) -#define HWG_HC (1 << HWGRP_HC) -#define HWG_HDA (1 << HWGRP_HDA) -#define HWG_ISP (1 << HWGRP_ISP) -#define HWG_MPE (1 << HWGRP_MPE) -#define HWG_NV (1 << HWG |