static struct msm_iommu_dev jpegd_iommu = {
.name = "jpegd",
+ .ncb = 2,
};
static struct msm_iommu_dev vpe_iommu = {
- .name = "vpe"
+ .name = "vpe",
+ .ncb = 2,
};
static struct msm_iommu_dev mdp0_iommu = {
- .name = "mdp0"
+ .name = "mdp0",
+ .ncb = 2,
};
static struct msm_iommu_dev mdp1_iommu = {
- .name = "mdp1"
+ .name = "mdp1",
+ .ncb = 2,
};
static struct msm_iommu_dev rot_iommu = {
- .name = "rot"
+ .name = "rot",
+ .ncb = 2,
};
static struct msm_iommu_dev ijpeg_iommu = {
- .name = "ijpeg"
+ .name = "ijpeg",
+ .ncb = 2,
};
static struct msm_iommu_dev vfe_iommu = {
.name = "vfe",
+ .ncb = 2,
};
static struct msm_iommu_dev vcodec_a_iommu = {
- .name = "vcodec_a"
+ .name = "vcodec_a",
+ .ncb = 2,
};
static struct msm_iommu_dev vcodec_b_iommu = {
- .name = "vcodec_b"
+ .name = "vcodec_b",
+ .ncb = 2,
};
static struct msm_iommu_dev gfx3d_iommu = {
.name = "gfx3d",
+ .ncb = 3,
};
static struct msm_iommu_dev gfx2d0_iommu = {
.name = "gfx2d0",
+ .ncb = 2,
};
static struct msm_iommu_dev gfx2d1_iommu = {
.name = "gfx2d1",
+ .ncb = 2,
};
static struct platform_device msm_device_iommu_jpegd = {
/**
* struct msm_iommu_dev - a single IOMMU hardware instance
* name Human-readable name given to this IOMMU HW instance
+ * ncb Number of context banks present on this IOMMU HW instance
*/
struct msm_iommu_dev {
const char *name;
+ int ncb;
};
/**
/**
* struct msm_iommu_drvdata - A single IOMMU hardware instance
* @base: IOMMU config port base address (VA)
+ * @ncb The number of contexts on this IOMMU
* @irq: Interrupt number
* @clk: The bus clock for this IOMMU hardware instance
* @pclk: The clock for the IOMMU bus interconnect
struct msm_iommu_drvdata {
void __iomem *base;
int irq;
+ int ncb;
struct clk *clk;
struct clk *pclk;
};
}
EXPORT_SYMBOL(msm_iommu_get_ctx);
-static void msm_iommu_reset(void __iomem *base)
+static void msm_iommu_reset(void __iomem *base, int ncb)
{
- int ctx, ncb;
+ int ctx;
SET_RPUE(base, 0);
SET_RPUEIE(base, 0);
SET_GLOBAL_TLBIALL(base, 0);
SET_RPU_ACR(base, 0);
SET_TLBLKCRWE(base, 1);
- ncb = GET_NCB(base)+1;
for (ctx = 0; ctx < ncb; ctx++) {
SET_BPRCOSH(base, ctx, 0);
struct msm_iommu_dev *iommu_dev = pdev->dev.platform_data;
void __iomem *regs_base;
resource_size_t len;
- int ret, ncb, nm2v, irq;
+ int ret, irq, par;
if (pdev->id == -1) {
msm_iommu_root_dev = pdev;
goto fail_io;
}
- mb();
+ msm_iommu_reset(regs_base, iommu_dev->ncb);
- if (GET_IDR(regs_base) == 0) {
- pr_err("Invalid IDR value detected\n");
+ SET_M(regs_base, 0, 1);
+ SET_PAR(regs_base, 0, 0);
+ SET_V2PCFG(regs_base, 0, 1);
+ SET_V2PPR(regs_base, 0, 0);
+ par = GET_PAR(regs_base, 0);
+ SET_V2PCFG(regs_base, 0, 0);
+ SET_M(regs_base, 0, 0);
+
+ if (!par) {
+ pr_err("%s: Invalid PAR value detected\n", iommu_dev->name);
ret = -ENODEV;
goto fail_io;
}
goto fail_io;
}
- msm_iommu_reset(regs_base);
+
drvdata->pclk = iommu_pclk;
drvdata->clk = iommu_clk;
drvdata->base = regs_base;
drvdata->irq = irq;
-
- nm2v = GET_NM2VCBMT((unsigned long) regs_base);
- ncb = GET_NCB((unsigned long) regs_base);
+ drvdata->ncb = iommu_dev->ncb;
pr_info("device %s mapped at %p, irq %d with %d ctx banks\n",
- iommu_dev->name, regs_base, irq, ncb+1);
+ iommu_dev->name, regs_base, irq, iommu_dev->ncb);
platform_set_drvdata(pdev, drvdata);