From: Laurentiu Palcu <laurentiu.palcu@xxxxxxx> Component framework is needed by HDP driver. Signed-off-by: Laurentiu Palcu <laurentiu.palcu@xxxxxxx> --- drivers/gpu/drm/imx/dcss/dcss-drv.c | 89 ++++++++++++++++++++++------- drivers/gpu/drm/imx/dcss/dcss-kms.c | 14 ++++- drivers/gpu/drm/imx/dcss/dcss-kms.h | 4 +- 3 files changed, 80 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/imx/dcss/dcss-drv.c b/drivers/gpu/drm/imx/dcss/dcss-drv.c index 8dc2f85c514b..09d0ac28e28a 100644 --- a/drivers/gpu/drm/imx/dcss/dcss-drv.c +++ b/drivers/gpu/drm/imx/dcss/dcss-drv.c @@ -6,6 +6,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/platform_device.h> +#include <linux/component.h> #include <drm/drm_of.h> #include "dcss-dev.h" @@ -14,6 +15,8 @@ struct dcss_drv { struct dcss_dev *dcss; struct dcss_kms_dev *kms; + + bool is_componentized; }; struct dcss_dev *dcss_drv_dev_to_dcss(struct device *dev) @@ -30,30 +33,18 @@ struct drm_device *dcss_drv_dev_to_drm(struct device *dev) return mdrv ? &mdrv->kms->base : NULL; } -static int dcss_drv_platform_probe(struct platform_device *pdev) +static int dcss_drv_init(struct device *dev, bool componentized) { - struct device *dev = &pdev->dev; - struct device_node *remote; struct dcss_drv *mdrv; int err = 0; - bool hdmi_output = true; - - if (!dev->of_node) - return -ENODEV; - - remote = of_graph_get_remote_node(dev->of_node, 0, 0); - if (!remote) - return -ENODEV; - - hdmi_output = !of_device_is_compatible(remote, "fsl,imx8mq-nwl-dsi"); - - of_node_put(remote); mdrv = kzalloc(sizeof(*mdrv), GFP_KERNEL); if (!mdrv) return -ENOMEM; - mdrv->dcss = dcss_dev_create(dev, hdmi_output); + mdrv->is_componentized = componentized; + + mdrv->dcss = dcss_dev_create(dev, componentized); if (IS_ERR(mdrv->dcss)) { err = PTR_ERR(mdrv->dcss); goto err; @@ -61,7 +52,7 @@ static int dcss_drv_platform_probe(struct platform_device *pdev) dev_set_drvdata(dev, mdrv); - mdrv->kms = dcss_kms_attach(mdrv->dcss); + mdrv->kms = dcss_kms_attach(mdrv->dcss, componentized); if (IS_ERR(mdrv->kms)) { err = PTR_ERR(mdrv->kms); goto dcss_shutoff; @@ -79,19 +70,73 @@ static int dcss_drv_platform_probe(struct platform_device *pdev) return err; } -static int dcss_drv_platform_remove(struct platform_device *pdev) +static void dcss_drv_deinit(struct device *dev, bool componentized) { - struct dcss_drv *mdrv = dev_get_drvdata(&pdev->dev); + struct dcss_drv *mdrv = dev_get_drvdata(dev); if (!mdrv) - return 0; + return; - dcss_kms_detach(mdrv->kms); + dcss_kms_detach(mdrv->kms, componentized); dcss_dev_destroy(mdrv->dcss); - dev_set_drvdata(&pdev->dev, NULL); + dev_set_drvdata(dev, NULL); kfree(mdrv); +} + +static int dcss_drv_bind(struct device *dev) +{ + return dcss_drv_init(dev, true); +} + +static void dcss_drv_unbind(struct device *dev) +{ + return dcss_drv_deinit(dev, true); +} + +static const struct component_master_ops dcss_master_ops = { + .bind = dcss_drv_bind, + .unbind = dcss_drv_unbind, +}; + +static int compare_of(struct device *dev, void *data) +{ + return dev->of_node == data; +} + +static int dcss_drv_platform_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct component_match *match = NULL; + struct device_node *remote; + + if (!dev->of_node) + return -ENODEV; + + remote = of_graph_get_remote_node(dev->of_node, 0, 0); + if (!remote) + return -ENODEV; + + if (of_device_is_compatible(remote, "fsl,imx8mq-nwl-dsi")) { + of_node_put(remote); + return dcss_drv_init(dev, false); + } + + drm_of_component_match_add(dev, &match, compare_of, remote); + of_node_put(remote); + + return component_master_add_with_match(dev, &dcss_master_ops, match); +} + +static int dcss_drv_platform_remove(struct platform_device *pdev) +{ + struct dcss_drv *mdrv = dev_get_drvdata(&pdev->dev); + + if (mdrv->is_componentized) + component_master_del(&pdev->dev, &dcss_master_ops); + else + dcss_drv_deinit(&pdev->dev, false); return 0; } diff --git a/drivers/gpu/drm/imx/dcss/dcss-kms.c b/drivers/gpu/drm/imx/dcss/dcss-kms.c index 3ca49d0a3e61..bb009f3a878f 100644 --- a/drivers/gpu/drm/imx/dcss/dcss-kms.c +++ b/drivers/gpu/drm/imx/dcss/dcss-kms.c @@ -12,6 +12,7 @@ #include <drm/drm_of.h> #include <drm/drm_probe_helper.h> #include <drm/drm_vblank.h> +#include <linux/component.h> #include "dcss-dev.h" #include "dcss-kms.h" @@ -106,7 +107,7 @@ static int dcss_kms_setup_encoder(struct dcss_kms_dev *kms) return drm_bridge_attach(encoder, bridge, NULL, 0); } -struct dcss_kms_dev *dcss_kms_attach(struct dcss_dev *dcss) +struct dcss_kms_dev *dcss_kms_attach(struct dcss_dev *dcss, bool componentized) { struct dcss_kms_dev *kms; struct drm_device *drm; @@ -135,7 +136,11 @@ struct dcss_kms_dev *dcss_kms_attach(struct dcss_dev *dcss) if (ret) goto cleanup_mode_config; - ret = dcss_kms_setup_encoder(kms); + if (componentized) + ret = component_bind_all(dcss->dev, kms); + else + ret = dcss_kms_setup_encoder(kms); + if (ret) goto cleanup_crtc; @@ -162,9 +167,10 @@ struct dcss_kms_dev *dcss_kms_attach(struct dcss_dev *dcss) return ERR_PTR(ret); } -void dcss_kms_detach(struct dcss_kms_dev *kms) +void dcss_kms_detach(struct dcss_kms_dev *kms, bool componentized) { struct drm_device *drm = &kms->base; + struct dcss_dev *dcss = drm->dev_private; drm_dev_unregister(drm); drm_kms_helper_poll_fini(drm); @@ -173,5 +179,7 @@ void dcss_kms_detach(struct dcss_kms_dev *kms) drm->irq_enabled = false; drm_mode_config_cleanup(drm); dcss_crtc_deinit(&kms->crtc, drm); + if (componentized) + component_unbind_all(dcss->dev, drm); drm->dev_private = NULL; } diff --git a/drivers/gpu/drm/imx/dcss/dcss-kms.h b/drivers/gpu/drm/imx/dcss/dcss-kms.h index 1f51c86c6986..9b3bc7be9e84 100644 --- a/drivers/gpu/drm/imx/dcss/dcss-kms.h +++ b/drivers/gpu/drm/imx/dcss/dcss-kms.h @@ -31,8 +31,8 @@ struct dcss_kms_dev { struct drm_encoder encoder; }; -struct dcss_kms_dev *dcss_kms_attach(struct dcss_dev *dcss); -void dcss_kms_detach(struct dcss_kms_dev *kms); +struct dcss_kms_dev *dcss_kms_attach(struct dcss_dev *dcss, bool componentized); +void dcss_kms_detach(struct dcss_kms_dev *kms, bool componentized); int dcss_crtc_init(struct dcss_crtc *crtc, struct drm_device *drm); void dcss_crtc_deinit(struct dcss_crtc *crtc, struct drm_device *drm); struct dcss_plane *dcss_plane_init(struct drm_device *drm, -- 2.23.0 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel