struct msm_kms *mdp4_kms_init(struct drm_device *dev) { struct platform_device *pdev = to_platform_device(dev->dev); struct mdp4_platform_config *config = mdp4_get_config(pdev); struct mdp4_kms *mdp4_kms; struct msm_kms *kms = NULL; struct msm_gem_address_space *aspace; int irq, ret; mdp4_kms = kzalloc(sizeof(*mdp4_kms), GFP_KERNEL); if (!mdp4_kms) { dev_err(dev->dev, "failed to allocate kms\n"); ret = -ENOMEM; goto fail; } mdp_kms_init(&mdp4_kms->base, &kms_funcs); kms = &mdp4_kms->base.base; mdp4_kms->dev = dev; mdp4_kms->mmio = msm_ioremap(pdev, NULL, "MDP4"); if (IS_ERR(mdp4_kms->mmio)) { ret = PTR_ERR(mdp4_kms->mmio); goto fail; } irq = platform_get_irq(pdev, 0); if (irq < 0) { ret = irq; dev_err(dev->dev, "failed to get irq: %d\n", ret); goto fail; } kms->irq = irq; /* NOTE: driver for this regulator still missing upstream.. use * _get_exclusive() and ignore the error if it does not exist * (and hope that the bootloader left it on for us) */ mdp4_kms->vdd = devm_regulator_get_exclusive(&pdev->dev, "vdd"); if (IS_ERR(mdp4_kms->vdd)) mdp4_kms->vdd = NULL; if (mdp4_kms->vdd) { ret = regulator_enable(mdp4_kms->vdd); if (ret) { dev_err(dev->dev, "failed to enable regulator vdd: %d\n", ret); goto fail; } } mdp4_kms->clk = devm_clk_get(&pdev->dev, "core_clk"); if (IS_ERR(mdp4_kms->clk)) { dev_err(dev->dev, "failed to get core_clk\n"); ret = PTR_ERR(mdp4_kms->clk); goto fail; } mdp4_kms->pclk = devm_clk_get(&pdev->dev, "iface_clk"); if (IS_ERR(mdp4_kms->pclk)) mdp4_kms->pclk = NULL; // XXX if (rev >= MDP_REV_42) { ??? mdp4_kms->lut_clk = devm_clk_get(&pdev->dev, "lut_clk"); if (IS_ERR(mdp4_kms->lut_clk)) { dev_err(dev->dev, "failed to get lut_clk\n"); ret = PTR_ERR(mdp4_kms->lut_clk); goto fail; } mdp4_kms->axi_clk = devm_clk_get(&pdev->dev, "bus_clk"); if (IS_ERR(mdp4_kms->axi_clk)) { dev_err(dev->dev, "failed to get axi_clk\n"); ret = PTR_ERR(mdp4_kms->axi_clk); goto fail; } clk_set_rate(mdp4_kms->clk, config->max_clk); clk_set_rate(mdp4_kms->lut_clk, config->max_clk); pm_runtime_enable(dev->dev); mdp4_kms->rpm_enabled = true; /* make sure things are off before attaching iommu (bootloader could * have left things on, in which case we'll start getting faults if * we don't disable): */ mdp4_enable(mdp4_kms); mdp4_write(mdp4_kms, REG_MDP4_DTV_ENABLE, 0); mdp4_write(mdp4_kms, REG_MDP4_LCDC_ENABLE, 0); mdp4_write(mdp4_kms, REG_MDP4_DSI_ENABLE, 0); mdp4_disable(mdp4_kms); mdelay(16); if (config->iommu) { aspace = msm_gem_address_space_create(&pdev->dev, config->iommu, "mdp4"); if (IS_ERR(aspace)) { ret = PTR_ERR(aspace); goto fail; } kms->aspace = aspace; ret = aspace->mmu->funcs->attach(aspace->mmu, iommu_ports, ARRAY_SIZE(iommu_ports)); if (ret) goto fail; } else { dev_info(dev->dev, "no iommu, fallback to phys " "contig buffers for scanout\n"); aspace = NULL; } ret = modeset_init(mdp4_kms); if (ret) { dev_err(dev->dev, "modeset_init failed: %d\n", ret); goto fail; } mdp4_kms->blank_cursor_bo = msm_gem_new(dev, SZ_16K, MSM_BO_WC); if (IS_ERR(mdp4_kms->blank_cursor_bo)) { ret = PTR_ERR(mdp4_kms->blank_cursor_bo); dev_err(dev->dev, "could not allocate blank-cursor bo: %d\n", ret); mdp4_kms->blank_cursor_bo = NULL; goto fail; } ret = msm_gem_get_iova(mdp4_kms->blank_cursor_bo, kms->aspace, &mdp4_kms->blank_cursor_iova); if (ret) { dev_err(dev->dev, "could not pin blank-cursor bo: %d\n", ret); goto fail; } dev->mode_config.min_width = 0; dev->mode_config.min_height = 0; dev->mode_config.max_width = 2048; dev->mode_config.max_height = 2048; return kms; fail: if (kms) mdp4_destroy(kms); return ERR_PTR(ret); }
struct msm_kms *mdp4_kms_init(struct drm_device *dev) { struct platform_device *pdev = dev->platformdev; struct mdp4_platform_config *config = mdp4_get_config(pdev); struct mdp4_kms *mdp4_kms; struct msm_kms *kms = NULL; struct msm_mmu *mmu; int ret; mdp4_kms = kzalloc(sizeof(*mdp4_kms), GFP_KERNEL); if (!mdp4_kms) { dev_err(dev->dev, "failed to allocate kms\n"); ret = -ENOMEM; goto fail; } mdp_kms_init(&mdp4_kms->base, &kms_funcs); kms = &mdp4_kms->base.base; mdp4_kms->dev = dev; mdp4_kms->mmio = msm_ioremap(pdev, NULL, "MDP4"); if (IS_ERR(mdp4_kms->mmio)) { ret = PTR_ERR(mdp4_kms->mmio); goto fail; } mdp4_kms->dsi_pll_vdda = devm_regulator_get_optional(&pdev->dev, "dsi_pll_vdda"); if (IS_ERR(mdp4_kms->dsi_pll_vdda)) mdp4_kms->dsi_pll_vdda = NULL; mdp4_kms->dsi_pll_vddio = devm_regulator_get_optional(&pdev->dev, "dsi_pll_vddio"); if (IS_ERR(mdp4_kms->dsi_pll_vddio)) mdp4_kms->dsi_pll_vddio = NULL; mdp4_kms->vdd = devm_regulator_get_exclusive(&pdev->dev, "vdd"); if (IS_ERR(mdp4_kms->vdd)) mdp4_kms->vdd = NULL; if (mdp4_kms->vdd) { ret = regulator_enable(mdp4_kms->vdd); if (ret) { dev_err(dev->dev, "failed to enable regulator vdd: %d\n", ret); goto fail; } } mdp4_kms->clk = devm_clk_get(&pdev->dev, "core_clk"); if (IS_ERR(mdp4_kms->clk)) { dev_err(dev->dev, "failed to get core_clk\n"); ret = PTR_ERR(mdp4_kms->clk); goto fail; } mdp4_kms->pclk = devm_clk_get(&pdev->dev, "iface_clk"); if (IS_ERR(mdp4_kms->pclk)) mdp4_kms->pclk = NULL; // XXX if (rev >= MDP_REV_42) { ??? mdp4_kms->lut_clk = devm_clk_get(&pdev->dev, "lut_clk"); if (IS_ERR(mdp4_kms->lut_clk)) { dev_err(dev->dev, "failed to get lut_clk\n"); ret = PTR_ERR(mdp4_kms->lut_clk); goto fail; } mdp4_kms->axi_clk = devm_clk_get(&pdev->dev, "mdp_axi_clk"); if (IS_ERR(mdp4_kms->axi_clk)) { dev_err(dev->dev, "failed to get axi_clk\n"); ret = PTR_ERR(mdp4_kms->axi_clk); goto fail; } clk_set_rate(mdp4_kms->clk, config->max_clk); clk_set_rate(mdp4_kms->lut_clk, config->max_clk); /* make sure things are off before attaching iommu (bootloader could * have left things on, in which case we'll start getting faults if * we don't disable): */ mdp4_enable(mdp4_kms); mdp4_write(mdp4_kms, REG_MDP4_DTV_ENABLE, 0); mdp4_write(mdp4_kms, REG_MDP4_LCDC_ENABLE, 0); mdp4_write(mdp4_kms, REG_MDP4_DSI_ENABLE, 0); mdp4_disable(mdp4_kms); mdelay(16); if (config->iommu) { mmu = msm_iommu_new(&pdev->dev, config->iommu); if (IS_ERR(mmu)) { ret = PTR_ERR(mmu); goto fail; } ret = mmu->funcs->attach(mmu, iommu_ports, ARRAY_SIZE(iommu_ports)); if (ret) goto fail; } else { dev_info(dev->dev, "no iommu, fallback to phys " "contig buffers for scanout\n"); mmu = NULL; } mdp4_kms->id = msm_register_mmu(dev, mmu); if (mdp4_kms->id < 0) { ret = mdp4_kms->id; dev_err(dev->dev, "failed to register mdp4 iommu: %d\n", ret); goto fail; } ret = modeset_init(mdp4_kms); if (ret) { dev_err(dev->dev, "modeset_init failed: %d\n", ret); goto fail; } mutex_lock(&dev->struct_mutex); mdp4_kms->blank_cursor_bo = msm_gem_new(dev, SZ_16K, MSM_BO_WC); mutex_unlock(&dev->struct_mutex); if (IS_ERR(mdp4_kms->blank_cursor_bo)) { ret = PTR_ERR(mdp4_kms->blank_cursor_bo); dev_err(dev->dev, "could not allocate blank-cursor bo: %d\n", ret); mdp4_kms->blank_cursor_bo = NULL; goto fail; } ret = msm_gem_get_iova(mdp4_kms->blank_cursor_bo, mdp4_kms->id, &mdp4_kms->blank_cursor_iova); if (ret) { dev_err(dev->dev, "could not pin blank-cursor bo: %d\n", ret); goto fail; } return kms; fail: if (kms) mdp4_destroy(kms); return ERR_PTR(ret); }