diff options
Diffstat (limited to 'drivers/gpu/drm/exynos/exynos_drm_fimd.c')
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_fimd.c | 196 |
1 files changed, 97 insertions, 99 deletions
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 | ||
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; |
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 | ||
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[] = { | 187 | static 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 | ||
217 | static void fimd_wait_for_vblank(struct exynos_drm_manager *mgr) | 211 | static 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 | ||
262 | static void fimd_clear_channel(struct exynos_drm_manager *mgr) | 256 | static 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 | ||
294 | static int fimd_mgr_initialize(struct exynos_drm_manager *mgr, | 288 | static 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 | ||
317 | static void fimd_mgr_remove(struct exynos_drm_manager *mgr) | 317 | static 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 | ||
346 | static bool fimd_mode_fixup(struct exynos_drm_manager *mgr, | 344 | static 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 | ||
356 | static void fimd_mode_set(struct exynos_drm_manager *mgr, | 354 | static 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 | |||
364 | static 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 | ||
464 | static int fimd_enable_vblank(struct exynos_drm_manager *mgr) | 454 | static 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 | ||
496 | static void fimd_disable_vblank(struct exynos_drm_manager *mgr) | 486 | static 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 | ||
520 | static void fimd_win_mode_set(struct exynos_drm_manager *mgr, | 510 | static 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 | ||
569 | static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win) | 559 | static 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 | ||
679 | static void fimd_win_commit(struct exynos_drm_manager *mgr, int zpos) | 669 | static 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 | ||
802 | static void fimd_win_disable(struct exynos_drm_manager *mgr, int zpos) | 792 | static 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 | ||
836 | static void fimd_window_suspend(struct exynos_drm_manager *mgr) | 826 | static 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 | ||
850 | static void fimd_window_resume(struct exynos_drm_manager *mgr) | 840 | static 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 | ||
863 | static void fimd_apply(struct exynos_drm_manager *mgr) | 853 | static 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 | ||
880 | static int fimd_poweron(struct exynos_drm_manager *mgr) | 870 | static 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 | ||
928 | static int fimd_poweroff(struct exynos_drm_manager *mgr) | 918 | static 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 | ||
951 | static void fimd_dpms(struct exynos_drm_manager *mgr, int mode) | 941 | static 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 | ||
999 | static void fimd_te_handler(struct exynos_drm_manager *mgr) | 989 | static 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 | ||
1024 | static struct exynos_drm_manager_ops fimd_manager_ops = { | 1014 | static 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 | ||
1100 | static const struct component_ops fimd_component_ops = { | 1101 | static 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 | ||