Lines Matching refs:as

273 	struct tegra_smmu_as *as;  in tegra_smmu_domain_alloc()  local
278 as = kzalloc(sizeof(*as), GFP_KERNEL); in tegra_smmu_domain_alloc()
279 if (!as) in tegra_smmu_domain_alloc()
282 as->attr = SMMU_PD_READABLE | SMMU_PD_WRITABLE | SMMU_PD_NONSECURE; in tegra_smmu_domain_alloc()
284 as->pd = alloc_page(GFP_KERNEL | __GFP_DMA | __GFP_ZERO); in tegra_smmu_domain_alloc()
285 if (!as->pd) { in tegra_smmu_domain_alloc()
286 kfree(as); in tegra_smmu_domain_alloc()
290 as->count = kcalloc(SMMU_NUM_PDE, sizeof(u32), GFP_KERNEL); in tegra_smmu_domain_alloc()
291 if (!as->count) { in tegra_smmu_domain_alloc()
292 __free_page(as->pd); in tegra_smmu_domain_alloc()
293 kfree(as); in tegra_smmu_domain_alloc()
297 as->pts = kcalloc(SMMU_NUM_PDE, sizeof(*as->pts), GFP_KERNEL); in tegra_smmu_domain_alloc()
298 if (!as->pts) { in tegra_smmu_domain_alloc()
299 kfree(as->count); in tegra_smmu_domain_alloc()
300 __free_page(as->pd); in tegra_smmu_domain_alloc()
301 kfree(as); in tegra_smmu_domain_alloc()
306 as->domain.geometry.aperture_start = 0; in tegra_smmu_domain_alloc()
307 as->domain.geometry.aperture_end = 0xffffffff; in tegra_smmu_domain_alloc()
308 as->domain.geometry.force_aperture = true; in tegra_smmu_domain_alloc()
310 return &as->domain; in tegra_smmu_domain_alloc()
315 struct tegra_smmu_as *as = to_smmu_as(domain); in tegra_smmu_domain_free() local
319 kfree(as); in tegra_smmu_domain_free()
395 struct tegra_smmu_as *as) in tegra_smmu_as_prepare() argument
400 if (as->use_count > 0) { in tegra_smmu_as_prepare()
401 as->use_count++; in tegra_smmu_as_prepare()
405 as->pd_dma = dma_map_page(smmu->dev, as->pd, 0, SMMU_SIZE_PD, in tegra_smmu_as_prepare()
407 if (dma_mapping_error(smmu->dev, as->pd_dma)) in tegra_smmu_as_prepare()
411 if (!smmu_dma_addr_valid(smmu, as->pd_dma)) { in tegra_smmu_as_prepare()
416 err = tegra_smmu_alloc_asid(smmu, &as->id); in tegra_smmu_as_prepare()
420 smmu_flush_ptc(smmu, as->pd_dma, 0); in tegra_smmu_as_prepare()
421 smmu_flush_tlb_asid(smmu, as->id); in tegra_smmu_as_prepare()
423 smmu_writel(smmu, as->id & 0x7f, SMMU_PTB_ASID); in tegra_smmu_as_prepare()
424 value = SMMU_PTB_DATA_VALUE(as->pd_dma, as->attr); in tegra_smmu_as_prepare()
428 as->smmu = smmu; in tegra_smmu_as_prepare()
429 as->use_count++; in tegra_smmu_as_prepare()
434 dma_unmap_page(smmu->dev, as->pd_dma, SMMU_SIZE_PD, DMA_TO_DEVICE); in tegra_smmu_as_prepare()
439 struct tegra_smmu_as *as) in tegra_smmu_as_unprepare() argument
441 if (--as->use_count > 0) in tegra_smmu_as_unprepare()
444 tegra_smmu_free_asid(smmu, as->id); in tegra_smmu_as_unprepare()
446 dma_unmap_page(smmu->dev, as->pd_dma, SMMU_SIZE_PD, DMA_TO_DEVICE); in tegra_smmu_as_unprepare()
448 as->smmu = NULL; in tegra_smmu_as_unprepare()
455 struct tegra_smmu_as *as = to_smmu_as(domain); in tegra_smmu_attach_dev() local
472 err = tegra_smmu_as_prepare(smmu, as); in tegra_smmu_attach_dev()
476 tegra_smmu_enable(smmu, swgroup, as->id); in tegra_smmu_attach_dev()
488 struct tegra_smmu_as *as = to_smmu_as(domain); in tegra_smmu_detach_dev() local
490 struct tegra_smmu *smmu = as->smmu; in tegra_smmu_detach_dev()
505 tegra_smmu_disable(smmu, swgroup, as->id); in tegra_smmu_detach_dev()
506 tegra_smmu_as_unprepare(smmu, as); in tegra_smmu_detach_dev()
511 static void tegra_smmu_set_pde(struct tegra_smmu_as *as, unsigned long iova, in tegra_smmu_set_pde() argument
515 struct tegra_smmu *smmu = as->smmu; in tegra_smmu_set_pde()
516 u32 *pd = page_address(as->pd); in tegra_smmu_set_pde()
523 dma_sync_single_range_for_device(smmu->dev, as->pd_dma, offset, in tegra_smmu_set_pde()
527 smmu_flush_ptc(smmu, as->pd_dma, offset); in tegra_smmu_set_pde()
528 smmu_flush_tlb_section(smmu, as->id, iova); in tegra_smmu_set_pde()
539 static u32 *tegra_smmu_pte_lookup(struct tegra_smmu_as *as, unsigned long iova, in tegra_smmu_pte_lookup() argument
546 pt_page = as->pts[pd_index]; in tegra_smmu_pte_lookup()
550 pd = page_address(as->pd); in tegra_smmu_pte_lookup()
556 static u32 *as_get_pte(struct tegra_smmu_as *as, dma_addr_t iova, in as_get_pte() argument
560 struct tegra_smmu *smmu = as->smmu; in as_get_pte()
562 if (!as->pts[pde]) { in as_get_pte()
584 as->pts[pde] = page; in as_get_pte()
586 tegra_smmu_set_pde(as, iova, SMMU_MK_PDE(dma, SMMU_PDE_ATTR | in as_get_pte()
591 u32 *pd = page_address(as->pd); in as_get_pte()
596 return tegra_smmu_pte_offset(as->pts[pde], iova); in as_get_pte()
599 static void tegra_smmu_pte_get_use(struct tegra_smmu_as *as, unsigned long iova) in tegra_smmu_pte_get_use() argument
603 as->count[pd_index]++; in tegra_smmu_pte_get_use()
606 static void tegra_smmu_pte_put_use(struct tegra_smmu_as *as, unsigned long iova) in tegra_smmu_pte_put_use() argument
609 struct page *page = as->pts[pde]; in tegra_smmu_pte_put_use()
615 if (--as->count[pde] == 0) { in tegra_smmu_pte_put_use()
616 struct tegra_smmu *smmu = as->smmu; in tegra_smmu_pte_put_use()
617 u32 *pd = page_address(as->pd); in tegra_smmu_pte_put_use()
620 tegra_smmu_set_pde(as, iova, 0); in tegra_smmu_pte_put_use()
624 as->pts[pde] = NULL; in tegra_smmu_pte_put_use()
628 static void tegra_smmu_set_pte(struct tegra_smmu_as *as, unsigned long iova, in tegra_smmu_set_pte() argument
631 struct tegra_smmu *smmu = as->smmu; in tegra_smmu_set_pte()
639 smmu_flush_tlb_group(smmu, as->id, iova); in tegra_smmu_set_pte()
646 struct tegra_smmu_as *as = to_smmu_as(domain); in tegra_smmu_map() local
650 pte = as_get_pte(as, iova, &pte_dma); in tegra_smmu_map()
656 tegra_smmu_pte_get_use(as, iova); in tegra_smmu_map()
658 tegra_smmu_set_pte(as, iova, pte, pte_dma, in tegra_smmu_map()
667 struct tegra_smmu_as *as = to_smmu_as(domain); in tegra_smmu_unmap() local
671 pte = tegra_smmu_pte_lookup(as, iova, &pte_dma); in tegra_smmu_unmap()
675 tegra_smmu_set_pte(as, iova, pte, pte_dma, 0); in tegra_smmu_unmap()
676 tegra_smmu_pte_put_use(as, iova); in tegra_smmu_unmap()
684 struct tegra_smmu_as *as = to_smmu_as(domain); in tegra_smmu_iova_to_phys() local
689 pte = tegra_smmu_pte_lookup(as, iova, &pte_dma); in tegra_smmu_iova_to_phys()
693 pfn = *pte & as->smmu->pfn_mask; in tegra_smmu_iova_to_phys()