int mdss_iommu_init(void) { struct iommu_domain *domain; int domain_idx, i; domain_idx = msm_register_domain(&mdp_iommu_layout); if (IS_ERR_VALUE(domain_idx)) return -EINVAL; domain = msm_get_iommu_domain(domain_idx); if (!domain) { pr_err("unable to get iommu domain(%d)\n", domain_idx); return -EINVAL; } iommu_set_fault_handler(domain, mdss_iommu_fault_handler); for (i = 0; i < ARRAY_SIZE(mdp_iommu_ctx); i++) { mdp_iommu_ctx[i].ctx = msm_iommu_get_ctx(mdp_iommu_ctx[i].name); if (!mdp_iommu_ctx[i].ctx) { pr_warn("unable to get iommu ctx(%s)\n", mdp_iommu_ctx[i].name); return -EINVAL; } } mdss_res->iommu_domain = domain_idx; return 0; }
/* * kgsl_iommu_create_pagetable - Create a IOMMU pagetable * * Allocate memory to hold a pagetable and allocate the IOMMU * domain which is the actual IOMMU pagetable * Return - void */ void *kgsl_iommu_create_pagetable(void) { struct kgsl_iommu_pt *iommu_pt; iommu_pt = kzalloc(sizeof(struct kgsl_iommu_pt), GFP_KERNEL); if (!iommu_pt) { KGSL_CORE_ERR("kzalloc(%d) failed\n", sizeof(struct kgsl_iommu_pt)); return NULL; } /* L2 redirect is not stable on IOMMU v2 */ if (msm_soc_version_supports_iommu_v1()) iommu_pt->domain = iommu_domain_alloc(&platform_bus_type, MSM_IOMMU_DOMAIN_PT_CACHEABLE); else iommu_pt->domain = iommu_domain_alloc(&platform_bus_type, 0); if (!iommu_pt->domain) { KGSL_CORE_ERR("Failed to create iommu domain\n"); kfree(iommu_pt); return NULL; } else { iommu_set_fault_handler(iommu_pt->domain, kgsl_iommu_fault_handler); } return iommu_pt; }
gceSTATUS gckIOMMU_Construct( IN gckOS Os, OUT gckIOMMU * Iommu ) { gceSTATUS status; gckIOMMU iommu = gcvNULL; struct device *dev; int ret; gcmkHEADER(); dev = &Os->device->platform->device->dev; gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(gcsIOMMU), (gctPOINTER *)&iommu)); gckOS_ZeroMemory(iommu, gcmSIZEOF(gcsIOMMU)); iommu->domain = iommu_domain_alloc(&platform_bus_type); if (!iommu->domain) { gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_OS, "iommu_domain_alloc() fail"); gcmkONERROR(gcvSTATUS_NOT_SUPPORTED); } iommu_set_fault_handler(iommu->domain, _IOMMU_Fault_Handler, dev); ret = iommu_attach_device(iommu->domain, dev); if (ret) { gcmkTRACE_ZONE( gcvLEVEL_INFO, gcvZONE_OS, "iommu_attach_device() fail %d", ret); gcmkONERROR(gcvSTATUS_NOT_SUPPORTED); } iommu->device = dev; _FlatMapping(iommu); *Iommu = iommu; gcmkFOOTER_NO(); return gcvSTATUS_OK; OnError: gckIOMMU_Destory(Os, iommu); gcmkFOOTER(); return status; }
struct msm_mmu *msm_iommu_new(struct device *dev, struct iommu_domain *domain) { struct msm_iommu *iommu; iommu = kzalloc(sizeof(*iommu), GFP_KERNEL); if (!iommu) return ERR_PTR(-ENOMEM); iommu->domain = domain; msm_mmu_init(&iommu->base, dev, &funcs); iommu_set_fault_handler(domain, msm_fault_handler, iommu); return &iommu->base; }
int mdss_iommu_init(struct mdss_data_type *mdata) { struct msm_iova_layout layout; struct iommu_domain *domain; struct mdss_iommu_map_type *iomap; int i; if (mdata->iommu_map) { pr_warn("iommu already initialized\n"); return 0; } for (i = 0; i < MDSS_IOMMU_MAX_DOMAIN; i++) { iomap = &mdss_iommu_map[i]; layout.client_name = iomap->client_name; layout.partitions = iomap->partitions; layout.npartitions = iomap->npartitions; layout.is_secure = (i == MDSS_IOMMU_DOMAIN_SECURE); iomap->domain_idx = msm_register_domain(&layout); if (IS_ERR_VALUE(iomap->domain_idx)) return -EINVAL; domain = msm_get_iommu_domain(iomap->domain_idx); if (!domain) { pr_err("unable to get iommu domain(%d)\n", iomap->domain_idx); return -EINVAL; } iommu_set_fault_handler(domain, mdss_iommu_fault_handler, NULL); iomap->ctx = msm_iommu_get_ctx(iomap->ctx_name); if (!iomap->ctx) { pr_warn("unable to get iommu ctx(%s)\n", iomap->ctx_name); return -EINVAL; } } mdata->iommu_map = mdss_iommu_map; return 0; }
/* * kgsl_iommu_create_pagetable - Create a IOMMU pagetable * * Allocate memory to hold a pagetable and allocate the IOMMU * domain which is the actual IOMMU pagetable * Return - void */ void *kgsl_iommu_create_pagetable(void) { struct kgsl_iommu_pt *iommu_pt; iommu_pt = kzalloc(sizeof(struct kgsl_iommu_pt), GFP_KERNEL); if (!iommu_pt) { KGSL_CORE_ERR("kzalloc(%d) failed\n", sizeof(struct kgsl_iommu_pt)); return NULL; } iommu_pt->domain = iommu_domain_alloc(&platform_bus_type, MSM_IOMMU_DOMAIN_PT_CACHEABLE); if (!iommu_pt->domain) { KGSL_CORE_ERR("Failed to create iommu domain\n"); kfree(iommu_pt); return NULL; } else { iommu_set_fault_handler(iommu_pt->domain, kgsl_iommu_fault_handler); } return iommu_pt; }
static struct msm_panel_common_pdata *mdss_mdp_populate_pdata( struct device *dev) { struct msm_panel_common_pdata *pdata; struct msm_iova_layout layout; struct iommu_domain *domain; struct mdss_iommu_map_type *iomap; int i; if (mdata->iommu_map) { pr_warn("iommu already initialized\n"); return 0; } for (i = 0; i < MDSS_IOMMU_MAX_DOMAIN; i++) { iomap = &mdss_iommu_map[i]; layout.client_name = iomap->client_name; layout.partitions = iomap->partitions; layout.npartitions = iomap->npartitions; layout.is_secure = (i == MDSS_IOMMU_DOMAIN_SECURE); iomap->domain_idx = msm_register_domain(&layout); if (IS_ERR_VALUE(iomap->domain_idx)) return -EINVAL; domain = msm_get_iommu_domain(iomap->domain_idx); if (!domain) { pr_err("unable to get iommu domain(%d)\n", iomap->domain_idx); return -EINVAL; } iommu_set_fault_handler(domain, mdss_iommu_fault_handler, NULL); pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) dev_err(dev, "could not allocate memory for pdata\n"); return pdata; } static u32 mdss_mdp_res_init(struct platform_device *pdev) { u32 rc; rc = mdss_mdp_irq_clk_setup(pdev); if (rc) return rc; mdss_res->clk_ctrl_wq = create_singlethread_workqueue("mdp_clk_wq"); INIT_DELAYED_WORK(&mdss_res->clk_ctrl_worker, mdss_mdp_clk_ctrl_workqueue_handler); mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false); mdss_res->rev = MDSS_MDP_REG_READ(MDSS_REG_HW_VERSION); mdss_res->mdp_rev = MDSS_MDP_REG_READ(MDSS_MDP_REG_HW_VERSION); mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false); mdss_res->smp_mb_cnt = MDSS_MDP_SMP_MMB_BLOCKS; mdss_res->smp_mb_size = MDSS_MDP_SMP_MMB_SIZE; mdss_res->pipe_type_map = mdss_mdp_pipe_type_map; mdss_res->mixer_type_map = mdss_mdp_mixer_type_map; pr_info("mdss_revision=%x\n", mdss_res->rev); pr_info("mdp_hw_revision=%x\n", mdss_res->mdp_rev); mdss_res->res_init = true; mdss_res->timeout = HZ/20; mdss_res->clk_ena = false; mdss_res->irq_mask = MDSS_MDP_DEFAULT_INTR_MASK; mdss_res->suspend = false; mdss_res->prim_ptype = NO_PANEL; mdss_res->irq_ena = false; return 0; }