diff options
author | Varun Sethi <Varun.Sethi@freescale.com> | 2013-07-22 13:50:25 (GMT) |
---|---|---|
committer | Andy Fleming <afleming@freescale.com> | 2013-07-24 20:12:27 (GMT) |
commit | 436f839bf8032f50f91fd2866ce012d0c20a8465 (patch) | |
tree | a160c83ac09ab3f1d8b29054ceda42ba75e33a25 /drivers | |
parent | 09f24fdb479b51ff7d55c4d3bccda909689a0510 (diff) | |
download | linux-fsl-qoriq-436f839bf8032f50f91fd2866ce012d0c20a8465.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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/iommu/fsl_pamu.c | 4 | ||||
-rw-r--r-- | drivers/iommu/fsl_pamu.h | 1 | ||||
-rw-r--r-- | drivers/iommu/fsl_pamu_domain.c | 58 |
3 files changed, 63 insertions, 0 deletions
diff --git a/drivers/iommu/fsl_pamu.c b/drivers/iommu/fsl_pamu.c index 75fe204..ddd0836 100644 --- a/drivers/iommu/fsl_pamu.c +++ b/drivers/iommu/fsl_pamu.c @@ -293,6 +293,10 @@ int pamu_update_paace_field(int liodn, u32 subwin, int field, u32 value) 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; diff --git a/drivers/iommu/fsl_pamu.h b/drivers/iommu/fsl_pamu.h index 82a9160..fd9dd6d 100644 --- a/drivers/iommu/fsl_pamu.h +++ b/drivers/iommu/fsl_pamu.h @@ -386,6 +386,7 @@ struct ome { enum paace_field { PAACE_STASH_FIELD, + PAACE_OMI_FIELD, PAACE_FIELD_MAX, }; diff --git a/drivers/iommu/fsl_pamu_domain.c b/drivers/iommu/fsl_pamu_domain.c index ea93e1f..99c182d 100644 --- a/drivers/iommu/fsl_pamu_domain.c +++ b/drivers/iommu/fsl_pamu_domain.c @@ -800,6 +800,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) { @@ -897,6 +940,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; @@ -932,6 +978,18 @@ static int fsl_pamu_get_domain_attr(struct iommu_domain *domain, 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; |