diff options
Diffstat (limited to 'drivers/gpu/drm/exynos/exynos_drm_crtc.c')
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_crtc.c | 67 |
1 files changed, 32 insertions, 35 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 | } |