summaryrefslogtreecommitdiff
path: root/drivers/iommu
diff options
context:
space:
mode:
authorVarun Sethi <Varun.Sethi@freescale.com>2013-07-22 13:50:25 (GMT)
committerZhenhua Luo <zhenhua.luo@freescale.com>2013-08-26 07:47:30 (GMT)
commitbe3b76372527f0a1b823168c92023dc4b02603b5 (patch)
treee5efd736101c86ec4481117ee078b269697d7626 /drivers/iommu
parent0b8dc3c3c79d1b7ccd6bcffc0cabc8dde66ef478 (diff)
downloadlinux-fsl-qoriq-be3b76372527f0a1b823168c92023dc4b02603b5.tar.xz
Introduce an API for setting operation mapping index per window.
This API can be used for setting operation mapping per DMA window. Signed-off-by: Varun Sethi <Varun.Sethi@freescale.com> Change-Id: Iea6d7993f09bddbaae94c475fd192f5106784bde Reviewed-on: http://git.am.freescale.net:8181/3440 Reviewed-by: Yoder Stuart-B08248 <stuart.yoder@freescale.com> Reviewed-by: Fleming Andrew-AFLEMING <AFLEMING@freescale.com> Tested-by: Fleming Andrew-AFLEMING <AFLEMING@freescale.com> Conflicts: drivers/iommu/fsl_pamu.c drivers/iommu/fsl_pamu.h drivers/iommu/fsl_pamu_domain.c Change-Id: Iea6d7993f09bddbaae94c475fd192f5106784bde Reviewed-on: http://git.am.freescale.net:8181/3440 Reviewed-by: Schmitt Richard-B43082 <B43082@freescale.com> Tested-by: Schmitt Richard-B43082 <B43082@freescale.com>
Diffstat (limited to 'drivers/iommu')
-rw-r--r--drivers/iommu/fsl_pamu.c12
-rw-r--r--drivers/iommu/fsl_pamu.h6
-rw-r--r--drivers/iommu/fsl_pamu_domain.c70
3 files changed, 88 insertions, 0 deletions
diff --git a/drivers/iommu/fsl_pamu.c b/drivers/iommu/fsl_pamu.c
index 1f69fd1..a646275 100644
--- a/drivers/iommu/fsl_pamu.c
+++ b/drivers/iommu/fsl_pamu.c
@@ -295,6 +295,18 @@ int pamu_update_paace_stash(int liodn, u32 subwin, u32 value)
}
set_bf(paace->impl_attr, PAACE_IA_CID, value);
+ switch (field) {
+ case PAACE_STASH_FIELD:
+ set_bf(paace->impl_attr, PAACE_IA_CID, value);
+ break;
+ case PAACE_OMI_FIELD:
+ set_bf(paace->impl_attr, PAACE_IA_OTM, PAACE_OTM_INDEXED);
+ paace->op_encode.index_ot.omi = value;
+ break;
+ default:
+ pr_debug("Invalid field, can't update\n");
+ return -EINVAL;
+ }
mb();
return 0;
diff --git a/drivers/iommu/fsl_pamu.h b/drivers/iommu/fsl_pamu.h
index 83cbd26..480ec23 100644
--- a/drivers/iommu/fsl_pamu.h
+++ b/drivers/iommu/fsl_pamu.h
@@ -384,6 +384,12 @@ struct ome {
#define EOE_WWSAOL 0x1e /* Write with stash allocate only and lock */
#define EOE_VALID 0x80
+enum paace_field {
+ PAACE_STASH_FIELD,
+ PAACE_OMI_FIELD,
+ PAACE_FIELD_MAX,
+};
+
/* Function prototypes */
int pamu_domain_init(void);
int pamu_enable_liodn(int liodn);
diff --git a/drivers/iommu/fsl_pamu_domain.c b/drivers/iommu/fsl_pamu_domain.c
index 5b54505..07ec977 100644
--- a/drivers/iommu/fsl_pamu_domain.c
+++ b/drivers/iommu/fsl_pamu_domain.c
@@ -794,6 +794,49 @@ static int configure_domain_geometry(struct iommu_domain *domain, void *data)
return 0;
}
+/* Set the domain operation mapping attribute */
+static int configure_domain_op_map(struct fsl_dma_domain *dma_domain,
+ void *data)
+{
+ struct dma_window *wnd;
+ unsigned long flags;
+ struct pamu_attr_info attr_info;
+ int ret, i;
+ struct iommu_omi_attribute *omi_attr = data;
+
+ spin_lock_irqsave(&dma_domain->domain_lock, flags);
+
+ if (!dma_domain->win_arr) {
+ pr_err("Number of windows not configured\n");
+ spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
+ return -ENODEV;
+ }
+
+ if (omi_attr->omi >= OMI_MAX) {
+ pr_err("Invalid operation mapping index\n");
+ spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
+ return -EINVAL;
+ }
+
+ if (~omi_attr->window == 0) {
+ wnd = &dma_domain->win_arr[0];
+ for (i = 0; i < dma_domain->win_cnt; i++)
+ wnd[i].omi = omi_attr->omi;
+ } else {
+ wnd = &dma_domain->win_arr[omi_attr->window];
+ wnd->omi = omi_attr->omi;
+ }
+
+ attr_info.window = omi_attr->window;
+ attr_info.field = PAACE_OMI_FIELD;
+ attr_info.value = omi_attr->omi;
+ ret = update_domain_attr(dma_domain, &attr_info);
+
+ spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
+
+ return ret;
+}
+
/* Set the domain stash attribute */
static int configure_domain_stash(struct fsl_dma_domain *dma_domain, void *data)
{
@@ -869,6 +912,9 @@ static int fsl_pamu_set_domain_attr(struct iommu_domain *domain,
case DOMAIN_ATTR_PAMU_ENABLE:
ret = configure_domain_dma_state(dma_domain, *(int *)data);
break;
+ case DOMAIN_ATTR_PAMU_OP_MAP:
+ ret = configure_domain_op_map(dma_domain, data);
+ break;
default:
pr_err("Unsupported attribute type\n");
ret = -EINVAL;
@@ -896,6 +942,30 @@ static int fsl_pamu_get_domain_attr(struct iommu_domain *domain,
case DOMAIN_ATTR_FSL_PAMUV1:
*(int *)data = DOMAIN_ATTR_FSL_PAMUV1;
break;
+ case DOMAIN_ATTR_PAMU_STASH: {
+ struct iommu_stash_attribute *stash_attr = data;
+ struct dma_window *wnd;
+
+ if (stash_attr->window >= dma_domain->win_cnt ||
+ ~stash_attr->window == 0)
+ return -EINVAL;
+
+ wnd = &dma_domain->win_arr[stash_attr->window];
+ memcpy(stash_attr, &wnd->stash_attr, sizeof(struct iommu_stash_attribute));
+ break;
+ }
+ case DOMAIN_ATTR_PAMU_OP_MAP: {
+ struct iommu_omi_attribute *omi_attr = data;
+ struct dma_window *wnd;
+
+ if (omi_attr->window >= dma_domain->win_cnt ||
+ ~omi_attr->window == 0)
+ return -EINVAL;
+
+ wnd = &dma_domain->win_arr[omi_attr->window];
+ omi_attr->omi = wnd->omi;
+ break;
+ }
default:
pr_err("Unsupported attribute type\n");
ret = -EINVAL;