static int ipu_crtc_init(struct ipu_crtc *ipu_crtc, struct ipu_client_platformdata *pdata) { int ret; ret = ipu_get_resources(ipu_crtc, pdata); if (ret) { dev_err(ipu_crtc->dev, "getting resources failed with %d.\n", ret); return ret; } ret = imx_drm_add_crtc(&ipu_crtc->base, &ipu_crtc->imx_crtc, &ipu_crtc_helper_funcs, THIS_MODULE, ipu_crtc->dev->parent->of_node, pdata->di); if (ret) { dev_err(ipu_crtc->dev, "adding crtc failed with %d.\n", ret); goto err_put_resources; } return 0; err_put_resources: ipu_put_resources(ipu_crtc); return ret; }
static void ipu_drm_unbind(struct device *dev, struct device *master, void *data) { struct ipu_crtc *ipu_crtc = dev_get_drvdata(dev); imx_drm_remove_crtc(ipu_crtc->imx_crtc); ipu_plane_put_resources(ipu_crtc->plane[0]); ipu_put_resources(ipu_crtc); }
static int ipu_drm_remove(struct platform_device *pdev) { struct ipu_crtc *ipu_crtc = platform_get_drvdata(pdev); imx_drm_remove_crtc(ipu_crtc->imx_crtc); ipu_put_resources(ipu_crtc); return 0; }
static int ipu_get_resources(struct ipu_crtc *ipu_crtc, struct ipu_client_platformdata *pdata) { struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent); int ret; ipu_crtc->ipu_ch = ipu_idmac_get(ipu, pdata->dma[0]); if (IS_ERR(ipu_crtc->ipu_ch)) { ret = PTR_ERR(ipu_crtc->ipu_ch); goto err_out; } ipu_crtc->dc = ipu_dc_get(ipu, pdata->dc); if (IS_ERR(ipu_crtc->dc)) { ret = PTR_ERR(ipu_crtc->dc); goto err_out; } ipu_crtc->dmfc = ipu_dmfc_get(ipu, pdata->dma[0]); if (IS_ERR(ipu_crtc->dmfc)) { ret = PTR_ERR(ipu_crtc->dmfc); goto err_out; } if (pdata->dp >= 0) { ipu_crtc->dp = ipu_dp_get(ipu, pdata->dp); if (IS_ERR(ipu_crtc->dp)) { ret = PTR_ERR(ipu_crtc->dp); goto err_out; } } ipu_crtc->di = ipu_di_get(ipu, pdata->di); if (IS_ERR(ipu_crtc->di)) { ret = PTR_ERR(ipu_crtc->di); goto err_out; } ipu_crtc->irq = ipu_idmac_channel_irq(ipu, ipu_crtc->ipu_ch, IPU_IRQ_EOF); ret = devm_request_irq(ipu_crtc->dev, ipu_crtc->irq, ipu_irq_handler, 0, "imx_drm", ipu_crtc); if (ret < 0) { dev_err(ipu_crtc->dev, "irq request failed with %d.\n", ret); goto err_out; } disable_irq(ipu_crtc->irq); return 0; err_out: ipu_put_resources(ipu_crtc); return ret; }
static int ipu_get_resources(struct ipu_crtc *ipu_crtc, struct ipu_client_platformdata *pdata) { struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent); int ret; ipu_crtc->ipu_ch = ipu_idmac_get(ipu, pdata->dma[0]); if (IS_ERR(ipu_crtc->ipu_ch)) { ret = PTR_ERR(ipu_crtc->ipu_ch); goto err_out; } ipu_crtc->dc = ipu_dc_get(ipu, pdata->dc); if (IS_ERR(ipu_crtc->dc)) { ret = PTR_ERR(ipu_crtc->dc); goto err_out; } ipu_crtc->dmfc = ipu_dmfc_get(ipu, pdata->dma[0]); if (IS_ERR(ipu_crtc->dmfc)) { ret = PTR_ERR(ipu_crtc->dmfc); goto err_out; } if (pdata->dp >= 0) { ipu_crtc->dp = ipu_dp_get(ipu, pdata->dp); if (IS_ERR(ipu_crtc->dp)) { ret = PTR_ERR(ipu_crtc->dp); goto err_out; } } ipu_crtc->di = ipu_di_get(ipu, pdata->di); if (IS_ERR(ipu_crtc->di)) { ret = PTR_ERR(ipu_crtc->di); goto err_out; } return 0; err_out: ipu_put_resources(ipu_crtc); return ret; }
static int ipu_crtc_init(struct ipu_crtc *ipu_crtc, struct ipu_client_platformdata *pdata) { struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent); int ret; ret = ipu_get_resources(ipu_crtc, pdata); if (ret) { dev_err(ipu_crtc->dev, "getting resources failed with %d.\n", ret); return ret; } ret = imx_drm_add_crtc(&ipu_crtc->base, &ipu_crtc->imx_crtc, &ipu_crtc_helper_funcs, THIS_MODULE, ipu_crtc->dev->parent->of_node, pdata->di); if (ret) { dev_err(ipu_crtc->dev, "adding crtc failed with %d.\n", ret); goto err_put_resources; } ipu_crtc->irq = ipu_idmac_channel_irq(ipu, ipu_crtc->ipu_ch, IPU_IRQ_EOF); ret = devm_request_irq(ipu_crtc->dev, ipu_crtc->irq, ipu_irq_handler, 0, "imx_drm", ipu_crtc); if (ret < 0) { dev_err(ipu_crtc->dev, "irq request failed with %d.\n", ret); goto err_put_resources; } disable_irq(ipu_crtc->irq); return 0; err_put_resources: ipu_put_resources(ipu_crtc); return ret; }
static int ipu_crtc_init(struct ipu_crtc *ipu_crtc, struct ipu_client_platformdata *pdata, struct drm_device *drm) { struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent); int dp = -EINVAL; int ret; int id; ret = ipu_get_resources(ipu_crtc, pdata); if (ret) { dev_err(ipu_crtc->dev, "getting resources failed with %d.\n", ret); return ret; } ret = imx_drm_add_crtc(drm, &ipu_crtc->base, &ipu_crtc->imx_crtc, &ipu_crtc_helper_funcs, ipu_crtc->dev->of_node); if (ret) { dev_err(ipu_crtc->dev, "adding crtc failed with %d.\n", ret); goto err_put_resources; } if (pdata->dp >= 0) dp = IPU_DP_FLOW_SYNC_BG; id = imx_drm_crtc_id(ipu_crtc->imx_crtc); ipu_crtc->plane[0] = ipu_plane_init(ipu_crtc->base.dev, ipu, pdata->dma[0], dp, BIT(id), true); ret = ipu_plane_get_resources(ipu_crtc->plane[0]); if (ret) { dev_err(ipu_crtc->dev, "getting plane 0 resources failed with %d.\n", ret); goto err_remove_crtc; } /* If this crtc is using the DP, add an overlay plane */ if (pdata->dp >= 0 && pdata->dma[1] > 0) { ipu_crtc->plane[1] = ipu_plane_init(ipu_crtc->base.dev, ipu, pdata->dma[1], IPU_DP_FLOW_SYNC_FG, BIT(id), false); if (IS_ERR(ipu_crtc->plane[1])) ipu_crtc->plane[1] = NULL; } ipu_crtc->irq = ipu_plane_irq(ipu_crtc->plane[0]); ret = devm_request_irq(ipu_crtc->dev, ipu_crtc->irq, ipu_irq_handler, 0, "imx_drm", ipu_crtc); if (ret < 0) { dev_err(ipu_crtc->dev, "irq request failed with %d.\n", ret); goto err_put_plane_res; } return 0; err_put_plane_res: ipu_plane_put_resources(ipu_crtc->plane[0]); err_remove_crtc: imx_drm_remove_crtc(ipu_crtc->imx_crtc); err_put_resources: ipu_put_resources(ipu_crtc); return ret; }
static int ipu_crtc_init(struct ipu_crtc *ipu_crtc, struct ipu_client_platformdata *pdata, struct drm_device *drm) { struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent); int dp = -EINVAL; int ret; ret = ipu_get_resources(ipu_crtc, pdata); if (ret) { dev_err(ipu_crtc->dev, "getting resources failed with %d.\n", ret); return ret; } if (pdata->dp >= 0) dp = IPU_DP_FLOW_SYNC_BG; ipu_crtc->plane[0] = ipu_plane_init(drm, ipu, pdata->dma[0], dp, 0, DRM_PLANE_TYPE_PRIMARY); if (IS_ERR(ipu_crtc->plane[0])) { ret = PTR_ERR(ipu_crtc->plane[0]); goto err_put_resources; } ret = imx_drm_add_crtc(drm, &ipu_crtc->base, &ipu_crtc->imx_crtc, &ipu_crtc->plane[0]->base, &ipu_crtc_helper_funcs, pdata->of_node); if (ret) { dev_err(ipu_crtc->dev, "adding crtc failed with %d.\n", ret); goto err_put_resources; } ret = ipu_plane_get_resources(ipu_crtc->plane[0]); if (ret) { dev_err(ipu_crtc->dev, "getting plane 0 resources failed with %d.\n", ret); goto err_remove_crtc; } /* If this crtc is using the DP, add an overlay plane */ if (pdata->dp >= 0 && pdata->dma[1] > 0) { ipu_crtc->plane[1] = ipu_plane_init(drm, ipu, pdata->dma[1], IPU_DP_FLOW_SYNC_FG, drm_crtc_mask(&ipu_crtc->base), DRM_PLANE_TYPE_OVERLAY); if (IS_ERR(ipu_crtc->plane[1])) ipu_crtc->plane[1] = NULL; } ipu_crtc->irq = ipu_plane_irq(ipu_crtc->plane[0]); ret = devm_request_irq(ipu_crtc->dev, ipu_crtc->irq, ipu_irq_handler, 0, "imx_drm", ipu_crtc); if (ret < 0) { dev_err(ipu_crtc->dev, "irq request failed with %d.\n", ret); goto err_put_plane_res; } /* Only enable IRQ when we actually need it to trigger work. */ disable_irq(ipu_crtc->irq); ipu_crtc->flip_queue = create_singlethread_workqueue("ipu-crtc-flip"); return 0; err_put_plane_res: ipu_plane_put_resources(ipu_crtc->plane[0]); err_remove_crtc: imx_drm_remove_crtc(ipu_crtc->imx_crtc); err_put_resources: ipu_put_resources(ipu_crtc); return ret; }