Skip to content

Commit

Permalink
Merge branch 'for-3.19/iommu' into for-3.19/dt
Browse files Browse the repository at this point in the history
  • Loading branch information
Thierry Reding committed Dec 4, 2014
2 parents 0df1f24 + 8918465 commit f538c50
Show file tree
Hide file tree
Showing 45 changed files with 4,189 additions and 1,527 deletions.
Original file line number Diff line number Diff line change
@@ -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>;
};
3 changes: 0 additions & 3 deletions arch/arm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1259,9 +1259,6 @@ source "arch/arm/common/Kconfig"

menu "Bus support"

config ARM_AMBA
bool

config ISA
bool
help
Expand Down
9 changes: 1 addition & 8 deletions arch/arm/mach-tegra/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
3 changes: 0 additions & 3 deletions arch/arm64/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,6 @@ endmenu

menu "Bus support"

config ARM_AMBA
bool

config PCI
bool "PCI support"
help
Expand Down
17 changes: 10 additions & 7 deletions arch/powerpc/include/asm/iommu.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
8 changes: 4 additions & 4 deletions arch/powerpc/kernel/dma-iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
16 changes: 8 additions & 8 deletions arch/powerpc/kernel/iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;

Expand Down
9 changes: 5 additions & 4 deletions arch/powerpc/platforms/cell/iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions drivers/Kconfig
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
menu "Device Drivers"

source "drivers/amba/Kconfig"

source "drivers/base/Kconfig"

source "drivers/bus/Kconfig"
Expand Down
14 changes: 14 additions & 0 deletions drivers/amba/Kconfig
Original file line number Diff line number Diff line change
@@ -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
13 changes: 13 additions & 0 deletions drivers/clk/tegra/clk-divider.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
7 changes: 6 additions & 1 deletion drivers/clk/tegra/clk-tegra114.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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];
Expand Down
7 changes: 6 additions & 1 deletion drivers/clk/tegra/clk-tegra124.c
Original file line number Diff line number Diff line change
Expand Up @@ -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[] = {
Expand Down Expand Up @@ -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,
Expand Down
8 changes: 7 additions & 1 deletion drivers/clk/tegra/clk-tegra20.c
Original file line number Diff line number Diff line change
Expand Up @@ -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, \
Expand Down Expand Up @@ -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);
Expand Down
7 changes: 6 additions & 1 deletion drivers/clk/tegra/clk-tegra30.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) \
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions drivers/clk/tegra/clk.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
12 changes: 6 additions & 6 deletions drivers/iommu/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
1 change: 1 addition & 0 deletions drivers/iommu/amd_iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
Expand Down
1 change: 1 addition & 0 deletions drivers/iommu/arm-smmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions drivers/iommu/exynos-iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions drivers/iommu/intel-iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Loading

0 comments on commit f538c50

Please sign in to comment.