diff options
Diffstat (limited to 'drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c')
-rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c | 94 |
1 files changed, 59 insertions, 35 deletions
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c index 077f7521a971..5e812b60a69d 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c @@ -182,9 +182,20 @@ static void mdp4_preclose(struct msm_kms *kms, struct drm_file *file) mdp4_crtc_cancel_pending_flip(priv->crtcs[i], file); } +static const char *iommu_ports[] = { + "mdp_port0_cb0", "mdp_port1_cb0", +}; + static void mdp4_destroy(struct msm_kms *kms) { struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms)); + struct msm_mmu *mmu = mdp4_kms->mmu; + + if (mmu) { + mmu->funcs->detach(mmu, iommu_ports, ARRAY_SIZE(iommu_ports)); + mmu->funcs->destroy(mmu); + } + if (mdp4_kms->blank_cursor_iova) msm_gem_put_iova(mdp4_kms->blank_cursor_bo, mdp4_kms->id); if (mdp4_kms->blank_cursor_bo) @@ -262,6 +273,11 @@ static struct drm_panel *detect_panel(struct drm_device *dev) of_node_put(endpoint); + if (!of_device_is_available(panel_node)) { + dev_err(dev->dev, "panel is not enabled in DT\n"); + return ERR_PTR(-ENODEV); + } + panel = of_drm_find_panel(panel_node); if (!panel) { of_node_put(panel_node); @@ -313,45 +329,55 @@ static int modeset_init(struct mdp4_kms *mdp4_kms) if (IS_ERR(panel)) { ret = PTR_ERR(panel); dev_err(dev->dev, "failed to detect LVDS panel: %d\n", ret); - goto fail; - } + /** + * Only fail if there is panel but not ready yet + * continue with other stuff if there is no panel connected. + */ + if (ret == -EPROBE_DEFER) + goto fail; + } else { + plane = mdp4_plane_init(dev, RGB2, true); + if (IS_ERR(plane)) { + dev_err(dev->dev, + "failed to construct plane for RGB2\n"); + ret = PTR_ERR(plane); + goto fail; + } - plane = mdp4_plane_init(dev, RGB2, true); - if (IS_ERR(plane)) { - dev_err(dev->dev, "failed to construct plane for RGB2\n"); - ret = PTR_ERR(plane); - goto fail; - } + crtc = mdp4_crtc_init(dev, plane, priv->num_crtcs, 0, DMA_P); + if (IS_ERR(crtc)) { + dev_err(dev->dev, + "failed to construct crtc for DMA_P\n"); + ret = PTR_ERR(crtc); + goto fail; + } - crtc = mdp4_crtc_init(dev, plane, priv->num_crtcs, 0, DMA_P); - if (IS_ERR(crtc)) { - dev_err(dev->dev, "failed to construct crtc for DMA_P\n"); - ret = PTR_ERR(crtc); - goto fail; - } + encoder = mdp4_lcdc_encoder_init(dev, panel); + if (IS_ERR(encoder)) { + dev_err(dev->dev, + "failed to construct LCDC encoder\n"); + ret = PTR_ERR(encoder); + goto fail; + } - encoder = mdp4_lcdc_encoder_init(dev, panel); - if (IS_ERR(encoder)) { - dev_err(dev->dev, "failed to construct LCDC encoder\n"); - ret = PTR_ERR(encoder); - goto fail; - } + /* LCDC can be hooked to DMA_P: */ + encoder->possible_crtcs = 1 << priv->num_crtcs; - /* LCDC can be hooked to DMA_P: */ - encoder->possible_crtcs = 1 << priv->num_crtcs; + priv->crtcs[priv->num_crtcs++] = crtc; + priv->encoders[priv->num_encoders++] = encoder; - priv->crtcs[priv->num_crtcs++] = crtc; - priv->encoders[priv->num_encoders++] = encoder; + connector = mdp4_lvds_connector_init(dev, panel, encoder); + if (IS_ERR(connector)) { + ret = PTR_ERR(connector); + dev_err(dev->dev, + "failed to initialize LVDS connector: %d\n", + ret); + goto fail; + } - connector = mdp4_lvds_connector_init(dev, panel, encoder); - if (IS_ERR(connector)) { - ret = PTR_ERR(connector); - dev_err(dev->dev, "failed to initialize LVDS connector: %d\n", ret); - goto fail; + priv->connectors[priv->num_connectors++] = connector; } - priv->connectors[priv->num_connectors++] = connector; - /* * Setup DTV/HDMI path: RGB1 -> DMA_E -> DTV -> HDMI: */ @@ -398,10 +424,6 @@ fail: return ret; } -static const char *iommu_ports[] = { - "mdp_port0_cb0", "mdp_port1_cb0", -}; - struct msm_kms *mdp4_kms_init(struct drm_device *dev) { struct platform_device *pdev = dev->platformdev; @@ -506,6 +528,8 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev) ARRAY_SIZE(iommu_ports)); if (ret) goto fail; + + mdp4_kms->mmu = mmu; } else { dev_info(dev->dev, "no iommu, fallback to phys " "contig buffers for scanout\n"); |