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

Commit 93bca243 authored by Gustavo Padovan's avatar Gustavo Padovan Committed by Inki Dae
Browse files

drm/exynos: remove struct exynos_drm_manager



exynos_drm_manager was just a redundant struct to represent the crtc as
well. In this commit we merge exynos_drm_manager into exynos_drm_crtc to
remove an unnecessary level of indirection easing the understand of the
flow on exynos.

Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
Signed-off-by: default avatarInki Dae <inki.dae@samsung.com>
parent eb88e422
Loading
Loading
Loading
Loading
+32 −35
Original line number Diff line number Diff line
@@ -23,7 +23,6 @@
static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
{
	struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
	struct exynos_drm_manager *manager = exynos_crtc->manager;

	DRM_DEBUG_KMS("crtc[%d] mode[%d]\n", crtc->base.id, mode);

@@ -41,8 +40,8 @@ static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
		drm_crtc_vblank_off(crtc);
	}

	if (manager->ops->dpms)
		manager->ops->dpms(manager, mode);
	if (exynos_crtc->ops->dpms)
		exynos_crtc->ops->dpms(exynos_crtc, mode);

	exynos_crtc->dpms = mode;

@@ -58,16 +57,15 @@ static void exynos_drm_crtc_prepare(struct drm_crtc *crtc)
static void exynos_drm_crtc_commit(struct drm_crtc *crtc)
{
	struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
	struct exynos_drm_manager *manager = exynos_crtc->manager;
	struct exynos_drm_plane *exynos_plane = to_exynos_plane(crtc->primary);

	exynos_drm_crtc_dpms(crtc, DRM_MODE_DPMS_ON);

	if (manager->ops->win_commit)
		manager->ops->win_commit(manager, exynos_plane->zpos);
	if (exynos_crtc->ops->win_commit)
		exynos_crtc->ops->win_commit(exynos_crtc, exynos_plane->zpos);

	if (manager->ops->commit)
		manager->ops->commit(manager);
	if (exynos_crtc->ops->commit)
		exynos_crtc->ops->commit(exynos_crtc);

	exynos_plane_dpms(crtc->primary, DRM_MODE_DPMS_ON);
}
@@ -78,10 +76,10 @@ exynos_drm_crtc_mode_fixup(struct drm_crtc *crtc,
			    struct drm_display_mode *adjusted_mode)
{
	struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
	struct exynos_drm_manager *manager = exynos_crtc->manager;

	if (manager->ops->mode_fixup)
		return manager->ops->mode_fixup(manager, mode, adjusted_mode);
	if (exynos_crtc->ops->mode_fixup)
		return exynos_crtc->ops->mode_fixup(exynos_crtc, mode,
						    adjusted_mode);

	return true;
}
@@ -92,7 +90,6 @@ exynos_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
			  struct drm_framebuffer *old_fb)
{
	struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
	struct exynos_drm_manager *manager = exynos_crtc->manager;
	struct drm_framebuffer *fb = crtc->primary->fb;
	unsigned int crtc_w;
	unsigned int crtc_h;
@@ -106,8 +103,8 @@ exynos_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
	crtc_w = fb->width - x;
	crtc_h = fb->height - y;

	if (manager->ops->mode_set)
		manager->ops->mode_set(manager, &crtc->mode);
	if (exynos_crtc->ops->mode_set)
		exynos_crtc->ops->mode_set(exynos_crtc, &crtc->mode);

	return exynos_plane_mode_set(crtc->primary, crtc, fb, 0, 0,
				     crtc_w, crtc_h, x, y, crtc_w, crtc_h);
@@ -299,9 +296,11 @@ static void exynos_drm_crtc_attach_mode_property(struct drm_crtc *crtc)
	drm_object_attach_property(&crtc->base, prop, 0);
}

int exynos_drm_crtc_create(struct exynos_drm_manager *manager,
			   struct drm_device *drm_dev, int pipe,
			   enum exynos_drm_output_type type)
struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev,
					       int pipe,
					       enum exynos_drm_output_type type,
					       struct exynos_drm_crtc_ops *ops,
					       void *ctx)
{
	struct exynos_drm_crtc *exynos_crtc;
	struct drm_plane *plane;
@@ -311,15 +310,16 @@ int exynos_drm_crtc_create(struct exynos_drm_manager *manager,

	exynos_crtc = kzalloc(sizeof(*exynos_crtc), GFP_KERNEL);
	if (!exynos_crtc)
		return -ENOMEM;
		return ERR_PTR(-ENOMEM);

	init_waitqueue_head(&exynos_crtc->pending_flip_queue);
	atomic_set(&exynos_crtc->pending_flip, 0);

	exynos_crtc->dpms = DRM_MODE_DPMS_OFF;
	exynos_crtc->manager = manager;
	exynos_crtc->pipe = pipe;
	exynos_crtc->type = type;
	exynos_crtc->ops = ops;
	exynos_crtc->ctx = ctx;
	plane = exynos_plane_init(drm_dev, 1 << pipe,
				  DRM_PLANE_TYPE_PRIMARY);
	if (IS_ERR(plane)) {
@@ -327,7 +327,6 @@ int exynos_drm_crtc_create(struct exynos_drm_manager *manager,
		goto err_plane;
	}

	manager->crtc = &exynos_crtc->base;
	crtc = &exynos_crtc->base;

	private->crtc[pipe] = crtc;
@@ -341,13 +340,13 @@ int exynos_drm_crtc_create(struct exynos_drm_manager *manager,

	exynos_drm_crtc_attach_mode_property(crtc);

	return 0;
	return exynos_crtc;

err_crtc:
	plane->funcs->destroy(plane);
err_plane:
	kfree(exynos_crtc);
	return ret;
	return ERR_PTR(ret);
}

int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int pipe)
@@ -355,13 +354,12 @@ int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int pipe)
	struct exynos_drm_private *private = dev->dev_private;
	struct exynos_drm_crtc *exynos_crtc =
		to_exynos_crtc(private->crtc[pipe]);
	struct exynos_drm_manager *manager = exynos_crtc->manager;

	if (exynos_crtc->dpms != DRM_MODE_DPMS_ON)
		return -EPERM;

	if (manager->ops->enable_vblank)
		manager->ops->enable_vblank(manager);
	if (exynos_crtc->ops->enable_vblank)
		exynos_crtc->ops->enable_vblank(exynos_crtc);

	return 0;
}
@@ -371,13 +369,12 @@ void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int pipe)
	struct exynos_drm_private *private = dev->dev_private;
	struct exynos_drm_crtc *exynos_crtc =
		to_exynos_crtc(private->crtc[pipe]);
	struct exynos_drm_manager *manager = exynos_crtc->manager;

	if (exynos_crtc->dpms != DRM_MODE_DPMS_ON)
		return;

	if (manager->ops->disable_vblank)
		manager->ops->disable_vblank(manager);
	if (exynos_crtc->ops->disable_vblank)
		exynos_crtc->ops->disable_vblank(exynos_crtc);
}

void exynos_drm_crtc_finish_pageflip(struct drm_device *dev, int pipe)
@@ -408,7 +405,7 @@ void exynos_drm_crtc_finish_pageflip(struct drm_device *dev, int pipe)

void exynos_drm_crtc_complete_scanout(struct drm_framebuffer *fb)
{
	struct exynos_drm_manager *manager;
	struct exynos_drm_crtc *exynos_crtc;
	struct drm_device *dev = fb->dev;
	struct drm_crtc *crtc;

@@ -417,15 +414,15 @@ void exynos_drm_crtc_complete_scanout(struct drm_framebuffer *fb)
	 * for all encoders.
	 */
	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
		manager = to_exynos_crtc(crtc)->manager;
		exynos_crtc = to_exynos_crtc(crtc);

		/*
		 * wait for vblank interrupt
		 * - this makes sure that overlay data are updated to
		 *	real hardware.
		 */
		if (manager->ops->wait_for_vblank)
			manager->ops->wait_for_vblank(manager);
		if (exynos_crtc->ops->wait_for_vblank)
			exynos_crtc->ops->wait_for_vblank(exynos_crtc);
	}
}

@@ -447,8 +444,8 @@ int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev,

void exynos_drm_crtc_te_handler(struct drm_crtc *crtc)
{
	struct exynos_drm_manager *manager = to_exynos_crtc(crtc)->manager;
	struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);

	if (manager->ops->te_handler)
		manager->ops->te_handler(manager);
	if (exynos_crtc->ops->te_handler)
		exynos_crtc->ops->te_handler(exynos_crtc);
}
+5 −3
Original line number Diff line number Diff line
@@ -17,9 +17,11 @@

#include "exynos_drm_drv.h"

int exynos_drm_crtc_create(struct exynos_drm_manager *manager,
			   struct drm_device *drm_dev, int pipe,
			   enum exynos_drm_output_type type);
struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev,
					       int pipe,
					       enum exynos_drm_output_type type,
					       struct exynos_drm_crtc_ops *ops,
					       void *context);
int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int pipe);
void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int pipe);
void exynos_drm_crtc_finish_pageflip(struct drm_device *dev, int pipe);
+19 −32
Original line number Diff line number Diff line
@@ -163,7 +163,7 @@ struct exynos_drm_display {
};

/*
 * Exynos drm manager ops
 * Exynos drm crtc ops
 *
 * @dpms: control device power.
 * @mode_fixup: fix mode data before applying it
@@ -180,39 +180,24 @@ struct exynos_drm_display {
 * @te_handler: trigger to transfer video image at the tearing effect
 *	synchronization signal if there is a page flip request.
 */
struct exynos_drm_manager;
struct exynos_drm_manager_ops {
	void (*dpms)(struct exynos_drm_manager *mgr, int mode);
	bool (*mode_fixup)(struct exynos_drm_manager *mgr,
struct exynos_drm_crtc;
struct exynos_drm_crtc_ops {
	void (*dpms)(struct exynos_drm_crtc *crtc, int mode);
	bool (*mode_fixup)(struct exynos_drm_crtc *crtc,
				const struct drm_display_mode *mode,
				struct drm_display_mode *adjusted_mode);
	void (*mode_set)(struct exynos_drm_manager *mgr,
	void (*mode_set)(struct exynos_drm_crtc *crtc,
				const struct drm_display_mode *mode);
	void (*commit)(struct exynos_drm_manager *mgr);
	int (*enable_vblank)(struct exynos_drm_manager *mgr);
	void (*disable_vblank)(struct exynos_drm_manager *mgr);
	void (*wait_for_vblank)(struct exynos_drm_manager *mgr);
	void (*win_mode_set)(struct exynos_drm_manager *mgr,
	void (*commit)(struct exynos_drm_crtc *crtc);
	int (*enable_vblank)(struct exynos_drm_crtc *crtc);
	void (*disable_vblank)(struct exynos_drm_crtc *crtc);
	void (*wait_for_vblank)(struct exynos_drm_crtc *crtc);
	void (*win_mode_set)(struct exynos_drm_crtc *crtc,
				struct exynos_drm_plane *plane);
	void (*win_commit)(struct exynos_drm_manager *mgr, int zpos);
	void (*win_enable)(struct exynos_drm_manager *mgr, int zpos);
	void (*win_disable)(struct exynos_drm_manager *mgr, int zpos);
	void (*te_handler)(struct exynos_drm_manager *mgr);
};

/*
 * Exynos drm common manager structure, maps 1:1 with a crtc
 *
 * @list: the list entry for this manager
 * @drm_dev: pointer to the drm device
 * @crtc: crtc object.
 * @ops: pointer to callbacks for exynos drm specific functionality
 * @ctx: A pointer to the manager's implementation specific context
 */
struct exynos_drm_manager {
	struct list_head list;
	struct drm_crtc *crtc;
	struct exynos_drm_manager_ops *ops;
	void (*win_commit)(struct exynos_drm_crtc *crtc, int zpos);
	void (*win_enable)(struct exynos_drm_crtc *crtc, int zpos);
	void (*win_disable)(struct exynos_drm_crtc *crtc, int zpos);
	void (*te_handler)(struct exynos_drm_crtc *crtc);
};

enum exynos_crtc_mode {
@@ -224,7 +209,6 @@ enum exynos_crtc_mode {
 * Exynos specific crtc structure.
 *
 * @base: crtc object.
 * @manager: the manager associated with this crtc
 * @type: one of EXYNOS_DISPLAY_TYPE_LCD and HDMI.
 * @pipe: a crtc index created at load() with a new crtc object creation
 *	and the crtc object would be set to private->crtc array
@@ -235,16 +219,19 @@ enum exynos_crtc_mode {
 *	this pipe value.
 * @dpms: store the crtc dpms value
 * @mode: store the crtc mode value
 * @ops: pointer to callbacks for exynos drm specific functionality
 * @ctx: A pointer to the crtc's implementation specific context
 */
struct exynos_drm_crtc {
	struct drm_crtc			base;
	struct exynos_drm_manager	*manager;
	enum exynos_drm_output_type	type;
	unsigned int			pipe;
	unsigned int			dpms;
	enum exynos_crtc_mode		mode;
	wait_queue_head_t		pending_flip_queue;
	atomic_t			pending_flip;
	struct exynos_drm_crtc_ops	*ops;
	void				*ctx;
};

struct exynos_drm_g2d_private {
+58 −63
Original line number Diff line number Diff line
@@ -157,9 +157,9 @@ struct fimd_win_data {
};

struct fimd_context {
	struct exynos_drm_manager	manager;
	struct device			*dev;
	struct drm_device		*drm_dev;
	struct exynos_drm_crtc		*crtc;
	struct clk			*bus_clk;
	struct clk			*lcd_clk;
	void __iomem			*regs;
@@ -185,11 +185,6 @@ struct fimd_context {
	struct exynos_drm_display *display;
};

static inline struct fimd_context *mgr_to_fimd(struct exynos_drm_manager *mgr)
{
	return container_of(mgr, struct fimd_context, manager);
}

static const struct of_device_id fimd_driver_dt_match[] = {
	{ .compatible = "samsung,s3c6400-fimd",
	  .data = &s3c64xx_fimd_driver_data },
@@ -214,9 +209,9 @@ static inline struct fimd_driver_data *drm_fimd_get_driver_data(
	return (struct fimd_driver_data *)of_id->data;
}

static void fimd_wait_for_vblank(struct exynos_drm_manager *mgr)
static void fimd_wait_for_vblank(struct exynos_drm_crtc *crtc)
{
	struct fimd_context *ctx = mgr_to_fimd(mgr);
	struct fimd_context *ctx = crtc->ctx;

	if (ctx->suspended)
		return;
@@ -259,9 +254,9 @@ static void fimd_enable_shadow_channel_path(struct fimd_context *ctx, int win,
	writel(val, ctx->regs + SHADOWCON);
}

static void fimd_clear_channel(struct exynos_drm_manager *mgr)
static void fimd_clear_channel(struct exynos_drm_crtc *crtc)
{
	struct fimd_context *ctx = mgr_to_fimd(mgr);
	struct fimd_context *ctx = crtc->ctx;
	int win, ch_enabled = 0;

	DRM_DEBUG_KMS("%s\n", __FILE__);
@@ -286,15 +281,14 @@ static void fimd_clear_channel(struct exynos_drm_manager *mgr)
		unsigned int state = ctx->suspended;

		ctx->suspended = 0;
		fimd_wait_for_vblank(mgr);
		fimd_wait_for_vblank(crtc);
		ctx->suspended = state;
	}
}

static int fimd_mgr_initialize(struct exynos_drm_manager *mgr,
static int fimd_ctx_initialize(struct fimd_context *ctx,
			struct drm_device *drm_dev)
{
	struct fimd_context *ctx = mgr_to_fimd(mgr);
	struct exynos_drm_private *priv;
	priv = drm_dev->dev_private;

@@ -307,17 +301,15 @@ static int fimd_mgr_initialize(struct exynos_drm_manager *mgr,
		 * If any channel is already active, iommu will throw
		 * a PAGE FAULT when enabled. So clear any channel if enabled.
		 */
		fimd_clear_channel(mgr);
		fimd_clear_channel(ctx->crtc);
		drm_iommu_attach_device(ctx->drm_dev, ctx->dev);
	}

	return 0;
}

static void fimd_mgr_remove(struct exynos_drm_manager *mgr)
static void fimd_ctx_remove(struct fimd_context *ctx)
{
	struct fimd_context *ctx = mgr_to_fimd(mgr);

	/* detach this sub driver from iommu mapping if supported. */
	if (is_drm_iommu_supported(ctx->drm_dev))
		drm_iommu_detach_device(ctx->drm_dev, ctx->dev);
@@ -343,7 +335,7 @@ static u32 fimd_calc_clkdiv(struct fimd_context *ctx,
	return (clkdiv < 0x100) ? clkdiv : 0xff;
}

static bool fimd_mode_fixup(struct exynos_drm_manager *mgr,
static bool fimd_mode_fixup(struct exynos_drm_crtc *crtc,
		const struct drm_display_mode *mode,
		struct drm_display_mode *adjusted_mode)
{
@@ -353,17 +345,17 @@ static bool fimd_mode_fixup(struct exynos_drm_manager *mgr,
	return true;
}

static void fimd_mode_set(struct exynos_drm_manager *mgr,
static void fimd_mode_set(struct exynos_drm_crtc *crtc,
		const struct drm_display_mode *in_mode)
{
	struct fimd_context *ctx = mgr_to_fimd(mgr);
	struct fimd_context *ctx = crtc->ctx;

	drm_mode_copy(&ctx->mode, in_mode);
}

static void fimd_commit(struct exynos_drm_manager *mgr)
static void fimd_commit(struct exynos_drm_crtc *crtc)
{
	struct fimd_context *ctx = mgr_to_fimd(mgr);
	struct fimd_context *ctx = crtc->ctx;
	struct drm_display_mode *mode = &ctx->mode;
	struct fimd_driver_data *driver_data = ctx->driver_data;
	void *timing_base = ctx->regs + driver_data->timing_base;
@@ -461,9 +453,9 @@ static void fimd_commit(struct exynos_drm_manager *mgr)
	writel(val, ctx->regs + VIDCON0);
}

static int fimd_enable_vblank(struct exynos_drm_manager *mgr)
static int fimd_enable_vblank(struct exynos_drm_crtc *crtc)
{
	struct fimd_context *ctx = mgr_to_fimd(mgr);
	struct fimd_context *ctx = crtc->ctx;
	u32 val;

	if (ctx->suspended)
@@ -493,9 +485,9 @@ static int fimd_enable_vblank(struct exynos_drm_manager *mgr)
	return 0;
}

static void fimd_disable_vblank(struct exynos_drm_manager *mgr)
static void fimd_disable_vblank(struct exynos_drm_crtc *crtc)
{
	struct fimd_context *ctx = mgr_to_fimd(mgr);
	struct fimd_context *ctx = crtc->ctx;
	u32 val;

	if (ctx->suspended)
@@ -517,10 +509,10 @@ static void fimd_disable_vblank(struct exynos_drm_manager *mgr)
	}
}

static void fimd_win_mode_set(struct exynos_drm_manager *mgr,
static void fimd_win_mode_set(struct exynos_drm_crtc *crtc,
			struct exynos_drm_plane *plane)
{
	struct fimd_context *ctx = mgr_to_fimd(mgr);
	struct fimd_context *ctx = crtc->ctx;
	struct fimd_win_data *win_data;
	int win;
	unsigned long offset;
@@ -676,9 +668,9 @@ static void fimd_shadow_protect_win(struct fimd_context *ctx,
	writel(val, ctx->regs + reg);
}

static void fimd_win_commit(struct exynos_drm_manager *mgr, int zpos)
static void fimd_win_commit(struct exynos_drm_crtc *crtc, int zpos)
{
	struct fimd_context *ctx = mgr_to_fimd(mgr);
	struct fimd_context *ctx = crtc->ctx;
	struct fimd_win_data *win_data;
	int win = zpos;
	unsigned long val, alpha, size;
@@ -799,9 +791,9 @@ static void fimd_win_commit(struct exynos_drm_manager *mgr, int zpos)
		atomic_set(&ctx->win_updated, 1);
}

static void fimd_win_disable(struct exynos_drm_manager *mgr, int zpos)
static void fimd_win_disable(struct exynos_drm_crtc *crtc, int zpos)
{
	struct fimd_context *ctx = mgr_to_fimd(mgr);
	struct fimd_context *ctx = crtc->ctx;
	struct fimd_win_data *win_data;
	int win = zpos;

@@ -833,9 +825,9 @@ static void fimd_win_disable(struct exynos_drm_manager *mgr, int zpos)
	win_data->enabled = false;
}

static void fimd_window_suspend(struct exynos_drm_manager *mgr)
static void fimd_window_suspend(struct exynos_drm_crtc *crtc)
{
	struct fimd_context *ctx = mgr_to_fimd(mgr);
	struct fimd_context *ctx = crtc->ctx;
	struct fimd_win_data *win_data;
	int i;

@@ -843,13 +835,13 @@ static void fimd_window_suspend(struct exynos_drm_manager *mgr)
		win_data = &ctx->win_data[i];
		win_data->resume = win_data->enabled;
		if (win_data->enabled)
			fimd_win_disable(mgr, i);
			fimd_win_disable(crtc, i);
	}
}

static void fimd_window_resume(struct exynos_drm_manager *mgr)
static void fimd_window_resume(struct exynos_drm_crtc *crtc)
{
	struct fimd_context *ctx = mgr_to_fimd(mgr);
	struct fimd_context *ctx = crtc->ctx;
	struct fimd_win_data *win_data;
	int i;

@@ -860,26 +852,26 @@ static void fimd_window_resume(struct exynos_drm_manager *mgr)
	}
}

static void fimd_apply(struct exynos_drm_manager *mgr)
static void fimd_apply(struct exynos_drm_crtc *crtc)
{
	struct fimd_context *ctx = mgr_to_fimd(mgr);
	struct fimd_context *ctx = crtc->ctx;
	struct fimd_win_data *win_data;
	int i;

	for (i = 0; i < WINDOWS_NR; i++) {
		win_data = &ctx->win_data[i];
		if (win_data->enabled)
			fimd_win_commit(mgr, i);
			fimd_win_commit(crtc, i);
		else
			fimd_win_disable(mgr, i);
			fimd_win_disable(crtc, i);
	}

	fimd_commit(mgr);
	fimd_commit(crtc);
}

static int fimd_poweron(struct exynos_drm_manager *mgr)
static int fimd_poweron(struct exynos_drm_crtc *crtc)
{
	struct fimd_context *ctx = mgr_to_fimd(mgr);
	struct fimd_context *ctx = crtc->ctx;
	int ret;

	if (!ctx->suspended)
@@ -903,16 +895,16 @@ static int fimd_poweron(struct exynos_drm_manager *mgr)

	/* if vblank was enabled status, enable it again. */
	if (test_and_clear_bit(0, &ctx->irq_flags)) {
		ret = fimd_enable_vblank(mgr);
		ret = fimd_enable_vblank(crtc);
		if (ret) {
			DRM_ERROR("Failed to re-enable vblank [%d]\n", ret);
			goto enable_vblank_err;
		}
	}

	fimd_window_resume(mgr);
	fimd_window_resume(crtc);

	fimd_apply(mgr);
	fimd_apply(crtc);

	return 0;

@@ -925,9 +917,9 @@ static int fimd_poweron(struct exynos_drm_manager *mgr)
	return ret;
}

static int fimd_poweroff(struct exynos_drm_manager *mgr)
static int fimd_poweroff(struct exynos_drm_crtc *crtc)
{
	struct fimd_context *ctx = mgr_to_fimd(mgr);
	struct fimd_context *ctx = crtc->ctx;

	if (ctx->suspended)
		return 0;
@@ -937,7 +929,7 @@ static int fimd_poweroff(struct exynos_drm_manager *mgr)
	 * suspend that connector. Otherwise we might try to scan from
	 * a destroyed buffer later.
	 */
	fimd_window_suspend(mgr);
	fimd_window_suspend(crtc);

	clk_disable_unprepare(ctx->lcd_clk);
	clk_disable_unprepare(ctx->bus_clk);
@@ -948,18 +940,18 @@ static int fimd_poweroff(struct exynos_drm_manager *mgr)
	return 0;
}

static void fimd_dpms(struct exynos_drm_manager *mgr, int mode)
static void fimd_dpms(struct exynos_drm_crtc *crtc, int mode)
{
	DRM_DEBUG_KMS("%s, %d\n", __FILE__, mode);

	switch (mode) {
	case DRM_MODE_DPMS_ON:
		fimd_poweron(mgr);
		fimd_poweron(crtc);
		break;
	case DRM_MODE_DPMS_STANDBY:
	case DRM_MODE_DPMS_SUSPEND:
	case DRM_MODE_DPMS_OFF:
		fimd_poweroff(mgr);
		fimd_poweroff(crtc);
		break;
	default:
		DRM_DEBUG_KMS("unspecified mode %d\n", mode);
@@ -996,9 +988,9 @@ static void fimd_trigger(struct device *dev)
		atomic_set(&ctx->triggering, 0);
}

static void fimd_te_handler(struct exynos_drm_manager *mgr)
static void fimd_te_handler(struct exynos_drm_crtc *crtc)
{
	struct fimd_context *ctx = mgr_to_fimd(mgr);
	struct fimd_context *ctx = crtc->ctx;

	/* Checks the crtc is detached already from encoder */
	if (ctx->pipe < 0 || !ctx->drm_dev)
@@ -1021,7 +1013,7 @@ static void fimd_te_handler(struct exynos_drm_manager *mgr)
		drm_handle_vblank(ctx->drm_dev, ctx->pipe);
}

static struct exynos_drm_manager_ops fimd_manager_ops = {
static struct exynos_drm_crtc_ops fimd_crtc_ops = {
	.dpms = fimd_dpms,
	.mode_fixup = fimd_mode_fixup,
	.mode_set = fimd_mode_set,
@@ -1075,9 +1067,14 @@ static int fimd_bind(struct device *dev, struct device *master, void *data)
	struct fimd_context *ctx = dev_get_drvdata(dev);
	struct drm_device *drm_dev = data;

	fimd_mgr_initialize(&ctx->manager, drm_dev);
	exynos_drm_crtc_create(&ctx->manager, drm_dev, ctx->pipe,
			       EXYNOS_DISPLAY_TYPE_LCD);
	ctx->crtc = exynos_drm_crtc_create(drm_dev, ctx->pipe,
					   EXYNOS_DISPLAY_TYPE_LCD,
					   &fimd_crtc_ops, ctx);
	if (IS_ERR(ctx->crtc))
		return PTR_ERR(ctx->crtc);

	fimd_ctx_initialize(ctx, drm_dev);

	if (ctx->display)
		exynos_drm_create_enc_conn(drm_dev, ctx->display);

@@ -1090,12 +1087,12 @@ static void fimd_unbind(struct device *dev, struct device *master,
{
	struct fimd_context *ctx = dev_get_drvdata(dev);

	fimd_dpms(&ctx->manager, DRM_MODE_DPMS_OFF);
	fimd_dpms(ctx->crtc, DRM_MODE_DPMS_OFF);

	if (ctx->display)
		exynos_dpi_remove(ctx->display);

	fimd_mgr_remove(&ctx->manager);
	fimd_ctx_remove(ctx);
}

static const struct component_ops fimd_component_ops = {
@@ -1118,8 +1115,6 @@ static int fimd_probe(struct platform_device *pdev)
	if (!ctx)
		return -ENOMEM;

	ctx->manager.ops = &fimd_manager_ops;

	ret = exynos_drm_component_add(dev, EXYNOS_DEVICE_TYPE_CRTC,
				       EXYNOS_DISPLAY_TYPE_LCD);
	if (ret)
+13 −13
Original line number Diff line number Diff line
@@ -68,7 +68,7 @@ int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,
			  uint32_t src_w, uint32_t src_h)
{
	struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
	struct exynos_drm_manager *manager = to_exynos_crtc(crtc)->manager;
	struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
	unsigned int actual_w;
	unsigned int actual_h;
	int nr;
@@ -133,8 +133,8 @@ int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,

	plane->crtc = crtc;

	if (manager->ops->win_mode_set)
		manager->ops->win_mode_set(manager, exynos_plane);
	if (exynos_crtc->ops->win_mode_set)
		exynos_crtc->ops->win_mode_set(exynos_crtc, exynos_plane);

	return 0;
}
@@ -142,24 +142,24 @@ int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,
void exynos_plane_dpms(struct drm_plane *plane, int mode)
{
	struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
	struct exynos_drm_manager *manager;
	struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(plane->crtc);

	if (mode == DRM_MODE_DPMS_ON) {
		if (exynos_plane->enabled)
			return;

		manager = to_exynos_crtc(plane->crtc)->manager;
		if (manager->ops->win_enable)
			manager->ops->win_enable(manager, exynos_plane->zpos);
		if (exynos_crtc->ops->win_enable)
			exynos_crtc->ops->win_enable(exynos_crtc,
						     exynos_plane->zpos);

		exynos_plane->enabled = true;
	} else {
		if (!exynos_plane->enabled)
			return;

		manager = to_exynos_crtc(plane->crtc)->manager;
		if (manager->ops->win_disable)
			manager->ops->win_disable(manager, exynos_plane->zpos);
		if (exynos_crtc->ops->win_disable)
			exynos_crtc->ops->win_disable(exynos_crtc,
						      exynos_plane->zpos);

		exynos_plane->enabled = false;
	}
@@ -173,7 +173,7 @@ exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
		     uint32_t src_w, uint32_t src_h)
{

	struct exynos_drm_manager *manager = to_exynos_crtc(crtc)->manager;
	struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
	struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
	int ret;

@@ -183,8 +183,8 @@ exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
	if (ret < 0)
		return ret;

	if (manager->ops->win_commit)
		manager->ops->win_commit(manager, exynos_plane->zpos);
	if (exynos_crtc->ops->win_commit)
		exynos_crtc->ops->win_commit(exynos_crtc, exynos_plane->zpos);

	return 0;
}
Loading