Lines Matching +full:tegra20 +full:- +full:mc +full:- +full:gart

1 // SPDX-License-Identifier: GPL-2.0-only
5 * Copyright (c) 2010-2013, NVIDIA Corporation.
10 #include <linux/dma-mapping.h>
27 #include <asm/dma-iommu.h>
47 writel(v, host1x->common_regs + r); in host1x_common_writel()
52 writel(v, host1x->hv_regs + r); in host1x_hypervisor_writel()
57 return readl(host1x->hv_regs + r); in host1x_hypervisor_readl()
62 void __iomem *sync_regs = host1x->regs + host1x->info->sync_offset; in host1x_sync_writel()
69 void __iomem *sync_regs = host1x->regs + host1x->info->sync_offset; in host1x_sync_readl()
76 writel(v, ch->regs + r); in host1x_ch_writel()
81 return readl(ch->regs + r); in host1x_ch_readl()
264 { .compatible = "nvidia,tegra234-host1x", .data = &host1x08_info, },
265 { .compatible = "nvidia,tegra194-host1x", .data = &host1x07_info, },
266 { .compatible = "nvidia,tegra186-host1x", .data = &host1x06_info, },
267 { .compatible = "nvidia,tegra210-host1x", .data = &host1x05_info, },
268 { .compatible = "nvidia,tegra124-host1x", .data = &host1x04_info, },
269 { .compatible = "nvidia,tegra114-host1x", .data = &host1x02_info, },
270 { .compatible = "nvidia,tegra30-host1x", .data = &host1x01_info, },
271 { .compatible = "nvidia,tegra20-host1x", .data = &host1x01_info, },
278 const struct host1x_info *info = host->info; in host1x_setup_virtualization_tables()
281 if (!info->has_hypervisor) in host1x_setup_virtualization_tables()
284 for (i = 0; i < info->num_sid_entries; i++) { in host1x_setup_virtualization_tables()
285 const struct host1x_sid_entry *entry = &info->sid_table[i]; in host1x_setup_virtualization_tables()
287 host1x_hypervisor_writel(host, entry->offset, entry->base); in host1x_setup_virtualization_tables()
288 host1x_hypervisor_writel(host, entry->limit, entry->base + 4); in host1x_setup_virtualization_tables()
291 for (i = 0; i < info->streamid_vm_table.count; i++) { in host1x_setup_virtualization_tables()
293 host1x_hypervisor_writel(host, 0xff, info->streamid_vm_table.base + 4 * i); in host1x_setup_virtualization_tables()
296 for (i = 0; i < info->classid_vm_table.count; i++) { in host1x_setup_virtualization_tables()
298 host1x_hypervisor_writel(host, 0xff, info->classid_vm_table.base + 4 * i); in host1x_setup_virtualization_tables()
301 for (i = 0; i < info->mmio_vm_table.count; i++) { in host1x_setup_virtualization_tables()
303 host1x_hypervisor_writel(host, 0x1, info->mmio_vm_table.base + 4 * i); in host1x_setup_virtualization_tables()
309 /* Our IOMMU usage policy doesn't currently play well with GART */ in host1x_wants_iommu()
310 if (of_machine_is_compatible("nvidia,tegra20")) in host1x_wants_iommu()
316 * IOMMU support. This can happen for example on Tegra20, Tegra30 in host1x_wants_iommu()
330 * buffers will be mapped into a 32-bit IOVA space that host1x can in host1x_wants_iommu()
338 if (host1x->info->dma_mask <= DMA_BIT_MASK(32)) { in host1x_wants_iommu()
348 struct iommu_domain *domain = iommu_get_domain_for_dev(host->dev); in host1x_iommu_attach()
352 if (host->dev->archdata.mapping) { in host1x_iommu_attach()
354 to_dma_iommu_mapping(host->dev); in host1x_iommu_attach()
355 arm_iommu_detach_device(host->dev); in host1x_iommu_attach()
358 domain = iommu_get_domain_for_dev(host->dev); in host1x_iommu_attach()
373 host->group = iommu_group_get(host->dev); in host1x_iommu_attach()
374 if (host->group) { in host1x_iommu_attach()
383 host->domain = iommu_domain_alloc(&platform_bus_type); in host1x_iommu_attach()
384 if (!host->domain) { in host1x_iommu_attach()
385 err = -ENOMEM; in host1x_iommu_attach()
389 err = iommu_attach_group(host->domain, host->group); in host1x_iommu_attach()
391 if (err == -ENODEV) in host1x_iommu_attach()
397 geometry = &host->domain->geometry; in host1x_iommu_attach()
398 start = geometry->aperture_start & host->info->dma_mask; in host1x_iommu_attach()
399 end = geometry->aperture_end & host->info->dma_mask; in host1x_iommu_attach()
401 order = __ffs(host->domain->pgsize_bitmap); in host1x_iommu_attach()
402 init_iova_domain(&host->iova, 1UL << order, start >> order); in host1x_iommu_attach()
403 host->iova_end = end; in host1x_iommu_attach()
405 domain = host->domain; in host1x_iommu_attach()
411 iommu_domain_free(host->domain); in host1x_iommu_attach()
412 host->domain = NULL; in host1x_iommu_attach()
416 iommu_group_put(host->group); in host1x_iommu_attach()
417 host->group = NULL; in host1x_iommu_attach()
424 u64 mask = host->info->dma_mask; in host1x_iommu_init()
431 dev_err(host->dev, "failed to attach to IOMMU: %d\n", err); in host1x_iommu_init()
443 if (!domain && !host->info->has_wide_gather) in host1x_iommu_init()
446 err = dma_coerce_mask_and_coherent(host->dev, mask); in host1x_iommu_init()
448 dev_err(host->dev, "failed to set DMA mask: %d\n", err); in host1x_iommu_init()
457 if (host->domain) { in host1x_iommu_exit()
458 put_iova_domain(&host->iova); in host1x_iommu_exit()
459 iommu_detach_group(host->domain, host->group); in host1x_iommu_exit()
461 iommu_domain_free(host->domain); in host1x_iommu_exit()
462 host->domain = NULL; in host1x_iommu_exit()
466 iommu_group_put(host->group); in host1x_iommu_exit()
467 host->group = NULL; in host1x_iommu_exit()
475 host->resets[0].id = "mc"; in host1x_get_resets()
476 host->resets[1].id = "host1x"; in host1x_get_resets()
477 host->nresets = ARRAY_SIZE(host->resets); in host1x_get_resets()
480 host->dev, host->nresets, host->resets); in host1x_get_resets()
482 dev_err(host->dev, "failed to get reset: %d\n", err); in host1x_get_resets()
494 host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL); in host1x_probe()
496 return -ENOMEM; in host1x_probe()
498 host->info = of_device_get_match_data(&pdev->dev); in host1x_probe()
500 if (host->info->has_hypervisor) { in host1x_probe()
501 host->regs = devm_platform_ioremap_resource_byname(pdev, "vm"); in host1x_probe()
502 if (IS_ERR(host->regs)) in host1x_probe()
503 return PTR_ERR(host->regs); in host1x_probe()
505 host->hv_regs = devm_platform_ioremap_resource_byname(pdev, "hypervisor"); in host1x_probe()
506 if (IS_ERR(host->hv_regs)) in host1x_probe()
507 return PTR_ERR(host->hv_regs); in host1x_probe()
509 if (host->info->has_common) { in host1x_probe()
510 host->common_regs = devm_platform_ioremap_resource_byname(pdev, "common"); in host1x_probe()
511 if (IS_ERR(host->common_regs)) in host1x_probe()
512 return PTR_ERR(host->common_regs); in host1x_probe()
515 host->regs = devm_platform_ioremap_resource(pdev, 0); in host1x_probe()
516 if (IS_ERR(host->regs)) in host1x_probe()
517 return PTR_ERR(host->regs); in host1x_probe()
520 for (i = 0; i < ARRAY_SIZE(host->syncpt_irqs); i++) { in host1x_probe()
526 if (err == -ENXIO) in host1x_probe()
531 host->syncpt_irqs[i] = err; in host1x_probe()
534 host->num_syncpt_irqs = i; in host1x_probe()
538 host->syncpt_irqs[0] = platform_get_irq(pdev, 0); in host1x_probe()
539 if (host->syncpt_irqs[0] < 0) in host1x_probe()
540 return host->syncpt_irqs[0]; in host1x_probe()
542 host->num_syncpt_irqs = 1; in host1x_probe()
545 mutex_init(&host->devices_lock); in host1x_probe()
546 INIT_LIST_HEAD(&host->devices); in host1x_probe()
547 INIT_LIST_HEAD(&host->list); in host1x_probe()
548 host->dev = &pdev->dev; in host1x_probe()
553 host->dev->dma_parms = &host->dma_parms; in host1x_probe()
554 dma_set_max_seg_size(host->dev, UINT_MAX); in host1x_probe()
556 if (host->info->init) { in host1x_probe()
557 err = host->info->init(host); in host1x_probe()
562 host->clk = devm_clk_get(&pdev->dev, NULL); in host1x_probe()
563 if (IS_ERR(host->clk)) { in host1x_probe()
564 err = PTR_ERR(host->clk); in host1x_probe()
566 if (err != -EPROBE_DEFER) in host1x_probe()
567 dev_err(&pdev->dev, "failed to get clock: %d\n", err); in host1x_probe()
576 host1x_bo_cache_init(&host->cache); in host1x_probe()
580 dev_err(&pdev->dev, "failed to setup IOMMU: %d\n", err); in host1x_probe()
584 err = host1x_channel_list_init(&host->channel_list, in host1x_probe()
585 host->info->nb_channels); in host1x_probe()
587 dev_err(&pdev->dev, "failed to initialize channel list\n"); in host1x_probe()
593 dev_err(&pdev->dev, "failed to initialize context list\n"); in host1x_probe()
599 dev_err(&pdev->dev, "failed to initialize syncpts\n"); in host1x_probe()
605 dev_err(&pdev->dev, "failed to initialize interrupts\n"); in host1x_probe()
609 pm_runtime_enable(&pdev->dev); in host1x_probe()
611 err = devm_tegra_core_dev_init_opp_table_common(&pdev->dev); in host1x_probe()
616 err = pm_runtime_resume_and_get(&pdev->dev); in host1x_probe()
626 err = devm_of_platform_populate(&pdev->dev); in host1x_probe()
637 pm_runtime_put_sync_suspend(&pdev->dev); in host1x_probe()
639 pm_runtime_disable(&pdev->dev); in host1x_probe()
645 host1x_memory_context_list_free(&host->context_list); in host1x_probe()
647 host1x_channel_list_free(&host->channel_list); in host1x_probe()
651 host1x_bo_cache_destroy(&host->cache); in host1x_probe()
663 pm_runtime_force_suspend(&pdev->dev); in host1x_remove()
667 host1x_memory_context_list_free(&host->context_list); in host1x_remove()
668 host1x_channel_list_free(&host->channel_list); in host1x_remove()
670 host1x_bo_cache_destroy(&host->cache); in host1x_remove()
684 if (!host->info->skip_reset_assert) { in host1x_runtime_suspend()
685 err = reset_control_bulk_assert(host->nresets, host->resets); in host1x_runtime_suspend()
694 clk_disable_unprepare(host->clk); in host1x_runtime_suspend()
695 reset_control_bulk_release(host->nresets, host->resets); in host1x_runtime_suspend()
712 err = reset_control_bulk_acquire(host->nresets, host->resets); in host1x_runtime_resume()
718 err = clk_prepare_enable(host->clk); in host1x_runtime_resume()
724 err = reset_control_bulk_deassert(host->nresets, host->resets); in host1x_runtime_resume()
737 clk_disable_unprepare(host->clk); in host1x_runtime_resume()
739 reset_control_bulk_release(host->nresets, host->resets); in host1x_runtime_resume()
752 .name = "tegra-host1x",
789 * host1x_get_dma_mask() - query the supported DMA mask for host1x
797 return host1x->info->dma_mask; in host1x_get_dma_mask()
801 MODULE_AUTHOR("Thierry Reding <thierry.reding@avionic-design.de>");