Lines Matching refs:as

262 	struct tegra_smmu_as *as;  in tegra_smmu_domain_alloc()  local
267 as = kzalloc(sizeof(*as), GFP_KERNEL); in tegra_smmu_domain_alloc()
268 if (!as) in tegra_smmu_domain_alloc()
271 as->attr = SMMU_PD_READABLE | SMMU_PD_WRITABLE | SMMU_PD_NONSECURE; in tegra_smmu_domain_alloc()
273 as->pd = alloc_page(GFP_KERNEL | __GFP_DMA | __GFP_ZERO); in tegra_smmu_domain_alloc()
274 if (!as->pd) { in tegra_smmu_domain_alloc()
275 kfree(as); in tegra_smmu_domain_alloc()
279 as->count = kcalloc(SMMU_NUM_PDE, sizeof(u32), GFP_KERNEL); in tegra_smmu_domain_alloc()
280 if (!as->count) { in tegra_smmu_domain_alloc()
281 __free_page(as->pd); in tegra_smmu_domain_alloc()
282 kfree(as); in tegra_smmu_domain_alloc()
286 as->pts = kcalloc(SMMU_NUM_PDE, sizeof(*as->pts), GFP_KERNEL); in tegra_smmu_domain_alloc()
287 if (!as->pts) { in tegra_smmu_domain_alloc()
288 kfree(as->count); in tegra_smmu_domain_alloc()
289 __free_page(as->pd); in tegra_smmu_domain_alloc()
290 kfree(as); in tegra_smmu_domain_alloc()
295 as->domain.geometry.aperture_start = 0; in tegra_smmu_domain_alloc()
296 as->domain.geometry.aperture_end = 0xffffffff; in tegra_smmu_domain_alloc()
297 as->domain.geometry.force_aperture = true; in tegra_smmu_domain_alloc()
299 return &as->domain; in tegra_smmu_domain_alloc()
304 struct tegra_smmu_as *as = to_smmu_as(domain); in tegra_smmu_domain_free() local
308 kfree(as); in tegra_smmu_domain_free()
384 struct tegra_smmu_as *as) in tegra_smmu_as_prepare() argument
389 if (as->use_count > 0) { in tegra_smmu_as_prepare()
390 as->use_count++; in tegra_smmu_as_prepare()
394 as->pd_dma = dma_map_page(smmu->dev, as->pd, 0, SMMU_SIZE_PD, in tegra_smmu_as_prepare()
396 if (dma_mapping_error(smmu->dev, as->pd_dma)) in tegra_smmu_as_prepare()
400 if (!smmu_dma_addr_valid(smmu, as->pd_dma)) { in tegra_smmu_as_prepare()
405 err = tegra_smmu_alloc_asid(smmu, &as->id); in tegra_smmu_as_prepare()
409 smmu_flush_ptc(smmu, as->pd_dma, 0); in tegra_smmu_as_prepare()
410 smmu_flush_tlb_asid(smmu, as->id); in tegra_smmu_as_prepare()
412 smmu_writel(smmu, as->id & 0x7f, SMMU_PTB_ASID); in tegra_smmu_as_prepare()
413 value = SMMU_PTB_DATA_VALUE(as->pd_dma, as->attr); in tegra_smmu_as_prepare()
417 as->smmu = smmu; in tegra_smmu_as_prepare()
418 as->use_count++; in tegra_smmu_as_prepare()
423 dma_unmap_page(smmu->dev, as->pd_dma, SMMU_SIZE_PD, DMA_TO_DEVICE); in tegra_smmu_as_prepare()
428 struct tegra_smmu_as *as) in tegra_smmu_as_unprepare() argument
430 if (--as->use_count > 0) in tegra_smmu_as_unprepare()
433 tegra_smmu_free_asid(smmu, as->id); in tegra_smmu_as_unprepare()
435 dma_unmap_page(smmu->dev, as->pd_dma, SMMU_SIZE_PD, DMA_TO_DEVICE); in tegra_smmu_as_unprepare()
437 as->smmu = NULL; in tegra_smmu_as_unprepare()
444 struct tegra_smmu_as *as = to_smmu_as(domain); in tegra_smmu_attach_dev() local
461 err = tegra_smmu_as_prepare(smmu, as); in tegra_smmu_attach_dev()
465 tegra_smmu_enable(smmu, swgroup, as->id); in tegra_smmu_attach_dev()
477 struct tegra_smmu_as *as = to_smmu_as(domain); in tegra_smmu_detach_dev() local
479 struct tegra_smmu *smmu = as->smmu; in tegra_smmu_detach_dev()
494 tegra_smmu_disable(smmu, swgroup, as->id); in tegra_smmu_detach_dev()
495 tegra_smmu_as_unprepare(smmu, as); in tegra_smmu_detach_dev()
500 static void tegra_smmu_set_pde(struct tegra_smmu_as *as, unsigned long iova, in tegra_smmu_set_pde() argument
504 struct tegra_smmu *smmu = as->smmu; in tegra_smmu_set_pde()
505 u32 *pd = page_address(as->pd); in tegra_smmu_set_pde()
512 dma_sync_single_range_for_device(smmu->dev, as->pd_dma, offset, in tegra_smmu_set_pde()
516 smmu_flush_ptc(smmu, as->pd_dma, offset); in tegra_smmu_set_pde()
517 smmu_flush_tlb_section(smmu, as->id, iova); in tegra_smmu_set_pde()
528 static u32 *tegra_smmu_pte_lookup(struct tegra_smmu_as *as, unsigned long iova, in tegra_smmu_pte_lookup() argument
535 pt_page = as->pts[pd_index]; in tegra_smmu_pte_lookup()
539 pd = page_address(as->pd); in tegra_smmu_pte_lookup()
545 static u32 *as_get_pte(struct tegra_smmu_as *as, dma_addr_t iova, in as_get_pte() argument
549 struct tegra_smmu *smmu = as->smmu; in as_get_pte()
551 if (!as->pts[pde]) { in as_get_pte()
573 as->pts[pde] = page; in as_get_pte()
575 tegra_smmu_set_pde(as, iova, SMMU_MK_PDE(dma, SMMU_PDE_ATTR | in as_get_pte()
580 u32 *pd = page_address(as->pd); in as_get_pte()
585 return tegra_smmu_pte_offset(as->pts[pde], iova); in as_get_pte()
588 static void tegra_smmu_pte_get_use(struct tegra_smmu_as *as, unsigned long iova) in tegra_smmu_pte_get_use() argument
592 as->count[pd_index]++; in tegra_smmu_pte_get_use()
595 static void tegra_smmu_pte_put_use(struct tegra_smmu_as *as, unsigned long iova) in tegra_smmu_pte_put_use() argument
598 struct page *page = as->pts[pde]; in tegra_smmu_pte_put_use()
604 if (--as->count[pde] == 0) { in tegra_smmu_pte_put_use()
605 struct tegra_smmu *smmu = as->smmu; in tegra_smmu_pte_put_use()
606 u32 *pd = page_address(as->pd); in tegra_smmu_pte_put_use()
609 tegra_smmu_set_pde(as, iova, 0); in tegra_smmu_pte_put_use()
613 as->pts[pde] = NULL; in tegra_smmu_pte_put_use()
617 static void tegra_smmu_set_pte(struct tegra_smmu_as *as, unsigned long iova, in tegra_smmu_set_pte() argument
620 struct tegra_smmu *smmu = as->smmu; in tegra_smmu_set_pte()
628 smmu_flush_tlb_group(smmu, as->id, iova); in tegra_smmu_set_pte()
635 struct tegra_smmu_as *as = to_smmu_as(domain); in tegra_smmu_map() local
639 pte = as_get_pte(as, iova, &pte_dma); in tegra_smmu_map()
645 tegra_smmu_pte_get_use(as, iova); in tegra_smmu_map()
647 tegra_smmu_set_pte(as, iova, pte, pte_dma, in tegra_smmu_map()
656 struct tegra_smmu_as *as = to_smmu_as(domain); in tegra_smmu_unmap() local
660 pte = tegra_smmu_pte_lookup(as, iova, &pte_dma); in tegra_smmu_unmap()
664 tegra_smmu_set_pte(as, iova, pte, pte_dma, 0); in tegra_smmu_unmap()
665 tegra_smmu_pte_put_use(as, iova); in tegra_smmu_unmap()
673 struct tegra_smmu_as *as = to_smmu_as(domain); in tegra_smmu_iova_to_phys() local
678 pte = tegra_smmu_pte_lookup(as, iova, &pte_dma); in tegra_smmu_iova_to_phys()
682 pfn = *pte & as->smmu->pfn_mask; in tegra_smmu_iova_to_phys()