Skip to content

Commit

Permalink
iommu/omap: Add support for configuring dsp iommus on DRA7xx
Browse files Browse the repository at this point in the history
The DSP MMUs on DRA7xx SoC requires configuring an additional
MMU_CONFIG register present in the DSP_SYSTEM sub module. This
setting dictates whether the DSP Core's MDMA and EDMA traffic
is routed through the respective MMU or not. Add the support
to the OMAP iommu driver so that the traffic is not bypassed
when enabling the MMUs.

The MMU_CONFIG register has two different bits for enabling
each of these two MMUs present in the DSP processor sub-system
on DRA7xx. An id field is added to the OMAP iommu object to
identify and enable each IOMMU. The id information and the
DSP_SYSTEM.MMU_CONFIG register programming is achieved through
the processing of the optional "ti,syscon-mmuconfig" property.
A proper value is assigned to the id field only when this
property is present.

Signed-off-by: Suman Anna <s-anna@ti.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
  • Loading branch information
Suman Anna authored and Joerg Roedel committed Oct 14, 2015
1 parent c0e4492 commit 3ca9299
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 0 deletions.
58 changes: 58 additions & 0 deletions drivers/iommu/omap-iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
#include <linux/of_iommu.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/regmap.h>
#include <linux/mfd/syscon.h>

#include <asm/cacheflush.h>

Expand Down Expand Up @@ -112,6 +114,18 @@ void omap_iommu_restore_ctx(struct device *dev)
}
EXPORT_SYMBOL_GPL(omap_iommu_restore_ctx);

static void dra7_cfg_dspsys_mmu(struct omap_iommu *obj, bool enable)
{
u32 val, mask;

if (!obj->syscfg)
return;

mask = (1 << (obj->id * DSP_SYS_MMU_CONFIG_EN_SHIFT));
val = enable ? mask : 0;
regmap_update_bits(obj->syscfg, DSP_SYS_MMU_CONFIG, mask, val);
}

static void __iommu_set_twl(struct omap_iommu *obj, bool on)
{
u32 l = iommu_read_reg(obj, MMU_CNTL);
Expand Down Expand Up @@ -147,6 +161,8 @@ static int omap2_iommu_enable(struct omap_iommu *obj)

iommu_write_reg(obj, pa, MMU_TTB);

dra7_cfg_dspsys_mmu(obj, true);

if (obj->has_bus_err_back)
iommu_write_reg(obj, MMU_GP_REG_BUS_ERR_BACK_EN, MMU_GP_REG);

Expand All @@ -161,6 +177,7 @@ static void omap2_iommu_disable(struct omap_iommu *obj)

l &= ~MMU_CNTL_MASK;
iommu_write_reg(obj, l, MMU_CNTL);
dra7_cfg_dspsys_mmu(obj, false);

dev_dbg(obj->dev, "%s is shutting down\n", obj->name);
}
Expand Down Expand Up @@ -864,6 +881,42 @@ static void omap_iommu_detach(struct omap_iommu *obj)
dev_dbg(obj->dev, "%s: %s\n", __func__, obj->name);
}

static int omap_iommu_dra7_get_dsp_system_cfg(struct platform_device *pdev,
struct omap_iommu *obj)
{
struct device_node *np = pdev->dev.of_node;
int ret;

if (!of_device_is_compatible(np, "ti,dra7-dsp-iommu"))
return 0;

if (!of_property_read_bool(np, "ti,syscon-mmuconfig")) {
dev_err(&pdev->dev, "ti,syscon-mmuconfig property is missing\n");
return -EINVAL;
}

obj->syscfg =
syscon_regmap_lookup_by_phandle(np, "ti,syscon-mmuconfig");
if (IS_ERR(obj->syscfg)) {
/* can fail with -EPROBE_DEFER */
ret = PTR_ERR(obj->syscfg);
return ret;
}

if (of_property_read_u32_index(np, "ti,syscon-mmuconfig", 1,
&obj->id)) {
dev_err(&pdev->dev, "couldn't get the IOMMU instance id within subsystem\n");
return -EINVAL;
}

if (obj->id != 0 && obj->id != 1) {
dev_err(&pdev->dev, "invalid IOMMU instance id\n");
return -EINVAL;
}

return 0;
}

/*
* OMAP Device MMU(IOMMU) detection
*/
Expand Down Expand Up @@ -907,6 +960,10 @@ static int omap_iommu_probe(struct platform_device *pdev)
if (IS_ERR(obj->regbase))
return PTR_ERR(obj->regbase);

err = omap_iommu_dra7_get_dsp_system_cfg(pdev, obj);
if (err)
return err;

irq = platform_get_irq(pdev, 0);
if (irq < 0)
return -ENODEV;
Expand Down Expand Up @@ -943,6 +1000,7 @@ static const struct of_device_id omap_iommu_of_match[] = {
{ .compatible = "ti,omap2-iommu" },
{ .compatible = "ti,omap4-iommu" },
{ .compatible = "ti,dra7-iommu" },
{ .compatible = "ti,dra7-dsp-iommu" },
{},
};

Expand Down
9 changes: 9 additions & 0 deletions drivers/iommu/omap-iommu.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ struct iotlb_entry {
struct omap_iommu {
const char *name;
void __iomem *regbase;
struct regmap *syscfg;
struct device *dev;
struct iommu_domain *domain;
struct dentry *debug_dir;
Expand All @@ -48,6 +49,7 @@ struct omap_iommu {
void *ctx; /* iommu context: registres saved area */

int has_bus_err_back;
u32 id;
};

struct cr_regs {
Expand Down Expand Up @@ -158,6 +160,13 @@ static inline struct omap_iommu *dev_to_omap_iommu(struct device *dev)
((pgsz) == MMU_CAM_PGSZ_64K) ? 0xffff0000 : \
((pgsz) == MMU_CAM_PGSZ_4K) ? 0xfffff000 : 0)

/*
* DSP_SYSTEM registers and bit definitions (applicable only for DRA7xx DSP)
*/
#define DSP_SYS_REVISION 0x00
#define DSP_SYS_MMU_CONFIG 0x18
#define DSP_SYS_MMU_CONFIG_EN_SHIFT 4

/*
* utilities for super page(16MB, 1MB, 64KB and 4KB)
*/
Expand Down

0 comments on commit 3ca9299

Please sign in to comment.