[PATCH] drm/exynos: separate dpi from fimd
Inki Dae
inki.dae at samsung.com
Thu Apr 3 09:29:25 PDT 2014
Hi Andrzej,
2014-04-03 23:26 GMT+09:00 Andrzej Hajda <a.hajda at samsung.com>:
> The patch separates dpi related routines from fimd.
>
> Signed-off-by: Andrzej Hajda <a.hajda at samsung.com>
> ---
> Hi Inki,
>
> This is my attempt to separate DPI from FIMD,
Ah, I understood now. Right, if we can separate DPI from FIMD, we can
also move some codes for getting resources from fimd_bind to
fimd_probe.
Picked it up.
Thanks,
Inki Dae
> it requires putting real probe back into fimd_probe, but I
> guess it should not be a problem, as it is done already for dsi.
> It is based on v4 of your patch.
>
> The patch was written quickly without proper review, I can
> do it tomorrow if you are interested.
> If it is OK for you, please merge it with your patch.
> Anyway, I have made few tests - it works.
>
> Regards
> Andrzej
> ---
> drivers/gpu/drm/exynos/exynos_drm_dpi.c | 40 ++++++------
> drivers/gpu/drm/exynos/exynos_drm_drv.h | 15 ++---
> drivers/gpu/drm/exynos/exynos_drm_fimd.c | 109 +++++++++++++------------------
> 3 files changed, 69 insertions(+), 95 deletions(-)
>
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_dpi.c b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
> index ac206e7..03cb126 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_dpi.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_dpi.c
> @@ -40,20 +40,10 @@ exynos_dpi_detect(struct drm_connector *connector, bool force)
> {
> struct exynos_dpi *ctx = connector_to_dpi(connector);
>
> - /* panels supported only by boot-loader are always connected */
> - if (!ctx->panel_node)
> - return connector_status_connected;
> -
> - if (!ctx->panel) {
> - ctx->panel = of_drm_find_panel(ctx->panel_node);
> - if (ctx->panel)
> - drm_panel_attach(ctx->panel, &ctx->connector);
> - }
> + if (!ctx->panel->connector)
> + drm_panel_attach(ctx->panel, &ctx->connector);
>
> - if (ctx->panel)
> - return connector_status_connected;
> -
> - return connector_status_disconnected;
> + return connector_status_connected;
> }
>
> static void exynos_dpi_connector_destroy(struct drm_connector *connector)
> @@ -291,8 +281,10 @@ static int exynos_dpi_parse_dt(struct exynos_dpi *ctx)
> return -ENOMEM;
>
> ret = of_get_videomode(dn, vm, 0);
> - if (ret < 0)
> + if (ret < 0) {
> + devm_kfree(dev, vm);
> return ret;
> + }
>
> ctx->vm = vm;
>
> @@ -305,27 +297,35 @@ static int exynos_dpi_parse_dt(struct exynos_dpi *ctx)
> return 0;
> }
>
> -int exynos_dpi_probe(struct drm_device *drm_dev, struct device *dev)
> +struct exynos_drm_display *exynos_dpi_probe(struct device *dev)
> {
> struct exynos_dpi *ctx;
> int ret;
>
> ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
> if (!ctx)
> - return -ENOMEM;
> + return NULL;
>
> ctx->dev = dev;
> exynos_dpi_display.ctx = ctx;
> ctx->dpms_mode = DRM_MODE_DPMS_OFF;
>
> ret = exynos_dpi_parse_dt(ctx);
> - if (ret < 0)
> - return ret;
> + if (ret < 0) {
> + devm_kfree(dev, ctx);
> + return NULL;
> + }
> +
> + if (ctx->panel_node) {
> + ctx->panel = of_drm_find_panel(ctx->panel_node);
> + if (!ctx->panel)
> + return ERR_PTR(-EPROBE_DEFER);
> + }
>
> - return exynos_drm_create_enc_conn(drm_dev, &exynos_dpi_display);
> + return &exynos_dpi_display;
> }
>
> -int exynos_dpi_remove(struct drm_device *drm_dev, struct device *dev)
> +int exynos_dpi_remove(struct device *dev)
> {
> struct drm_encoder *encoder = exynos_dpi_display.encoder;
> struct exynos_dpi *ctx = exynos_dpi_display.ctx;
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
> index 2b87eb7..583a0bd 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
> +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
> @@ -334,17 +334,12 @@ int exynos_platform_device_ipp_register(void);
> void exynos_platform_device_ipp_unregister(void);
>
> #ifdef CONFIG_DRM_EXYNOS_DPI
> -int exynos_dpi_probe(struct drm_device *drm_dev, struct device *dev);
> -int exynos_dpi_remove(struct drm_device *drm_dev, struct device *dev);
> -struct device_node *exynos_dpi_of_find_panel_node(struct device *dev);
> +struct exynos_drm_display * exynos_dpi_probe(struct device *dev);
> +int exynos_dpi_remove(struct device *dev);
> #else
> -static inline int exynos_dpi_probe(struct drm_device *drm_dev,
> - struct device *dev) { return 0; }
> -static inline int exynos_dpi_remove(struct drm_device *drm_dev,
> - struct device *dev) { return 0; }
> -static inline struct device_node
> - *exynos_dpi_of_find_panel_node(struct device *dev)
> -{ return NULL; }
> +static inline struct exynos_drm_display *
> +exynos_dpi_probe(struct device *dev) { return 0; }
> +static inline int exynos_dpi_remove(struct device *dev) { return 0; }
> #endif
>
> /*
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
> index 76282b3..11cce7b 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
> @@ -24,7 +24,6 @@
> #include <video/of_display_timing.h>
> #include <video/of_videomode.h>
> #include <video/samsung_fimd.h>
> -#include <drm/drm_panel.h>
> #include <drm/exynos_drm.h>
>
> #include "exynos_drm_drv.h"
> @@ -124,6 +123,7 @@ struct fimd_context {
>
> struct exynos_drm_panel_info panel;
> struct fimd_driver_data *driver_data;
> + struct exynos_drm_display *dpi;
> };
>
> static const struct of_device_id fimd_driver_dt_match[] = {
> @@ -853,12 +853,49 @@ out:
>
> static int fimd_bind(struct device *dev, struct device *master, void *data)
> {
> - struct platform_device *pdev = to_platform_device(dev);
> + struct fimd_context *ctx = fimd_manager.ctx;
> struct drm_device *drm_dev = data;
> + int win;
> +
> + fimd_mgr_initialize(&fimd_manager, drm_dev);
> + exynos_drm_crtc_create(&fimd_manager);
> + if (ctx->dpi)
> + exynos_drm_create_enc_conn(drm_dev, ctx->dpi);
> +
> + for (win = 0; win < WINDOWS_NR; win++)
> + fimd_clear_win(ctx, win);
> +
> + return 0;
> +
> +}
> +
> +static void fimd_unbind(struct device *dev, struct device *master,
> + void *data)
> +{
> + struct exynos_drm_manager *mgr = dev_get_drvdata(dev);
> + struct fimd_context *ctx = fimd_manager.ctx;
> + struct drm_crtc *crtc = mgr->crtc;
> +
> + fimd_dpms(mgr, DRM_MODE_DPMS_OFF);
> +
> + if (ctx->dpi)
> + exynos_dpi_remove(dev);
> +
> + fimd_mgr_remove(mgr);
> +
> + crtc->funcs->destroy(crtc);
> +}
> +
> +static const struct component_ops fimd_component_ops = {
> + .bind = fimd_bind,
> + .unbind = fimd_unbind,
> +};
> +
> +static int fimd_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> struct fimd_context *ctx;
> - struct device_node *dn;
> struct resource *res;
> - int win;
> int ret = -EINVAL;
>
> if (!dev->of_node)
> @@ -914,68 +951,10 @@ static int fimd_bind(struct device *dev, struct device *master, void *data)
> platform_set_drvdata(pdev, &fimd_manager);
>
> fimd_manager.ctx = ctx;
> - fimd_mgr_initialize(&fimd_manager, drm_dev);
> -
> - exynos_drm_crtc_create(&fimd_manager);
> -
> - dn = exynos_dpi_of_find_panel_node(&pdev->dev);
> - if (dn) {
> - /*
> - * It should be called after exynos_drm_crtc_create call
> - * because exynos_dpi_probe call will try to find same lcd
> - * type of manager to setup possible_crtcs.
> - */
> - exynos_dpi_probe(drm_dev, dev);
> - }
> -
> - for (win = 0; win < WINDOWS_NR; win++)
> - fimd_clear_win(ctx, win);
> -
> - return 0;
> -}
> -
> -static void fimd_unbind(struct device *dev, struct device *master,
> - void *data)
> -{
> - struct exynos_drm_manager *mgr = dev_get_drvdata(dev);
> - struct drm_crtc *crtc = mgr->crtc;
> - struct device_node *dn;
>
> - fimd_dpms(mgr, DRM_MODE_DPMS_OFF);
> -
> - dn = exynos_dpi_of_find_panel_node(dev);
> - if (dn)
> - exynos_dpi_remove(mgr->drm_dev, dev);
> -
> - fimd_mgr_remove(mgr);
> -
> - crtc->funcs->destroy(crtc);
> -}
> -
> -static const struct component_ops fimd_component_ops = {
> - .bind = fimd_bind,
> - .unbind = fimd_unbind,
> -};
> -
> -static int fimd_probe(struct platform_device *pdev)
> -{
> - struct device_node *dn;
> -
> - /* Check if fimd node has port node. */
> - dn = exynos_dpi_of_find_panel_node(&pdev->dev);
> - if (dn) {
> - struct drm_panel *panel;
> -
> - /*
> - * Do not bind if there is the port node but a drm_panel
> - * isn't added to panel_list yet.
> - * In this case, fimd_probe will be called by defered probe
> - * again after the drm_panel is added to panel_list.
> - */
> - panel = of_drm_find_panel(dn);
> - if (!panel)
> - return -EPROBE_DEFER;
> - }
> + ctx->dpi = exynos_dpi_probe(dev);
> + if (IS_ERR(ctx->dpi))
> + return PTR_ERR(ctx->dpi);
>
> pm_runtime_enable(&pdev->dev);
>
> --
> 1.8.3.2
>
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
More information about the dri-devel
mailing list