aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/exynos/exynos_drm_fimd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/exynos/exynos_drm_fimd.c')
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimd.c196
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
159struct fimd_context { 159struct fimd_context {
160 struct exynos_drm_manager manager;
161 struct device *dev; 160 struct device *dev;
162 struct drm_device *drm_dev; 161 struct drm_device *drm_dev;
162 struct exynos_drm_crtc *crtc;
163 struct clk *bus_clk; 163 struct clk *bus_clk;
164 struct clk *lcd_clk; 164 struct clk *lcd_clk;
165 void __iomem *regs; 165 void __iomem *regs;
166 struct regmap *sysreg; 166 struct regmap *sysreg;
167 struct drm_display_mode mode;
168 struct fimd_win_data win_data[WINDOWS_NR]; 167 struct fimd_win_data win_data[WINDOWS_NR];
169 unsigned int default_win; 168 unsigned int default_win;
170 unsigned long irq_flags; 169 unsigned long irq_flags;
@@ -185,11 +184,6 @@ struct fimd_context {
185 struct exynos_drm_display *display; 184 struct exynos_drm_display *display;
186}; 185};
187 186
188static inline struct fimd_context *mgr_to_fimd(struct exynos_drm_manager *mgr)
189{
190 return container_of(mgr, struct fimd_context, manager);
191}
192
193static const struct of_device_id fimd_driver_dt_match[] = { 187static const struct of_device_id fimd_driver_dt_match[] = {
194 { .compatible = "samsung,s3c6400-fimd", 188 { .compatible = "samsung,s3c6400-fimd",
195 .data = &s3c64xx_fimd_driver_data }, 189 .data = &s3c64xx_fimd_driver_data },
@@ -214,9 +208,9 @@ static inline struct fimd_driver_data *drm_fimd_get_driver_data(
214 return (struct fimd_driver_data *)of_id->data; 208 return (struct fimd_driver_data *)of_id->data;
215} 209}
216 210
217static void fimd_wait_for_vblank(struct exynos_drm_manager *mgr) 211static void fimd_wait_for_vblank(struct exynos_drm_crtc *crtc)
218{ 212{
219 struct fimd_context *ctx = mgr_to_fimd(mgr); 213 struct fimd_context *ctx = crtc->ctx;
220 214
221 if (ctx->suspended) 215 if (ctx->suspended)
222 return; 216 return;
@@ -259,9 +253,9 @@ static void fimd_enable_shadow_channel_path(struct fimd_context *ctx, int win,
259 writel(val, ctx->regs + SHADOWCON); 253 writel(val, ctx->regs + SHADOWCON);
260} 254}
261 255
262static void fimd_clear_channel(struct exynos_drm_manager *mgr) 256static void fimd_clear_channel(struct exynos_drm_crtc *crtc)
263{ 257{
264 struct fimd_context *ctx = mgr_to_fimd(mgr); 258 struct fimd_context *ctx = crtc->ctx;
265 int win, ch_enabled = 0; 259 int win, ch_enabled = 0;
266 260
267 DRM_DEBUG_KMS("%s\n", __FILE__); 261 DRM_DEBUG_KMS("%s\n", __FILE__);
@@ -286,38 +280,42 @@ static void fimd_clear_channel(struct exynos_drm_manager *mgr)
286 unsigned int state = ctx->suspended; 280 unsigned int state = ctx->suspended;
287 281
288 ctx->suspended = 0; 282 ctx->suspended = 0;
289 fimd_wait_for_vblank(mgr); 283 fimd_wait_for_vblank(crtc);
290 ctx->suspended = state; 284 ctx->suspended = state;
291 } 285 }
292} 286}
293 287
294static int fimd_mgr_initialize(struct exynos_drm_manager *mgr, 288static int fimd_ctx_initialize(struct fimd_context *ctx,
295 struct drm_device *drm_dev) 289 struct drm_device *drm_dev)
296{ 290{
297 struct fimd_context *ctx = mgr_to_fimd(mgr);
298 struct exynos_drm_private *priv; 291 struct exynos_drm_private *priv;
299 priv = drm_dev->dev_private; 292 priv = drm_dev->dev_private;
300 293
301 mgr->drm_dev = ctx->drm_dev = drm_dev; 294 ctx->drm_dev = drm_dev;
302 mgr->pipe = ctx->pipe = priv->pipe++; 295 ctx->pipe = priv->pipe++;
303 296
304 /* attach this sub driver to iommu mapping if supported. */ 297 /* attach this sub driver to iommu mapping if supported. */
305 if (is_drm_iommu_supported(ctx->drm_dev)) { 298 if (is_drm_iommu_supported(ctx->drm_dev)) {
299 int ret;
300
306 /* 301 /*
307 * If any channel is already active, iommu will throw 302 * If any channel is already active, iommu will throw
308 * a PAGE FAULT when enabled. So clear any channel if enabled. 303 * a PAGE FAULT when enabled. So clear any channel if enabled.
309 */ 304 */
310 fimd_clear_channel(mgr); 305 fimd_clear_channel(ctx->crtc);
311 drm_iommu_attach_device(ctx->drm_dev, ctx->dev); 306 ret = drm_iommu_attach_device(ctx->drm_dev, ctx->dev);
307 if (ret) {
308 DRM_ERROR("drm_iommu_attach failed.\n");
309 return ret;
310 }
311
312 } 312 }
313 313
314 return 0; 314 return 0;
315} 315}
316 316
317static void fimd_mgr_remove(struct exynos_drm_manager *mgr) 317static void fimd_ctx_remove(struct fimd_context *ctx)
318{ 318{
319 struct fimd_context *ctx = mgr_to_fimd(mgr);
320
321 /* detach this sub driver from iommu mapping if supported. */ 319 /* detach this sub driver from iommu mapping if supported. */
322 if (is_drm_iommu_supported(ctx->drm_dev)) 320 if (is_drm_iommu_supported(ctx->drm_dev))
323 drm_iommu_detach_device(ctx->drm_dev, ctx->dev); 321 drm_iommu_detach_device(ctx->drm_dev, ctx->dev);
@@ -343,7 +341,7 @@ static u32 fimd_calc_clkdiv(struct fimd_context *ctx,
343 return (clkdiv < 0x100) ? clkdiv : 0xff; 341 return (clkdiv < 0x100) ? clkdiv : 0xff;
344} 342}
345 343
346static bool fimd_mode_fixup(struct exynos_drm_manager *mgr, 344static bool fimd_mode_fixup(struct exynos_drm_crtc *crtc,
347 const struct drm_display_mode *mode, 345 const struct drm_display_mode *mode,
348 struct drm_display_mode *adjusted_mode) 346 struct drm_display_mode *adjusted_mode)
349{ 347{
@@ -353,18 +351,10 @@ static bool fimd_mode_fixup(struct exynos_drm_manager *mgr,
353 return true; 351 return true;
354} 352}
355 353
356static void fimd_mode_set(struct exynos_drm_manager *mgr, 354static void fimd_commit(struct exynos_drm_crtc *crtc)
357 const struct drm_display_mode *in_mode)
358{ 355{
359 struct fimd_context *ctx = mgr_to_fimd(mgr); 356 struct fimd_context *ctx = crtc->ctx;
360 357 struct drm_display_mode *mode = &crtc->base.mode;
361 drm_mode_copy(&ctx->mode, in_mode);
362}
363
364static void fimd_commit(struct exynos_drm_manager *mgr)
365{
366 struct fimd_context *ctx = mgr_to_fimd(mgr);
367 struct drm_display_mode *mode = &ctx->mode;
368 struct fimd_driver_data *driver_data = ctx->driver_data; 358 struct fimd_driver_data *driver_data = ctx->driver_data;
369 void *timing_base = ctx->regs + driver_data->timing_base; 359 void *timing_base = ctx->regs + driver_data->timing_base;
370 u32 val, clkdiv; 360 u32 val, clkdiv;
@@ -461,9 +451,9 @@ static void fimd_commit(struct exynos_drm_manager *mgr)
461 writel(val, ctx->regs + VIDCON0); 451 writel(val, ctx->regs + VIDCON0);
462} 452}
463 453
464static int fimd_enable_vblank(struct exynos_drm_manager *mgr) 454static int fimd_enable_vblank(struct exynos_drm_crtc *crtc)
465{ 455{
466 struct fimd_context *ctx = mgr_to_fimd(mgr); 456 struct fimd_context *ctx = crtc->ctx;
467 u32 val; 457 u32 val;
468 458
469 if (ctx->suspended) 459 if (ctx->suspended)
@@ -493,9 +483,9 @@ static int fimd_enable_vblank(struct exynos_drm_manager *mgr)
493 return 0; 483 return 0;
494} 484}
495 485
496static void fimd_disable_vblank(struct exynos_drm_manager *mgr) 486static void fimd_disable_vblank(struct exynos_drm_crtc *crtc)
497{ 487{
498 struct fimd_context *ctx = mgr_to_fimd(mgr); 488 struct fimd_context *ctx = crtc->ctx;
499 u32 val; 489 u32 val;
500 490
501 if (ctx->suspended) 491 if (ctx->suspended)
@@ -517,45 +507,45 @@ static void fimd_disable_vblank(struct exynos_drm_manager *mgr)
517 } 507 }
518} 508}
519 509
520static void fimd_win_mode_set(struct exynos_drm_manager *mgr, 510static void fimd_win_mode_set(struct exynos_drm_crtc *crtc,
521 struct exynos_drm_overlay *overlay) 511 struct exynos_drm_plane *plane)
522{ 512{
523 struct fimd_context *ctx = mgr_to_fimd(mgr); 513 struct fimd_context *ctx = crtc->ctx;
524 struct fimd_win_data *win_data; 514 struct fimd_win_data *win_data;
525 int win; 515 int win;
526 unsigned long offset; 516 unsigned long offset;
527 517
528 if (!overlay) { 518 if (!plane) {
529 DRM_ERROR("overlay is NULL\n"); 519 DRM_ERROR("plane is NULL\n");
530 return; 520 return;
531 } 521 }
532 522
533 win = overlay->zpos; 523 win = plane->zpos;
534 if (win == DEFAULT_ZPOS) 524 if (win == DEFAULT_ZPOS)
535 win = ctx->default_win; 525 win = ctx->default_win;
536 526
537 if (win < 0 || win >= WINDOWS_NR) 527 if (win < 0 || win >= WINDOWS_NR)
538 return; 528 return;
539 529
540 offset = overlay->fb_x * (overlay->bpp >> 3); 530 offset = plane->fb_x * (plane->bpp >> 3);
541 offset += overlay->fb_y * overlay->pitch; 531 offset += plane->fb_y * plane->pitch;
542 532
543 DRM_DEBUG_KMS("offset = 0x%lx, pitch = %x\n", offset, overlay->pitch); 533 DRM_DEBUG_KMS("offset = 0x%lx, pitch = %x\n", offset, plane->pitch);
544 534
545 win_data = &ctx->win_data[win]; 535 win_data = &ctx->win_data[win];
546 536
547 win_data->offset_x = overlay->crtc_x; 537 win_data->offset_x = plane->crtc_x;
548 win_data->offset_y = overlay->crtc_y; 538 win_data->offset_y = plane->crtc_y;
549 win_data->ovl_width = overlay->crtc_width; 539 win_data->ovl_width = plane->crtc_width;
550 win_data->ovl_height = overlay->crtc_height; 540 win_data->ovl_height = plane->crtc_height;
551 win_data->fb_width = overlay->fb_width; 541 win_data->fb_width = plane->fb_width;
552 win_data->fb_height = overlay->fb_height; 542 win_data->fb_height = plane->fb_height;
553 win_data->dma_addr = overlay->dma_addr[0] + offset; 543 win_data->dma_addr = plane->dma_addr[0] + offset;
554 win_data->bpp = overlay->bpp; 544 win_data->bpp = plane->bpp;
555 win_data->pixel_format = overlay->pixel_format; 545 win_data->pixel_format = plane->pixel_format;
556 win_data->buf_offsize = (overlay->fb_width - overlay->crtc_width) * 546 win_data->buf_offsize = (plane->fb_width - plane->crtc_width) *
557 (overlay->bpp >> 3); 547 (plane->bpp >> 3);
558 win_data->line_size = overlay->crtc_width * (overlay->bpp >> 3); 548 win_data->line_size = plane->crtc_width * (plane->bpp >> 3);
559 549
560 DRM_DEBUG_KMS("offset_x = %d, offset_y = %d\n", 550 DRM_DEBUG_KMS("offset_x = %d, offset_y = %d\n",
561 win_data->offset_x, win_data->offset_y); 551 win_data->offset_x, win_data->offset_y);
@@ -563,7 +553,7 @@ static void fimd_win_mode_set(struct exynos_drm_manager *mgr,
563 win_data->ovl_width, win_data->ovl_height); 553 win_data->ovl_width, win_data->ovl_height);
564 DRM_DEBUG_KMS("paddr = 0x%lx\n", (unsigned long)win_data->dma_addr); 554 DRM_DEBUG_KMS("paddr = 0x%lx\n", (unsigned long)win_data->dma_addr);
565 DRM_DEBUG_KMS("fb_width = %d, crtc_width = %d\n", 555 DRM_DEBUG_KMS("fb_width = %d, crtc_width = %d\n",
566 overlay->fb_width, overlay->crtc_width); 556 plane->fb_width, plane->crtc_width);
567} 557}
568 558
569static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win) 559static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win)
@@ -623,8 +613,8 @@ static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win)
623 /* 613 /*
624 * In case of exynos, setting dma-burst to 16Word causes permanent 614 * In case of exynos, setting dma-burst to 16Word causes permanent
625 * tearing for very small buffers, e.g. cursor buffer. Burst Mode 615 * tearing for very small buffers, e.g. cursor buffer. Burst Mode
626 * switching which is based on overlay size is not recommended as 616 * switching which is based on plane size is not recommended as
627 * overlay size varies alot towards the end of the screen and rapid 617 * plane size varies alot towards the end of the screen and rapid
628 * movement causes unstable DMA which results into iommu crash/tear. 618 * movement causes unstable DMA which results into iommu crash/tear.
629 */ 619 */
630 620
@@ -676,9 +666,9 @@ static void fimd_shadow_protect_win(struct fimd_context *ctx,
676 writel(val, ctx->regs + reg); 666 writel(val, ctx->regs + reg);
677} 667}
678 668
679static void fimd_win_commit(struct exynos_drm_manager *mgr, int zpos) 669static void fimd_win_commit(struct exynos_drm_crtc *crtc, int zpos)
680{ 670{
681 struct fimd_context *ctx = mgr_to_fimd(mgr); 671 struct fimd_context *ctx = crtc->ctx;
682 struct fimd_win_data *win_data; 672 struct fimd_win_data *win_data;
683 int win = zpos; 673 int win = zpos;
684 unsigned long val, alpha, size; 674 unsigned long val, alpha, size;
@@ -799,9 +789,9 @@ static void fimd_win_commit(struct exynos_drm_manager *mgr, int zpos)
799 atomic_set(&ctx->win_updated, 1); 789 atomic_set(&ctx->win_updated, 1);
800} 790}
801 791
802static void fimd_win_disable(struct exynos_drm_manager *mgr, int zpos) 792static void fimd_win_disable(struct exynos_drm_crtc *crtc, int zpos)
803{ 793{
804 struct fimd_context *ctx = mgr_to_fimd(mgr); 794 struct fimd_context *ctx = crtc->ctx;
805 struct fimd_win_data *win_data; 795 struct fimd_win_data *win_data;
806 int win = zpos; 796 int win = zpos;
807 797
@@ -833,9 +823,9 @@ static void fimd_win_disable(struct exynos_drm_manager *mgr, int zpos)
833 win_data->enabled = false; 823 win_data->enabled = false;
834} 824}
835 825
836static void fimd_window_suspend(struct exynos_drm_manager *mgr) 826static void fimd_window_suspend(struct exynos_drm_crtc *crtc)
837{ 827{
838 struct fimd_context *ctx = mgr_to_fimd(mgr); 828 struct fimd_context *ctx = crtc->ctx;
839 struct fimd_win_data *win_data; 829 struct fimd_win_data *win_data;
840 int i; 830 int i;
841 831
@@ -843,13 +833,13 @@ static void fimd_window_suspend(struct exynos_drm_manager *mgr)
843 win_data = &ctx->win_data[i]; 833 win_data = &ctx->win_data[i];
844 win_data->resume = win_data->enabled; 834 win_data->resume = win_data->enabled;
845 if (win_data->enabled) 835 if (win_data->enabled)
846 fimd_win_disable(mgr, i); 836 fimd_win_disable(crtc, i);
847 } 837 }
848} 838}
849 839
850static void fimd_window_resume(struct exynos_drm_manager *mgr) 840static void fimd_window_resume(struct exynos_drm_crtc *crtc)
851{ 841{
852 struct fimd_context *ctx = mgr_to_fimd(mgr); 842 struct fimd_context *ctx = crtc->ctx;
853 struct fimd_win_data *win_data; 843 struct fimd_win_data *win_data;
854 int i; 844 int i;
855 845
@@ -860,26 +850,26 @@ static void fimd_window_resume(struct exynos_drm_manager *mgr)
860 } 850 }
861} 851}
862 852
863static void fimd_apply(struct exynos_drm_manager *mgr) 853static void fimd_apply(struct exynos_drm_crtc *crtc)
864{ 854{
865 struct fimd_context *ctx = mgr_to_fimd(mgr); 855 struct fimd_context *ctx = crtc->ctx;
866 struct fimd_win_data *win_data; 856 struct fimd_win_data *win_data;
867 int i; 857 int i;
868 858
869 for (i = 0; i < WINDOWS_NR; i++) { 859 for (i = 0; i < WINDOWS_NR; i++) {
870 win_data = &ctx->win_data[i]; 860 win_data = &ctx->win_data[i];
871 if (win_data->enabled) 861 if (win_data->enabled)
872 fimd_win_commit(mgr, i); 862 fimd_win_commit(crtc, i);
873 else 863 else
874 fimd_win_disable(mgr, i); 864 fimd_win_disable(crtc, i);
875 } 865 }
876 866
877 fimd_commit(mgr); 867 fimd_commit(crtc);
878} 868}
879 869
880static int fimd_poweron(struct exynos_drm_manager *mgr) 870static int fimd_poweron(struct exynos_drm_crtc *crtc)
881{ 871{
882 struct fimd_context *ctx = mgr_to_fimd(mgr); 872 struct fimd_context *ctx = crtc->ctx;
883 int ret; 873 int ret;
884 874
885 if (!ctx->suspended) 875 if (!ctx->suspended)
@@ -903,16 +893,16 @@ static int fimd_poweron(struct exynos_drm_manager *mgr)
903 893
904 /* if vblank was enabled status, enable it again. */ 894 /* if vblank was enabled status, enable it again. */
905 if (test_and_clear_bit(0, &ctx->irq_flags)) { 895 if (test_and_clear_bit(0, &ctx->irq_flags)) {
906 ret = fimd_enable_vblank(mgr); 896 ret = fimd_enable_vblank(crtc);
907 if (ret) { 897 if (ret) {
908 DRM_ERROR("Failed to re-enable vblank [%d]\n", ret); 898 DRM_ERROR("Failed to re-enable vblank [%d]\n", ret);
909 goto enable_vblank_err; 899 goto enable_vblank_err;
910 } 900 }
911 } 901 }
912 902
913 fimd_window_resume(mgr); 903 fimd_window_resume(crtc);
914 904
915 fimd_apply(mgr); 905 fimd_apply(crtc);
916 906
917 return 0; 907 return 0;
918 908
@@ -925,9 +915,9 @@ bus_clk_err:
925 return ret; 915 return ret;
926} 916}
927 917
928static int fimd_poweroff(struct exynos_drm_manager *mgr) 918static int fimd_poweroff(struct exynos_drm_crtc *crtc)
929{ 919{
930 struct fimd_context *ctx = mgr_to_fimd(mgr); 920 struct fimd_context *ctx = crtc->ctx;
931 921
932 if (ctx->suspended) 922 if (ctx->suspended)
933 return 0; 923 return 0;
@@ -937,7 +927,7 @@ static int fimd_poweroff(struct exynos_drm_manager *mgr)
937 * suspend that connector. Otherwise we might try to scan from 927 * suspend that connector. Otherwise we might try to scan from
938 * a destroyed buffer later. 928 * a destroyed buffer later.
939 */ 929 */
940 fimd_window_suspend(mgr); 930 fimd_window_suspend(crtc);
941 931
942 clk_disable_unprepare(ctx->lcd_clk); 932 clk_disable_unprepare(ctx->lcd_clk);
943 clk_disable_unprepare(ctx->bus_clk); 933 clk_disable_unprepare(ctx->bus_clk);
@@ -948,18 +938,18 @@ static int fimd_poweroff(struct exynos_drm_manager *mgr)
948 return 0; 938 return 0;
949} 939}
950 940
951static void fimd_dpms(struct exynos_drm_manager *mgr, int mode) 941static void fimd_dpms(struct exynos_drm_crtc *crtc, int mode)
952{ 942{
953 DRM_DEBUG_KMS("%s, %d\n", __FILE__, mode); 943 DRM_DEBUG_KMS("%s, %d\n", __FILE__, mode);
954 944
955 switch (mode) { 945 switch (mode) {
956 case DRM_MODE_DPMS_ON: 946 case DRM_MODE_DPMS_ON:
957 fimd_poweron(mgr); 947 fimd_poweron(crtc);
958 break; 948 break;
959 case DRM_MODE_DPMS_STANDBY: 949 case DRM_MODE_DPMS_STANDBY:
960 case DRM_MODE_DPMS_SUSPEND: 950 case DRM_MODE_DPMS_SUSPEND:
961 case DRM_MODE_DPMS_OFF: 951 case DRM_MODE_DPMS_OFF:
962 fimd_poweroff(mgr); 952 fimd_poweroff(crtc);
963 break; 953 break;
964 default: 954 default:
965 DRM_DEBUG_KMS("unspecified mode %d\n", mode); 955 DRM_DEBUG_KMS("unspecified mode %d\n", mode);
@@ -996,9 +986,9 @@ static void fimd_trigger(struct device *dev)
996 atomic_set(&ctx->triggering, 0); 986 atomic_set(&ctx->triggering, 0);
997} 987}
998 988
999static void fimd_te_handler(struct exynos_drm_manager *mgr) 989static void fimd_te_handler(struct exynos_drm_crtc *crtc)
1000{ 990{
1001 struct fimd_context *ctx = mgr_to_fimd(mgr); 991 struct fimd_context *ctx = crtc->ctx;
1002 992
1003 /* Checks the crtc is detached already from encoder */ 993 /* Checks the crtc is detached already from encoder */
1004 if (ctx->pipe < 0 || !ctx->drm_dev) 994 if (ctx->pipe < 0 || !ctx->drm_dev)
@@ -1021,10 +1011,9 @@ static void fimd_te_handler(struct exynos_drm_manager *mgr)
1021 drm_handle_vblank(ctx->drm_dev, ctx->pipe); 1011 drm_handle_vblank(ctx->drm_dev, ctx->pipe);
1022} 1012}
1023 1013
1024static struct exynos_drm_manager_ops fimd_manager_ops = { 1014static struct exynos_drm_crtc_ops fimd_crtc_ops = {
1025 .dpms = fimd_dpms, 1015 .dpms = fimd_dpms,
1026 .mode_fixup = fimd_mode_fixup, 1016 .mode_fixup = fimd_mode_fixup,
1027 .mode_set = fimd_mode_set,
1028 .commit = fimd_commit, 1017 .commit = fimd_commit,
1029 .enable_vblank = fimd_enable_vblank, 1018 .enable_vblank = fimd_enable_vblank,
1030 .disable_vblank = fimd_disable_vblank, 1019 .disable_vblank = fimd_disable_vblank,
@@ -1074,9 +1063,21 @@ static int fimd_bind(struct device *dev, struct device *master, void *data)
1074{ 1063{
1075 struct fimd_context *ctx = dev_get_drvdata(dev); 1064 struct fimd_context *ctx = dev_get_drvdata(dev);
1076 struct drm_device *drm_dev = data; 1065 struct drm_device *drm_dev = data;
1066 int ret;
1067
1068 ctx->crtc = exynos_drm_crtc_create(drm_dev, ctx->pipe,
1069 EXYNOS_DISPLAY_TYPE_LCD,
1070 &fimd_crtc_ops, ctx);
1071 if (IS_ERR(ctx->crtc))
1072 return PTR_ERR(ctx->crtc);
1073
1074 ret = fimd_ctx_initialize(ctx, drm_dev);
1075 if (ret) {
1076 DRM_ERROR("fimd_ctx_initialize failed.\n");
1077 return ret;
1078 }
1079
1077 1080
1078 fimd_mgr_initialize(&ctx->manager, drm_dev);
1079 exynos_drm_crtc_create(&ctx->manager);
1080 if (ctx->display) 1081 if (ctx->display)
1081 exynos_drm_create_enc_conn(drm_dev, ctx->display); 1082 exynos_drm_create_enc_conn(drm_dev, ctx->display);
1082 1083
@@ -1089,12 +1090,12 @@ static void fimd_unbind(struct device *dev, struct device *master,
1089{ 1090{
1090 struct fimd_context *ctx = dev_get_drvdata(dev); 1091 struct fimd_context *ctx = dev_get_drvdata(dev);
1091 1092
1092 fimd_dpms(&ctx->manager, DRM_MODE_DPMS_OFF); 1093 fimd_dpms(ctx->crtc, DRM_MODE_DPMS_OFF);
1093 1094
1094 if (ctx->display) 1095 if (ctx->display)
1095 exynos_dpi_remove(ctx->display); 1096 exynos_dpi_remove(ctx->display);
1096 1097
1097 fimd_mgr_remove(&ctx->manager); 1098 fimd_ctx_remove(ctx);
1098} 1099}
1099 1100
1100static const struct component_ops fimd_component_ops = { 1101static const struct component_ops fimd_component_ops = {
@@ -1108,7 +1109,7 @@ static int fimd_probe(struct platform_device *pdev)
1108 struct fimd_context *ctx; 1109 struct fimd_context *ctx;
1109 struct device_node *i80_if_timings; 1110 struct device_node *i80_if_timings;
1110 struct resource *res; 1111 struct resource *res;
1111 int ret = -EINVAL; 1112 int ret;
1112 1113
1113 if (!dev->of_node) 1114 if (!dev->of_node)
1114 return -ENODEV; 1115 return -ENODEV;
@@ -1117,11 +1118,8 @@ static int fimd_probe(struct platform_device *pdev)
1117 if (!ctx) 1118 if (!ctx)
1118 return -ENOMEM; 1119 return -ENOMEM;
1119 1120
1120 ctx->manager.type = EXYNOS_DISPLAY_TYPE_LCD;
1121 ctx->manager.ops = &fimd_manager_ops;
1122
1123 ret = exynos_drm_component_add(dev, EXYNOS_DEVICE_TYPE_CRTC, 1121 ret = exynos_drm_component_add(dev, EXYNOS_DEVICE_TYPE_CRTC,
1124 ctx->manager.type); 1122 EXYNOS_DISPLAY_TYPE_LCD);
1125 if (ret) 1123 if (ret)
1126 return ret; 1124 return ret;
1127 1125