@@ -42,7 +42,7 @@
struct decon_context {
struct device *dev;
struct drm_device *drm_dev;
- struct exynos_drm_crtc *crtc;
+ struct exynos_drm_crtc crtc;
struct exynos_drm_plane planes[WINDOWS_NR];
struct clk *pclk;
struct clk *aclk;
@@ -58,6 +58,8 @@ struct decon_context {
struct drm_encoder *encoder;
};
+#define to_decon(ptr) container_of(ptr, struct decon_context, ptr)
+
static const struct of_device_id decon_driver_dt_match[] = {
{.compatible = "samsung,exynos7-decon"},
{},
@@ -83,7 +85,7 @@ static const enum drm_plane_type decon_win_types[WINDOWS_NR] = {
static void decon_wait_for_vblank(struct exynos_drm_crtc *crtc)
{
- struct decon_context *ctx = crtc->ctx;
+ struct decon_context *ctx = to_decon(crtc);
if (ctx->suspended)
return;
@@ -102,7 +104,7 @@ static void decon_wait_for_vblank(struct exynos_drm_crtc *crtc)
static void decon_clear_channels(struct exynos_drm_crtc *crtc)
{
- struct decon_context *ctx = crtc->ctx;
+ struct decon_context *ctx = to_decon(crtc);
unsigned int win, ch_enabled = 0;
DRM_DEBUG_KMS("%s\n", __FILE__);
@@ -120,7 +122,7 @@ static void decon_clear_channels(struct exynos_drm_crtc *crtc)
/* Wait for vsync, as disable channel takes effect at next vsync */
if (ch_enabled)
- decon_wait_for_vblank(ctx->crtc);
+ decon_wait_for_vblank(&ctx->crtc);
}
static int decon_ctx_initialize(struct decon_context *ctx,
@@ -128,7 +130,7 @@ static int decon_ctx_initialize(struct decon_context *ctx,
{
ctx->drm_dev = drm_dev;
- decon_clear_channels(ctx->crtc);
+ decon_clear_channels(&ctx->crtc);
return exynos_drm_register_dma(drm_dev, ctx->dev);
}
@@ -153,7 +155,7 @@ static u32 decon_calc_clkdiv(struct decon_context *ctx,
static void decon_commit(struct exynos_drm_crtc *crtc)
{
- struct decon_context *ctx = crtc->ctx;
+ struct decon_context *ctx = to_decon(crtc);
struct drm_display_mode *mode = &crtc->base.state->adjusted_mode;
u32 val, clkdiv;
@@ -218,7 +220,7 @@ static void decon_commit(struct exynos_drm_crtc *crtc)
static int decon_enable_vblank(struct exynos_drm_crtc *crtc)
{
- struct decon_context *ctx = crtc->ctx;
+ struct decon_context *ctx = to_decon(crtc);
u32 val;
if (ctx->suspended)
@@ -243,7 +245,7 @@ static int decon_enable_vblank(struct exynos_drm_crtc *crtc)
static void decon_disable_vblank(struct exynos_drm_crtc *crtc)
{
- struct decon_context *ctx = crtc->ctx;
+ struct decon_context *ctx = to_decon(crtc);
u32 val;
if (ctx->suspended)
@@ -368,7 +370,7 @@ static void decon_shadow_protect_win(struct decon_context *ctx,
static void decon_atomic_begin(struct exynos_drm_crtc *crtc)
{
- struct decon_context *ctx = crtc->ctx;
+ struct decon_context *ctx = to_decon(crtc);
int i;
if (ctx->suspended)
@@ -383,7 +385,7 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
{
struct exynos_drm_plane_state *state =
to_exynos_plane_state(plane->base.state);
- struct decon_context *ctx = crtc->ctx;
+ struct decon_context *ctx = to_decon(crtc);
struct drm_framebuffer *fb = state->base.fb;
int padding;
unsigned long val, alpha;
@@ -479,7 +481,7 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
static void decon_disable_plane(struct exynos_drm_crtc *crtc,
struct exynos_drm_plane *plane)
{
- struct decon_context *ctx = crtc->ctx;
+ struct decon_context *ctx = to_decon(crtc);
unsigned int win = plane->index;
u32 val;
@@ -501,7 +503,7 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc,
static void decon_atomic_flush(struct exynos_drm_crtc *crtc)
{
- struct decon_context *ctx = crtc->ctx;
+ struct decon_context *ctx = to_decon(crtc);
int i;
if (ctx->suspended)
@@ -531,7 +533,7 @@ static void decon_init(struct decon_context *ctx)
static void decon_enable(struct exynos_drm_crtc *crtc)
{
- struct decon_context *ctx = crtc->ctx;
+ struct decon_context *ctx = to_decon(crtc);
if (!ctx->suspended)
return;
@@ -542,16 +544,16 @@ static void decon_enable(struct exynos_drm_crtc *crtc)
/* if vblank was enabled status, enable it again. */
if (test_and_clear_bit(0, &ctx->irq_flags))
- decon_enable_vblank(ctx->crtc);
+ decon_enable_vblank(&ctx->crtc);
- decon_commit(ctx->crtc);
+ decon_commit(&ctx->crtc);
ctx->suspended = false;
}
static void decon_disable(struct exynos_drm_crtc *crtc)
{
- struct decon_context *ctx = crtc->ctx;
+ struct decon_context *ctx = to_decon(crtc);
int i;
if (ctx->suspended)
@@ -598,7 +600,7 @@ static irqreturn_t decon_irq_handler(int irq, void *dev_id)
goto out;
if (!ctx->i80_if) {
- drm_crtc_handle_vblank(&ctx->crtc->base);
+ drm_crtc_handle_vblank(&ctx->crtc.base);
/* set wait vsync event to zero and wake up queue. */
if (atomic_read(&ctx->wait_vsync_event)) {
@@ -614,7 +616,6 @@ static int decon_bind(struct device *dev, struct device *master, void *data)
{
struct decon_context *ctx = dev_get_drvdata(dev);
struct drm_device *drm_dev = data;
- struct exynos_drm_plane *exynos_plane;
unsigned int i;
int ret;
@@ -632,13 +633,14 @@ static int decon_bind(struct device *dev, struct device *master, void *data)
return ret;
}
- exynos_plane = &ctx->planes[DEFAULT_WIN];
- ctx->crtc = exynos_drm_crtc_create(drm_dev, &exynos_plane->base,
- EXYNOS_DISPLAY_TYPE_LCD, &decon_crtc_ops, ctx);
- if (IS_ERR(ctx->crtc)) {
+ ctx->crtc.type = EXYNOS_DISPLAY_TYPE_LCD;
+ ctx->crtc.ops = &decon_crtc_ops;
+ ret = exynos_drm_crtc_init(&ctx->crtc, drm_dev);
+ if (ret) {
decon_ctx_remove(ctx);
- return PTR_ERR(ctx->crtc);
+ return ret;
}
+ ctx->crtc.base.primary = &ctx->planes[DEFAULT_WIN].base;
if (ctx->encoder)
exynos_dpi_bind(drm_dev, ctx->encoder);
@@ -652,7 +654,7 @@ static void decon_unbind(struct device *dev, struct device *master,
{
struct decon_context *ctx = dev_get_drvdata(dev);
- decon_disable(ctx->crtc);
+ decon_disable(&ctx->crtc);
if (ctx->encoder)
exynos_dpi_remove(ctx->encoder);
Since crtc maps 1:1 to the device there is no point in allocating it separately, another benefit is possibility of direct initialisation of its fields which is more readable and allows further expansion. Signed-off-by: Andrzej Hajda <a.hajda@samsung.com> --- drivers/gpu/drm/exynos/exynos7_drm_decon.c | 50 +++++++++++----------- 1 file changed, 26 insertions(+), 24 deletions(-)