aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_crtc.c185
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_crtc.h8
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.h83
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimd.c196
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_plane.c138
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_plane.h17
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_vidi.c135
-rw-r--r--drivers/gpu/drm/exynos/exynos_mixer.c159
8 files changed, 426 insertions, 495 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index 45026e693225..a85c451ba392 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -20,43 +20,9 @@
20#include "exynos_drm_encoder.h" 20#include "exynos_drm_encoder.h"
21#include "exynos_drm_plane.h" 21#include "exynos_drm_plane.h"
22 22
23#define to_exynos_crtc(x) container_of(x, struct exynos_drm_crtc,\
24 drm_crtc)
25
26enum exynos_crtc_mode {
27 CRTC_MODE_NORMAL, /* normal mode */
28 CRTC_MODE_BLANK, /* The private plane of crtc is blank */
29};
30
31/*
32 * Exynos specific crtc structure.
33 *
34 * @drm_crtc: crtc object.
35 * @manager: the manager associated with this crtc
36 * @pipe: a crtc index created at load() with a new crtc object creation
37 * and the crtc object would be set to private->crtc array
38 * to get a crtc object corresponding to this pipe from private->crtc
39 * array when irq interrupt occurred. the reason of using this pipe is that
40 * drm framework doesn't support multiple irq yet.
41 * we can refer to the crtc to current hardware interrupt occurred through
42 * this pipe value.
43 * @dpms: store the crtc dpms value
44 * @mode: store the crtc mode value
45 */
46struct exynos_drm_crtc {
47 struct drm_crtc drm_crtc;
48 struct exynos_drm_manager *manager;
49 unsigned int pipe;
50 unsigned int dpms;
51 enum exynos_crtc_mode mode;
52 wait_queue_head_t pending_flip_queue;
53 atomic_t pending_flip;
54};
55
56static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode) 23static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
57{ 24{
58 struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); 25 struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
59 struct exynos_drm_manager *manager = exynos_crtc->manager;
60 26
61 DRM_DEBUG_KMS("crtc[%d] mode[%d]\n", crtc->base.id, mode); 27 DRM_DEBUG_KMS("crtc[%d] mode[%d]\n", crtc->base.id, mode);
62 28
@@ -74,8 +40,8 @@ static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
74 drm_crtc_vblank_off(crtc); 40 drm_crtc_vblank_off(crtc);
75 } 41 }
76 42
77 if (manager->ops->dpms) 43 if (exynos_crtc->ops->dpms)
78 manager->ops->dpms(manager, mode); 44 exynos_crtc->ops->dpms(exynos_crtc, mode);
79 45
80 exynos_crtc->dpms = mode; 46 exynos_crtc->dpms = mode;
81 47
@@ -91,14 +57,15 @@ static void exynos_drm_crtc_prepare(struct drm_crtc *crtc)
91static void exynos_drm_crtc_commit(struct drm_crtc *crtc) 57static void exynos_drm_crtc_commit(struct drm_crtc *crtc)
92{ 58{
93 struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); 59 struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
94 struct exynos_drm_manager *manager = exynos_crtc->manager; 60 struct exynos_drm_plane *exynos_plane = to_exynos_plane(crtc->primary);
95 61
96 exynos_drm_crtc_dpms(crtc, DRM_MODE_DPMS_ON); 62 exynos_drm_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
97 63
98 exynos_plane_commit(crtc->primary); 64 if (exynos_crtc->ops->win_commit)
65 exynos_crtc->ops->win_commit(exynos_crtc, exynos_plane->zpos);
99 66
100 if (manager->ops->commit) 67 if (exynos_crtc->ops->commit)
101 manager->ops->commit(manager); 68 exynos_crtc->ops->commit(exynos_crtc);
102 69
103 exynos_plane_dpms(crtc->primary, DRM_MODE_DPMS_ON); 70 exynos_plane_dpms(crtc->primary, DRM_MODE_DPMS_ON);
104} 71}
@@ -109,10 +76,10 @@ exynos_drm_crtc_mode_fixup(struct drm_crtc *crtc,
109 struct drm_display_mode *adjusted_mode) 76 struct drm_display_mode *adjusted_mode)
110{ 77{
111 struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); 78 struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
112 struct exynos_drm_manager *manager = exynos_crtc->manager;
113 79
114 if (manager->ops->mode_fixup) 80 if (exynos_crtc->ops->mode_fixup)
115 return manager->ops->mode_fixup(manager, mode, adjusted_mode); 81 return exynos_crtc->ops->mode_fixup(exynos_crtc, mode,
82 adjusted_mode);
116 83
117 return true; 84 return true;
118} 85}
@@ -122,11 +89,10 @@ exynos_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
122 struct drm_display_mode *adjusted_mode, int x, int y, 89 struct drm_display_mode *adjusted_mode, int x, int y,
123 struct drm_framebuffer *old_fb) 90 struct drm_framebuffer *old_fb)
124{ 91{
125 struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
126 struct exynos_drm_manager *manager = exynos_crtc->manager;
127 struct drm_framebuffer *fb = crtc->primary->fb; 92 struct drm_framebuffer *fb = crtc->primary->fb;
128 unsigned int crtc_w; 93 unsigned int crtc_w;
129 unsigned int crtc_h; 94 unsigned int crtc_h;
95 int ret;
130 96
131 /* 97 /*
132 * copy the mode data adjusted by mode_fixup() into crtc->mode 98 * copy the mode data adjusted by mode_fixup() into crtc->mode
@@ -134,24 +100,25 @@ exynos_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
134 */ 100 */
135 memcpy(&crtc->mode, adjusted_mode, sizeof(*adjusted_mode)); 101 memcpy(&crtc->mode, adjusted_mode, sizeof(*adjusted_mode));
136 102
103 ret = exynos_check_plane(crtc->primary, fb);
104 if (ret < 0)
105 return ret;
106
137 crtc_w = fb->width - x; 107 crtc_w = fb->width - x;
138 crtc_h = fb->height - y; 108 crtc_h = fb->height - y;
109 exynos_plane_mode_set(crtc->primary, crtc, fb, 0, 0,
110 crtc_w, crtc_h, x, y, crtc_w, crtc_h);
139 111
140 if (manager->ops->mode_set) 112 return 0;
141 manager->ops->mode_set(manager, &crtc->mode);
142
143 return exynos_plane_mode_set(crtc->primary, crtc, fb, 0, 0,
144 crtc_w, crtc_h, x, y, crtc_w, crtc_h);
145} 113}
146 114
147static int exynos_drm_crtc_mode_set_commit(struct drm_crtc *crtc, int x, int y, 115static int exynos_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
148 struct drm_framebuffer *old_fb) 116 struct drm_framebuffer *old_fb)
149{ 117{
150 struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); 118 struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
151 struct drm_framebuffer *fb = crtc->primary->fb; 119 struct drm_framebuffer *fb = crtc->primary->fb;
152 unsigned int crtc_w; 120 unsigned int crtc_w;
153 unsigned int crtc_h; 121 unsigned int crtc_h;
154 int ret;
155 122
156 /* when framebuffer changing is requested, crtc's dpms should be on */ 123 /* when framebuffer changing is requested, crtc's dpms should be on */
157 if (exynos_crtc->dpms > DRM_MODE_DPMS_ON) { 124 if (exynos_crtc->dpms > DRM_MODE_DPMS_ON) {
@@ -162,20 +129,8 @@ static int exynos_drm_crtc_mode_set_commit(struct drm_crtc *crtc, int x, int y,
162 crtc_w = fb->width - x; 129 crtc_w = fb->width - x;
163 crtc_h = fb->height - y; 130 crtc_h = fb->height - y;
164 131
165 ret = exynos_plane_mode_set(crtc->primary, crtc, fb, 0, 0, 132 return exynos_update_plane(crtc->primary, crtc, fb, 0, 0,
166 crtc_w, crtc_h, x, y, crtc_w, crtc_h); 133 crtc_w, crtc_h, x, y, crtc_w, crtc_h);
167 if (ret)
168 return ret;
169
170 exynos_drm_crtc_commit(crtc);
171
172 return 0;
173}
174
175static int exynos_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
176 struct drm_framebuffer *old_fb)
177{
178 return exynos_drm_crtc_mode_set_commit(crtc, x, y, old_fb);
179} 134}
180 135
181static void exynos_drm_crtc_disable(struct drm_crtc *crtc) 136static void exynos_drm_crtc_disable(struct drm_crtc *crtc)
@@ -214,6 +169,7 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc,
214 struct exynos_drm_private *dev_priv = dev->dev_private; 169 struct exynos_drm_private *dev_priv = dev->dev_private;
215 struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); 170 struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
216 struct drm_framebuffer *old_fb = crtc->primary->fb; 171 struct drm_framebuffer *old_fb = crtc->primary->fb;
172 unsigned int crtc_w, crtc_h;
217 int ret = -EINVAL; 173 int ret = -EINVAL;
218 174
219 /* when the page flip is requested, crtc's dpms should be on */ 175 /* when the page flip is requested, crtc's dpms should be on */
@@ -245,8 +201,11 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc,
245 spin_unlock_irq(&dev->event_lock); 201 spin_unlock_irq(&dev->event_lock);
246 202
247 crtc->primary->fb = fb; 203 crtc->primary->fb = fb;
248 ret = exynos_drm_crtc_mode_set_commit(crtc, crtc->x, crtc->y, 204 crtc_w = fb->width - crtc->x;
249 NULL); 205 crtc_h = fb->height - crtc->y;
206 ret = exynos_update_plane(crtc->primary, crtc, fb, 0, 0,
207 crtc_w, crtc_h, crtc->x, crtc->y,
208 crtc_w, crtc_h);
250 if (ret) { 209 if (ret) {
251 crtc->primary->fb = old_fb; 210 crtc->primary->fb = old_fb;
252 211
@@ -339,37 +298,42 @@ static void exynos_drm_crtc_attach_mode_property(struct drm_crtc *crtc)
339 drm_object_attach_property(&crtc->base, prop, 0); 298 drm_object_attach_property(&crtc->base, prop, 0);
340} 299}
341 300
342int exynos_drm_crtc_create(struct exynos_drm_manager *manager) 301struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev,
302 int pipe,
303 enum exynos_drm_output_type type,
304 struct exynos_drm_crtc_ops *ops,
305 void *ctx)
343{ 306{
344 struct exynos_drm_crtc *exynos_crtc; 307 struct exynos_drm_crtc *exynos_crtc;
345 struct drm_plane *plane; 308 struct drm_plane *plane;
346 struct exynos_drm_private *private = manager->drm_dev->dev_private; 309 struct exynos_drm_private *private = drm_dev->dev_private;
347 struct drm_crtc *crtc; 310 struct drm_crtc *crtc;
348 int ret; 311 int ret;
349 312
350 exynos_crtc = kzalloc(sizeof(*exynos_crtc), GFP_KERNEL); 313 exynos_crtc = kzalloc(sizeof(*exynos_crtc), GFP_KERNEL);
351 if (!exynos_crtc) 314 if (!exynos_crtc)
352 return -ENOMEM; 315 return ERR_PTR(-ENOMEM);
353 316
354 init_waitqueue_head(&exynos_crtc->pending_flip_queue); 317 init_waitqueue_head(&exynos_crtc->pending_flip_queue);
355 atomic_set(&exynos_crtc->pending_flip, 0); 318 atomic_set(&exynos_crtc->pending_flip, 0);
356 319
357 exynos_crtc->dpms = DRM_MODE_DPMS_OFF; 320 exynos_crtc->dpms = DRM_MODE_DPMS_OFF;
358 exynos_crtc->manager = manager; 321 exynos_crtc->pipe = pipe;
359 exynos_crtc->pipe = manager->pipe; 322 exynos_crtc->type = type;
360 plane = exynos_plane_init(manager->drm_dev, 1 << manager->pipe, 323 exynos_crtc->ops = ops;
324 exynos_crtc->ctx = ctx;
325 plane = exynos_plane_init(drm_dev, 1 << pipe,
361 DRM_PLANE_TYPE_PRIMARY); 326 DRM_PLANE_TYPE_PRIMARY);
362 if (IS_ERR(plane)) { 327 if (IS_ERR(plane)) {
363 ret = PTR_ERR(plane); 328 ret = PTR_ERR(plane);
364 goto err_plane; 329 goto err_plane;
365 } 330 }
366 331
367 manager->crtc = &exynos_crtc->drm_crtc; 332 crtc = &exynos_crtc->base;
368 crtc = &exynos_crtc->drm_crtc;
369 333
370 private->crtc[manager->pipe] = crtc; 334 private->crtc[pipe] = crtc;
371 335
372 ret = drm_crtc_init_with_planes(manager->drm_dev, crtc, plane, NULL, 336 ret = drm_crtc_init_with_planes(drm_dev, crtc, plane, NULL,
373 &exynos_crtc_funcs); 337 &exynos_crtc_funcs);
374 if (ret < 0) 338 if (ret < 0)
375 goto err_crtc; 339 goto err_crtc;
@@ -378,13 +342,13 @@ int exynos_drm_crtc_create(struct exynos_drm_manager *manager)
378 342
379 exynos_drm_crtc_attach_mode_property(crtc); 343 exynos_drm_crtc_attach_mode_property(crtc);
380 344
381 return 0; 345 return exynos_crtc;
382 346
383err_crtc: 347err_crtc:
384 plane->funcs->destroy(plane); 348 plane->funcs->destroy(plane);
385err_plane: 349err_plane:
386 kfree(exynos_crtc); 350 kfree(exynos_crtc);
387 return ret; 351 return ERR_PTR(ret);
388} 352}
389 353
390int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int pipe) 354int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int pipe)
@@ -392,13 +356,12 @@ int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int pipe)
392 struct exynos_drm_private *private = dev->dev_private; 356 struct exynos_drm_private *private = dev->dev_private;
393 struct exynos_drm_crtc *exynos_crtc = 357 struct exynos_drm_crtc *exynos_crtc =
394 to_exynos_crtc(private->crtc[pipe]); 358 to_exynos_crtc(private->crtc[pipe]);
395 struct exynos_drm_manager *manager = exynos_crtc->manager;
396 359
397 if (exynos_crtc->dpms != DRM_MODE_DPMS_ON) 360 if (exynos_crtc->dpms != DRM_MODE_DPMS_ON)
398 return -EPERM; 361 return -EPERM;
399 362
400 if (manager->ops->enable_vblank) 363 if (exynos_crtc->ops->enable_vblank)
401 manager->ops->enable_vblank(manager); 364 exynos_crtc->ops->enable_vblank(exynos_crtc);
402 365
403 return 0; 366 return 0;
404} 367}
@@ -408,13 +371,12 @@ void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int pipe)
408 struct exynos_drm_private *private = dev->dev_private; 371 struct exynos_drm_private *private = dev->dev_private;
409 struct exynos_drm_crtc *exynos_crtc = 372 struct exynos_drm_crtc *exynos_crtc =
410 to_exynos_crtc(private->crtc[pipe]); 373 to_exynos_crtc(private->crtc[pipe]);
411 struct exynos_drm_manager *manager = exynos_crtc->manager;
412 374
413 if (exynos_crtc->dpms != DRM_MODE_DPMS_ON) 375 if (exynos_crtc->dpms != DRM_MODE_DPMS_ON)
414 return; 376 return;
415 377
416 if (manager->ops->disable_vblank) 378 if (exynos_crtc->ops->disable_vblank)
417 manager->ops->disable_vblank(manager); 379 exynos_crtc->ops->disable_vblank(exynos_crtc);
418} 380}
419 381
420void exynos_drm_crtc_finish_pageflip(struct drm_device *dev, int pipe) 382void exynos_drm_crtc_finish_pageflip(struct drm_device *dev, int pipe)
@@ -443,42 +405,9 @@ void exynos_drm_crtc_finish_pageflip(struct drm_device *dev, int pipe)
443 spin_unlock_irqrestore(&dev->event_lock, flags); 405 spin_unlock_irqrestore(&dev->event_lock, flags);
444} 406}
445 407
446void exynos_drm_crtc_plane_mode_set(struct drm_crtc *crtc,
447 struct exynos_drm_overlay *overlay)
448{
449 struct exynos_drm_manager *manager = to_exynos_crtc(crtc)->manager;
450
451 if (manager->ops->win_mode_set)
452 manager->ops->win_mode_set(manager, overlay);
453}
454
455void exynos_drm_crtc_plane_commit(struct drm_crtc *crtc, int zpos)
456{
457 struct exynos_drm_manager *manager = to_exynos_crtc(crtc)->manager;
458
459 if (manager->ops->win_commit)
460 manager->ops->win_commit(manager, zpos);
461}
462
463void exynos_drm_crtc_plane_enable(struct drm_crtc *crtc, int zpos)
464{
465 struct exynos_drm_manager *manager = to_exynos_crtc(crtc)->manager;
466
467 if (manager->ops->win_enable)
468 manager->ops->win_enable(manager, zpos);
469}
470
471void exynos_drm_crtc_plane_disable(struct drm_crtc *crtc, int zpos)
472{
473 struct exynos_drm_manager *manager = to_exynos_crtc(crtc)->manager;
474
475 if (manager->ops->win_disable)
476 manager->ops->win_disable(manager, zpos);
477}
478
479void exynos_drm_crtc_complete_scanout(struct drm_framebuffer *fb) 408void exynos_drm_crtc_complete_scanout(struct drm_framebuffer *fb)
480{ 409{
481 struct exynos_drm_manager *manager; 410 struct exynos_drm_crtc *exynos_crtc;
482 struct drm_device *dev = fb->dev; 411 struct drm_device *dev = fb->dev;
483 struct drm_crtc *crtc; 412 struct drm_crtc *crtc;
484 413
@@ -487,15 +416,15 @@ void exynos_drm_crtc_complete_scanout(struct drm_framebuffer *fb)
487 * for all encoders. 416 * for all encoders.
488 */ 417 */
489 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 418 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
490 manager = to_exynos_crtc(crtc)->manager; 419 exynos_crtc = to_exynos_crtc(crtc);
491 420
492 /* 421 /*
493 * wait for vblank interrupt 422 * wait for vblank interrupt
494 * - this makes sure that overlay data are updated to 423 * - this makes sure that overlay data are updated to
495 * real hardware. 424 * real hardware.
496 */ 425 */
497 if (manager->ops->wait_for_vblank) 426 if (exynos_crtc->ops->wait_for_vblank)
498 manager->ops->wait_for_vblank(manager); 427 exynos_crtc->ops->wait_for_vblank(exynos_crtc);
499 } 428 }
500} 429}
501 430
@@ -508,8 +437,8 @@ int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev,
508 struct exynos_drm_crtc *exynos_crtc; 437 struct exynos_drm_crtc *exynos_crtc;
509 438
510 exynos_crtc = to_exynos_crtc(crtc); 439 exynos_crtc = to_exynos_crtc(crtc);
511 if (exynos_crtc->manager->type == out_type) 440 if (exynos_crtc->type == out_type)
512 return exynos_crtc->manager->pipe; 441 return exynos_crtc->pipe;
513 } 442 }
514 443
515 return -EPERM; 444 return -EPERM;
@@ -517,8 +446,8 @@ int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev,
517 446
518void exynos_drm_crtc_te_handler(struct drm_crtc *crtc) 447void exynos_drm_crtc_te_handler(struct drm_crtc *crtc)
519{ 448{
520 struct exynos_drm_manager *manager = to_exynos_crtc(crtc)->manager; 449 struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
521 450
522 if (manager->ops->te_handler) 451 if (exynos_crtc->ops->te_handler)
523 manager->ops->te_handler(manager); 452 exynos_crtc->ops->te_handler(exynos_crtc);
524} 453}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.h b/drivers/gpu/drm/exynos/exynos_drm_crtc.h
index e353d353836f..6258b800aab8 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.h
@@ -17,14 +17,18 @@
17 17
18#include "exynos_drm_drv.h" 18#include "exynos_drm_drv.h"
19 19
20int exynos_drm_crtc_create(struct exynos_drm_manager *manager); 20struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev,
21 int pipe,
22 enum exynos_drm_output_type type,
23 struct exynos_drm_crtc_ops *ops,
24 void *context);
21int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int pipe); 25int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int pipe);
22void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int pipe); 26void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int pipe);
23void exynos_drm_crtc_finish_pageflip(struct drm_device *dev, int pipe); 27void exynos_drm_crtc_finish_pageflip(struct drm_device *dev, int pipe);
24void exynos_drm_crtc_complete_scanout(struct drm_framebuffer *fb); 28void exynos_drm_crtc_complete_scanout(struct drm_framebuffer *fb);
25 29
26void exynos_drm_crtc_plane_mode_set(struct drm_crtc *crtc, 30void exynos_drm_crtc_plane_mode_set(struct drm_crtc *crtc,
27 struct exynos_drm_overlay *overlay); 31 struct exynos_drm_plane *plane);
28void exynos_drm_crtc_plane_commit(struct drm_crtc *crtc, int zpos); 32void exynos_drm_crtc_plane_commit(struct drm_crtc *crtc, int zpos);
29void exynos_drm_crtc_plane_enable(struct drm_crtc *crtc, int zpos); 33void exynos_drm_crtc_plane_enable(struct drm_crtc *crtc, int zpos);
30void exynos_drm_crtc_plane_disable(struct drm_crtc *crtc, int zpos); 34void exynos_drm_crtc_plane_disable(struct drm_crtc *crtc, int zpos);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index 2e5063488c50..d490b49f71c9 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -23,6 +23,9 @@
23#define MAX_FB_BUFFER 4 23#define MAX_FB_BUFFER 4
24#define DEFAULT_ZPOS -1 24#define DEFAULT_ZPOS -1
25 25
26#define to_exynos_crtc(x) container_of(x, struct exynos_drm_crtc, base)
27#define to_exynos_plane(x) container_of(x, struct exynos_drm_plane, base)
28
26/* This enumerates device type. */ 29/* This enumerates device type. */
27enum exynos_drm_device_type { 30enum exynos_drm_device_type {
28 EXYNOS_DEVICE_TYPE_NONE, 31 EXYNOS_DEVICE_TYPE_NONE,
@@ -44,6 +47,7 @@ enum exynos_drm_output_type {
44/* 47/*
45 * Exynos drm common overlay structure. 48 * Exynos drm common overlay structure.
46 * 49 *
50 * @base: plane object
47 * @fb_x: offset x on a framebuffer to be displayed. 51 * @fb_x: offset x on a framebuffer to be displayed.
48 * - the unit is screen coordinates. 52 * - the unit is screen coordinates.
49 * @fb_y: offset y on a framebuffer to be displayed. 53 * @fb_y: offset y on a framebuffer to be displayed.
@@ -73,11 +77,14 @@ enum exynos_drm_output_type {
73 * @local_path: in case of lcd type, local path mode on or off. 77 * @local_path: in case of lcd type, local path mode on or off.
74 * @transparency: transparency on or off. 78 * @transparency: transparency on or off.
75 * @activated: activated or not. 79 * @activated: activated or not.
80 * @enabled: enabled or not.
76 * 81 *
77 * this structure is common to exynos SoC and its contents would be copied 82 * this structure is common to exynos SoC and its contents would be copied
78 * to hardware specific overlay info. 83 * to hardware specific overlay info.
79 */ 84 */
80struct exynos_drm_overlay { 85
86struct exynos_drm_plane {
87 struct drm_plane base;
81 unsigned int fb_x; 88 unsigned int fb_x;
82 unsigned int fb_y; 89 unsigned int fb_y;
83 unsigned int fb_width; 90 unsigned int fb_width;
@@ -104,6 +111,7 @@ struct exynos_drm_overlay {
104 bool local_path:1; 111 bool local_path:1;
105 bool transparency:1; 112 bool transparency:1;
106 bool activated:1; 113 bool activated:1;
114 bool enabled:1;
107}; 115};
108 116
109/* 117/*
@@ -155,11 +163,10 @@ struct exynos_drm_display {
155}; 163};
156 164
157/* 165/*
158 * Exynos drm manager ops 166 * Exynos drm crtc ops
159 * 167 *
160 * @dpms: control device power. 168 * @dpms: control device power.
161 * @mode_fixup: fix mode data before applying it 169 * @mode_fixup: fix mode data before applying it
162 * @mode_set: set the given mode to the manager
163 * @commit: set current hw specific display mode to hw. 170 * @commit: set current hw specific display mode to hw.
164 * @enable_vblank: specific driver callback for enabling vblank interrupt. 171 * @enable_vblank: specific driver callback for enabling vblank interrupt.
165 * @disable_vblank: specific driver callback for disabling vblank interrupt. 172 * @disable_vblank: specific driver callback for disabling vblank interrupt.
@@ -172,44 +179,56 @@ struct exynos_drm_display {
172 * @te_handler: trigger to transfer video image at the tearing effect 179 * @te_handler: trigger to transfer video image at the tearing effect
173 * synchronization signal if there is a page flip request. 180 * synchronization signal if there is a page flip request.
174 */ 181 */
175struct exynos_drm_manager; 182struct exynos_drm_crtc;
176struct exynos_drm_manager_ops { 183struct exynos_drm_crtc_ops {
177 void (*dpms)(struct exynos_drm_manager *mgr, int mode); 184 void (*dpms)(struct exynos_drm_crtc *crtc, int mode);
178 bool (*mode_fixup)(struct exynos_drm_manager *mgr, 185 bool (*mode_fixup)(struct exynos_drm_crtc *crtc,
179 const struct drm_display_mode *mode, 186 const struct drm_display_mode *mode,
180 struct drm_display_mode *adjusted_mode); 187 struct drm_display_mode *adjusted_mode);
181 void (*mode_set)(struct exynos_drm_manager *mgr, 188 void (*commit)(struct exynos_drm_crtc *crtc);
182 const struct drm_display_mode *mode); 189 int (*enable_vblank)(struct exynos_drm_crtc *crtc);
183 void (*commit)(struct exynos_drm_manager *mgr); 190 void (*disable_vblank)(struct exynos_drm_crtc *crtc);
184 int (*enable_vblank)(struct exynos_drm_manager *mgr); 191 void (*wait_for_vblank)(struct exynos_drm_crtc *crtc);
185 void (*disable_vblank)(struct exynos_drm_manager *mgr); 192 void (*win_mode_set)(struct exynos_drm_crtc *crtc,
186 void (*wait_for_vblank)(struct exynos_drm_manager *mgr); 193 struct exynos_drm_plane *plane);
187 void (*win_mode_set)(struct exynos_drm_manager *mgr, 194 void (*win_commit)(struct exynos_drm_crtc *crtc, int zpos);
188 struct exynos_drm_overlay *overlay); 195 void (*win_enable)(struct exynos_drm_crtc *crtc, int zpos);
189 void (*win_commit)(struct exynos_drm_manager *mgr, int zpos); 196 void (*win_disable)(struct exynos_drm_crtc *crtc, int zpos);
190 void (*win_enable)(struct exynos_drm_manager *mgr, int zpos); 197 void (*te_handler)(struct exynos_drm_crtc *crtc);
191 void (*win_disable)(struct exynos_drm_manager *mgr, int zpos); 198};
192 void (*te_handler)(struct exynos_drm_manager *mgr); 199
200enum exynos_crtc_mode {
201 CRTC_MODE_NORMAL, /* normal mode */
202 CRTC_MODE_BLANK, /* The private plane of crtc is blank */
193}; 203};
194 204
195/* 205/*
196 * Exynos drm common manager structure, maps 1:1 with a crtc 206 * Exynos specific crtc structure.
197 * 207 *
198 * @list: the list entry for this manager 208 * @base: crtc object.
199 * @type: one of EXYNOS_DISPLAY_TYPE_LCD and HDMI. 209 * @type: one of EXYNOS_DISPLAY_TYPE_LCD and HDMI.
200 * @drm_dev: pointer to the drm device 210 * @pipe: a crtc index created at load() with a new crtc object creation
201 * @crtc: crtc object. 211 * and the crtc object would be set to private->crtc array
202 * @pipe: the pipe number for this crtc/manager 212 * to get a crtc object corresponding to this pipe from private->crtc
213 * array when irq interrupt occurred. the reason of using this pipe is that
214 * drm framework doesn't support multiple irq yet.
215 * we can refer to the crtc to current hardware interrupt occurred through
216 * this pipe value.
217 * @dpms: store the crtc dpms value
218 * @mode: store the crtc mode value
203 * @ops: pointer to callbacks for exynos drm specific functionality 219 * @ops: pointer to callbacks for exynos drm specific functionality
204 * @ctx: A pointer to the manager's implementation specific context 220 * @ctx: A pointer to the crtc's implementation specific context
205 */ 221 */
206struct exynos_drm_manager { 222struct exynos_drm_crtc {
207 struct list_head list; 223 struct drm_crtc base;
208 enum exynos_drm_output_type type; 224 enum exynos_drm_output_type type;
209 struct drm_device *drm_dev; 225 unsigned int pipe;
210 struct drm_crtc *crtc; 226 unsigned int dpms;
211 int pipe; 227 enum exynos_crtc_mode mode;
212 struct exynos_drm_manager_ops *ops; 228 wait_queue_head_t pending_flip_queue;
229 atomic_t pending_flip;
230 struct exynos_drm_crtc_ops *ops;
231 void *ctx;
213}; 232};
214 233
215struct exynos_drm_g2d_private { 234struct exynos_drm_g2d_private {
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index e5810d13bf9c..682806ef4d33 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -157,14 +157,13 @@ struct fimd_win_data {
157}; 157};
158 158
159struct fimd_context { 159struct fimd_context {
160 struct exynos_drm_manager manager;
161 struct device *dev; 160 struct device *dev;
162 struct drm_device *drm_dev; 161 struct drm_device *drm_dev;
162 struct exynos_drm_crtc *crtc;
163 struct clk *bus_clk; 163 struct clk *bus_clk;
164 struct clk *lcd_clk; 164 struct clk *lcd_clk;
165 void __iomem *regs; 165 void __iomem *regs;
166 struct regmap *sysreg; 166 struct regmap *sysreg;
167 struct drm_display_mode mode;
168 struct fimd_win_data win_data[WINDOWS_NR]; 167 struct fimd_win_data win_data[WINDOWS_NR];
169 unsigned int default_win; 168 unsigned int default_win;
170 unsigned long irq_flags; 169 unsigned long irq_flags;
@@ -185,11 +184,6 @@ struct fimd_context {
185 struct exynos_drm_display *display; 184 struct exynos_drm_display *display;
186}; 185};
187 186
188static inline struct fimd_context *mgr_to_fimd(struct exynos_drm_manager *mgr)
189{
190 return container_of(mgr, struct fimd_context, manager);
191}
192
193static const struct of_device_id fimd_driver_dt_match[] = { 187static const struct of_device_id fimd_driver_dt_match[] = {
194 { .compatible = "samsung,s3c6400-fimd", 188 { .compatible = "samsung,s3c6400-fimd",
195 .data = &s3c64xx_fimd_driver_data }, 189 .data = &s3c64xx_fimd_driver_data },
@@ -214,9 +208,9 @@ static inline struct fimd_driver_data *drm_fimd_get_driver_data(
214 return (struct fimd_driver_data *)of_id->data; 208 return (struct fimd_driver_data *)of_id->data;
215} 209}
216 210
217static void fimd_wait_for_vblank(struct exynos_drm_manager *mgr) 211static void fimd_wait_for_vblank(struct exynos_drm_crtc *crtc)
218{ 212{
219 struct fimd_context *ctx = mgr_to_fimd(mgr); 213 struct fimd_context *ctx = crtc->ctx;
220 214
221 if (ctx->suspended) 215 if (ctx->suspended)
222 return; 216 return;
@@ -259,9 +253,9 @@ static void fimd_enable_shadow_channel_path(struct fimd_context *ctx, int win,
259 writel(val, ctx->regs + SHADOWCON); 253 writel(val, ctx->regs + SHADOWCON);
260} 254}
261 255
262static void fimd_clear_channel(struct exynos_drm_manager *mgr) 256static void fimd_clear_channel(struct exynos_drm_crtc *crtc)
263{ 257{
264 struct fimd_context *ctx = mgr_to_fimd(mgr); 258 struct fimd_context *ctx = crtc->ctx;
265 int win, ch_enabled = 0; 259 int win, ch_enabled = 0;
266 260
267 DRM_DEBUG_KMS("%s\n", __FILE__); 261 DRM_DEBUG_KMS("%s\n", __FILE__);
@@ -286,38 +280,42 @@ static void fimd_clear_channel(struct exynos_drm_manager *mgr)
286 unsigned int state = ctx->suspended; 280 unsigned int state = ctx->suspended;
287 281
288 ctx->suspended = 0; 282 ctx->suspended = 0;
289 fimd_wait_for_vblank(mgr); 283 fimd_wait_for_vblank(crtc);
290 ctx->suspended = state; 284 ctx->suspended = state;
291 } 285 }
292} 286}
293 287
294static int fimd_mgr_initialize(struct exynos_drm_manager *mgr, 288static int fimd_ctx_initialize(struct fimd_context *ctx,
295 struct drm_device *drm_dev) 289 struct drm_device *drm_dev)
296{ 290{
297 struct fimd_context *ctx = mgr_to_fimd(mgr);
298 struct exynos_drm_private *priv; 291 struct exynos_drm_private *priv;
299 priv = drm_dev->dev_private; 292 priv = drm_dev->dev_private;
300 293
301 mgr->drm_dev = ctx->drm_dev = drm_dev; 294 ctx->drm_dev = drm_dev;
302 mgr->pipe = ctx->pipe = priv->pipe++; 295 ctx->pipe = priv->pipe++;
303 296
304 /* attach this sub driver to iommu mapping if supported. */ 297 /* attach this sub driver to iommu mapping if supported. */
305 if (is_drm_iommu_supported(ctx->drm_dev)) { 298 if (is_drm_iommu_supported(ctx->drm_dev)) {
299 int ret;
300
306 /* 301 /*
307 * If any channel is already active, iommu will throw 302 * If any channel is already active, iommu will throw
308 * a PAGE FAULT when enabled. So clear any channel if enabled. 303 * a PAGE FAULT when enabled. So clear any channel if enabled.
309 */ 304 */
310 fimd_clear_channel(mgr); 305 fimd_clear_channel(ctx->crtc);
311 drm_iommu_attach_device(ctx->drm_dev, ctx->dev); 306 ret = drm_iommu_attach_device(ctx->drm_dev, ctx->dev);
307 if (ret) {
308 DRM_ERROR("drm_iommu_attach failed.\n");
309 return ret;
310 }
311
312 } 312 }
313 313
314 return 0; 314 return 0;
315} 315}
316 316
317static void fimd_mgr_remove(struct exynos_drm_manager *mgr) 317static void fimd_ctx_remove(struct fimd_context *ctx)
318{ 318{
319 struct fimd_context *ctx = mgr_to_fimd(mgr);
320
321 /* detach this sub driver from iommu mapping if supported. */ 319 /* detach this sub driver from iommu mapping if supported. */
322 if (is_drm_iommu_supported(ctx->drm_dev)) 320 if (is_drm_iommu_supported(ctx->drm_dev))
323 drm_iommu_detach_device(ctx->drm_dev, ctx->dev); 321 drm_iommu_detach_device(ctx->drm_dev, ctx->dev);
@@ -343,7 +341,7 @@ static u32 fimd_calc_clkdiv(struct fimd_context *ctx,
343 return (clkdiv < 0x100) ? clkdiv : 0xff; 341 return (clkdiv < 0x100) ? clkdiv : 0xff;
344} 342}
345 343
346static bool fimd_mode_fixup(struct exynos_drm_manager *mgr, 344static bool fimd_mode_fixup(struct exynos_drm_crtc *crtc,
347 const struct drm_display_mode *mode, 345 const struct drm_display_mode *mode,
348 struct drm_display_mode *adjusted_mode) 346 struct drm_display_mode *adjusted_mode)
349{ 347{
@@ -353,18 +351,10 @@ static bool fimd_mode_fixup(struct exynos_drm_manager *mgr,
353 return true; 351 return true;
354} 352}
355 353
356static void fimd_mode_set(struct exynos_drm_manager *mgr, 354static void fimd_commit(struct exynos_drm_crtc *crtc)
357 const struct drm_display_mode *in_mode)
358{ 355{
359 struct fimd_context *ctx = mgr_to_fimd(mgr); 356 struct fimd_context *ctx = crtc->ctx;
360 357 struct drm_display_mode *mode = &crtc->base.mode;
361 drm_mode_copy(&ctx->mode, in_mode);
362}
363
364static void fimd_commit(struct exynos_drm_manager *mgr)
365{
366 struct fimd_context *ctx = mgr_to_fimd(mgr);
367 struct drm_display_mode *mode = &ctx->mode;
368 struct fimd_driver_data *driver_data = ctx->driver_data; 358 struct fimd_driver_data *driver_data = ctx->driver_data;
369 void *timing_base = ctx->regs + driver_data->timing_base; 359 void *timing_base = ctx->regs + driver_data->timing_base;
370 u32 val, clkdiv; 360 u32 val, clkdiv;
@@ -461,9 +451,9 @@ static void fimd_commit(struct exynos_drm_manager *mgr)
461 writel(val, ctx->regs + VIDCON0); 451 writel(val, ctx->regs + VIDCON0);
462} 452}
463 453
464static int fimd_enable_vblank(struct exynos_drm_manager *mgr) 454static int fimd_enable_vblank(struct exynos_drm_crtc *crtc)
465{ 455{
466 struct fimd_context *ctx = mgr_to_fimd(mgr); 456 struct fimd_context *ctx = crtc->ctx;
467 u32 val; 457 u32 val;
468 458
469 if (ctx->suspended) 459 if (ctx->suspended)
@@ -493,9 +483,9 @@ static int fimd_enable_vblank(struct exynos_drm_manager *mgr)
493 return 0; 483 return 0;
494} 484}
495 485
496static void fimd_disable_vblank(struct exynos_drm_manager *mgr) 486static void fimd_disable_vblank(struct exynos_drm_crtc *crtc)
497{ 487{
498 struct fimd_context *ctx = mgr_to_fimd(mgr); 488 struct fimd_context *ctx = crtc->ctx;
499 u32 val; 489 u32 val;
500 490
501 if (ctx->suspended) 491 if (ctx->suspended)
@@ -517,45 +507,45 @@ static void fimd_disable_vblank(struct exynos_drm_manager *mgr)
517 } 507 }
518} 508}
519 509
520static void fimd_win_mode_set(struct exynos_drm_manager *mgr, 510static void fimd_win_mode_set(struct exynos_drm_crtc *crtc,
521 struct exynos_drm_overlay *overlay) 511 struct exynos_drm_plane *plane)
522{ 512{
523 struct fimd_context *ctx = mgr_to_fimd(mgr); 513 struct fimd_context *ctx = crtc->ctx;
524 struct fimd_win_data *win_data; 514 struct fimd_win_data *win_data;
525 int win; 515 int win;
526 unsigned long offset; 516 unsigned long offset;
527 517
528 if (!overlay) { 518 if (!plane) {
529 DRM_ERROR("overlay is NULL\n"); 519 DRM_ERROR("plane is NULL\n");
530 return; 520 return;
531 } 521 }
532 522
533 win = overlay->zpos; 523 win = plane->zpos;
534 if (win == DEFAULT_ZPOS) 524 if (win == DEFAULT_ZPOS)
535 win = ctx->default_win; 525 win = ctx->default_win;
536 526
537 if (win < 0 || win >= WINDOWS_NR) 527 if (win < 0 || win >= WINDOWS_NR)
538 return; 528 return;
539 529
540 offset = overlay->fb_x * (overlay->bpp >> 3); 530 offset = plane->fb_x * (plane->bpp >> 3);
541 offset += overlay->fb_y * overlay->pitch; 531 offset += plane->fb_y * plane->pitch;
542 532
543 DRM_DEBUG_KMS("offset = 0x%lx, pitch = %x\n", offset, overlay->pitch); 533 DRM_DEBUG_KMS("offset = 0x%lx, pitch = %x\n", offset, plane->pitch);
544 534
545 win_data = &ctx->win_data[win]; 535 win_data = &ctx->win_data[win];
546 536
547 win_data->offset_x = overlay->crtc_x; 537 win_data->offset_x = plane->crtc_x;
548 win_data->offset_y = overlay->crtc_y; 538 win_data->offset_y = plane->crtc_y;
549 win_data->ovl_width = overlay->crtc_width; 539 win_data->ovl_width = plane->crtc_width;
550 win_data->ovl_height = overlay->crtc_height; 540 win_data->ovl_height = plane->crtc_height;
551 win_data->fb_width = overlay->fb_width; 541 win_data->fb_width = plane->fb_width;
552 win_data->fb_height = overlay->fb_height; 542 win_data->fb_height = plane->fb_height;
553 win_data->dma_addr = overlay->dma_addr[0] + offset; 543 win_data->dma_addr = plane->dma_addr[0] + offset;
554 win_data->bpp = overlay->bpp; 544 win_data->bpp = plane->bpp;
555 win_data->pixel_format = overlay->pixel_format; 545 win_data->pixel_format = plane->pixel_format;
556 win_data->buf_offsize = (overlay->fb_width - overlay->crtc_width) * 546 win_data->buf_offsize = (plane->fb_width - plane->crtc_width) *
557 (overlay->bpp >> 3); 547 (plane->bpp >> 3);
558 win_data->line_size = overlay->crtc_width * (overlay->bpp >> 3); 548 win_data->line_size = plane->crtc_width * (plane->bpp >> 3);
559 549
560 DRM_DEBUG_KMS("offset_x = %d, offset_y = %d\n", 550 DRM_DEBUG_KMS("offset_x = %d, offset_y = %d\n",
561 win_data->offset_x, win_data->offset_y); 551 win_data->offset_x, win_data->offset_y);
@@ -563,7 +553,7 @@ static void fimd_win_mode_set(struct exynos_drm_manager *mgr,
563 win_data->ovl_width, win_data->ovl_height); 553 win_data->ovl_width, win_data->ovl_height);
564 DRM_DEBUG_KMS("paddr = 0x%lx\n", (unsigned long)win_data->dma_addr); 554 DRM_DEBUG_KMS("paddr = 0x%lx\n", (unsigned long)win_data->dma_addr);
565 DRM_DEBUG_KMS("fb_width = %d, crtc_width = %d\n", 555 DRM_DEBUG_KMS("fb_width = %d, crtc_width = %d\n",
566 overlay->fb_width, overlay->crtc_width); 556 plane->fb_width, plane->crtc_width);
567} 557}
568 558
569static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win) 559static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win)
@@ -623,8 +613,8 @@ static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win)
623 /* 613 /*
624 * In case of exynos, setting dma-burst to 16Word causes permanent 614 * In case of exynos, setting dma-burst to 16Word causes permanent
625 * tearing for very small buffers, e.g. cursor buffer. Burst Mode 615 * tearing for very small buffers, e.g. cursor buffer. Burst Mode
626 * switching which is based on overlay size is not recommended as 616 * switching which is based on plane size is not recommended as
627 * overlay size varies alot towards the end of the screen and rapid 617 * plane size varies alot towards the end of the screen and rapid
628 * movement causes unstable DMA which results into iommu crash/tear. 618 * movement causes unstable DMA which results into iommu crash/tear.
629 */ 619 */
630 620
@@ -676,9 +666,9 @@ static void fimd_shadow_protect_win(struct fimd_context *ctx,
676 writel(val, ctx->regs + reg); 666 writel(val, ctx->regs + reg);
677} 667}
678 668
679static void fimd_win_commit(struct exynos_drm_manager *mgr, int zpos) 669static void fimd_win_commit(struct exynos_drm_crtc *crtc, int zpos)
680{ 670{
681 struct fimd_context *ctx = mgr_to_fimd(mgr); 671 struct fimd_context *ctx = crtc->ctx;
682 struct fimd_win_data *win_data; 672 struct fimd_win_data *win_data;
683 int win = zpos; 673 int win = zpos;
684 unsigned long val, alpha, size; 674 unsigned long val, alpha, size;
@@ -799,9 +789,9 @@ static void fimd_win_commit(struct exynos_drm_manager *mgr, int zpos)
799 atomic_set(&ctx->win_updated, 1); 789 atomic_set(&ctx->win_updated, 1);
800} 790}
801 791
802static void fimd_win_disable(struct exynos_drm_manager *mgr, int zpos) 792static void fimd_win_disable(struct exynos_drm_crtc *crtc, int zpos)
803{ 793{
804 struct fimd_context *ctx = mgr_to_fimd(mgr); 794 struct fimd_context *ctx = crtc->ctx;
805 struct fimd_win_data *win_data; 795 struct fimd_win_data *win_data;
806 int win = zpos; 796 int win = zpos;
807 797
@@ -833,9 +823,9 @@ static void fimd_win_disable(struct exynos_drm_manager *mgr, int zpos)
833 win_data->enabled = false; 823 win_data->enabled = false;
834} 824}
835 825
836static void fimd_window_suspend(struct exynos_drm_manager *mgr) 826static void fimd_window_suspend(struct exynos_drm_crtc *crtc)
837{ 827{
838 struct fimd_context *ctx = mgr_to_fimd(mgr); 828 struct fimd_context *ctx = crtc->ctx;
839 struct fimd_win_data *win_data; 829 struct fimd_win_data *win_data;
840 int i; 830 int i;
841 831
@@ -843,13 +833,13 @@ static void fimd_window_suspend(struct exynos_drm_manager *mgr)
843 win_data = &ctx->win_data[i]; 833 win_data = &ctx->win_data[i];
844 win_data->resume = win_data->enabled; 834 win_data->resume = win_data->enabled;
845 if (win_data->enabled) 835 if (win_data->enabled)
846 fimd_win_disable(mgr, i); 836 fimd_win_disable(crtc, i);
847 } 837 }
848} 838}
849 839
850static void fimd_window_resume(struct exynos_drm_manager *mgr) 840static void fimd_window_resume(struct exynos_drm_crtc *crtc)
851{ 841{
852 struct fimd_context *ctx = mgr_to_fimd(mgr); 842 struct fimd_context *ctx = crtc->ctx;
853 struct fimd_win_data *win_data; 843 struct fimd_win_data *win_data;
854 int i; 844 int i;
855 845
@@ -860,26 +850,26 @@ static void fimd_window_resume(struct exynos_drm_manager *mgr)
860 } 850 }
861} 851}
862 852
863static void fimd_apply(struct exynos_drm_manager *mgr) 853static void fimd_apply(struct exynos_drm_crtc *crtc)
864{ 854{
865 struct fimd_context *ctx = mgr_to_fimd(mgr); 855 struct fimd_context *ctx = crtc->ctx;
866 struct fimd_win_data *win_data; 856 struct fimd_win_data *win_data;
867 int i; 857 int i;
868 858
869 for (i = 0; i < WINDOWS_NR; i++) { 859 for (i = 0; i < WINDOWS_NR; i++) {
870 win_data = &ctx->win_data[i]; 860 win_data = &ctx->win_data[i];
871 if (win_data->enabled) 861 if (win_data->enabled)
872 fimd_win_commit(mgr, i); 862 fimd_win_commit(crtc, i);
873 else 863 else
874 fimd_win_disable(mgr, i); 864 fimd_win_disable(crtc, i);
875 } 865 }
876 866
877 fimd_commit(mgr); 867 fimd_commit(crtc);
878} 868}
879 869
880static int fimd_poweron(struct exynos_drm_manager *mgr) 870static int fimd_poweron(struct exynos_drm_crtc *crtc)
881{ 871{
882 struct fimd_context *ctx = mgr_to_fimd(mgr); 872 struct fimd_context *ctx = crtc->ctx;
883 int ret; 873 int ret;
884 874
885 if (!ctx->suspended) 875 if (!ctx->suspended)
@@ -903,16 +893,16 @@ static int fimd_poweron(struct exynos_drm_manager *mgr)
903 893
904 /* if vblank was enabled status, enable it again. */ 894 /* if vblank was enabled status, enable it again. */
905 if (test_and_clear_bit(0, &ctx->irq_flags)) { 895 if (test_and_clear_bit(0, &ctx->irq_flags)) {
906 ret = fimd_enable_vblank(mgr); 896 ret = fimd_enable_vblank(crtc);
907 if (ret) { 897 if (ret) {
908 DRM_ERROR("Failed to re-enable vblank [%d]\n", ret); 898 DRM_ERROR("Failed to re-enable vblank [%d]\n", ret);
909 goto enable_vblank_err; 899 goto enable_vblank_err;
910 } 900 }
911 } 901 }
912 902
913 fimd_window_resume(mgr); 903 fimd_window_resume(crtc);
914 904
915 fimd_apply(mgr); 905 fimd_apply(crtc);
916 906
917 return 0; 907 return 0;
918 908
@@ -925,9 +915,9 @@ bus_clk_err:
925 return ret; 915 return ret;
926} 916}
927 917
928static int fimd_poweroff(struct exynos_drm_manager *mgr) 918static int fimd_poweroff(struct exynos_drm_crtc *crtc)
929{ 919{
930 struct fimd_context *ctx = mgr_to_fimd(mgr); 920 struct fimd_context *ctx = crtc->ctx;
931 921
932 if (ctx->suspended) 922 if (ctx->suspended)
933 return 0; 923 return 0;
@@ -937,7 +927,7 @@ static int fimd_poweroff(struct exynos_drm_manager *mgr)
937 * suspend that connector. Otherwise we might try to scan from 927 * suspend that connector. Otherwise we might try to scan from
938 * a destroyed buffer later. 928 * a destroyed buffer later.
939 */ 929 */
940 fimd_window_suspend(mgr); 930 fimd_window_suspend(crtc);
941 931
942 clk_disable_unprepare(ctx->lcd_clk); 932 clk_disable_unprepare(ctx->lcd_clk);
943 clk_disable_unprepare(ctx->bus_clk); 933 clk_disable_unprepare(ctx->bus_clk);
@@ -948,18 +938,18 @@ static int fimd_poweroff(struct exynos_drm_manager *mgr)
948 return 0; 938 return 0;
949} 939}
950 940
951static void fimd_dpms(struct exynos_drm_manager *mgr, int mode) 941static void fimd_dpms(struct exynos_drm_crtc *crtc, int mode)
952{ 942{
953 DRM_DEBUG_KMS("%s, %d\n", __FILE__, mode); 943 DRM_DEBUG_KMS("%s, %d\n", __FILE__, mode);
954 944
955 switch (mode) { 945 switch (mode) {
956 case DRM_MODE_DPMS_ON: 946 case DRM_MODE_DPMS_ON:
957 fimd_poweron(mgr); 947 fimd_poweron(crtc);
958 break; 948 break;
959 case DRM_MODE_DPMS_STANDBY: 949 case DRM_MODE_DPMS_STANDBY:
960 case DRM_MODE_DPMS_SUSPEND: 950 case DRM_MODE_DPMS_SUSPEND:
961 case DRM_MODE_DPMS_OFF: 951 case DRM_MODE_DPMS_OFF:
962 fimd_poweroff(mgr); 952 fimd_poweroff(crtc);
963 break; 953 break;
964 default: 954 default:
965 DRM_DEBUG_KMS("unspecified mode %d\n", mode); 955 DRM_DEBUG_KMS("unspecified mode %d\n", mode);
@@ -996,9 +986,9 @@ static void fimd_trigger(struct device *dev)
996 atomic_set(&ctx->triggering, 0); 986 atomic_set(&ctx->triggering, 0);
997} 987}
998 988
999static void fimd_te_handler(struct exynos_drm_manager *mgr) 989static void fimd_te_handler(struct exynos_drm_crtc *crtc)
1000{ 990{
1001 struct fimd_context *ctx = mgr_to_fimd(mgr); 991 struct fimd_context *ctx = crtc->ctx;
1002 992
1003 /* Checks the crtc is detached already from encoder */ 993 /* Checks the crtc is detached already from encoder */
1004 if (ctx->pipe < 0 || !ctx->drm_dev) 994 if (ctx->pipe < 0 || !ctx->drm_dev)
@@ -1021,10 +1011,9 @@ static void fimd_te_handler(struct exynos_drm_manager *mgr)
1021 drm_handle_vblank(ctx->drm_dev, ctx->pipe); 1011 drm_handle_vblank(ctx->drm_dev, ctx->pipe);
1022} 1012}
1023 1013
1024static struct exynos_drm_manager_ops fimd_manager_ops = { 1014static struct exynos_drm_crtc_ops fimd_crtc_ops = {
1025 .dpms = fimd_dpms, 1015 .dpms = fimd_dpms,
1026 .mode_fixup = fimd_mode_fixup, 1016 .mode_fixup = fimd_mode_fixup,
1027 .mode_set = fimd_mode_set,
1028 .commit = fimd_commit, 1017 .commit = fimd_commit,
1029 .enable_vblank = fimd_enable_vblank, 1018 .enable_vblank = fimd_enable_vblank,
1030 .disable_vblank = fimd_disable_vblank, 1019 .disable_vblank = fimd_disable_vblank,
@@ -1074,9 +1063,21 @@ static int fimd_bind(struct device *dev, struct device *master, void *data)
1074{ 1063{
1075 struct fimd_context *ctx = dev_get_drvdata(dev); 1064 struct fimd_context *ctx = dev_get_drvdata(dev);
1076 struct drm_device *drm_dev = data; 1065 struct drm_device *drm_dev = data;
1066 int ret;
1067
1068 ctx->crtc = exynos_drm_crtc_create(drm_dev, ctx->pipe,
1069 EXYNOS_DISPLAY_TYPE_LCD,
1070 &fimd_crtc_ops, ctx);
1071 if (IS_ERR(ctx->crtc))
1072 return PTR_ERR(ctx->crtc);
1073
1074 ret = fimd_ctx_initialize(ctx, drm_dev);
1075 if (ret) {
1076 DRM_ERROR("fimd_ctx_initialize failed.\n");
1077 return ret;
1078 }
1079
1077 1080
1078 fimd_mgr_initialize(&ctx->manager, drm_dev);
1079 exynos_drm_crtc_create(&ctx->manager);
1080 if (ctx->display) 1081 if (ctx->display)
1081 exynos_drm_create_enc_conn(drm_dev, ctx->display); 1082 exynos_drm_create_enc_conn(drm_dev, ctx->display);
1082 1083
@@ -1089,12 +1090,12 @@ static void fimd_unbind(struct device *dev, struct device *master,
1089{ 1090{
1090 struct fimd_context *ctx = dev_get_drvdata(dev); 1091 struct fimd_context *ctx = dev_get_drvdata(dev);
1091 1092
1092 fimd_dpms(&ctx->manager, DRM_MODE_DPMS_OFF); 1093 fimd_dpms(ctx->crtc, DRM_MODE_DPMS_OFF);
1093 1094
1094 if (ctx->display) 1095 if (ctx->display)
1095 exynos_dpi_remove(ctx->display); 1096 exynos_dpi_remove(ctx->display);
1096 1097
1097 fimd_mgr_remove(&ctx->manager); 1098 fimd_ctx_remove(ctx);
1098} 1099}
1099 1100
1100static const struct component_ops fimd_component_ops = { 1101static const struct component_ops fimd_component_ops = {
@@ -1108,7 +1109,7 @@ static int fimd_probe(struct platform_device *pdev)
1108 struct fimd_context *ctx; 1109 struct fimd_context *ctx;
1109 struct device_node *i80_if_timings; 1110 struct device_node *i80_if_timings;
1110 struct resource *res; 1111 struct resource *res;
1111 int ret = -EINVAL; 1112 int ret;
1112 1113
1113 if (!dev->of_node) 1114 if (!dev->of_node)
1114 return -ENODEV; 1115 return -ENODEV;
@@ -1117,11 +1118,8 @@ static int fimd_probe(struct platform_device *pdev)
1117 if (!ctx) 1118 if (!ctx)
1118 return -ENOMEM; 1119 return -ENOMEM;
1119 1120
1120 ctx->manager.type = EXYNOS_DISPLAY_TYPE_LCD;
1121 ctx->manager.ops = &fimd_manager_ops;
1122
1123 ret = exynos_drm_component_add(dev, EXYNOS_DEVICE_TYPE_CRTC, 1121 ret = exynos_drm_component_add(dev, EXYNOS_DEVICE_TYPE_CRTC,
1124 ctx->manager.type); 1122 EXYNOS_DISPLAY_TYPE_LCD);
1125 if (ret) 1123 if (ret)
1126 return ret; 1124 return ret;
1127 1125
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
index c7045a663763..358cff67e5ce 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -12,20 +12,13 @@
12#include <drm/drmP.h> 12#include <drm/drmP.h>
13 13
14#include <drm/exynos_drm.h> 14#include <drm/exynos_drm.h>
15#include <drm/drm_plane_helper.h>
15#include "exynos_drm_drv.h" 16#include "exynos_drm_drv.h"
16#include "exynos_drm_crtc.h" 17#include "exynos_drm_crtc.h"
17#include "exynos_drm_fb.h" 18#include "exynos_drm_fb.h"
18#include "exynos_drm_gem.h" 19#include "exynos_drm_gem.h"
19#include "exynos_drm_plane.h" 20#include "exynos_drm_plane.h"
20 21
21#define to_exynos_plane(x) container_of(x, struct exynos_plane, base)
22
23struct exynos_plane {
24 struct drm_plane base;
25 struct exynos_drm_overlay overlay;
26 bool enabled;
27};
28
29static const uint32_t formats[] = { 22static const uint32_t formats[] = {
30 DRM_FORMAT_XRGB8888, 23 DRM_FORMAT_XRGB8888,
31 DRM_FORMAT_ARGB8888, 24 DRM_FORMAT_ARGB8888,
@@ -69,16 +62,9 @@ static int exynos_plane_get_size(int start, unsigned length, unsigned last)
69 return size; 62 return size;
70} 63}
71 64
72int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc, 65int exynos_check_plane(struct drm_plane *plane, struct drm_framebuffer *fb)
73 struct drm_framebuffer *fb, int crtc_x, int crtc_y,
74 unsigned int crtc_w, unsigned int crtc_h,
75 uint32_t src_x, uint32_t src_y,
76 uint32_t src_w, uint32_t src_h)
77{ 66{
78 struct exynos_plane *exynos_plane = to_exynos_plane(plane); 67 struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
79 struct exynos_drm_overlay *overlay = &exynos_plane->overlay;
80 unsigned int actual_w;
81 unsigned int actual_h;
82 int nr; 68 int nr;
83 int i; 69 int i;
84 70
@@ -91,12 +77,26 @@ int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,
91 return -EFAULT; 77 return -EFAULT;
92 } 78 }
93 79
94 overlay->dma_addr[i] = buffer->dma_addr; 80 exynos_plane->dma_addr[i] = buffer->dma_addr;
95 81
96 DRM_DEBUG_KMS("buffer: %d, dma_addr = 0x%lx\n", 82 DRM_DEBUG_KMS("buffer: %d, dma_addr = 0x%lx\n",
97 i, (unsigned long)overlay->dma_addr[i]); 83 i, (unsigned long)exynos_plane->dma_addr[i]);
98 } 84 }
99 85
86 return 0;
87}
88
89void exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,
90 struct drm_framebuffer *fb, int crtc_x, int crtc_y,
91 unsigned int crtc_w, unsigned int crtc_h,
92 uint32_t src_x, uint32_t src_y,
93 uint32_t src_w, uint32_t src_h)
94{
95 struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
96 struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
97 unsigned int actual_w;
98 unsigned int actual_h;
99
100 actual_w = exynos_plane_get_size(crtc_x, crtc_w, crtc->mode.hdisplay); 100 actual_w = exynos_plane_get_size(crtc_x, crtc_w, crtc->mode.hdisplay);
101 actual_h = exynos_plane_get_size(crtc_y, crtc_h, crtc->mode.vdisplay); 101 actual_h = exynos_plane_get_size(crtc_y, crtc_h, crtc->mode.vdisplay);
102 102
@@ -113,84 +113,86 @@ int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,
113 } 113 }
114 114
115 /* set drm framebuffer data. */ 115 /* set drm framebuffer data. */
116 overlay->fb_x = src_x; 116 exynos_plane->fb_x = src_x;
117 overlay->fb_y = src_y; 117 exynos_plane->fb_y = src_y;
118 overlay->fb_width = fb->width; 118 exynos_plane->fb_width = fb->width;
119 overlay->fb_height = fb->height; 119 exynos_plane->fb_height = fb->height;
120 overlay->src_width = src_w; 120 exynos_plane->src_width = src_w;
121 overlay->src_height = src_h; 121 exynos_plane->src_height = src_h;
122 overlay->bpp = fb->bits_per_pixel; 122 exynos_plane->bpp = fb->bits_per_pixel;
123 overlay->pitch = fb->pitches[0]; 123 exynos_plane->pitch = fb->pitches[0];
124 overlay->pixel_format = fb->pixel_format; 124 exynos_plane->pixel_format = fb->pixel_format;
125 125
126 /* set overlay range to be displayed. */ 126 /* set plane range to be displayed. */
127 overlay->crtc_x = crtc_x; 127 exynos_plane->crtc_x = crtc_x;
128 overlay->crtc_y = crtc_y; 128 exynos_plane->crtc_y = crtc_y;
129 overlay->crtc_width = actual_w; 129 exynos_plane->crtc_width = actual_w;
130 overlay->crtc_height = actual_h; 130 exynos_plane->crtc_height = actual_h;
131 131
132 /* set drm mode data. */ 132 /* set drm mode data. */
133 overlay->mode_width = crtc->mode.hdisplay; 133 exynos_plane->mode_width = crtc->mode.hdisplay;
134 overlay->mode_height = crtc->mode.vdisplay; 134 exynos_plane->mode_height = crtc->mode.vdisplay;
135 overlay->refresh = crtc->mode.vrefresh; 135 exynos_plane->refresh = crtc->mode.vrefresh;
136 overlay->scan_flag = crtc->mode.flags; 136 exynos_plane->scan_flag = crtc->mode.flags;
137 137
138 DRM_DEBUG_KMS("overlay : offset_x/y(%d,%d), width/height(%d,%d)", 138 DRM_DEBUG_KMS("plane : offset_x/y(%d,%d), width/height(%d,%d)",
139 overlay->crtc_x, overlay->crtc_y, 139 exynos_plane->crtc_x, exynos_plane->crtc_y,
140 overlay->crtc_width, overlay->crtc_height); 140 exynos_plane->crtc_width, exynos_plane->crtc_height);
141 141
142 plane->crtc = crtc; 142 plane->crtc = crtc;
143 143
144 exynos_drm_crtc_plane_mode_set(crtc, overlay); 144 if (exynos_crtc->ops->win_mode_set)
145 145 exynos_crtc->ops->win_mode_set(exynos_crtc, exynos_plane);
146 return 0;
147}
148
149void exynos_plane_commit(struct drm_plane *plane)
150{
151 struct exynos_plane *exynos_plane = to_exynos_plane(plane);
152 struct exynos_drm_overlay *overlay = &exynos_plane->overlay;
153
154 exynos_drm_crtc_plane_commit(plane->crtc, overlay->zpos);
155} 146}
156 147
157void exynos_plane_dpms(struct drm_plane *plane, int mode) 148void exynos_plane_dpms(struct drm_plane *plane, int mode)
158{ 149{
159 struct exynos_plane *exynos_plane = to_exynos_plane(plane); 150 struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
160 struct exynos_drm_overlay *overlay = &exynos_plane->overlay; 151 struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(plane->crtc);
161 152
162 if (mode == DRM_MODE_DPMS_ON) { 153 if (mode == DRM_MODE_DPMS_ON) {
163 if (exynos_plane->enabled) 154 if (exynos_plane->enabled)
164 return; 155 return;
165 156
166 exynos_drm_crtc_plane_enable(plane->crtc, overlay->zpos); 157 if (exynos_crtc->ops->win_enable)
158 exynos_crtc->ops->win_enable(exynos_crtc,
159 exynos_plane->zpos);
160
167 exynos_plane->enabled = true; 161 exynos_plane->enabled = true;
168 } else { 162 } else {
169 if (!exynos_plane->enabled) 163 if (!exynos_plane->enabled)
170 return; 164 return;
171 165
172 exynos_drm_crtc_plane_disable(plane->crtc, overlay->zpos); 166 if (exynos_crtc->ops->win_disable)
167 exynos_crtc->ops->win_disable(exynos_crtc,
168 exynos_plane->zpos);
169
173 exynos_plane->enabled = false; 170 exynos_plane->enabled = false;
174 } 171 }
175} 172}
176 173
177static int 174int
178exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, 175exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
179 struct drm_framebuffer *fb, int crtc_x, int crtc_y, 176 struct drm_framebuffer *fb, int crtc_x, int crtc_y,
180 unsigned int crtc_w, unsigned int crtc_h, 177 unsigned int crtc_w, unsigned int crtc_h,
181 uint32_t src_x, uint32_t src_y, 178 uint32_t src_x, uint32_t src_y,
182 uint32_t src_w, uint32_t src_h) 179 uint32_t src_w, uint32_t src_h)
183{ 180{
181
182 struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
183 struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
184 int ret; 184 int ret;
185 185
186 ret = exynos_plane_mode_set(plane, crtc, fb, crtc_x, crtc_y, 186 ret = exynos_check_plane(plane, fb);
187 crtc_w, crtc_h, src_x >> 16, src_y >> 16,
188 src_w >> 16, src_h >> 16);
189 if (ret < 0) 187 if (ret < 0)
190 return ret; 188 return ret;
191 189
192 exynos_plane_commit(plane); 190 exynos_plane_mode_set(plane, crtc, fb, crtc_x, crtc_y,
193 exynos_plane_dpms(plane, DRM_MODE_DPMS_ON); 191 crtc_w, crtc_h, src_x >> 16, src_y >> 16,
192 src_w >> 16, src_h >> 16);
193
194 if (exynos_crtc->ops->win_commit)
195 exynos_crtc->ops->win_commit(exynos_crtc, exynos_plane->zpos);
194 196
195 return 0; 197 return 0;
196} 198}
@@ -204,7 +206,7 @@ static int exynos_disable_plane(struct drm_plane *plane)
204 206
205static void exynos_plane_destroy(struct drm_plane *plane) 207static void exynos_plane_destroy(struct drm_plane *plane)
206{ 208{
207 struct exynos_plane *exynos_plane = to_exynos_plane(plane); 209 struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
208 210
209 exynos_disable_plane(plane); 211 exynos_disable_plane(plane);
210 drm_plane_cleanup(plane); 212 drm_plane_cleanup(plane);
@@ -216,11 +218,11 @@ static int exynos_plane_set_property(struct drm_plane *plane,
216 uint64_t val) 218 uint64_t val)
217{ 219{
218 struct drm_device *dev = plane->dev; 220 struct drm_device *dev = plane->dev;
219 struct exynos_plane *exynos_plane = to_exynos_plane(plane); 221 struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
220 struct exynos_drm_private *dev_priv = dev->dev_private; 222 struct exynos_drm_private *dev_priv = dev->dev_private;
221 223
222 if (property == dev_priv->plane_zpos_property) { 224 if (property == dev_priv->plane_zpos_property) {
223 exynos_plane->overlay.zpos = val; 225 exynos_plane->zpos = val;
224 return 0; 226 return 0;
225 } 227 }
226 228
@@ -257,10 +259,10 @@ struct drm_plane *exynos_plane_init(struct drm_device *dev,
257 unsigned long possible_crtcs, 259 unsigned long possible_crtcs,
258 enum drm_plane_type type) 260 enum drm_plane_type type)
259{ 261{
260 struct exynos_plane *exynos_plane; 262 struct exynos_drm_plane *exynos_plane;
261 int err; 263 int err;
262 264
263 exynos_plane = kzalloc(sizeof(struct exynos_plane), GFP_KERNEL); 265 exynos_plane = kzalloc(sizeof(struct exynos_drm_plane), GFP_KERNEL);
264 if (!exynos_plane) 266 if (!exynos_plane)
265 return ERR_PTR(-ENOMEM); 267 return ERR_PTR(-ENOMEM);
266 268
@@ -274,7 +276,7 @@ struct drm_plane *exynos_plane_init(struct drm_device *dev,
274 } 276 }
275 277
276 if (type == DRM_PLANE_TYPE_PRIMARY) 278 if (type == DRM_PLANE_TYPE_PRIMARY)
277 exynos_plane->overlay.zpos = DEFAULT_ZPOS; 279 exynos_plane->zpos = DEFAULT_ZPOS;
278 else 280 else
279 exynos_plane_attach_zpos_property(&exynos_plane->base); 281 exynos_plane_attach_zpos_property(&exynos_plane->base);
280 282
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.h b/drivers/gpu/drm/exynos/exynos_drm_plane.h
index 0d1986b115f8..59d40755095b 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.h
@@ -9,12 +9,17 @@
9 * 9 *
10 */ 10 */
11 11
12int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc, 12int exynos_check_plane(struct drm_plane *plane, struct drm_framebuffer *fb);
13 struct drm_framebuffer *fb, int crtc_x, int crtc_y, 13void exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,
14 unsigned int crtc_w, unsigned int crtc_h, 14 struct drm_framebuffer *fb, int crtc_x, int crtc_y,
15 uint32_t src_x, uint32_t src_y, 15 unsigned int crtc_w, unsigned int crtc_h,
16 uint32_t src_w, uint32_t src_h); 16 uint32_t src_x, uint32_t src_y,
17void exynos_plane_commit(struct drm_plane *plane); 17 uint32_t src_w, uint32_t src_h);
18int exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
19 struct drm_framebuffer *fb, int crtc_x, int crtc_y,
20 unsigned int crtc_w, unsigned int crtc_h,
21 uint32_t src_x, uint32_t src_y,
22 uint32_t src_w, uint32_t src_h);
18void exynos_plane_dpms(struct drm_plane *plane, int mode); 23void exynos_plane_dpms(struct drm_plane *plane, int mode);
19struct drm_plane *exynos_plane_init(struct drm_device *dev, 24struct drm_plane *exynos_plane_init(struct drm_device *dev,
20 unsigned long possible_crtcs, 25 unsigned long possible_crtcs,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
index 45899fb63272..9c8300edd348 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
@@ -47,11 +47,10 @@ struct vidi_win_data {
47}; 47};
48 48
49struct vidi_context { 49struct vidi_context {
50 struct exynos_drm_manager manager;
51 struct exynos_drm_display display; 50 struct exynos_drm_display display;
52 struct platform_device *pdev; 51 struct platform_device *pdev;
53 struct drm_device *drm_dev; 52 struct drm_device *drm_dev;
54 struct drm_crtc *crtc; 53 struct exynos_drm_crtc *crtc;
55 struct drm_encoder *encoder; 54 struct drm_encoder *encoder;
56 struct drm_connector connector; 55 struct drm_connector connector;
57 struct vidi_win_data win_data[WINDOWS_NR]; 56 struct vidi_win_data win_data[WINDOWS_NR];
@@ -68,11 +67,6 @@ struct vidi_context {
68 int pipe; 67 int pipe;
69}; 68};
70 69
71static inline struct vidi_context *manager_to_vidi(struct exynos_drm_manager *m)
72{
73 return container_of(m, struct vidi_context, manager);
74}
75
76static inline struct vidi_context *display_to_vidi(struct exynos_drm_display *d) 70static inline struct vidi_context *display_to_vidi(struct exynos_drm_display *d)
77{ 71{
78 return container_of(d, struct vidi_context, display); 72 return container_of(d, struct vidi_context, display);
@@ -103,34 +97,23 @@ static const char fake_edid_info[] = {
103 0x00, 0x00, 0x00, 0x06 97 0x00, 0x00, 0x00, 0x06
104}; 98};
105 99
106static void vidi_apply(struct exynos_drm_manager *mgr) 100static void vidi_apply(struct exynos_drm_crtc *crtc)
107{ 101{
108 struct vidi_context *ctx = manager_to_vidi(mgr); 102 struct vidi_context *ctx = crtc->ctx;
109 struct exynos_drm_manager_ops *mgr_ops = mgr->ops; 103 struct exynos_drm_crtc_ops *crtc_ops = crtc->ops;
110 struct vidi_win_data *win_data; 104 struct vidi_win_data *win_data;
111 int i; 105 int i;
112 106
113 for (i = 0; i < WINDOWS_NR; i++) { 107 for (i = 0; i < WINDOWS_NR; i++) {
114 win_data = &ctx->win_data[i]; 108 win_data = &ctx->win_data[i];
115 if (win_data->enabled && (mgr_ops && mgr_ops->win_commit)) 109 if (win_data->enabled && (crtc_ops && crtc_ops->win_commit))
116 mgr_ops->win_commit(mgr, i); 110 crtc_ops->win_commit(crtc, i);
117 } 111 }
118
119 if (mgr_ops && mgr_ops->commit)
120 mgr_ops->commit(mgr);
121}
122
123static void vidi_commit(struct exynos_drm_manager *mgr)
124{
125 struct vidi_context *ctx = manager_to_vidi(mgr);
126
127 if (ctx->suspended)
128 return;
129} 112}
130 113
131static int vidi_enable_vblank(struct exynos_drm_manager *mgr) 114static int vidi_enable_vblank(struct exynos_drm_crtc *crtc)
132{ 115{
133 struct vidi_context *ctx = manager_to_vidi(mgr); 116 struct vidi_context *ctx = crtc->ctx;
134 117
135 if (ctx->suspended) 118 if (ctx->suspended)
136 return -EPERM; 119 return -EPERM;
@@ -143,16 +126,16 @@ static int vidi_enable_vblank(struct exynos_drm_manager *mgr)
143 /* 126 /*
144 * in case of page flip request, vidi_finish_pageflip function 127 * in case of page flip request, vidi_finish_pageflip function
145 * will not be called because direct_vblank is true and then 128 * will not be called because direct_vblank is true and then
146 * that function will be called by manager_ops->win_commit callback 129 * that function will be called by crtc_ops->win_commit callback
147 */ 130 */
148 schedule_work(&ctx->work); 131 schedule_work(&ctx->work);
149 132
150 return 0; 133 return 0;
151} 134}
152 135
153static void vidi_disable_vblank(struct exynos_drm_manager *mgr) 136static void vidi_disable_vblank(struct exynos_drm_crtc *crtc)
154{ 137{
155 struct vidi_context *ctx = manager_to_vidi(mgr); 138 struct vidi_context *ctx = crtc->ctx;
156 139
157 if (ctx->suspended) 140 if (ctx->suspended)
158 return; 141 return;
@@ -161,44 +144,44 @@ static void vidi_disable_vblank(struct exynos_drm_manager *mgr)
161 ctx->vblank_on = false; 144 ctx->vblank_on = false;
162} 145}
163 146
164static void vidi_win_mode_set(struct exynos_drm_manager *mgr, 147static void vidi_win_mode_set(struct exynos_drm_crtc *crtc,
165 struct exynos_drm_overlay *overlay) 148 struct exynos_drm_plane *plane)
166{ 149{
167 struct vidi_context *ctx = manager_to_vidi(mgr); 150 struct vidi_context *ctx = crtc->ctx;
168 struct vidi_win_data *win_data; 151 struct vidi_win_data *win_data;
169 int win; 152 int win;
170 unsigned long offset; 153 unsigned long offset;
171 154
172 if (!overlay) { 155 if (!plane) {
173 DRM_ERROR("overlay is NULL\n"); 156 DRM_ERROR("plane is NULL\n");
174 return; 157 return;
175 } 158 }
176 159
177 win = overlay->zpos; 160 win = plane->zpos;
178 if (win == DEFAULT_ZPOS) 161 if (win == DEFAULT_ZPOS)
179 win = ctx->default_win; 162 win = ctx->default_win;
180 163
181 if (win < 0 || win >= WINDOWS_NR) 164 if (win < 0 || win >= WINDOWS_NR)
182 return; 165 return;
183 166
184 offset = overlay->fb_x * (overlay->bpp >> 3); 167 offset = plane->fb_x * (plane->bpp >> 3);
185 offset += overlay->fb_y * overlay->pitch; 168 offset += plane->fb_y * plane->pitch;
186 169
187 DRM_DEBUG_KMS("offset = 0x%lx, pitch = %x\n", offset, overlay->pitch); 170 DRM_DEBUG_KMS("offset = 0x%lx, pitch = %x\n", offset, plane->pitch);
188 171
189 win_data = &ctx->win_data[win]; 172 win_data = &ctx->win_data[win];
190 173
191 win_data->offset_x = overlay->crtc_x; 174 win_data->offset_x = plane->crtc_x;
192 win_data->offset_y = overlay->crtc_y; 175 win_data->offset_y = plane->crtc_y;
193 win_data->ovl_width = overlay->crtc_width; 176 win_data->ovl_width = plane->crtc_width;
194 win_data->ovl_height = overlay->crtc_height; 177 win_data->ovl_height = plane->crtc_height;
195 win_data->fb_width = overlay->fb_width; 178 win_data->fb_width = plane->fb_width;
196 win_data->fb_height = overlay->fb_height; 179 win_data->fb_height = plane->fb_height;
197 win_data->dma_addr = overlay->dma_addr[0] + offset; 180 win_data->dma_addr = plane->dma_addr[0] + offset;
198 win_data->bpp = overlay->bpp; 181 win_data->bpp = plane->bpp;
199 win_data->buf_offsize = (overlay->fb_width - overlay->crtc_width) * 182 win_data->buf_offsize = (plane->fb_width - plane->crtc_width) *
200 (overlay->bpp >> 3); 183 (plane->bpp >> 3);
201 win_data->line_size = overlay->crtc_width * (overlay->bpp >> 3); 184 win_data->line_size = plane->crtc_width * (plane->bpp >> 3);
202 185
203 /* 186 /*
204 * some parts of win_data should be transferred to user side 187 * some parts of win_data should be transferred to user side
@@ -211,12 +194,12 @@ static void vidi_win_mode_set(struct exynos_drm_manager *mgr,
211 win_data->ovl_width, win_data->ovl_height); 194 win_data->ovl_width, win_data->ovl_height);
212 DRM_DEBUG_KMS("paddr = 0x%lx\n", (unsigned long)win_data->dma_addr); 195 DRM_DEBUG_KMS("paddr = 0x%lx\n", (unsigned long)win_data->dma_addr);
213 DRM_DEBUG_KMS("fb_width = %d, crtc_width = %d\n", 196 DRM_DEBUG_KMS("fb_width = %d, crtc_width = %d\n",
214 overlay->fb_width, overlay->crtc_width); 197 plane->fb_width, plane->crtc_width);
215} 198}
216 199
217static void vidi_win_commit(struct exynos_drm_manager *mgr, int zpos) 200static void vidi_win_commit(struct exynos_drm_crtc *crtc, int zpos)
218{ 201{
219 struct vidi_context *ctx = manager_to_vidi(mgr); 202 struct vidi_context *ctx = crtc->ctx;
220 struct vidi_win_data *win_data; 203 struct vidi_win_data *win_data;
221 int win = zpos; 204 int win = zpos;
222 205
@@ -239,9 +222,9 @@ static void vidi_win_commit(struct exynos_drm_manager *mgr, int zpos)
239 schedule_work(&ctx->work); 222 schedule_work(&ctx->work);
240} 223}
241 224
242static void vidi_win_disable(struct exynos_drm_manager *mgr, int zpos) 225static void vidi_win_disable(struct exynos_drm_crtc *crtc, int zpos)
243{ 226{
244 struct vidi_context *ctx = manager_to_vidi(mgr); 227 struct vidi_context *ctx = crtc->ctx;
245 struct vidi_win_data *win_data; 228 struct vidi_win_data *win_data;
246 int win = zpos; 229 int win = zpos;
247 230
@@ -257,9 +240,9 @@ static void vidi_win_disable(struct exynos_drm_manager *mgr, int zpos)
257 /* TODO. */ 240 /* TODO. */
258} 241}
259 242
260static int vidi_power_on(struct exynos_drm_manager *mgr, bool enable) 243static int vidi_power_on(struct exynos_drm_crtc *crtc, bool enable)
261{ 244{
262 struct vidi_context *ctx = manager_to_vidi(mgr); 245 struct vidi_context *ctx = crtc->ctx;
263 246
264 DRM_DEBUG_KMS("%s\n", __FILE__); 247 DRM_DEBUG_KMS("%s\n", __FILE__);
265 248
@@ -271,9 +254,9 @@ static int vidi_power_on(struct exynos_drm_manager *mgr, bool enable)
271 254
272 /* if vblank was enabled status, enable it again. */ 255 /* if vblank was enabled status, enable it again. */
273 if (test_and_clear_bit(0, &ctx->irq_flags)) 256 if (test_and_clear_bit(0, &ctx->irq_flags))
274 vidi_enable_vblank(mgr); 257 vidi_enable_vblank(crtc);
275 258
276 vidi_apply(mgr); 259 vidi_apply(crtc);
277 } else { 260 } else {
278 ctx->suspended = true; 261 ctx->suspended = true;
279 } 262 }
@@ -281,9 +264,9 @@ static int vidi_power_on(struct exynos_drm_manager *mgr, bool enable)
281 return 0; 264 return 0;
282} 265}
283 266
284static void vidi_dpms(struct exynos_drm_manager *mgr, int mode) 267static void vidi_dpms(struct exynos_drm_crtc *crtc, int mode)
285{ 268{
286 struct vidi_context *ctx = manager_to_vidi(mgr); 269 struct vidi_context *ctx = crtc->ctx;
287 270
288 DRM_DEBUG_KMS("%d\n", mode); 271 DRM_DEBUG_KMS("%d\n", mode);
289 272
@@ -291,12 +274,12 @@ static void vidi_dpms(struct exynos_drm_manager *mgr, int mode)
291 274
292 switch (mode) { 275 switch (mode) {
293 case DRM_MODE_DPMS_ON: 276 case DRM_MODE_DPMS_ON:
294 vidi_power_on(mgr, true); 277 vidi_power_on(crtc, true);
295 break; 278 break;
296 case DRM_MODE_DPMS_STANDBY: 279 case DRM_MODE_DPMS_STANDBY:
297 case DRM_MODE_DPMS_SUSPEND: 280 case DRM_MODE_DPMS_SUSPEND:
298 case DRM_MODE_DPMS_OFF: 281 case DRM_MODE_DPMS_OFF:
299 vidi_power_on(mgr, false); 282 vidi_power_on(crtc, false);
300 break; 283 break;
301 default: 284 default:
302 DRM_DEBUG_KMS("unspecified mode %d\n", mode); 285 DRM_DEBUG_KMS("unspecified mode %d\n", mode);
@@ -306,21 +289,19 @@ static void vidi_dpms(struct exynos_drm_manager *mgr, int mode)
306 mutex_unlock(&ctx->lock); 289 mutex_unlock(&ctx->lock);
307} 290}
308 291
309static int vidi_mgr_initialize(struct exynos_drm_manager *mgr, 292static int vidi_ctx_initialize(struct vidi_context *ctx,
310 struct drm_device *drm_dev) 293 struct drm_device *drm_dev)
311{ 294{
312 struct vidi_context *ctx = manager_to_vidi(mgr);
313 struct exynos_drm_private *priv = drm_dev->dev_private; 295 struct exynos_drm_private *priv = drm_dev->dev_private;
314 296
315 mgr->drm_dev = ctx->drm_dev = drm_dev; 297 ctx->drm_dev = drm_dev;
316 mgr->pipe = ctx->pipe = priv->pipe++; 298 ctx->pipe = priv->pipe++;
317 299
318 return 0; 300 return 0;
319} 301}
320 302
321static struct exynos_drm_manager_ops vidi_manager_ops = { 303static struct exynos_drm_crtc_ops vidi_crtc_ops = {
322 .dpms = vidi_dpms, 304 .dpms = vidi_dpms,
323 .commit = vidi_commit,
324 .enable_vblank = vidi_enable_vblank, 305 .enable_vblank = vidi_enable_vblank,
325 .disable_vblank = vidi_disable_vblank, 306 .disable_vblank = vidi_disable_vblank,
326 .win_mode_set = vidi_win_mode_set, 307 .win_mode_set = vidi_win_mode_set,
@@ -565,21 +546,21 @@ static int vidi_bind(struct device *dev, struct device *master, void *data)
565{ 546{
566 struct vidi_context *ctx = dev_get_drvdata(dev); 547 struct vidi_context *ctx = dev_get_drvdata(dev);
567 struct drm_device *drm_dev = data; 548 struct drm_device *drm_dev = data;
568 struct drm_crtc *crtc = ctx->crtc;
569 int ret; 549 int ret;
570 550
571 vidi_mgr_initialize(&ctx->manager, drm_dev); 551 ctx->crtc = exynos_drm_crtc_create(drm_dev, ctx->pipe,
572 552 EXYNOS_DISPLAY_TYPE_VIDI,
573 ret = exynos_drm_crtc_create(&ctx->manager); 553 &vidi_crtc_ops, ctx);
574 if (ret) { 554 if (IS_ERR(ctx->crtc)) {
575 DRM_ERROR("failed to create crtc.\n"); 555 DRM_ERROR("failed to create crtc.\n");
576 return ret; 556 return PTR_ERR(ctx->crtc);
577 } 557 }
578 558
559 vidi_ctx_initialize(ctx, drm_dev);
560
579 ret = exynos_drm_create_enc_conn(drm_dev, &ctx->display); 561 ret = exynos_drm_create_enc_conn(drm_dev, &ctx->display);
580 if (ret) { 562 if (ret) {
581 crtc->funcs->destroy(crtc); 563 ctx->crtc->base.funcs->destroy(&ctx->crtc->base);
582 DRM_ERROR("failed to create encoder and connector.\n");
583 return ret; 564 return ret;
584 } 565 }
585 566
@@ -605,15 +586,13 @@ static int vidi_probe(struct platform_device *pdev)
605 if (!ctx) 586 if (!ctx)
606 return -ENOMEM; 587 return -ENOMEM;
607 588
608 ctx->manager.type = EXYNOS_DISPLAY_TYPE_VIDI;
609 ctx->manager.ops = &vidi_manager_ops;
610 ctx->display.type = EXYNOS_DISPLAY_TYPE_VIDI; 589 ctx->display.type = EXYNOS_DISPLAY_TYPE_VIDI;
611 ctx->display.ops = &vidi_display_ops; 590 ctx->display.ops = &vidi_display_ops;
612 ctx->default_win = 0; 591 ctx->default_win = 0;
613 ctx->pdev = pdev; 592 ctx->pdev = pdev;
614 593
615 ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC, 594 ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC,
616 ctx->manager.type); 595 EXYNOS_DISPLAY_TYPE_VIDI);
617 if (ret) 596 if (ret)
618 return ret; 597 return ret;
619 598
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index 064ed6597def..ed44cd4f01f7 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -84,10 +84,10 @@ enum mixer_version_id {
84}; 84};
85 85
86struct mixer_context { 86struct mixer_context {
87 struct exynos_drm_manager manager;
88 struct platform_device *pdev; 87 struct platform_device *pdev;
89 struct device *dev; 88 struct device *dev;
90 struct drm_device *drm_dev; 89 struct drm_device *drm_dev;
90 struct exynos_drm_crtc *crtc;
91 int pipe; 91 int pipe;
92 bool interlace; 92 bool interlace;
93 bool powered; 93 bool powered;
@@ -103,11 +103,6 @@ struct mixer_context {
103 atomic_t wait_vsync_event; 103 atomic_t wait_vsync_event;
104}; 104};
105 105
106static inline struct mixer_context *mgr_to_mixer(struct exynos_drm_manager *mgr)
107{
108 return container_of(mgr, struct mixer_context, manager);
109}
110
111struct mixer_drv_data { 106struct mixer_drv_data {
112 enum mixer_version_id version; 107 enum mixer_version_id version;
113 bool is_vp_enabled; 108 bool is_vp_enabled;
@@ -854,16 +849,15 @@ static int vp_resources_init(struct mixer_context *mixer_ctx)
854 return 0; 849 return 0;
855} 850}
856 851
857static int mixer_initialize(struct exynos_drm_manager *mgr, 852static int mixer_initialize(struct mixer_context *mixer_ctx,
858 struct drm_device *drm_dev) 853 struct drm_device *drm_dev)
859{ 854{
860 int ret; 855 int ret;
861 struct mixer_context *mixer_ctx = mgr_to_mixer(mgr);
862 struct exynos_drm_private *priv; 856 struct exynos_drm_private *priv;
863 priv = drm_dev->dev_private; 857 priv = drm_dev->dev_private;
864 858
865 mgr->drm_dev = mixer_ctx->drm_dev = drm_dev; 859 mixer_ctx->drm_dev = drm_dev;
866 mgr->pipe = mixer_ctx->pipe = priv->pipe++; 860 mixer_ctx->pipe = priv->pipe++;
867 861
868 /* acquire resources: regs, irqs, clocks */ 862 /* acquire resources: regs, irqs, clocks */
869 ret = mixer_resources_init(mixer_ctx); 863 ret = mixer_resources_init(mixer_ctx);
@@ -887,17 +881,15 @@ static int mixer_initialize(struct exynos_drm_manager *mgr,
887 return drm_iommu_attach_device(mixer_ctx->drm_dev, mixer_ctx->dev); 881 return drm_iommu_attach_device(mixer_ctx->drm_dev, mixer_ctx->dev);
888} 882}
889 883
890static void mixer_mgr_remove(struct exynos_drm_manager *mgr) 884static void mixer_ctx_remove(struct mixer_context *mixer_ctx)
891{ 885{
892 struct mixer_context *mixer_ctx = mgr_to_mixer(mgr);
893
894 if (is_drm_iommu_supported(mixer_ctx->drm_dev)) 886 if (is_drm_iommu_supported(mixer_ctx->drm_dev))
895 drm_iommu_detach_device(mixer_ctx->drm_dev, mixer_ctx->dev); 887 drm_iommu_detach_device(mixer_ctx->drm_dev, mixer_ctx->dev);
896} 888}
897 889
898static int mixer_enable_vblank(struct exynos_drm_manager *mgr) 890static int mixer_enable_vblank(struct exynos_drm_crtc *crtc)
899{ 891{
900 struct mixer_context *mixer_ctx = mgr_to_mixer(mgr); 892 struct mixer_context *mixer_ctx = crtc->ctx;
901 struct mixer_resources *res = &mixer_ctx->mixer_res; 893 struct mixer_resources *res = &mixer_ctx->mixer_res;
902 894
903 if (!mixer_ctx->powered) { 895 if (!mixer_ctx->powered) {
@@ -912,34 +904,34 @@ static int mixer_enable_vblank(struct exynos_drm_manager *mgr)
912 return 0; 904 return 0;
913} 905}
914 906
915static void mixer_disable_vblank(struct exynos_drm_manager *mgr) 907static void mixer_disable_vblank(struct exynos_drm_crtc *crtc)
916{ 908{
917 struct mixer_context *mixer_ctx = mgr_to_mixer(mgr); 909 struct mixer_context *mixer_ctx = crtc->ctx;
918 struct mixer_resources *res = &mixer_ctx->mixer_res; 910 struct mixer_resources *res = &mixer_ctx->mixer_res;
919 911
920 /* disable vsync interrupt */ 912 /* disable vsync interrupt */
921 mixer_reg_writemask(res, MXR_INT_EN, 0, MXR_INT_EN_VSYNC); 913 mixer_reg_writemask(res, MXR_INT_EN, 0, MXR_INT_EN_VSYNC);
922} 914}
923 915
924static void mixer_win_mode_set(struct exynos_drm_manager *mgr, 916static void mixer_win_mode_set(struct exynos_drm_crtc *crtc,
925 struct exynos_drm_overlay *overlay) 917 struct exynos_drm_plane *plane)
926{ 918{
927 struct mixer_context *mixer_ctx = mgr_to_mixer(mgr); 919 struct mixer_context *mixer_ctx = crtc->ctx;
928 struct hdmi_win_data *win_data; 920 struct hdmi_win_data *win_data;
929 int win; 921 int win;
930 922
931 if (!overlay) { 923 if (!plane) {
932 DRM_ERROR("overlay is NULL\n"); 924 DRM_ERROR("plane is NULL\n");
933 return; 925 return;
934 } 926 }
935 927
936 DRM_DEBUG_KMS("set [%d]x[%d] at (%d,%d) to [%d]x[%d] at (%d,%d)\n", 928 DRM_DEBUG_KMS("set [%d]x[%d] at (%d,%d) to [%d]x[%d] at (%d,%d)\n",
937 overlay->fb_width, overlay->fb_height, 929 plane->fb_width, plane->fb_height,
938 overlay->fb_x, overlay->fb_y, 930 plane->fb_x, plane->fb_y,
939 overlay->crtc_width, overlay->crtc_height, 931 plane->crtc_width, plane->crtc_height,
940 overlay->crtc_x, overlay->crtc_y); 932 plane->crtc_x, plane->crtc_y);
941 933
942 win = overlay->zpos; 934 win = plane->zpos;
943 if (win == DEFAULT_ZPOS) 935 if (win == DEFAULT_ZPOS)
944 win = MIXER_DEFAULT_WIN; 936 win = MIXER_DEFAULT_WIN;
945 937
@@ -950,32 +942,32 @@ static void mixer_win_mode_set(struct exynos_drm_manager *mgr,
950 942
951 win_data = &mixer_ctx->win_data[win]; 943 win_data = &mixer_ctx->win_data[win];
952 944
953 win_data->dma_addr = overlay->dma_addr[0]; 945 win_data->dma_addr = plane->dma_addr[0];
954 win_data->chroma_dma_addr = overlay->dma_addr[1]; 946 win_data->chroma_dma_addr = plane->dma_addr[1];
955 win_data->pixel_format = overlay->pixel_format; 947 win_data->pixel_format = plane->pixel_format;
956 win_data->bpp = overlay->bpp; 948 win_data->bpp = plane->bpp;
957 949
958 win_data->crtc_x = overlay->crtc_x; 950 win_data->crtc_x = plane->crtc_x;
959 win_data->crtc_y = overlay->crtc_y; 951 win_data->crtc_y = plane->crtc_y;
960 win_data->crtc_width = overlay->crtc_width; 952 win_data->crtc_width = plane->crtc_width;
961 win_data->crtc_height = overlay->crtc_height; 953 win_data->crtc_height = plane->crtc_height;
962 954
963 win_data->fb_x = overlay->fb_x; 955 win_data->fb_x = plane->fb_x;
964 win_data->fb_y = overlay->fb_y; 956 win_data->fb_y = plane->fb_y;
965 win_data->fb_width = overlay->fb_width; 957 win_data->fb_width = plane->fb_width;
966 win_data->fb_height = overlay->fb_height; 958 win_data->fb_height = plane->fb_height;
967 win_data->src_width = overlay->src_width; 959 win_data->src_width = plane->src_width;
968 win_data->src_height = overlay->src_height; 960 win_data->src_height = plane->src_height;
969 961
970 win_data->mode_width = overlay->mode_width; 962 win_data->mode_width = plane->mode_width;
971 win_data->mode_height = overlay->mode_height; 963 win_data->mode_height = plane->mode_height;
972 964
973 win_data->scan_flags = overlay->scan_flag; 965 win_data->scan_flags = plane->scan_flag;
974} 966}
975 967
976static void mixer_win_commit(struct exynos_drm_manager *mgr, int zpos) 968static void mixer_win_commit(struct exynos_drm_crtc *crtc, int zpos)
977{ 969{
978 struct mixer_context *mixer_ctx = mgr_to_mixer(mgr); 970 struct mixer_context *mixer_ctx = crtc->ctx;
979 int win = zpos == DEFAULT_ZPOS ? MIXER_DEFAULT_WIN : zpos; 971 int win = zpos == DEFAULT_ZPOS ? MIXER_DEFAULT_WIN : zpos;
980 972
981 DRM_DEBUG_KMS("win: %d\n", win); 973 DRM_DEBUG_KMS("win: %d\n", win);
@@ -995,9 +987,9 @@ static void mixer_win_commit(struct exynos_drm_manager *mgr, int zpos)
995 mixer_ctx->win_data[win].enabled = true; 987 mixer_ctx->win_data[win].enabled = true;
996} 988}
997 989
998static void mixer_win_disable(struct exynos_drm_manager *mgr, int zpos) 990static void mixer_win_disable(struct exynos_drm_crtc *crtc, int zpos)
999{ 991{
1000 struct mixer_context *mixer_ctx = mgr_to_mixer(mgr); 992 struct mixer_context *mixer_ctx = crtc->ctx;
1001 struct mixer_resources *res = &mixer_ctx->mixer_res; 993 struct mixer_resources *res = &mixer_ctx->mixer_res;
1002 int win = zpos == DEFAULT_ZPOS ? MIXER_DEFAULT_WIN : zpos; 994 int win = zpos == DEFAULT_ZPOS ? MIXER_DEFAULT_WIN : zpos;
1003 unsigned long flags; 995 unsigned long flags;
@@ -1023,9 +1015,9 @@ static void mixer_win_disable(struct exynos_drm_manager *mgr, int zpos)
1023 mixer_ctx->win_data[win].enabled = false; 1015 mixer_ctx->win_data[win].enabled = false;
1024} 1016}
1025 1017
1026static void mixer_wait_for_vblank(struct exynos_drm_manager *mgr) 1018static void mixer_wait_for_vblank(struct exynos_drm_crtc *crtc)
1027{ 1019{
1028 struct mixer_context *mixer_ctx = mgr_to_mixer(mgr); 1020 struct mixer_context *mixer_ctx = crtc->ctx;
1029 int err; 1021 int err;
1030 1022
1031 mutex_lock(&mixer_ctx->mixer_mutex); 1023 mutex_lock(&mixer_ctx->mixer_mutex);
@@ -1035,7 +1027,7 @@ static void mixer_wait_for_vblank(struct exynos_drm_manager *mgr)
1035 } 1027 }
1036 mutex_unlock(&mixer_ctx->mixer_mutex); 1028 mutex_unlock(&mixer_ctx->mixer_mutex);
1037 1029
1038 err = drm_vblank_get(mgr->crtc->dev, mixer_ctx->pipe); 1030 err = drm_vblank_get(mixer_ctx->drm_dev, mixer_ctx->pipe);
1039 if (err < 0) { 1031 if (err < 0) {
1040 DRM_DEBUG_KMS("failed to acquire vblank counter\n"); 1032 DRM_DEBUG_KMS("failed to acquire vblank counter\n");
1041 return; 1033 return;
@@ -1052,26 +1044,26 @@ static void mixer_wait_for_vblank(struct exynos_drm_manager *mgr)
1052 HZ/20)) 1044 HZ/20))
1053 DRM_DEBUG_KMS("vblank wait timed out.\n"); 1045 DRM_DEBUG_KMS("vblank wait timed out.\n");
1054 1046
1055 drm_vblank_put(mgr->crtc->dev, mixer_ctx->pipe); 1047 drm_vblank_put(mixer_ctx->drm_dev, mixer_ctx->pipe);
1056} 1048}
1057 1049
1058static void mixer_window_suspend(struct exynos_drm_manager *mgr) 1050static void mixer_window_suspend(struct exynos_drm_crtc *crtc)
1059{ 1051{
1060 struct mixer_context *ctx = mgr_to_mixer(mgr); 1052 struct mixer_context *ctx = crtc->ctx;
1061 struct hdmi_win_data *win_data; 1053 struct hdmi_win_data *win_data;
1062 int i; 1054 int i;
1063 1055
1064 for (i = 0; i < MIXER_WIN_NR; i++) { 1056 for (i = 0; i < MIXER_WIN_NR; i++) {
1065 win_data = &ctx->win_data[i]; 1057 win_data = &ctx->win_data[i];
1066 win_data->resume = win_data->enabled; 1058 win_data->resume = win_data->enabled;
1067 mixer_win_disable(mgr, i); 1059 mixer_win_disable(crtc, i);
1068 } 1060 }
1069 mixer_wait_for_vblank(mgr); 1061 mixer_wait_for_vblank(crtc);
1070} 1062}
1071 1063
1072static void mixer_window_resume(struct exynos_drm_manager *mgr) 1064static void mixer_window_resume(struct exynos_drm_crtc *crtc)
1073{ 1065{
1074 struct mixer_context *ctx = mgr_to_mixer(mgr); 1066 struct mixer_context *ctx = crtc->ctx;
1075 struct hdmi_win_data *win_data; 1067 struct hdmi_win_data *win_data;
1076 int i; 1068 int i;
1077 1069
@@ -1080,13 +1072,13 @@ static void mixer_window_resume(struct exynos_drm_manager *mgr)
1080 win_data->enabled = win_data->resume; 1072 win_data->enabled = win_data->resume;
1081 win_data->resume = false; 1073 win_data->resume = false;
1082 if (win_data->enabled) 1074 if (win_data->enabled)
1083 mixer_win_commit(mgr, i); 1075 mixer_win_commit(crtc, i);
1084 } 1076 }
1085} 1077}
1086 1078
1087static void mixer_poweron(struct exynos_drm_manager *mgr) 1079static void mixer_poweron(struct exynos_drm_crtc *crtc)
1088{ 1080{
1089 struct mixer_context *ctx = mgr_to_mixer(mgr); 1081 struct mixer_context *ctx = crtc->ctx;
1090 struct mixer_resources *res = &ctx->mixer_res; 1082 struct mixer_resources *res = &ctx->mixer_res;
1091 1083
1092 mutex_lock(&ctx->mixer_mutex); 1084 mutex_lock(&ctx->mixer_mutex);
@@ -1115,12 +1107,12 @@ static void mixer_poweron(struct exynos_drm_manager *mgr)
1115 mixer_reg_write(res, MXR_INT_EN, ctx->int_en); 1107 mixer_reg_write(res, MXR_INT_EN, ctx->int_en);
1116 mixer_win_reset(ctx); 1108 mixer_win_reset(ctx);
1117 1109
1118 mixer_window_resume(mgr); 1110 mixer_window_resume(crtc);
1119} 1111}
1120 1112
1121static void mixer_poweroff(struct exynos_drm_manager *mgr) 1113static void mixer_poweroff(struct exynos_drm_crtc *crtc)
1122{ 1114{
1123 struct mixer_context *ctx = mgr_to_mixer(mgr); 1115 struct mixer_context *ctx = crtc->ctx;
1124 struct mixer_resources *res = &ctx->mixer_res; 1116 struct mixer_resources *res = &ctx->mixer_res;
1125 1117
1126 mutex_lock(&ctx->mixer_mutex); 1118 mutex_lock(&ctx->mixer_mutex);
@@ -1131,7 +1123,7 @@ static void mixer_poweroff(struct exynos_drm_manager *mgr)
1131 mutex_unlock(&ctx->mixer_mutex); 1123 mutex_unlock(&ctx->mixer_mutex);
1132 1124
1133 mixer_stop(ctx); 1125 mixer_stop(ctx);
1134 mixer_window_suspend(mgr); 1126 mixer_window_suspend(crtc);
1135 1127
1136 ctx->int_en = mixer_reg_read(res, MXR_INT_EN); 1128 ctx->int_en = mixer_reg_read(res, MXR_INT_EN);
1137 1129
@@ -1149,16 +1141,16 @@ static void mixer_poweroff(struct exynos_drm_manager *mgr)
1149 pm_runtime_put_sync(ctx->dev); 1141 pm_runtime_put_sync(ctx->dev);
1150} 1142}
1151 1143
1152static void mixer_dpms(struct exynos_drm_manager *mgr, int mode) 1144static void mixer_dpms(struct exynos_drm_crtc *crtc, int mode)
1153{ 1145{
1154 switch (mode) { 1146 switch (mode) {
1155 case DRM_MODE_DPMS_ON: 1147 case DRM_MODE_DPMS_ON:
1156 mixer_poweron(mgr); 1148 mixer_poweron(crtc);
1157 break; 1149 break;
1158 case DRM_MODE_DPMS_STANDBY: 1150 case DRM_MODE_DPMS_STANDBY:
1159 case DRM_MODE_DPMS_SUSPEND: 1151 case DRM_MODE_DPMS_SUSPEND:
1160 case DRM_MODE_DPMS_OFF: 1152 case DRM_MODE_DPMS_OFF:
1161 mixer_poweroff(mgr); 1153 mixer_poweroff(crtc);
1162 break; 1154 break;
1163 default: 1155 default:
1164 DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode); 1156 DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode);
@@ -1186,7 +1178,7 @@ int mixer_check_mode(struct drm_display_mode *mode)
1186 return -EINVAL; 1178 return -EINVAL;
1187} 1179}
1188 1180
1189static struct exynos_drm_manager_ops mixer_manager_ops = { 1181static struct exynos_drm_crtc_ops mixer_crtc_ops = {
1190 .dpms = mixer_dpms, 1182 .dpms = mixer_dpms,
1191 .enable_vblank = mixer_enable_vblank, 1183 .enable_vblank = mixer_enable_vblank,
1192 .disable_vblank = mixer_disable_vblank, 1184 .disable_vblank = mixer_disable_vblank,
@@ -1257,24 +1249,30 @@ static int mixer_bind(struct device *dev, struct device *manager, void *data)
1257 struct drm_device *drm_dev = data; 1249 struct drm_device *drm_dev = data;
1258 int ret; 1250 int ret;
1259 1251
1260 ret = mixer_initialize(&ctx->manager, drm_dev); 1252 ctx->crtc = exynos_drm_crtc_create(drm_dev, ctx->pipe,
1261 if (ret) 1253 EXYNOS_DISPLAY_TYPE_HDMI,
1262 return ret; 1254 &mixer_crtc_ops, ctx);
1263 1255 if (IS_ERR(ctx->crtc)) {
1264 ret = exynos_drm_crtc_create(&ctx->manager); 1256 ret = PTR_ERR(ctx->crtc);
1265 if (ret) { 1257 goto free_ctx;
1266 mixer_mgr_remove(&ctx->manager);
1267 return ret;
1268 } 1258 }
1269 1259
1260 ret = mixer_initialize(ctx, drm_dev);
1261 if (ret)
1262 goto free_ctx;
1263
1270 return 0; 1264 return 0;
1265
1266free_ctx:
1267 devm_kfree(dev, ctx);
1268 return ret;
1271} 1269}
1272 1270
1273static void mixer_unbind(struct device *dev, struct device *master, void *data) 1271static void mixer_unbind(struct device *dev, struct device *master, void *data)
1274{ 1272{
1275 struct mixer_context *ctx = dev_get_drvdata(dev); 1273 struct mixer_context *ctx = dev_get_drvdata(dev);
1276 1274
1277 mixer_mgr_remove(&ctx->manager); 1275 mixer_ctx_remove(ctx);
1278} 1276}
1279 1277
1280static const struct component_ops mixer_component_ops = { 1278static const struct component_ops mixer_component_ops = {
@@ -1297,9 +1295,6 @@ static int mixer_probe(struct platform_device *pdev)
1297 1295
1298 mutex_init(&ctx->mixer_mutex); 1296 mutex_init(&ctx->mixer_mutex);
1299 1297
1300 ctx->manager.type = EXYNOS_DISPLAY_TYPE_HDMI;
1301 ctx->manager.ops = &mixer_manager_ops;
1302
1303 if (dev->of_node) { 1298 if (dev->of_node) {
1304 const struct of_device_id *match; 1299 const struct of_device_id *match;
1305 1300
@@ -1321,7 +1316,7 @@ static int mixer_probe(struct platform_device *pdev)
1321 platform_set_drvdata(pdev, ctx); 1316 platform_set_drvdata(pdev, ctx);
1322 1317
1323 ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC, 1318 ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC,
1324 ctx->manager.type); 1319 EXYNOS_DISPLAY_TYPE_HDMI);
1325 if (ret) 1320 if (ret)
1326 return ret; 1321 return ret;
1327 1322