summaryrefslogtreecommitdiff
path: root/drivers/dma
diff options
context:
space:
mode:
authorjiaheng.fan <jiaheng.fan@nxp.com>2017-06-09 07:24:09 (GMT)
committerXie Xiaobo <xiaobo.xie@nxp.com>2017-09-25 07:25:40 (GMT)
commit9b1ded6d3527dbad9d282c5341587e0add658e30 (patch)
treea593c9fbf684c80f66047326586bc734c27ebc0e /drivers/dma
parent2294df192fa3e69cf3712348cfa899d08dd9fe80 (diff)
downloadlinux-9b1ded6d3527dbad9d282c5341587e0add658e30.tar.xz
dma: fsl-dpaa-qdma: support fsl-mc IOVA addr
fsl-mc works on IOVA addr if enabling smmu, otherwise it works on physics addr. Add judgement of smmu status, dpaa2-qdma will disalbe BMT bit in qdma-fd and qdma-list-table if enabling smmu. Signed-off-by: jiaheng.fan <jiaheng.fan@nxp.com>
Diffstat (limited to 'drivers/dma')
-rw-r--r--drivers/dma/dpaa2-qdma/dpaa2-qdma.c22
-rw-r--r--drivers/dma/dpaa2-qdma/dpaa2-qdma.h3
2 files changed, 19 insertions, 6 deletions
diff --git a/drivers/dma/dpaa2-qdma/dpaa2-qdma.c b/drivers/dma/dpaa2-qdma/dpaa2-qdma.c
index 270ccfa..6f89ee6 100644
--- a/drivers/dma/dpaa2-qdma/dpaa2-qdma.c
+++ b/drivers/dma/dpaa2-qdma/dpaa2-qdma.c
@@ -31,6 +31,7 @@
#include <linux/of_dma.h>
#include <linux/types.h>
#include <linux/delay.h>
+#include <linux/iommu.h>
#include "../virt-dma.h"
@@ -41,6 +42,8 @@
#include "fsl_dpdmai.h"
#include "dpaa2-qdma.h"
+static bool smmu_disable = true;
+
static struct dpaa2_qdma_chan *to_dpaa2_qdma_chan(struct dma_chan *chan)
{
return container_of(chan, struct dpaa2_qdma_chan, vchan.chan);
@@ -127,12 +130,12 @@ static void dpaa2_qdma_populate_fd(uint32_t format,
/* fd populated */
fd->simple.addr = dpaa2_comp->fl_bus_addr;
/* Bypass memory translation, Frame list format, short length disable */
- fd->simple.bpid = QMAN_FD_BMT_ENABLE;
+ /* we need to disable BMT if fsl-mc use iova addr */
+ if (smmu_disable)
+ fd->simple.bpid = QMAN_FD_BMT_ENABLE;
fd->simple.format_offset = QMAN_FD_FMT_ENABLE | QMAN_FD_SL_DISABLE;
fd->simple.frc = format | QDMA_SER_CTX;
- fd->simple.ctrl = QMAN_FD_VA_DISABLE |
- QMAN_FD_CBMT_ENABLE | QMAN_FD_SC_DISABLE;
}
/* first frame list for descriptor buffer */
@@ -155,7 +158,8 @@ static void dpaa2_qdma_populate_first_framel(
f_list->addr_hi = (dpaa2_comp->desc_bus_addr >> 32);
f_list->data_len.data_len_sl0 = 0x20; /* source/destination desc len */
f_list->fmt = QDMA_FL_FMT_SBF; /* single buffer frame */
- f_list->bmt = QDMA_FL_BMT_ENABLE; /* bypass memory translation */
+ if (smmu_disable)
+ f_list->bmt = QDMA_FL_BMT_ENABLE; /* bypass memory translation */
f_list->sl = QDMA_FL_SL_LONG; /* long length */
f_list->f = 0; /* not the last frame list */
}
@@ -170,7 +174,8 @@ static void dpaa2_qdma_populate_frames(struct dpaa2_frame_list *f_list,
f_list->addr_hi = (src >> 32);
f_list->data_len.data_len_sl0 = len;
f_list->fmt = fmt; /* single buffer frame or scatter gather frame */
- f_list->bmt = QDMA_FL_BMT_ENABLE; /* bypass memory translation */
+ if (smmu_disable)
+ f_list->bmt = QDMA_FL_BMT_ENABLE; /* bypass memory translation */
f_list->sl = QDMA_FL_SL_LONG; /* long length */
f_list->f = 0; /* not the last frame list */
@@ -181,7 +186,8 @@ static void dpaa2_qdma_populate_frames(struct dpaa2_frame_list *f_list,
f_list->addr_hi = (dst >> 32);
f_list->data_len.data_len_sl0 = len;
f_list->fmt = fmt; /* single buffer frame or scatter gather frame */
- f_list->bmt = QDMA_FL_BMT_ENABLE; /* bypass memory translation */
+ if (smmu_disable)
+ f_list->bmt = QDMA_FL_BMT_ENABLE; /* bypass memory translation */
f_list->sl = QDMA_FL_SL_LONG; /* long length */
f_list->f = QDMA_FL_F; /* Final bit: 1, for last frame list */
}
@@ -821,6 +827,10 @@ static int dpaa2_qdma_probe(struct fsl_mc_device *dpdmai_dev)
dev_set_drvdata(dev, priv);
priv->dpdmai_dev = dpdmai_dev;
+ priv->iommu_domain = iommu_get_domain_for_dev(dev);
+ if (priv->iommu_domain)
+ smmu_disable = false;
+
/* obtain a MC portal */
err = fsl_mc_portal_allocate(dpdmai_dev, 0, &priv->mc_io);
if (err) {
diff --git a/drivers/dma/dpaa2-qdma/dpaa2-qdma.h b/drivers/dma/dpaa2-qdma/dpaa2-qdma.h
index c5101e1..f0f238d 100644
--- a/drivers/dma/dpaa2-qdma/dpaa2-qdma.h
+++ b/drivers/dma/dpaa2-qdma/dpaa2-qdma.h
@@ -101,6 +101,7 @@ struct dpaa2_qdma_sg {
#define QMAN_FD_FMT_ENABLE (1 << 12) /* frame list table enable */
#define QMAN_FD_BMT_ENABLE (1 << 15) /* bypass memory translation */
+#define QMAN_FD_BMT_DISABLE (0 << 15) /* bypass memory translation */
#define QMAN_FD_SL_DISABLE (0 << 14) /* short lengthe disabled */
#define QMAN_FD_SL_ENABLE (1 << 14) /* short lengthe enabled */
@@ -126,6 +127,7 @@ struct dpaa2_qdma_sg {
#define QDMA_FL_FMT_SBF 0x0 /* Single buffer frame */
#define QDMA_FL_FMT_SGE 0x2 /* Scatter gather frame */
#define QDMA_FL_BMT_ENABLE 0x1 /* enable bypass memory translation */
+#define QDMA_FL_BMT_DISABLE 0x0 /* enable bypass memory translation */
#define QDMA_FL_SL_LONG 0x0 /* long length */
#define QDMA_FL_SL_SHORT 0x1 /* short length */
#define QDMA_FL_F 0x1 /* last frame list bit */
@@ -223,6 +225,7 @@ struct dpaa2_qdma_engine {
struct dpaa2_qdma_priv {
int dpqdma_id;
+ struct iommu_domain *iommu_domain;
struct dpdmai_attr dpdmai_attr;
struct device *dev;
struct fsl_mc_io *mc_io;