diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_crtc.c | 67 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_crtc.h | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_drv.h | 51 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_fimd.c | 121 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_plane.c | 26 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_vidi.c | 79 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_mixer.c | 103 |
7 files changed, 211 insertions, 244 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index 1eb5750a59c9..9e8ed5fd60ae 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c | |||
@@ -23,7 +23,6 @@ | |||
23 | static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode) | 23 | static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode) |
24 | { | 24 | { |
25 | struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); | 25 | struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); |
26 | struct exynos_drm_manager *manager = exynos_crtc->manager; | ||
27 | 26 | ||
28 | 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); |
29 | 28 | ||
@@ -41,8 +40,8 @@ static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
41 | drm_crtc_vblank_off(crtc); | 40 | drm_crtc_vblank_off(crtc); |
42 | } | 41 | } |
43 | 42 | ||
44 | if (manager->ops->dpms) | 43 | if (exynos_crtc->ops->dpms) |
45 | manager->ops->dpms(manager, mode); | 44 | exynos_crtc->ops->dpms(exynos_crtc, mode); |
46 | 45 | ||
47 | exynos_crtc->dpms = mode; | 46 | exynos_crtc->dpms = mode; |
48 | 47 | ||
@@ -58,16 +57,15 @@ static void exynos_drm_crtc_prepare(struct drm_crtc *crtc) | |||
58 | static void exynos_drm_crtc_commit(struct drm_crtc *crtc) | 57 | static void exynos_drm_crtc_commit(struct drm_crtc *crtc) |
59 | { | 58 | { |
60 | struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); | 59 | struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); |
61 | struct exynos_drm_manager *manager = exynos_crtc->manager; | ||
62 | struct exynos_drm_plane *exynos_plane = to_exynos_plane(crtc->primary); | 60 | struct exynos_drm_plane *exynos_plane = to_exynos_plane(crtc->primary); |
63 | 61 | ||
64 | exynos_drm_crtc_dpms(crtc, DRM_MODE_DPMS_ON); | 62 | exynos_drm_crtc_dpms(crtc, DRM_MODE_DPMS_ON); |
65 | 63 | ||
66 | if (manager->ops->win_commit) | 64 | if (exynos_crtc->ops->win_commit) |
67 | manager->ops->win_commit(manager, exynos_plane->zpos); | 65 | exynos_crtc->ops->win_commit(exynos_crtc, exynos_plane->zpos); |
68 | 66 | ||
69 | if (manager->ops->commit) | 67 | if (exynos_crtc->ops->commit) |
70 | manager->ops->commit(manager); | 68 | exynos_crtc->ops->commit(exynos_crtc); |
71 | 69 | ||
72 | exynos_plane_dpms(crtc->primary, DRM_MODE_DPMS_ON); | 70 | exynos_plane_dpms(crtc->primary, DRM_MODE_DPMS_ON); |
73 | } | 71 | } |
@@ -78,10 +76,10 @@ exynos_drm_crtc_mode_fixup(struct drm_crtc *crtc, | |||
78 | struct drm_display_mode *adjusted_mode) | 76 | struct drm_display_mode *adjusted_mode) |
79 | { | 77 | { |
80 | struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); | 78 | struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); |
81 | struct exynos_drm_manager *manager = exynos_crtc->manager; | ||
82 | 79 | ||
83 | if (manager->ops->mode_fixup) | 80 | if (exynos_crtc->ops->mode_fixup) |
84 | return manager->ops->mode_fixup(manager, mode, adjusted_mode); | 81 | return exynos_crtc->ops->mode_fixup(exynos_crtc, mode, |
82 | adjusted_mode); | ||
85 | 83 | ||
86 | return true; | 84 | return true; |
87 | } | 85 | } |
@@ -92,7 +90,6 @@ exynos_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, | |||
92 | struct drm_framebuffer *old_fb) | 90 | struct drm_framebuffer *old_fb) |
93 | { | 91 | { |
94 | struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); | 92 | struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); |
95 | struct exynos_drm_manager *manager = exynos_crtc->manager; | ||
96 | struct drm_framebuffer *fb = crtc->primary->fb; | 93 | struct drm_framebuffer *fb = crtc->primary->fb; |
97 | unsigned int crtc_w; | 94 | unsigned int crtc_w; |
98 | unsigned int crtc_h; | 95 | unsigned int crtc_h; |
@@ -106,8 +103,8 @@ exynos_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, | |||
106 | crtc_w = fb->width - x; | 103 | crtc_w = fb->width - x; |
107 | crtc_h = fb->height - y; | 104 | crtc_h = fb->height - y; |
108 | 105 | ||
109 | if (manager->ops->mode_set) | 106 | if (exynos_crtc->ops->mode_set) |
110 | manager->ops->mode_set(manager, &crtc->mode); | 107 | exynos_crtc->ops->mode_set(exynos_crtc, &crtc->mode); |
111 | 108 | ||
112 | return exynos_plane_mode_set(crtc->primary, crtc, fb, 0, 0, | 109 | return exynos_plane_mode_set(crtc->primary, crtc, fb, 0, 0, |
113 | crtc_w, crtc_h, x, y, crtc_w, crtc_h); | 110 | crtc_w, crtc_h, x, y, crtc_w, crtc_h); |
@@ -299,9 +296,11 @@ static void exynos_drm_crtc_attach_mode_property(struct drm_crtc *crtc) | |||
299 | drm_object_attach_property(&crtc->base, prop, 0); | 296 | drm_object_attach_property(&crtc->base, prop, 0); |
300 | } | 297 | } |
301 | 298 | ||
302 | int exynos_drm_crtc_create(struct exynos_drm_manager *manager, | 299 | struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev, |
303 | struct drm_device *drm_dev, int pipe, | 300 | int pipe, |
304 | enum exynos_drm_output_type type) | 301 | enum exynos_drm_output_type type, |
302 | struct exynos_drm_crtc_ops *ops, | ||
303 | void *ctx) | ||
305 | { | 304 | { |
306 | struct exynos_drm_crtc *exynos_crtc; | 305 | struct exynos_drm_crtc *exynos_crtc; |
307 | struct drm_plane *plane; | 306 | struct drm_plane *plane; |
@@ -311,15 +310,16 @@ int exynos_drm_crtc_create(struct exynos_drm_manager *manager, | |||
311 | 310 | ||
312 | exynos_crtc = kzalloc(sizeof(*exynos_crtc), GFP_KERNEL); | 311 | exynos_crtc = kzalloc(sizeof(*exynos_crtc), GFP_KERNEL); |
313 | if (!exynos_crtc) | 312 | if (!exynos_crtc) |
314 | return -ENOMEM; | 313 | return ERR_PTR(-ENOMEM); |
315 | 314 | ||
316 | init_waitqueue_head(&exynos_crtc->pending_flip_queue); | 315 | init_waitqueue_head(&exynos_crtc->pending_flip_queue); |
317 | atomic_set(&exynos_crtc->pending_flip, 0); | 316 | atomic_set(&exynos_crtc->pending_flip, 0); |
318 | 317 | ||
319 | exynos_crtc->dpms = DRM_MODE_DPMS_OFF; | 318 | exynos_crtc->dpms = DRM_MODE_DPMS_OFF; |
320 | exynos_crtc->manager = manager; | ||
321 | exynos_crtc->pipe = pipe; | 319 | exynos_crtc->pipe = pipe; |
322 | exynos_crtc->type = type; | 320 | exynos_crtc->type = type; |
321 | exynos_crtc->ops = ops; | ||
322 | exynos_crtc->ctx = ctx; | ||
323 | plane = exynos_plane_init(drm_dev, 1 << pipe, | 323 | plane = exynos_plane_init(drm_dev, 1 << pipe, |
324 | DRM_PLANE_TYPE_PRIMARY); | 324 | DRM_PLANE_TYPE_PRIMARY); |
325 | if (IS_ERR(plane)) { | 325 | if (IS_ERR(plane)) { |
@@ -327,7 +327,6 @@ int exynos_drm_crtc_create(struct exynos_drm_manager *manager, | |||
327 | goto err_plane; | 327 | goto err_plane; |
328 | } | 328 | } |
329 | 329 | ||
330 | manager->crtc = &exynos_crtc->base; | ||
331 | crtc = &exynos_crtc->base; | 330 | crtc = &exynos_crtc->base; |
332 | 331 | ||
333 | private->crtc[pipe] = crtc; | 332 | private->crtc[pipe] = crtc; |
@@ -341,13 +340,13 @@ int exynos_drm_crtc_create(struct exynos_drm_manager *manager, | |||
341 | 340 | ||
342 | exynos_drm_crtc_attach_mode_property(crtc); | 341 | exynos_drm_crtc_attach_mode_property(crtc); |
343 | 342 | ||
344 | return 0; | 343 | return exynos_crtc; |
345 | 344 | ||
346 | err_crtc: | 345 | err_crtc: |
347 | plane->funcs->destroy(plane); | 346 | plane->funcs->destroy(plane); |
348 | err_plane: | 347 | err_plane: |
349 | kfree(exynos_crtc); | 348 | kfree(exynos_crtc); |
350 | return ret; | 349 | return ERR_PTR(ret); |
351 | } | 350 | } |
352 | 351 | ||
353 | int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int pipe) | 352 | int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int pipe) |
@@ -355,13 +354,12 @@ int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int pipe) | |||
355 | struct exynos_drm_private *private = dev->dev_private; | 354 | struct exynos_drm_private *private = dev->dev_private; |
356 | struct exynos_drm_crtc *exynos_crtc = | 355 | struct exynos_drm_crtc *exynos_crtc = |
357 | to_exynos_crtc(private->crtc[pipe]); | 356 | to_exynos_crtc(private->crtc[pipe]); |
358 | struct exynos_drm_manager *manager = exynos_crtc->manager; | ||
359 | 357 | ||
360 | if (exynos_crtc->dpms != DRM_MODE_DPMS_ON) | 358 | if (exynos_crtc->dpms != DRM_MODE_DPMS_ON) |
361 | return -EPERM; | 359 | return -EPERM; |
362 | 360 | ||
363 | if (manager->ops->enable_vblank) | 361 | if (exynos_crtc->ops->enable_vblank) |
364 | manager->ops->enable_vblank(manager); | 362 | exynos_crtc->ops->enable_vblank(exynos_crtc); |
365 | 363 | ||
366 | return 0; | 364 | return 0; |
367 | } | 365 | } |
@@ -371,13 +369,12 @@ void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int pipe) | |||
371 | struct exynos_drm_private *private = dev->dev_private; | 369 | struct exynos_drm_private *private = dev->dev_private; |
372 | struct exynos_drm_crtc *exynos_crtc = | 370 | struct exynos_drm_crtc *exynos_crtc = |
373 | to_exynos_crtc(private->crtc[pipe]); | 371 | to_exynos_crtc(private->crtc[pipe]); |
374 | struct exynos_drm_manager *manager = exynos_crtc->manager; | ||
375 | 372 | ||
376 | if (exynos_crtc->dpms != DRM_MODE_DPMS_ON) | 373 | if (exynos_crtc->dpms != DRM_MODE_DPMS_ON) |
377 | return; | 374 | return; |
378 | 375 | ||
379 | if (manager->ops->disable_vblank) | 376 | if (exynos_crtc->ops->disable_vblank) |
380 | manager->ops->disable_vblank(manager); | 377 | exynos_crtc->ops->disable_vblank(exynos_crtc); |
381 | } | 378 | } |
382 | 379 | ||
383 | void exynos_drm_crtc_finish_pageflip(struct drm_device *dev, int pipe) | 380 | void exynos_drm_crtc_finish_pageflip(struct drm_device *dev, int pipe) |
@@ -408,7 +405,7 @@ void exynos_drm_crtc_finish_pageflip(struct drm_device *dev, int pipe) | |||
408 | 405 | ||
409 | void exynos_drm_crtc_complete_scanout(struct drm_framebuffer *fb) | 406 | void exynos_drm_crtc_complete_scanout(struct drm_framebuffer *fb) |
410 | { | 407 | { |
411 | struct exynos_drm_manager *manager; | 408 | struct exynos_drm_crtc *exynos_crtc; |
412 | struct drm_device *dev = fb->dev; | 409 | struct drm_device *dev = fb->dev; |
413 | struct drm_crtc *crtc; | 410 | struct drm_crtc *crtc; |
414 | 411 | ||
@@ -417,15 +414,15 @@ void exynos_drm_crtc_complete_scanout(struct drm_framebuffer *fb) | |||
417 | * for all encoders. | 414 | * for all encoders. |
418 | */ | 415 | */ |
419 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 416 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
420 | manager = to_exynos_crtc(crtc)->manager; | 417 | exynos_crtc = to_exynos_crtc(crtc); |
421 | 418 | ||
422 | /* | 419 | /* |
423 | * wait for vblank interrupt | 420 | * wait for vblank interrupt |
424 | * - this makes sure that overlay data are updated to | 421 | * - this makes sure that overlay data are updated to |
425 | * real hardware. | 422 | * real hardware. |
426 | */ | 423 | */ |
427 | if (manager->ops->wait_for_vblank) | 424 | if (exynos_crtc->ops->wait_for_vblank) |
428 | manager->ops->wait_for_vblank(manager); | 425 | exynos_crtc->ops->wait_for_vblank(exynos_crtc); |
429 | } | 426 | } |
430 | } | 427 | } |
431 | 428 | ||
@@ -447,8 +444,8 @@ int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev, | |||
447 | 444 | ||
448 | void exynos_drm_crtc_te_handler(struct drm_crtc *crtc) | 445 | void exynos_drm_crtc_te_handler(struct drm_crtc *crtc) |
449 | { | 446 | { |
450 | struct exynos_drm_manager *manager = to_exynos_crtc(crtc)->manager; | 447 | struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); |
451 | 448 | ||
452 | if (manager->ops->te_handler) | 449 | if (exynos_crtc->ops->te_handler) |
453 | manager->ops->te_handler(manager); | 450 | exynos_crtc->ops->te_handler(exynos_crtc); |
454 | } | 451 | } |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.h b/drivers/gpu/drm/exynos/exynos_drm_crtc.h index d7690e9e3e20..6258b800aab8 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.h +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.h | |||
@@ -17,9 +17,11 @@ | |||
17 | 17 | ||
18 | #include "exynos_drm_drv.h" | 18 | #include "exynos_drm_drv.h" |
19 | 19 | ||
20 | int exynos_drm_crtc_create(struct exynos_drm_manager *manager, | 20 | struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev, |
21 | struct drm_device *drm_dev, int pipe, | 21 | int pipe, |
22 | enum exynos_drm_output_type type); | 22 | enum exynos_drm_output_type type, |
23 | struct exynos_drm_crtc_ops *ops, | ||
24 | void *context); | ||
23 | int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int pipe); | 25 | int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int pipe); |
24 | void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int pipe); | 26 | void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int pipe); |
25 | void exynos_drm_crtc_finish_pageflip(struct drm_device *dev, int pipe); | 27 | void exynos_drm_crtc_finish_pageflip(struct drm_device *dev, int pipe); |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index 2d801a8402d2..4c930d066196 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h | |||
@@ -163,7 +163,7 @@ struct exynos_drm_display { | |||
163 | }; | 163 | }; |
164 | 164 | ||
165 | /* | 165 | /* |
166 | * Exynos drm manager ops | 166 | * Exynos drm crtc ops |
167 | * | 167 | * |
168 | * @dpms: control device power. | 168 | * @dpms: control device power. |
169 | * @mode_fixup: fix mode data before applying it | 169 | * @mode_fixup: fix mode data before applying it |
@@ -180,39 +180,24 @@ struct exynos_drm_display { | |||
180 | * @te_handler: trigger to transfer video image at the tearing effect | 180 | * @te_handler: trigger to transfer video image at the tearing effect |
181 | * synchronization signal if there is a page flip request. | 181 | * synchronization signal if there is a page flip request. |
182 | */ | 182 | */ |
183 | struct exynos_drm_manager; | 183 | struct exynos_drm_crtc; |
184 | struct exynos_drm_manager_ops { | 184 | struct exynos_drm_crtc_ops { |
185 | void (*dpms)(struct exynos_drm_manager *mgr, int mode); | 185 | void (*dpms)(struct exynos_drm_crtc *crtc, int mode); |
186 | bool (*mode_fixup)(struct exynos_drm_manager *mgr, | 186 | bool (*mode_fixup)(struct exynos_drm_crtc *crtc, |
187 | const struct drm_display_mode *mode, | 187 | const struct drm_display_mode *mode, |
188 | struct drm_display_mode *adjusted_mode); | 188 | struct drm_display_mode *adjusted_mode); |
189 | void (*mode_set)(struct exynos_drm_manager *mgr, | 189 | void (*mode_set)(struct exynos_drm_crtc *crtc, |
190 | const struct drm_display_mode *mode); | 190 | const struct drm_display_mode *mode); |
191 | void (*commit)(struct exynos_drm_manager *mgr); | 191 | void (*commit)(struct exynos_drm_crtc *crtc); |
192 | int (*enable_vblank)(struct exynos_drm_manager *mgr); | 192 | int (*enable_vblank)(struct exynos_drm_crtc *crtc); |
193 | void (*disable_vblank)(struct exynos_drm_manager *mgr); | 193 | void (*disable_vblank)(struct exynos_drm_crtc *crtc); |
194 | void (*wait_for_vblank)(struct exynos_drm_manager *mgr); | 194 | void (*wait_for_vblank)(struct exynos_drm_crtc *crtc); |
195 | void (*win_mode_set)(struct exynos_drm_manager *mgr, | 195 | void (*win_mode_set)(struct exynos_drm_crtc *crtc, |
196 | struct exynos_drm_plane *plane); | 196 | struct exynos_drm_plane *plane); |
197 | void (*win_commit)(struct exynos_drm_manager *mgr, int zpos); | 197 | void (*win_commit)(struct exynos_drm_crtc *crtc, int zpos); |
198 | void (*win_enable)(struct exynos_drm_manager *mgr, int zpos); | 198 | void (*win_enable)(struct exynos_drm_crtc *crtc, int zpos); |
199 | void (*win_disable)(struct exynos_drm_manager *mgr, int zpos); | 199 | void (*win_disable)(struct exynos_drm_crtc *crtc, int zpos); |
200 | void (*te_handler)(struct exynos_drm_manager *mgr); | 200 | void (*te_handler)(struct exynos_drm_crtc *crtc); |
201 | }; | ||
202 | |||
203 | /* | ||
204 | * Exynos drm common manager structure, maps 1:1 with a crtc | ||
205 | * | ||
206 | * @list: the list entry for this manager | ||
207 | * @drm_dev: pointer to the drm device | ||
208 | * @crtc: crtc object. | ||
209 | * @ops: pointer to callbacks for exynos drm specific functionality | ||
210 | * @ctx: A pointer to the manager's implementation specific context | ||
211 | */ | ||
212 | struct exynos_drm_manager { | ||
213 | struct list_head list; | ||
214 | struct drm_crtc *crtc; | ||
215 | struct exynos_drm_manager_ops *ops; | ||
216 | }; | 201 | }; |
217 | 202 | ||
218 | enum exynos_crtc_mode { | 203 | enum exynos_crtc_mode { |
@@ -224,7 +209,6 @@ enum exynos_crtc_mode { | |||
224 | * Exynos specific crtc structure. | 209 | * Exynos specific crtc structure. |
225 | * | 210 | * |
226 | * @base: crtc object. | 211 | * @base: crtc object. |
227 | * @manager: the manager associated with this crtc | ||
228 | * @type: one of EXYNOS_DISPLAY_TYPE_LCD and HDMI. | 212 | * @type: one of EXYNOS_DISPLAY_TYPE_LCD and HDMI. |
229 | * @pipe: a crtc index created at load() with a new crtc object creation | 213 | * @pipe: a crtc index created at load() with a new crtc object creation |
230 | * and the crtc object would be set to private->crtc array | 214 | * and the crtc object would be set to private->crtc array |
@@ -235,16 +219,19 @@ enum exynos_crtc_mode { | |||
235 | * this pipe value. | 219 | * this pipe value. |
236 | * @dpms: store the crtc dpms value | 220 | * @dpms: store the crtc dpms value |
237 | * @mode: store the crtc mode value | 221 | * @mode: store the crtc mode value |
222 | * @ops: pointer to callbacks for exynos drm specific functionality | ||
223 | * @ctx: A pointer to the crtc's implementation specific context | ||
238 | */ | 224 | */ |
239 | struct exynos_drm_crtc { | 225 | struct exynos_drm_crtc { |
240 | struct drm_crtc base; | 226 | struct drm_crtc base; |
241 | struct exynos_drm_manager *manager; | ||
242 | enum exynos_drm_output_type type; | 227 | enum exynos_drm_output_type type; |
243 | unsigned int pipe; | 228 | unsigned int pipe; |
244 | unsigned int dpms; | 229 | unsigned int dpms; |
245 | enum exynos_crtc_mode mode; | 230 | enum exynos_crtc_mode mode; |
246 | wait_queue_head_t pending_flip_queue; | 231 | wait_queue_head_t pending_flip_queue; |
247 | atomic_t pending_flip; | 232 | atomic_t pending_flip; |
233 | struct exynos_drm_crtc_ops *ops; | ||
234 | void *ctx; | ||
248 | }; | 235 | }; |
249 | 236 | ||
250 | struct exynos_drm_g2d_private { | 237 | struct 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 f67f11c702ca..9acd6890a3d6 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c | |||
@@ -157,9 +157,9 @@ struct fimd_win_data { | |||
157 | }; | 157 | }; |
158 | 158 | ||
159 | struct fimd_context { | 159 | struct 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; |
@@ -185,11 +185,6 @@ struct fimd_context { | |||
185 | struct exynos_drm_display *display; | 185 | struct exynos_drm_display *display; |
186 | }; | 186 | }; |
187 | 187 | ||
188 | static inline struct fimd_context *mgr_to_fimd(struct exynos_drm_manager *mgr) | ||
189 | { | ||
190 | return container_of(mgr, struct fimd_context, manager); | ||
191 | } | ||
192 | |||
193 | static const struct of_device_id fimd_driver_dt_match[] = { | 188 | static const struct of_device_id fimd_driver_dt_match[] = { |
194 | { .compatible = "samsung,s3c6400-fimd", | 189 | { .compatible = "samsung,s3c6400-fimd", |
195 | .data = &s3c64xx_fimd_driver_data }, | 190 | .data = &s3c64xx_fimd_driver_data }, |
@@ -214,9 +209,9 @@ static inline struct fimd_driver_data *drm_fimd_get_driver_data( | |||
214 | return (struct fimd_driver_data *)of_id->data; | 209 | return (struct fimd_driver_data *)of_id->data; |
215 | } | 210 | } |
216 | 211 | ||
217 | static void fimd_wait_for_vblank(struct exynos_drm_manager *mgr) | 212 | static void fimd_wait_for_vblank(struct exynos_drm_crtc *crtc) |
218 | { | 213 | { |
219 | struct fimd_context *ctx = mgr_to_fimd(mgr); | 214 | struct fimd_context *ctx = crtc->ctx; |
220 | 215 | ||
221 | if (ctx->suspended) | 216 | if (ctx->suspended) |
222 | return; | 217 | return; |
@@ -259,9 +254,9 @@ static void fimd_enable_shadow_channel_path(struct fimd_context *ctx, int win, | |||
259 | writel(val, ctx->regs + SHADOWCON); | 254 | writel(val, ctx->regs + SHADOWCON); |
260 | } | 255 | } |
261 | 256 | ||
262 | static void fimd_clear_channel(struct exynos_drm_manager *mgr) | 257 | static void fimd_clear_channel(struct exynos_drm_crtc *crtc) |
263 | { | 258 | { |
264 | struct fimd_context *ctx = mgr_to_fimd(mgr); | 259 | struct fimd_context *ctx = crtc->ctx; |
265 | int win, ch_enabled = 0; | 260 | int win, ch_enabled = 0; |
266 | 261 | ||
267 | DRM_DEBUG_KMS("%s\n", __FILE__); | 262 | DRM_DEBUG_KMS("%s\n", __FILE__); |
@@ -286,15 +281,14 @@ static void fimd_clear_channel(struct exynos_drm_manager *mgr) | |||
286 | unsigned int state = ctx->suspended; | 281 | unsigned int state = ctx->suspended; |
287 | 282 | ||
288 | ctx->suspended = 0; | 283 | ctx->suspended = 0; |
289 | fimd_wait_for_vblank(mgr); | 284 | fimd_wait_for_vblank(crtc); |
290 | ctx->suspended = state; | 285 | ctx->suspended = state; |
291 | } | 286 | } |
292 | } | 287 | } |
293 | 288 | ||
294 | static int fimd_mgr_initialize(struct exynos_drm_manager *mgr, | 289 | static int fimd_ctx_initialize(struct fimd_context *ctx, |
295 | struct drm_device *drm_dev) | 290 | struct drm_device *drm_dev) |
296 | { | 291 | { |
297 | struct fimd_context *ctx = mgr_to_fimd(mgr); | ||
298 | struct exynos_drm_private *priv; | 292 | struct exynos_drm_private *priv; |
299 | priv = drm_dev->dev_private; | 293 | priv = drm_dev->dev_private; |
300 | 294 | ||
@@ -307,17 +301,15 @@ static int fimd_mgr_initialize(struct exynos_drm_manager *mgr, | |||
307 | * If any channel is already active, iommu will throw | 301 | * If any channel is already active, iommu will throw |
308 | * a PAGE FAULT when enabled. So clear any channel if enabled. | 302 | * a PAGE FAULT when enabled. So clear any channel if enabled. |
309 | */ | 303 | */ |
310 | fimd_clear_channel(mgr); | 304 | fimd_clear_channel(ctx->crtc); |
311 | drm_iommu_attach_device(ctx->drm_dev, ctx->dev); | 305 | drm_iommu_attach_device(ctx->drm_dev, ctx->dev); |
312 | } | 306 | } |
313 | 307 | ||
314 | return 0; | 308 | return 0; |
315 | } | 309 | } |
316 | 310 | ||
317 | static void fimd_mgr_remove(struct exynos_drm_manager *mgr) | 311 | static void fimd_ctx_remove(struct fimd_context *ctx) |
318 | { | 312 | { |
319 | struct fimd_context *ctx = mgr_to_fimd(mgr); | ||
320 | |||
321 | /* detach this sub driver from iommu mapping if supported. */ | 313 | /* detach this sub driver from iommu mapping if supported. */ |
322 | if (is_drm_iommu_supported(ctx->drm_dev)) | 314 | if (is_drm_iommu_supported(ctx->drm_dev)) |
323 | drm_iommu_detach_device(ctx->drm_dev, ctx->dev); | 315 | drm_iommu_detach_device(ctx->drm_dev, ctx->dev); |
@@ -343,7 +335,7 @@ static u32 fimd_calc_clkdiv(struct fimd_context *ctx, | |||
343 | return (clkdiv < 0x100) ? clkdiv : 0xff; | 335 | return (clkdiv < 0x100) ? clkdiv : 0xff; |
344 | } | 336 | } |
345 | 337 | ||
346 | static bool fimd_mode_fixup(struct exynos_drm_manager *mgr, | 338 | static bool fimd_mode_fixup(struct exynos_drm_crtc *crtc, |
347 | const struct drm_display_mode *mode, | 339 | const struct drm_display_mode *mode, |
348 | struct drm_display_mode *adjusted_mode) | 340 | struct drm_display_mode *adjusted_mode) |
349 | { | 341 | { |
@@ -353,17 +345,17 @@ static bool fimd_mode_fixup(struct exynos_drm_manager *mgr, | |||
353 | return true; | 345 | return true; |
354 | } | 346 | } |
355 | 347 | ||
356 | static void fimd_mode_set(struct exynos_drm_manager *mgr, | 348 | static void fimd_mode_set(struct exynos_drm_crtc *crtc, |
357 | const struct drm_display_mode *in_mode) | 349 | const struct drm_display_mode *in_mode) |
358 | { | 350 | { |
359 | struct fimd_context *ctx = mgr_to_fimd(mgr); | 351 | struct fimd_context *ctx = crtc->ctx; |
360 | 352 | ||
361 | drm_mode_copy(&ctx->mode, in_mode); | 353 | drm_mode_copy(&ctx->mode, in_mode); |
362 | } | 354 | } |
363 | 355 | ||
364 | static void fimd_commit(struct exynos_drm_manager *mgr) | 356 | static void fimd_commit(struct exynos_drm_crtc *crtc) |
365 | { | 357 | { |
366 | struct fimd_context *ctx = mgr_to_fimd(mgr); | 358 | struct fimd_context *ctx = crtc->ctx; |
367 | struct drm_display_mode *mode = &ctx->mode; | 359 | struct drm_display_mode *mode = &ctx->mode; |
368 | struct fimd_driver_data *driver_data = ctx->driver_data; | 360 | struct fimd_driver_data *driver_data = ctx->driver_data; |
369 | void *timing_base = ctx->regs + driver_data->timing_base; | 361 | void *timing_base = ctx->regs + driver_data->timing_base; |
@@ -461,9 +453,9 @@ static void fimd_commit(struct exynos_drm_manager *mgr) | |||
461 | writel(val, ctx->regs + VIDCON0); | 453 | writel(val, ctx->regs + VIDCON0); |
462 | } | 454 | } |
463 | 455 | ||
464 | static int fimd_enable_vblank(struct exynos_drm_manager *mgr) | 456 | static int fimd_enable_vblank(struct exynos_drm_crtc *crtc) |
465 | { | 457 | { |
466 | struct fimd_context *ctx = mgr_to_fimd(mgr); | 458 | struct fimd_context *ctx = crtc->ctx; |
467 | u32 val; | 459 | u32 val; |
468 | 460 | ||
469 | if (ctx->suspended) | 461 | if (ctx->suspended) |
@@ -493,9 +485,9 @@ static int fimd_enable_vblank(struct exynos_drm_manager *mgr) | |||
493 | return 0; | 485 | return 0; |
494 | } | 486 | } |
495 | 487 | ||
496 | static void fimd_disable_vblank(struct exynos_drm_manager *mgr) | 488 | static void fimd_disable_vblank(struct exynos_drm_crtc *crtc) |
497 | { | 489 | { |
498 | struct fimd_context *ctx = mgr_to_fimd(mgr); | 490 | struct fimd_context *ctx = crtc->ctx; |
499 | u32 val; | 491 | u32 val; |
500 | 492 | ||
501 | if (ctx->suspended) | 493 | if (ctx->suspended) |
@@ -517,10 +509,10 @@ static void fimd_disable_vblank(struct exynos_drm_manager *mgr) | |||
517 | } | 509 | } |
518 | } | 510 | } |
519 | 511 | ||
520 | static void fimd_win_mode_set(struct exynos_drm_manager *mgr, | 512 | static void fimd_win_mode_set(struct exynos_drm_crtc *crtc, |
521 | struct exynos_drm_plane *plane) | 513 | struct exynos_drm_plane *plane) |
522 | { | 514 | { |
523 | struct fimd_context *ctx = mgr_to_fimd(mgr); | 515 | struct fimd_context *ctx = crtc->ctx; |
524 | struct fimd_win_data *win_data; | 516 | struct fimd_win_data *win_data; |
525 | int win; | 517 | int win; |
526 | unsigned long offset; | 518 | unsigned long offset; |
@@ -676,9 +668,9 @@ static void fimd_shadow_protect_win(struct fimd_context *ctx, | |||
676 | writel(val, ctx->regs + reg); | 668 | writel(val, ctx->regs + reg); |
677 | } | 669 | } |
678 | 670 | ||
679 | static void fimd_win_commit(struct exynos_drm_manager *mgr, int zpos) | 671 | static void fimd_win_commit(struct exynos_drm_crtc *crtc, int zpos) |
680 | { | 672 | { |
681 | struct fimd_context *ctx = mgr_to_fimd(mgr); | 673 | struct fimd_context *ctx = crtc->ctx; |
682 | struct fimd_win_data *win_data; | 674 | struct fimd_win_data *win_data; |
683 | int win = zpos; | 675 | int win = zpos; |
684 | unsigned long val, alpha, size; | 676 | unsigned long val, alpha, size; |
@@ -799,9 +791,9 @@ static void fimd_win_commit(struct exynos_drm_manager *mgr, int zpos) | |||
799 | atomic_set(&ctx->win_updated, 1); | 791 | atomic_set(&ctx->win_updated, 1); |
800 | } | 792 | } |
801 | 793 | ||
802 | static void fimd_win_disable(struct exynos_drm_manager *mgr, int zpos) | 794 | static void fimd_win_disable(struct exynos_drm_crtc *crtc, int zpos) |
803 | { | 795 | { |
804 | struct fimd_context *ctx = mgr_to_fimd(mgr); | 796 | struct fimd_context *ctx = crtc->ctx; |
805 | struct fimd_win_data *win_data; | 797 | struct fimd_win_data *win_data; |
806 | int win = zpos; | 798 | int win = zpos; |
807 | 799 | ||
@@ -833,9 +825,9 @@ static void fimd_win_disable(struct exynos_drm_manager *mgr, int zpos) | |||
833 | win_data->enabled = false; | 825 | win_data->enabled = false; |
834 | } | 826 | } |
835 | 827 | ||
836 | static void fimd_window_suspend(struct exynos_drm_manager *mgr) | 828 | static void fimd_window_suspend(struct exynos_drm_crtc *crtc) |
837 | { | 829 | { |
838 | struct fimd_context *ctx = mgr_to_fimd(mgr); | 830 | struct fimd_context *ctx = crtc->ctx; |
839 | struct fimd_win_data *win_data; | 831 | struct fimd_win_data *win_data; |
840 | int i; | 832 | int i; |
841 | 833 | ||
@@ -843,13 +835,13 @@ static void fimd_window_suspend(struct exynos_drm_manager *mgr) | |||
843 | win_data = &ctx->win_data[i]; | 835 | win_data = &ctx->win_data[i]; |
844 | win_data->resume = win_data->enabled; | 836 | win_data->resume = win_data->enabled; |
845 | if (win_data->enabled) | 837 | if (win_data->enabled) |
846 | fimd_win_disable(mgr, i); | 838 | fimd_win_disable(crtc, i); |
847 | } | 839 | } |
848 | } | 840 | } |
849 | 841 | ||
850 | static void fimd_window_resume(struct exynos_drm_manager *mgr) | 842 | static void fimd_window_resume(struct exynos_drm_crtc *crtc) |
851 | { | 843 | { |
852 | struct fimd_context *ctx = mgr_to_fimd(mgr); | 844 | struct fimd_context *ctx = crtc->ctx; |
853 | struct fimd_win_data *win_data; | 845 | struct fimd_win_data *win_data; |
854 | int i; | 846 | int i; |
855 | 847 | ||
@@ -860,26 +852,26 @@ static void fimd_window_resume(struct exynos_drm_manager *mgr) | |||
860 | } | 852 | } |
861 | } | 853 | } |
862 | 854 | ||
863 | static void fimd_apply(struct exynos_drm_manager *mgr) | 855 | static void fimd_apply(struct exynos_drm_crtc *crtc) |
864 | { | 856 | { |
865 | struct fimd_context *ctx = mgr_to_fimd(mgr); | 857 | struct fimd_context *ctx = crtc->ctx; |
866 | struct fimd_win_data *win_data; | 858 | struct fimd_win_data *win_data; |
867 | int i; | 859 | int i; |
868 | 860 | ||
869 | for (i = 0; i < WINDOWS_NR; i++) { | 861 | for (i = 0; i < WINDOWS_NR; i++) { |
870 | win_data = &ctx->win_data[i]; | 862 | win_data = &ctx->win_data[i]; |
871 | if (win_data->enabled) | 863 | if (win_data->enabled) |
872 | fimd_win_commit(mgr, i); | 864 | fimd_win_commit(crtc, i); |
873 | else | 865 | else |
874 | fimd_win_disable(mgr, i); | 866 | fimd_win_disable(crtc, i); |
875 | } | 867 | } |
876 | 868 | ||
877 | fimd_commit(mgr); | 869 | fimd_commit(crtc); |
878 | } | 870 | } |
879 | 871 | ||
880 | static int fimd_poweron(struct exynos_drm_manager *mgr) | 872 | static int fimd_poweron(struct exynos_drm_crtc *crtc) |
881 | { | 873 | { |
882 | struct fimd_context *ctx = mgr_to_fimd(mgr); | 874 | struct fimd_context *ctx = crtc->ctx; |
883 | int ret; | 875 | int ret; |
884 | 876 | ||
885 | if (!ctx->suspended) | 877 | if (!ctx->suspended) |
@@ -903,16 +895,16 @@ static int fimd_poweron(struct exynos_drm_manager *mgr) | |||
903 | 895 | ||
904 | /* if vblank was enabled status, enable it again. */ | 896 | /* if vblank was enabled status, enable it again. */ |
905 | if (test_and_clear_bit(0, &ctx->irq_flags)) { | 897 | if (test_and_clear_bit(0, &ctx->irq_flags)) { |
906 | ret = fimd_enable_vblank(mgr); | 898 | ret = fimd_enable_vblank(crtc); |
907 | if (ret) { | 899 | if (ret) { |
908 | DRM_ERROR("Failed to re-enable vblank [%d]\n", ret); | 900 | DRM_ERROR("Failed to re-enable vblank [%d]\n", ret); |
909 | goto enable_vblank_err; | 901 | goto enable_vblank_err; |
910 | } | 902 | } |
911 | } | 903 | } |
912 | 904 | ||
913 | fimd_window_resume(mgr); | 905 | fimd_window_resume(crtc); |
914 | 906 | ||
915 | fimd_apply(mgr); | 907 | fimd_apply(crtc); |
916 | 908 | ||
917 | return 0; | 909 | return 0; |
918 | 910 | ||
@@ -925,9 +917,9 @@ bus_clk_err: | |||
925 | return ret; | 917 | return ret; |
926 | } | 918 | } |
927 | 919 | ||
928 | static int fimd_poweroff(struct exynos_drm_manager *mgr) | 920 | static int fimd_poweroff(struct exynos_drm_crtc *crtc) |
929 | { | 921 | { |
930 | struct fimd_context *ctx = mgr_to_fimd(mgr); | 922 | struct fimd_context *ctx = crtc->ctx; |
931 | 923 | ||
932 | if (ctx->suspended) | 924 | if (ctx->suspended) |
933 | return 0; | 925 | return 0; |
@@ -937,7 +929,7 @@ static int fimd_poweroff(struct exynos_drm_manager *mgr) | |||
937 | * suspend that connector. Otherwise we might try to scan from | 929 | * suspend that connector. Otherwise we might try to scan from |
938 | * a destroyed buffer later. | 930 | * a destroyed buffer later. |
939 | */ | 931 | */ |
940 | fimd_window_suspend(mgr); | 932 | fimd_window_suspend(crtc); |
941 | 933 | ||
942 | clk_disable_unprepare(ctx->lcd_clk); | 934 | clk_disable_unprepare(ctx->lcd_clk); |
943 | clk_disable_unprepare(ctx->bus_clk); | 935 | clk_disable_unprepare(ctx->bus_clk); |
@@ -948,18 +940,18 @@ static int fimd_poweroff(struct exynos_drm_manager *mgr) | |||
948 | return 0; | 940 | return 0; |
949 | } | 941 | } |
950 | 942 | ||
951 | static void fimd_dpms(struct exynos_drm_manager *mgr, int mode) | 943 | static void fimd_dpms(struct exynos_drm_crtc *crtc, int mode) |
952 | { | 944 | { |
953 | DRM_DEBUG_KMS("%s, %d\n", __FILE__, mode); | 945 | DRM_DEBUG_KMS("%s, %d\n", __FILE__, mode); |
954 | 946 | ||
955 | switch (mode) { | 947 | switch (mode) { |
956 | case DRM_MODE_DPMS_ON: | 948 | case DRM_MODE_DPMS_ON: |
957 | fimd_poweron(mgr); | 949 | fimd_poweron(crtc); |
958 | break; | 950 | break; |
959 | case DRM_MODE_DPMS_STANDBY: | 951 | case DRM_MODE_DPMS_STANDBY: |
960 | case DRM_MODE_DPMS_SUSPEND: | 952 | case DRM_MODE_DPMS_SUSPEND: |
961 | case DRM_MODE_DPMS_OFF: | 953 | case DRM_MODE_DPMS_OFF: |
962 | fimd_poweroff(mgr); | 954 | fimd_poweroff(crtc); |
963 | break; | 955 | break; |
964 | default: | 956 | default: |
965 | DRM_DEBUG_KMS("unspecified mode %d\n", mode); | 957 | DRM_DEBUG_KMS("unspecified mode %d\n", mode); |
@@ -996,9 +988,9 @@ static void fimd_trigger(struct device *dev) | |||
996 | atomic_set(&ctx->triggering, 0); | 988 | atomic_set(&ctx->triggering, 0); |
997 | } | 989 | } |
998 | 990 | ||
999 | static void fimd_te_handler(struct exynos_drm_manager *mgr) | 991 | static void fimd_te_handler(struct exynos_drm_crtc *crtc) |
1000 | { | 992 | { |
1001 | struct fimd_context *ctx = mgr_to_fimd(mgr); | 993 | struct fimd_context *ctx = crtc->ctx; |
1002 | 994 | ||
1003 | /* Checks the crtc is detached already from encoder */ | 995 | /* Checks the crtc is detached already from encoder */ |
1004 | if (ctx->pipe < 0 || !ctx->drm_dev) | 996 | if (ctx->pipe < 0 || !ctx->drm_dev) |
@@ -1021,7 +1013,7 @@ static void fimd_te_handler(struct exynos_drm_manager *mgr) | |||
1021 | drm_handle_vblank(ctx->drm_dev, ctx->pipe); | 1013 | drm_handle_vblank(ctx->drm_dev, ctx->pipe); |
1022 | } | 1014 | } |
1023 | 1015 | ||
1024 | static struct exynos_drm_manager_ops fimd_manager_ops = { | 1016 | static struct exynos_drm_crtc_ops fimd_crtc_ops = { |
1025 | .dpms = fimd_dpms, | 1017 | .dpms = fimd_dpms, |
1026 | .mode_fixup = fimd_mode_fixup, | 1018 | .mode_fixup = fimd_mode_fixup, |
1027 | .mode_set = fimd_mode_set, | 1019 | .mode_set = fimd_mode_set, |
@@ -1075,9 +1067,14 @@ static int fimd_bind(struct device *dev, struct device *master, void *data) | |||
1075 | struct fimd_context *ctx = dev_get_drvdata(dev); | 1067 | struct fimd_context *ctx = dev_get_drvdata(dev); |
1076 | struct drm_device *drm_dev = data; | 1068 | struct drm_device *drm_dev = data; |
1077 | 1069 | ||
1078 | fimd_mgr_initialize(&ctx->manager, drm_dev); | 1070 | ctx->crtc = exynos_drm_crtc_create(drm_dev, ctx->pipe, |
1079 | exynos_drm_crtc_create(&ctx->manager, drm_dev, ctx->pipe, | 1071 | EXYNOS_DISPLAY_TYPE_LCD, |
1080 | EXYNOS_DISPLAY_TYPE_LCD); | 1072 | &fimd_crtc_ops, ctx); |
1073 | if (IS_ERR(ctx->crtc)) | ||
1074 | return PTR_ERR(ctx->crtc); | ||
1075 | |||
1076 | fimd_ctx_initialize(ctx, drm_dev); | ||
1077 | |||
1081 | if (ctx->display) | 1078 | if (ctx->display) |
1082 | exynos_drm_create_enc_conn(drm_dev, ctx->display); | 1079 | exynos_drm_create_enc_conn(drm_dev, ctx->display); |
1083 | 1080 | ||
@@ -1090,12 +1087,12 @@ static void fimd_unbind(struct device *dev, struct device *master, | |||
1090 | { | 1087 | { |
1091 | struct fimd_context *ctx = dev_get_drvdata(dev); | 1088 | struct fimd_context *ctx = dev_get_drvdata(dev); |
1092 | 1089 | ||
1093 | fimd_dpms(&ctx->manager, DRM_MODE_DPMS_OFF); | 1090 | fimd_dpms(ctx->crtc, DRM_MODE_DPMS_OFF); |
1094 | 1091 | ||
1095 | if (ctx->display) | 1092 | if (ctx->display) |
1096 | exynos_dpi_remove(ctx->display); | 1093 | exynos_dpi_remove(ctx->display); |
1097 | 1094 | ||
1098 | fimd_mgr_remove(&ctx->manager); | 1095 | fimd_ctx_remove(ctx); |
1099 | } | 1096 | } |
1100 | 1097 | ||
1101 | static const struct component_ops fimd_component_ops = { | 1098 | static const struct component_ops fimd_component_ops = { |
@@ -1118,8 +1115,6 @@ static int fimd_probe(struct platform_device *pdev) | |||
1118 | if (!ctx) | 1115 | if (!ctx) |
1119 | return -ENOMEM; | 1116 | return -ENOMEM; |
1120 | 1117 | ||
1121 | ctx->manager.ops = &fimd_manager_ops; | ||
1122 | |||
1123 | ret = exynos_drm_component_add(dev, EXYNOS_DEVICE_TYPE_CRTC, | 1118 | ret = exynos_drm_component_add(dev, EXYNOS_DEVICE_TYPE_CRTC, |
1124 | EXYNOS_DISPLAY_TYPE_LCD); | 1119 | EXYNOS_DISPLAY_TYPE_LCD); |
1125 | if (ret) | 1120 | if (ret) |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index dadd30631c18..95442e69db75 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c | |||
@@ -68,7 +68,7 @@ int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc, | |||
68 | uint32_t src_w, uint32_t src_h) | 68 | uint32_t src_w, uint32_t src_h) |
69 | { | 69 | { |
70 | struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane); | 70 | struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane); |
71 | struct exynos_drm_manager *manager = to_exynos_crtc(crtc)->manager; | 71 | struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); |
72 | unsigned int actual_w; | 72 | unsigned int actual_w; |
73 | unsigned int actual_h; | 73 | unsigned int actual_h; |
74 | int nr; | 74 | int nr; |
@@ -133,8 +133,8 @@ int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc, | |||
133 | 133 | ||
134 | plane->crtc = crtc; | 134 | plane->crtc = crtc; |
135 | 135 | ||
136 | if (manager->ops->win_mode_set) | 136 | if (exynos_crtc->ops->win_mode_set) |
137 | manager->ops->win_mode_set(manager, exynos_plane); | 137 | exynos_crtc->ops->win_mode_set(exynos_crtc, exynos_plane); |
138 | 138 | ||
139 | return 0; | 139 | return 0; |
140 | } | 140 | } |
@@ -142,24 +142,24 @@ int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc, | |||
142 | void exynos_plane_dpms(struct drm_plane *plane, int mode) | 142 | void exynos_plane_dpms(struct drm_plane *plane, int mode) |
143 | { | 143 | { |
144 | struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane); | 144 | struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane); |
145 | struct exynos_drm_manager *manager; | 145 | struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(plane->crtc); |
146 | 146 | ||
147 | if (mode == DRM_MODE_DPMS_ON) { | 147 | if (mode == DRM_MODE_DPMS_ON) { |
148 | if (exynos_plane->enabled) | 148 | if (exynos_plane->enabled) |
149 | return; | 149 | return; |
150 | 150 | ||
151 | manager = to_exynos_crtc(plane->crtc)->manager; | 151 | if (exynos_crtc->ops->win_enable) |
152 | if (manager->ops->win_enable) | 152 | exynos_crtc->ops->win_enable(exynos_crtc, |
153 | manager->ops->win_enable(manager, exynos_plane->zpos); | 153 | exynos_plane->zpos); |
154 | 154 | ||
155 | exynos_plane->enabled = true; | 155 | exynos_plane->enabled = true; |
156 | } else { | 156 | } else { |
157 | if (!exynos_plane->enabled) | 157 | if (!exynos_plane->enabled) |
158 | return; | 158 | return; |
159 | 159 | ||
160 | manager = to_exynos_crtc(plane->crtc)->manager; | 160 | if (exynos_crtc->ops->win_disable) |
161 | if (manager->ops->win_disable) | 161 | exynos_crtc->ops->win_disable(exynos_crtc, |
162 | manager->ops->win_disable(manager, exynos_plane->zpos); | 162 | exynos_plane->zpos); |
163 | 163 | ||
164 | exynos_plane->enabled = false; | 164 | exynos_plane->enabled = false; |
165 | } | 165 | } |
@@ -173,7 +173,7 @@ exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, | |||
173 | uint32_t src_w, uint32_t src_h) | 173 | uint32_t src_w, uint32_t src_h) |
174 | { | 174 | { |
175 | 175 | ||
176 | struct exynos_drm_manager *manager = to_exynos_crtc(crtc)->manager; | 176 | struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); |
177 | struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane); | 177 | struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane); |
178 | int ret; | 178 | int ret; |
179 | 179 | ||
@@ -183,8 +183,8 @@ exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, | |||
183 | if (ret < 0) | 183 | if (ret < 0) |
184 | return ret; | 184 | return ret; |
185 | 185 | ||
186 | if (manager->ops->win_commit) | 186 | if (exynos_crtc->ops->win_commit) |
187 | manager->ops->win_commit(manager, exynos_plane->zpos); | 187 | exynos_crtc->ops->win_commit(exynos_crtc, exynos_plane->zpos); |
188 | 188 | ||
189 | return 0; | 189 | return 0; |
190 | } | 190 | } |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index 03687db8f565..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 | ||
49 | struct vidi_context { | 49 | struct 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 | ||
71 | static inline struct vidi_context *manager_to_vidi(struct exynos_drm_manager *m) | ||
72 | { | ||
73 | return container_of(m, struct vidi_context, manager); | ||
74 | } | ||
75 | |||
76 | static inline struct vidi_context *display_to_vidi(struct exynos_drm_display *d) | 70 | static 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,23 +97,23 @@ static const char fake_edid_info[] = { | |||
103 | 0x00, 0x00, 0x00, 0x06 | 97 | 0x00, 0x00, 0x00, 0x06 |
104 | }; | 98 | }; |
105 | 99 | ||
106 | static void vidi_apply(struct exynos_drm_manager *mgr) | 100 | static 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 | } | 112 | } |
119 | 113 | ||
120 | static int vidi_enable_vblank(struct exynos_drm_manager *mgr) | 114 | static int vidi_enable_vblank(struct exynos_drm_crtc *crtc) |
121 | { | 115 | { |
122 | struct vidi_context *ctx = manager_to_vidi(mgr); | 116 | struct vidi_context *ctx = crtc->ctx; |
123 | 117 | ||
124 | if (ctx->suspended) | 118 | if (ctx->suspended) |
125 | return -EPERM; | 119 | return -EPERM; |
@@ -132,16 +126,16 @@ static int vidi_enable_vblank(struct exynos_drm_manager *mgr) | |||
132 | /* | 126 | /* |
133 | * in case of page flip request, vidi_finish_pageflip function | 127 | * in case of page flip request, vidi_finish_pageflip function |
134 | * will not be called because direct_vblank is true and then | 128 | * will not be called because direct_vblank is true and then |
135 | * that function will be called by manager_ops->win_commit callback | 129 | * that function will be called by crtc_ops->win_commit callback |
136 | */ | 130 | */ |
137 | schedule_work(&ctx->work); | 131 | schedule_work(&ctx->work); |
138 | 132 | ||
139 | return 0; | 133 | return 0; |
140 | } | 134 | } |
141 | 135 | ||
142 | static void vidi_disable_vblank(struct exynos_drm_manager *mgr) | 136 | static void vidi_disable_vblank(struct exynos_drm_crtc *crtc) |
143 | { | 137 | { |
144 | struct vidi_context *ctx = manager_to_vidi(mgr); | 138 | struct vidi_context *ctx = crtc->ctx; |
145 | 139 | ||
146 | if (ctx->suspended) | 140 | if (ctx->suspended) |
147 | return; | 141 | return; |
@@ -150,10 +144,10 @@ static void vidi_disable_vblank(struct exynos_drm_manager *mgr) | |||
150 | ctx->vblank_on = false; | 144 | ctx->vblank_on = false; |
151 | } | 145 | } |
152 | 146 | ||
153 | static void vidi_win_mode_set(struct exynos_drm_manager *mgr, | 147 | static void vidi_win_mode_set(struct exynos_drm_crtc *crtc, |
154 | struct exynos_drm_plane *plane) | 148 | struct exynos_drm_plane *plane) |
155 | { | 149 | { |
156 | struct vidi_context *ctx = manager_to_vidi(mgr); | 150 | struct vidi_context *ctx = crtc->ctx; |
157 | struct vidi_win_data *win_data; | 151 | struct vidi_win_data *win_data; |
158 | int win; | 152 | int win; |
159 | unsigned long offset; | 153 | unsigned long offset; |
@@ -203,9 +197,9 @@ static void vidi_win_mode_set(struct exynos_drm_manager *mgr, | |||
203 | plane->fb_width, plane->crtc_width); | 197 | plane->fb_width, plane->crtc_width); |
204 | } | 198 | } |
205 | 199 | ||
206 | static void vidi_win_commit(struct exynos_drm_manager *mgr, int zpos) | 200 | static void vidi_win_commit(struct exynos_drm_crtc *crtc, int zpos) |
207 | { | 201 | { |
208 | struct vidi_context *ctx = manager_to_vidi(mgr); | 202 | struct vidi_context *ctx = crtc->ctx; |
209 | struct vidi_win_data *win_data; | 203 | struct vidi_win_data *win_data; |
210 | int win = zpos; | 204 | int win = zpos; |
211 | 205 | ||
@@ -228,9 +222,9 @@ static void vidi_win_commit(struct exynos_drm_manager *mgr, int zpos) | |||
228 | schedule_work(&ctx->work); | 222 | schedule_work(&ctx->work); |
229 | } | 223 | } |
230 | 224 | ||
231 | static void vidi_win_disable(struct exynos_drm_manager *mgr, int zpos) | 225 | static void vidi_win_disable(struct exynos_drm_crtc *crtc, int zpos) |
232 | { | 226 | { |
233 | struct vidi_context *ctx = manager_to_vidi(mgr); | 227 | struct vidi_context *ctx = crtc->ctx; |
234 | struct vidi_win_data *win_data; | 228 | struct vidi_win_data *win_data; |
235 | int win = zpos; | 229 | int win = zpos; |
236 | 230 | ||
@@ -246,9 +240,9 @@ static void vidi_win_disable(struct exynos_drm_manager *mgr, int zpos) | |||
246 | /* TODO. */ | 240 | /* TODO. */ |
247 | } | 241 | } |
248 | 242 | ||
249 | static int vidi_power_on(struct exynos_drm_manager *mgr, bool enable) | 243 | static int vidi_power_on(struct exynos_drm_crtc *crtc, bool enable) |
250 | { | 244 | { |
251 | struct vidi_context *ctx = manager_to_vidi(mgr); | 245 | struct vidi_context *ctx = crtc->ctx; |
252 | 246 | ||
253 | DRM_DEBUG_KMS("%s\n", __FILE__); | 247 | DRM_DEBUG_KMS("%s\n", __FILE__); |
254 | 248 | ||
@@ -260,9 +254,9 @@ static int vidi_power_on(struct exynos_drm_manager *mgr, bool enable) | |||
260 | 254 | ||
261 | /* if vblank was enabled status, enable it again. */ | 255 | /* if vblank was enabled status, enable it again. */ |
262 | if (test_and_clear_bit(0, &ctx->irq_flags)) | 256 | if (test_and_clear_bit(0, &ctx->irq_flags)) |
263 | vidi_enable_vblank(mgr); | 257 | vidi_enable_vblank(crtc); |
264 | 258 | ||
265 | vidi_apply(mgr); | 259 | vidi_apply(crtc); |
266 | } else { | 260 | } else { |
267 | ctx->suspended = true; | 261 | ctx->suspended = true; |
268 | } | 262 | } |
@@ -270,9 +264,9 @@ static int vidi_power_on(struct exynos_drm_manager *mgr, bool enable) | |||
270 | return 0; | 264 | return 0; |
271 | } | 265 | } |
272 | 266 | ||
273 | static void vidi_dpms(struct exynos_drm_manager *mgr, int mode) | 267 | static void vidi_dpms(struct exynos_drm_crtc *crtc, int mode) |
274 | { | 268 | { |
275 | struct vidi_context *ctx = manager_to_vidi(mgr); | 269 | struct vidi_context *ctx = crtc->ctx; |
276 | 270 | ||
277 | DRM_DEBUG_KMS("%d\n", mode); | 271 | DRM_DEBUG_KMS("%d\n", mode); |
278 | 272 | ||
@@ -280,12 +274,12 @@ static void vidi_dpms(struct exynos_drm_manager *mgr, int mode) | |||
280 | 274 | ||
281 | switch (mode) { | 275 | switch (mode) { |
282 | case DRM_MODE_DPMS_ON: | 276 | case DRM_MODE_DPMS_ON: |
283 | vidi_power_on(mgr, true); | 277 | vidi_power_on(crtc, true); |
284 | break; | 278 | break; |
285 | case DRM_MODE_DPMS_STANDBY: | 279 | case DRM_MODE_DPMS_STANDBY: |
286 | case DRM_MODE_DPMS_SUSPEND: | 280 | case DRM_MODE_DPMS_SUSPEND: |
287 | case DRM_MODE_DPMS_OFF: | 281 | case DRM_MODE_DPMS_OFF: |
288 | vidi_power_on(mgr, false); | 282 | vidi_power_on(crtc, false); |
289 | break; | 283 | break; |
290 | default: | 284 | default: |
291 | DRM_DEBUG_KMS("unspecified mode %d\n", mode); | 285 | DRM_DEBUG_KMS("unspecified mode %d\n", mode); |
@@ -295,10 +289,9 @@ static void vidi_dpms(struct exynos_drm_manager *mgr, int mode) | |||
295 | mutex_unlock(&ctx->lock); | 289 | mutex_unlock(&ctx->lock); |
296 | } | 290 | } |
297 | 291 | ||
298 | static int vidi_mgr_initialize(struct exynos_drm_manager *mgr, | 292 | static int vidi_ctx_initialize(struct vidi_context *ctx, |
299 | struct drm_device *drm_dev) | 293 | struct drm_device *drm_dev) |
300 | { | 294 | { |
301 | struct vidi_context *ctx = manager_to_vidi(mgr); | ||
302 | struct exynos_drm_private *priv = drm_dev->dev_private; | 295 | struct exynos_drm_private *priv = drm_dev->dev_private; |
303 | 296 | ||
304 | ctx->drm_dev = drm_dev; | 297 | ctx->drm_dev = drm_dev; |
@@ -307,7 +300,7 @@ static int vidi_mgr_initialize(struct exynos_drm_manager *mgr, | |||
307 | return 0; | 300 | return 0; |
308 | } | 301 | } |
309 | 302 | ||
310 | static struct exynos_drm_manager_ops vidi_manager_ops = { | 303 | static struct exynos_drm_crtc_ops vidi_crtc_ops = { |
311 | .dpms = vidi_dpms, | 304 | .dpms = vidi_dpms, |
312 | .enable_vblank = vidi_enable_vblank, | 305 | .enable_vblank = vidi_enable_vblank, |
313 | .disable_vblank = vidi_disable_vblank, | 306 | .disable_vblank = vidi_disable_vblank, |
@@ -553,22 +546,21 @@ static int vidi_bind(struct device *dev, struct device *master, void *data) | |||
553 | { | 546 | { |
554 | struct vidi_context *ctx = dev_get_drvdata(dev); | 547 | struct vidi_context *ctx = dev_get_drvdata(dev); |
555 | struct drm_device *drm_dev = data; | 548 | struct drm_device *drm_dev = data; |
556 | struct drm_crtc *crtc = ctx->crtc; | ||
557 | int ret; | 549 | int ret; |
558 | 550 | ||
559 | vidi_mgr_initialize(&ctx->manager, drm_dev); | 551 | ctx->crtc = exynos_drm_crtc_create(drm_dev, ctx->pipe, |
560 | 552 | EXYNOS_DISPLAY_TYPE_VIDI, | |
561 | ret = exynos_drm_crtc_create(&ctx->manager, drm_dev, ctx->pipe, | 553 | &vidi_crtc_ops, ctx); |
562 | EXYNOS_DISPLAY_TYPE_VIDI); | 554 | if (IS_ERR(ctx->crtc)) { |
563 | if (ret) { | ||
564 | DRM_ERROR("failed to create crtc.\n"); | 555 | DRM_ERROR("failed to create crtc.\n"); |
565 | return ret; | 556 | return PTR_ERR(ctx->crtc); |
566 | } | 557 | } |
567 | 558 | ||
559 | vidi_ctx_initialize(ctx, drm_dev); | ||
560 | |||
568 | ret = exynos_drm_create_enc_conn(drm_dev, &ctx->display); | 561 | ret = exynos_drm_create_enc_conn(drm_dev, &ctx->display); |
569 | if (ret) { | 562 | if (ret) { |
570 | crtc->funcs->destroy(crtc); | 563 | ctx->crtc->base.funcs->destroy(&ctx->crtc->base); |
571 | DRM_ERROR("failed to create encoder and connector.\n"); | ||
572 | return ret; | 564 | return ret; |
573 | } | 565 | } |
574 | 566 | ||
@@ -594,7 +586,6 @@ static int vidi_probe(struct platform_device *pdev) | |||
594 | if (!ctx) | 586 | if (!ctx) |
595 | return -ENOMEM; | 587 | return -ENOMEM; |
596 | 588 | ||
597 | ctx->manager.ops = &vidi_manager_ops; | ||
598 | ctx->display.type = EXYNOS_DISPLAY_TYPE_VIDI; | 589 | ctx->display.type = EXYNOS_DISPLAY_TYPE_VIDI; |
599 | ctx->display.ops = &vidi_display_ops; | 590 | ctx->display.ops = &vidi_display_ops; |
600 | ctx->default_win = 0; | 591 | ctx->default_win = 0; |
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index c8adcf2d9d23..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 | ||
86 | struct mixer_context { | 86 | struct 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 | ||
106 | static inline struct mixer_context *mgr_to_mixer(struct exynos_drm_manager *mgr) | ||
107 | { | ||
108 | return container_of(mgr, struct mixer_context, manager); | ||
109 | } | ||
110 | |||
111 | struct mixer_drv_data { | 106 | struct 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,11 +849,10 @@ static int vp_resources_init(struct mixer_context *mixer_ctx) | |||
854 | return 0; | 849 | return 0; |
855 | } | 850 | } |
856 | 851 | ||
857 | static int mixer_initialize(struct exynos_drm_manager *mgr, | 852 | static 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 | ||
@@ -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 | ||
890 | static void mixer_mgr_remove(struct exynos_drm_manager *mgr) | 884 | static 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 | ||
898 | static int mixer_enable_vblank(struct exynos_drm_manager *mgr) | 890 | static 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,19 +904,19 @@ static int mixer_enable_vblank(struct exynos_drm_manager *mgr) | |||
912 | return 0; | 904 | return 0; |
913 | } | 905 | } |
914 | 906 | ||
915 | static void mixer_disable_vblank(struct exynos_drm_manager *mgr) | 907 | static 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 | ||
924 | static void mixer_win_mode_set(struct exynos_drm_manager *mgr, | 916 | static void mixer_win_mode_set(struct exynos_drm_crtc *crtc, |
925 | struct exynos_drm_plane *plane) | 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 | ||
@@ -973,9 +965,9 @@ static void mixer_win_mode_set(struct exynos_drm_manager *mgr, | |||
973 | win_data->scan_flags = plane->scan_flag; | 965 | win_data->scan_flags = plane->scan_flag; |
974 | } | 966 | } |
975 | 967 | ||
976 | static void mixer_win_commit(struct exynos_drm_manager *mgr, int zpos) | 968 | static 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 | ||
998 | static void mixer_win_disable(struct exynos_drm_manager *mgr, int zpos) | 990 | static 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 | ||
1026 | static void mixer_wait_for_vblank(struct exynos_drm_manager *mgr) | 1018 | static 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 | ||
1058 | static void mixer_window_suspend(struct exynos_drm_manager *mgr) | 1050 | static 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 | ||
1072 | static void mixer_window_resume(struct exynos_drm_manager *mgr) | 1064 | static 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 | ||
1087 | static void mixer_poweron(struct exynos_drm_manager *mgr) | 1079 | static 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 | ||
1121 | static void mixer_poweroff(struct exynos_drm_manager *mgr) | 1113 | static 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 | ||
1152 | static void mixer_dpms(struct exynos_drm_manager *mgr, int mode) | 1144 | static 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 | ||
1189 | static struct exynos_drm_manager_ops mixer_manager_ops = { | 1181 | static 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,25 +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, drm_dev, ctx->pipe, | 1256 | ret = PTR_ERR(ctx->crtc); |
1265 | EXYNOS_DISPLAY_TYPE_HDMI); | 1257 | goto free_ctx; |
1266 | if (ret) { | ||
1267 | mixer_mgr_remove(&ctx->manager); | ||
1268 | return ret; | ||
1269 | } | 1258 | } |
1270 | 1259 | ||
1260 | ret = mixer_initialize(ctx, drm_dev); | ||
1261 | if (ret) | ||
1262 | goto free_ctx; | ||
1263 | |||
1271 | return 0; | 1264 | return 0; |
1265 | |||
1266 | free_ctx: | ||
1267 | devm_kfree(dev, ctx); | ||
1268 | return ret; | ||
1272 | } | 1269 | } |
1273 | 1270 | ||
1274 | static void mixer_unbind(struct device *dev, struct device *master, void *data) | 1271 | static void mixer_unbind(struct device *dev, struct device *master, void *data) |
1275 | { | 1272 | { |
1276 | struct mixer_context *ctx = dev_get_drvdata(dev); | 1273 | struct mixer_context *ctx = dev_get_drvdata(dev); |
1277 | 1274 | ||
1278 | mixer_mgr_remove(&ctx->manager); | 1275 | mixer_ctx_remove(ctx); |
1279 | } | 1276 | } |
1280 | 1277 | ||
1281 | static const struct component_ops mixer_component_ops = { | 1278 | static const struct component_ops mixer_component_ops = { |
@@ -1298,8 +1295,6 @@ static int mixer_probe(struct platform_device *pdev) | |||
1298 | 1295 | ||
1299 | mutex_init(&ctx->mixer_mutex); | 1296 | mutex_init(&ctx->mixer_mutex); |
1300 | 1297 | ||
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 | ||