From be3b76372527f0a1b823168c92023dc4b02603b5 Mon Sep 17 00:00:00 2001 From: Varun Sethi Date: Mon, 22 Jul 2013 19:20:25 +0530 Subject: 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 Change-Id: Iea6d7993f09bddbaae94c475fd192f5106784bde Reviewed-on: http://git.am.freescale.net:8181/3440 Reviewed-by: Yoder Stuart-B08248 Reviewed-by: Fleming Andrew-AFLEMING Tested-by: Fleming Andrew-AFLEMING 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 Tested-by: Schmitt Richard-B43082 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; diff --git a/include/linux/iommu.h b/include/linux/iommu.h index f6c0fc7..bfcc382 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -59,6 +59,11 @@ struct iommu_stash_attribute { u32 cache; /* cache to stash to: L1,L2,L3 */ }; +struct iommu_omi_attribute { + u32 omi; /* index in the operation mapping table */ + u32 window; /* ~0 indicates all windows */ +}; + struct iommu_domain_geometry { dma_addr_t aperture_start; /* First address that can be mapped */ dma_addr_t aperture_end; /* Last address that can be mapped */ @@ -96,6 +101,7 @@ enum iommu_attr { DOMAIN_ATTR_PAMU_STASH, DOMAIN_ATTR_PAMU_ENABLE, DOMAIN_ATTR_FSL_PAMUV1, + DOMAIN_ATTR_PAMU_OP_MAP, DOMAIN_ATTR_MAX, }; -- cgit v0.10.2