diff options
Diffstat (limited to 'gxp-dma-iommu.c')
-rw-r--r-- | gxp-dma-iommu.c | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/gxp-dma-iommu.c b/gxp-dma-iommu.c index 1d60888..5aa8b5d 100644 --- a/gxp-dma-iommu.c +++ b/gxp-dma-iommu.c @@ -68,17 +68,16 @@ static int dma_info_to_prot(enum dma_data_direction dir, bool coherent, } } -static int gxp_dma_ssmt_program(struct gxp_dev *gxp, - struct iommu_domain *domain, uint core_list) +static int gxp_dma_ssmt_activate(struct gxp_dev *gxp, + struct iommu_domain *domain, uint core_list) { struct gxp_dma_iommu_manager *mgr = container_of( gxp->dma_mgr, struct gxp_dma_iommu_manager, dma_mgr); - int pasid; uint core; + int pasid = iommu_aux_get_pasid(domain, gxp->dev); /* Program VID only when cores are managed by us. */ if (gxp_is_direct_mode(gxp) || gxp_core_boot(gxp)) { - pasid = iommu_aux_get_pasid(domain, gxp->dev); for (core = 0; core < GXP_NUM_CORES; core++) if (BIT(core) & core_list) { dev_dbg(gxp->dev, "Assign core%u to PASID %d\n", @@ -86,11 +85,30 @@ static int gxp_dma_ssmt_program(struct gxp_dev *gxp, gxp_ssmt_set_core_vid(&mgr->ssmt, core, pasid); } } else { - gxp_ssmt_set_bypass(&mgr->ssmt); + gxp_ssmt_activate_scid(&mgr->ssmt, pasid); } return 0; } +static void gxp_dma_ssmt_deactivate(struct gxp_dev *gxp, + struct iommu_domain *domain, uint core_list) +{ + struct gxp_dma_iommu_manager *mgr = container_of( + gxp->dma_mgr, struct gxp_dma_iommu_manager, dma_mgr); + uint core; + int pasid = iommu_aux_get_pasid(domain, gxp->dev); + + /* Program VID only when cores are managed by us. */ + if (gxp_is_direct_mode(gxp) || gxp_core_boot(gxp)) { + for (core = 0; core < GXP_NUM_CORES; core++) { + if (BIT(core) & core_list) + gxp_ssmt_set_core_vid(&mgr->ssmt, core, 0); + } + } else { + gxp_ssmt_deactivate_scid(&mgr->ssmt, pasid); + } +} + /* Fault handler */ static int sysmmu_fault_handler(struct iommu_fault *fault, void *token) @@ -284,14 +302,15 @@ int gxp_dma_domain_attach_device(struct gxp_dev *gxp, ret = iommu_aux_attach_device(gdomain->domain, gxp->dev); if (ret) goto out; - gxp_dma_ssmt_program(gxp, gdomain->domain, core_list); + gxp_dma_ssmt_activate(gxp, gdomain->domain, core_list); out: return ret; } -void gxp_dma_domain_detach_device(struct gxp_dev *gxp, - struct gcip_iommu_domain *gdomain) +void gxp_dma_domain_detach_device(struct gxp_dev *gxp, struct gcip_iommu_domain *gdomain, + uint core_list) { + gxp_dma_ssmt_deactivate(gxp, gdomain->domain, core_list); iommu_aux_detach_device(gdomain->domain, gxp->dev); } |