Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 000cc920 authored by Andrzej Hajda's avatar Andrzej Hajda Committed by Inki Dae
Browse files

drm/exynos: separate dpi from fimd



The patch separates dpi related routines from fimd.

Changelog v2:
- Rename ctx->dpi to ctx->display

Signed-off-by: default avatarAndrzej Hajda <a.hajda@samsung.com>
Signed-off-by: default avatarInki Dae <inki.dae@samsung.com>
parent d1afe7d4
Loading
Loading
Loading
Loading
+20 −20
Original line number Diff line number Diff line
@@ -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)
	if (!ctx->panel->connector)
		drm_panel_attach(ctx->panel, &ctx->connector);
	}

	if (ctx->panel)
	return connector_status_connected;

	return connector_status_disconnected;
}

static void exynos_dpi_connector_destroy(struct drm_connector *connector)
@@ -284,8 +274,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;

@@ -298,27 +290,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;
+5 −10
Original line number Diff line number Diff line
@@ -332,17 +332,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

/*
+44 −65
Original line number Diff line number Diff line
@@ -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 *display;
};

static const struct of_device_id fimd_driver_dt_match[] = {
@@ -882,12 +882,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->display)
		exynos_drm_create_enc_conn(drm_dev, ctx->display);

	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->display)
		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)
@@ -943,68 +980,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->display = exynos_dpi_probe(dev);
	if (IS_ERR(ctx->display))
		return PTR_ERR(ctx->display);

	pm_runtime_enable(&pdev->dev);