diff options
author | Varun Sethi <Varun.Sethi@freescale.com> | 2013-07-22 13:50:25 (GMT) |
---|---|---|
committer | Zhenhua Luo <zhenhua.luo@freescale.com> | 2013-08-26 07:47:30 (GMT) |
commit | be3b76372527f0a1b823168c92023dc4b02603b5 (patch) | |
tree | e5efd736101c86ec4481117ee078b269697d7626 /drivers/iommu | |
parent | 0b8dc3c3c79d1b7ccd6bcffc0cabc8dde66ef478 (diff) | |
download | linux-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.c | 12 | ||||
-rw-r--r-- | drivers/iommu/fsl_pamu.h | 6 | ||||
-rw-r--r-- | drivers/iommu/fsl_pamu_domain.c | 70 |
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; |