summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/iommu/fsl_pamu.c3
-rw-r--r--drivers/iommu/fsl_pamu.h2
-rw-r--r--drivers/iommu/fsl_pamu_domain.c117
-rw-r--r--drivers/iommu/fsl_pamu_domain.h12
-rw-r--r--drivers/staging/fsl_qbman/qman_driver.c1
5 files changed, 85 insertions, 50 deletions
diff --git a/drivers/iommu/fsl_pamu.c b/drivers/iommu/fsl_pamu.c
index 9fb4ee2..ddd0836 100644
--- a/drivers/iommu/fsl_pamu.c
+++ b/drivers/iommu/fsl_pamu.c
@@ -273,7 +273,7 @@ void pamu_free_subwins(int liodn)
* Function used for updating stash destination for the coressponding
* LIODN.
*/
-int pamu_update_paace_stash(int liodn, u32 subwin, u32 value)
+int pamu_update_paace_field(int liodn, u32 subwin, int field, u32 value)
{
struct paace *paace;
@@ -288,7 +288,6 @@ int pamu_update_paace_stash(int liodn, u32 subwin, u32 value)
return -ENOENT;
}
}
- set_bf(paace->impl_attr, PAACE_IA_CID, value);
switch (field) {
case PAACE_STASH_FIELD:
diff --git a/drivers/iommu/fsl_pamu.h b/drivers/iommu/fsl_pamu.h
index 480ec23..fd9dd6d 100644
--- a/drivers/iommu/fsl_pamu.h
+++ b/drivers/iommu/fsl_pamu.h
@@ -404,7 +404,7 @@ int pamu_config_spaace(int liodn, u32 subwin_cnt, u32 subwin_addr,
u32 get_stash_id(u32 stash_dest_hint, u32 vcpu);
void get_ome_index(u32 *omi_index, struct device *dev);
-int pamu_update_paace_stash(int liodn, u32 subwin, u32 value);
+int pamu_update_paace_field(int liodn, u32 subwin, int field, u32 value);
int pamu_disable_spaace(int liodn, u32 subwin);
u32 pamu_get_max_subwin_cnt(void);
diff --git a/drivers/iommu/fsl_pamu_domain.c b/drivers/iommu/fsl_pamu_domain.c
index 07ec977..99c182d 100644
--- a/drivers/iommu/fsl_pamu_domain.c
+++ b/drivers/iommu/fsl_pamu_domain.c
@@ -122,10 +122,10 @@ static int map_subwins(int liodn, struct fsl_dma_domain *dma_domain)
spin_lock(&iommu_lock);
ret = pamu_config_spaace(liodn, dma_domain->win_cnt, i,
sub_win_ptr[i].size,
- ~(u32)0,
+ sub_win_ptr[i].omi,
rpn,
dma_domain->snoop_id,
- dma_domain->stash_id,
+ sub_win_ptr[i].stash_id,
(i > 0) ? 1 : 0,
sub_win_ptr[i].prot);
spin_unlock(&iommu_lock);
@@ -149,9 +149,9 @@ static int map_win(int liodn, struct fsl_dma_domain *dma_domain)
spin_lock(&iommu_lock);
ret = pamu_config_ppaace(liodn, wnd_addr,
wnd->size,
- ~(u32)0,
+ wnd->omi,
wnd->paddr >> PAMU_PAGE_SHIFT,
- dma_domain->snoop_id, dma_domain->stash_id,
+ dma_domain->snoop_id, wnd->stash_id,
0, wnd->prot);
spin_unlock(&iommu_lock);
if (ret)
@@ -181,10 +181,10 @@ static int update_liodn(int liodn, struct fsl_dma_domain *dma_domain, u32 wnd_nr
if (dma_domain->win_cnt > 1) {
ret = pamu_config_spaace(liodn, dma_domain->win_cnt, wnd_nr,
wnd->size,
- ~(u32)0,
+ wnd->omi,
wnd->paddr >> PAMU_PAGE_SHIFT,
dma_domain->snoop_id,
- dma_domain->stash_id,
+ wnd->stash_id,
(wnd_nr > 0) ? 1 : 0,
wnd->prot);
if (ret)
@@ -196,9 +196,9 @@ static int update_liodn(int liodn, struct fsl_dma_domain *dma_domain, u32 wnd_nr
ret = pamu_config_ppaace(liodn, wnd_addr,
wnd->size,
- ~(u32)0,
+ wnd->omi,
wnd->paddr >> PAMU_PAGE_SHIFT,
- dma_domain->snoop_id, dma_domain->stash_id,
+ dma_domain->snoop_id, wnd->stash_id,
0, wnd->prot);
if (ret)
pr_err("Window reconfiguration failed for liodn %d\n", liodn);
@@ -209,29 +209,31 @@ static int update_liodn(int liodn, struct fsl_dma_domain *dma_domain, u32 wnd_nr
return ret;
}
-static int update_liodn_stash(int liodn, struct fsl_dma_domain *dma_domain,
- u32 val)
+struct pamu_attr_info {
+ u32 window;
+ int field;
+ u32 value;
+};
+
+static int update_liodn_attr(int liodn, struct fsl_dma_domain *dma_domain,
+ struct pamu_attr_info *attr_info)
{
int ret = 0, i;
spin_lock(&iommu_lock);
- if (!dma_domain->win_cnt) {
- ret = pamu_update_paace_stash(liodn, 0, val);
- if (ret) {
- pr_err("Failed to update PAACE field for liodn %d\n ", liodn);
- spin_unlock(&iommu_lock);
- return ret;
- }
- } else {
+
+
+ if (~attr_info->window == 0) {
for (i = 0; i < dma_domain->win_cnt; i++) {
- ret = pamu_update_paace_stash(liodn, i, val);
- if (ret) {
- pr_err("Failed to update SPAACE %d field for liodn %d\n ", i, liodn);
- spin_unlock(&iommu_lock);
- return ret;
- }
+ ret = pamu_update_paace_field(liodn, i, attr_info->field,
+ attr_info->value);
+ if (ret)
+ break;
}
- }
+ } else
+ ret = pamu_update_paace_field(liodn, attr_info->window, attr_info->field,
+ attr_info->value);
+
spin_unlock(&iommu_lock);
return ret;
@@ -263,7 +265,7 @@ static int pamu_set_liodn(int liodn, struct device *dev,
if (!ret)
ret = pamu_config_ppaace(liodn, window_addr, window_size, omi_index,
0, dma_domain->snoop_id,
- dma_domain->stash_id, win_cnt, 0);
+ ~(u32)0, win_cnt, 0);
spin_unlock(&iommu_lock);
if (ret) {
pr_err("PAMU PAACE configuration failed for liodn %d, win_cnt =%d\n", liodn, win_cnt);
@@ -279,7 +281,7 @@ static int pamu_set_liodn(int liodn, struct device *dev,
ret = pamu_config_spaace(liodn, win_cnt, i,
subwin_size, omi_index,
0, dma_domain->snoop_id,
- dma_domain->stash_id,
+ ~(u32)0,
0, 0);
spin_unlock(&iommu_lock);
if (ret) {
@@ -320,7 +322,6 @@ static struct fsl_dma_domain *iommu_alloc_dma_domain(void)
if (!domain)
return NULL;
- domain->stash_id = ~(u32)0;
domain->snoop_id = ~(u32)0;
domain->win_cnt = pamu_get_max_subwin_cnt();
domain->geom_size = 0;
@@ -476,15 +477,20 @@ static int pamu_set_domain_geometry(struct fsl_dma_domain *dma_domain,
return ret;
}
-/* Update stash destination for all LIODNs associated with the domain */
-static int update_domain_stash(struct fsl_dma_domain *dma_domain, u32 val)
+/*
+ * Update attribute for all LIODNs associated with the domain
+ *
+ */
+static int update_domain_attr(struct fsl_dma_domain *dma_domain,
+ struct pamu_attr_info *attr_info)
{
struct device_domain_info *info;
int ret = 0;
if (!list_empty(&dma_domain->devices)) {
list_for_each_entry(info, &dma_domain->devices, link) {
- ret = update_liodn_stash(info->liodn, dma_domain, val);
+ ret = update_liodn_attr(info->liodn, dma_domain,
+ attr_info);
if (ret)
break;
}
@@ -841,23 +847,45 @@ static int configure_domain_op_map(struct fsl_dma_domain *dma_domain,
static int configure_domain_stash(struct fsl_dma_domain *dma_domain, void *data)
{
struct iommu_stash_attribute *stash_attr = data;
+ struct dma_window *wnd;
unsigned long flags;
- int ret;
+ u32 stash_id;
+ int ret, i;
+ struct pamu_attr_info attr_info;
spin_lock_irqsave(&dma_domain->domain_lock, flags);
- memcpy(&dma_domain->dma_stash, stash_attr,
- sizeof(struct iommu_stash_attribute));
+ if (!dma_domain->win_arr) {
+ pr_err("Number of windows not configured\n");
+ spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
+ return -ENODEV;
+ }
- dma_domain->stash_id = get_stash_id(stash_attr->cache,
+ stash_id = get_stash_id(stash_attr->cache,
stash_attr->cpu);
- if (dma_domain->stash_id == ~(u32)0) {
+ if (~stash_id == 0) {
pr_err("Invalid stash attributes\n");
spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
return -EINVAL;
}
- ret = update_domain_stash(dma_domain, dma_domain->stash_id);
+ if (~stash_attr->window == 0) {
+ wnd = &dma_domain->win_arr[0];
+ for (i = 0; i < dma_domain->win_cnt; i++) {
+ wnd[i].stash_id = stash_id;
+ memcpy(&wnd[i].stash_attr, stash_attr, sizeof(struct iommu_stash_attribute));
+ wnd[i].stash_attr.window = i;
+ }
+ } else {
+ wnd = &dma_domain->win_arr[stash_attr->window];
+ wnd->stash_id = stash_id;
+ memcpy(&wnd->stash_attr, stash_attr, sizeof(struct iommu_stash_attribute));
+ }
+
+ attr_info.window = stash_attr->window;
+ attr_info.field = PAACE_STASH_FIELD;
+ attr_info.value = stash_id;
+ ret = update_domain_attr(dma_domain, &attr_info);
spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
@@ -932,10 +960,6 @@ static int fsl_pamu_get_domain_attr(struct iommu_domain *domain,
switch (attr_type) {
- case DOMAIN_ATTR_PAMU_STASH:
- memcpy((struct iommu_stash_attribute *) data, &dma_domain->dma_stash,
- sizeof(struct iommu_stash_attribute));
- break;
case DOMAIN_ATTR_PAMU_ENABLE:
*(int *)data = dma_domain->enabled;
break;
@@ -1128,6 +1152,16 @@ static void fsl_pamu_remove_device(struct device *dev)
iommu_group_remove_device(dev);
}
+static void dma_domain_init_windows(struct fsl_dma_domain *dma_domain)
+{
+ int i;
+
+ for (i = 0; i < dma_domain->win_cnt; i++) {
+ dma_domain->win_arr[i].stash_id = ~(u32)0;
+ dma_domain->win_arr[i].omi = ~(u32)0;
+ }
+}
+
static int fsl_pamu_set_windows(struct iommu_domain *domain, u32 w_count)
{
struct fsl_dma_domain *dma_domain = domain->priv;
@@ -1171,6 +1205,7 @@ static int fsl_pamu_set_windows(struct iommu_domain *domain, u32 w_count)
return -ENOMEM;
}
dma_domain->win_cnt = w_count;
+ dma_domain_init_windows(dma_domain);
}
spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
diff --git a/drivers/iommu/fsl_pamu_domain.h b/drivers/iommu/fsl_pamu_domain.h
index 52dede7..1d55d25 100644
--- a/drivers/iommu/fsl_pamu_domain.h
+++ b/drivers/iommu/fsl_pamu_domain.h
@@ -22,10 +22,13 @@
#include "fsl_pamu.h"
struct dma_window {
- phys_addr_t paddr;
+ phys_addr_t paddr;
u64 size;
- int valid;
- int prot;
+ struct iommu_stash_attribute stash_attr;
+ int valid;
+ int prot;
+ u32 stash_id;
+ u32 omi;
};
struct fsl_dma_domain {
@@ -67,9 +70,6 @@ struct fsl_dma_domain {
*/
int mapped;
int enabled;
- /* stash_id obtained from the stash attribute details */
- u32 stash_id;
- struct iommu_stash_attribute dma_stash;
u32 snoop_id;
struct iommu_domain *iommu_domain;
spinlock_t domain_lock;
diff --git a/drivers/staging/fsl_qbman/qman_driver.c b/drivers/staging/fsl_qbman/qman_driver.c
index 4c9f6c6..875c0df 100644
--- a/drivers/staging/fsl_qbman/qman_driver.c
+++ b/drivers/staging/fsl_qbman/qman_driver.c
@@ -487,6 +487,7 @@ static void portal_set_cpu(struct qm_portal_config *pcfg, int cpu)
}
stash_attr.cpu = cpu;
stash_attr.cache = IOMMU_ATTR_CACHE_L1;
+ stash_attr.window = ~(u32)0;
ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_PAMU_STASH,
&stash_attr);
if (ret < 0) {