.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* drivers/gpu/drm/exynos/exynos7_drm_decon.c |
---|
2 | 3 | * |
---|
3 | 4 | * Copyright (C) 2014 Samsung Electronics Co.Ltd |
---|
4 | 5 | * Authors: |
---|
5 | 6 | * Akshu Agarwal <akshua@gmail.com> |
---|
6 | 7 | * Ajay Kumar <ajaykumar.rs@samsung.com> |
---|
7 | | - * |
---|
8 | | - * This program is free software; you can redistribute it and/or modify it |
---|
9 | | - * under the terms of the GNU General Public License as published by the |
---|
10 | | - * Free Software Foundation; either version 2 of the License, or (at your |
---|
11 | | - * option) any later version. |
---|
12 | | - * |
---|
13 | 8 | */ |
---|
14 | | -#include <drm/drmP.h> |
---|
15 | | -#include <drm/exynos_drm.h> |
---|
16 | 9 | |
---|
17 | 10 | #include <linux/clk.h> |
---|
18 | 11 | #include <linux/component.h> |
---|
.. | .. |
---|
26 | 19 | #include <video/of_display_timing.h> |
---|
27 | 20 | #include <video/of_videomode.h> |
---|
28 | 21 | |
---|
| 22 | +#include <drm/drm_fourcc.h> |
---|
| 23 | +#include <drm/drm_vblank.h> |
---|
| 24 | +#include <drm/exynos_drm.h> |
---|
| 25 | + |
---|
29 | 26 | #include "exynos_drm_crtc.h" |
---|
30 | | -#include "exynos_drm_plane.h" |
---|
31 | 27 | #include "exynos_drm_drv.h" |
---|
32 | 28 | #include "exynos_drm_fb.h" |
---|
33 | | -#include "exynos_drm_iommu.h" |
---|
| 29 | +#include "exynos_drm_plane.h" |
---|
34 | 30 | #include "regs-decon7.h" |
---|
35 | 31 | |
---|
36 | 32 | /* |
---|
.. | .. |
---|
44 | 40 | struct decon_context { |
---|
45 | 41 | struct device *dev; |
---|
46 | 42 | struct drm_device *drm_dev; |
---|
| 43 | + void *dma_priv; |
---|
47 | 44 | struct exynos_drm_crtc *crtc; |
---|
48 | 45 | struct exynos_drm_plane planes[WINDOWS_NR]; |
---|
49 | 46 | struct exynos_drm_plane_config configs[WINDOWS_NR]; |
---|
.. | .. |
---|
100 | 97 | if (!wait_event_timeout(ctx->wait_vsync_queue, |
---|
101 | 98 | !atomic_read(&ctx->wait_vsync_event), |
---|
102 | 99 | HZ/20)) |
---|
103 | | - DRM_DEBUG_KMS("vblank wait timed out.\n"); |
---|
| 100 | + DRM_DEV_DEBUG_KMS(ctx->dev, "vblank wait timed out.\n"); |
---|
104 | 101 | } |
---|
105 | 102 | |
---|
106 | 103 | static void decon_clear_channels(struct exynos_drm_crtc *crtc) |
---|
107 | 104 | { |
---|
108 | 105 | struct decon_context *ctx = crtc->ctx; |
---|
109 | 106 | unsigned int win, ch_enabled = 0; |
---|
110 | | - |
---|
111 | | - DRM_DEBUG_KMS("%s\n", __FILE__); |
---|
112 | 107 | |
---|
113 | 108 | /* Check if any channel is enabled. */ |
---|
114 | 109 | for (win = 0; win < WINDOWS_NR; win++) { |
---|
.. | .. |
---|
133 | 128 | |
---|
134 | 129 | decon_clear_channels(ctx->crtc); |
---|
135 | 130 | |
---|
136 | | - return drm_iommu_attach_device(drm_dev, ctx->dev); |
---|
| 131 | + return exynos_drm_register_dma(drm_dev, ctx->dev, &ctx->dma_priv); |
---|
137 | 132 | } |
---|
138 | 133 | |
---|
139 | 134 | static void decon_ctx_remove(struct decon_context *ctx) |
---|
140 | 135 | { |
---|
141 | 136 | /* detach this sub driver from iommu mapping if supported. */ |
---|
142 | | - drm_iommu_detach_device(ctx->drm_dev, ctx->dev); |
---|
| 137 | + exynos_drm_unregister_dma(ctx->drm_dev, ctx->dev, &ctx->dma_priv); |
---|
143 | 138 | } |
---|
144 | 139 | |
---|
145 | 140 | static u32 decon_calc_clkdiv(struct decon_context *ctx, |
---|
146 | 141 | const struct drm_display_mode *mode) |
---|
147 | 142 | { |
---|
148 | | - unsigned long ideal_clk = mode->htotal * mode->vtotal * mode->vrefresh; |
---|
| 143 | + unsigned long ideal_clk = mode->clock; |
---|
149 | 144 | u32 clkdiv; |
---|
150 | 145 | |
---|
151 | 146 | /* Find the clock divider value that gets us closest to ideal_clk */ |
---|
.. | .. |
---|
316 | 311 | break; |
---|
317 | 312 | } |
---|
318 | 313 | |
---|
319 | | - DRM_DEBUG_KMS("cpp = %d\n", fb->format->cpp[0]); |
---|
| 314 | + DRM_DEV_DEBUG_KMS(ctx->dev, "cpp = %d\n", fb->format->cpp[0]); |
---|
320 | 315 | |
---|
321 | 316 | /* |
---|
322 | 317 | * In case of exynos, setting dma-burst to 16Word causes permanent |
---|
.. | .. |
---|
423 | 418 | writel(state->src.x, ctx->regs + VIDW_OFFSET_X(win)); |
---|
424 | 419 | writel(state->src.y, ctx->regs + VIDW_OFFSET_Y(win)); |
---|
425 | 420 | |
---|
426 | | - DRM_DEBUG_KMS("start addr = 0x%lx\n", |
---|
| 421 | + DRM_DEV_DEBUG_KMS(ctx->dev, "start addr = 0x%lx\n", |
---|
427 | 422 | (unsigned long)val); |
---|
428 | | - DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n", |
---|
| 423 | + DRM_DEV_DEBUG_KMS(ctx->dev, "ovl_width = %d, ovl_height = %d\n", |
---|
429 | 424 | state->crtc.w, state->crtc.h); |
---|
430 | 425 | |
---|
431 | 426 | val = VIDOSDxA_TOPLEFT_X(state->crtc.x) | |
---|
.. | .. |
---|
443 | 438 | |
---|
444 | 439 | writel(val, ctx->regs + VIDOSD_B(win)); |
---|
445 | 440 | |
---|
446 | | - DRM_DEBUG_KMS("osd pos: tx = %d, ty = %d, bx = %d, by = %d\n", |
---|
| 441 | + DRM_DEV_DEBUG_KMS(ctx->dev, "osd pos: tx = %d, ty = %d, bx = %d, by = %d\n", |
---|
447 | 442 | state->crtc.x, state->crtc.y, last_x, last_y); |
---|
448 | 443 | |
---|
449 | 444 | /* OSD alpha */ |
---|
.. | .. |
---|
532 | 527 | writel(VIDCON1_VCLK_HOLD, ctx->regs + VIDCON1(0)); |
---|
533 | 528 | } |
---|
534 | 529 | |
---|
535 | | -static void decon_enable(struct exynos_drm_crtc *crtc) |
---|
| 530 | +static void decon_atomic_enable(struct exynos_drm_crtc *crtc) |
---|
536 | 531 | { |
---|
537 | 532 | struct decon_context *ctx = crtc->ctx; |
---|
538 | 533 | |
---|
.. | .. |
---|
552 | 547 | ctx->suspended = false; |
---|
553 | 548 | } |
---|
554 | 549 | |
---|
555 | | -static void decon_disable(struct exynos_drm_crtc *crtc) |
---|
| 550 | +static void decon_atomic_disable(struct exynos_drm_crtc *crtc) |
---|
556 | 551 | { |
---|
557 | 552 | struct decon_context *ctx = crtc->ctx; |
---|
558 | 553 | int i; |
---|
.. | .. |
---|
574 | 569 | } |
---|
575 | 570 | |
---|
576 | 571 | static const struct exynos_drm_crtc_ops decon_crtc_ops = { |
---|
577 | | - .enable = decon_enable, |
---|
578 | | - .disable = decon_disable, |
---|
| 572 | + .atomic_enable = decon_atomic_enable, |
---|
| 573 | + .atomic_disable = decon_atomic_disable, |
---|
579 | 574 | .enable_vblank = decon_enable_vblank, |
---|
580 | 575 | .disable_vblank = decon_disable_vblank, |
---|
581 | 576 | .atomic_begin = decon_atomic_begin, |
---|
.. | .. |
---|
623 | 618 | |
---|
624 | 619 | ret = decon_ctx_initialize(ctx, drm_dev); |
---|
625 | 620 | if (ret) { |
---|
626 | | - DRM_ERROR("decon_ctx_initialize failed.\n"); |
---|
| 621 | + DRM_DEV_ERROR(dev, "decon_ctx_initialize failed.\n"); |
---|
627 | 622 | return ret; |
---|
628 | 623 | } |
---|
629 | 624 | |
---|
.. | .. |
---|
659 | 654 | { |
---|
660 | 655 | struct decon_context *ctx = dev_get_drvdata(dev); |
---|
661 | 656 | |
---|
662 | | - decon_disable(ctx->crtc); |
---|
| 657 | + decon_atomic_disable(ctx->crtc); |
---|
663 | 658 | |
---|
664 | 659 | if (ctx->encoder) |
---|
665 | 660 | exynos_dpi_remove(ctx->encoder); |
---|
.. | .. |
---|
803 | 798 | |
---|
804 | 799 | ret = clk_prepare_enable(ctx->pclk); |
---|
805 | 800 | if (ret < 0) { |
---|
806 | | - DRM_ERROR("Failed to prepare_enable the pclk [%d]\n", ret); |
---|
807 | | - return ret; |
---|
| 801 | + DRM_DEV_ERROR(dev, "Failed to prepare_enable the pclk [%d]\n", |
---|
| 802 | + ret); |
---|
| 803 | + goto err_pclk_enable; |
---|
808 | 804 | } |
---|
809 | 805 | |
---|
810 | 806 | ret = clk_prepare_enable(ctx->aclk); |
---|
811 | 807 | if (ret < 0) { |
---|
812 | | - DRM_ERROR("Failed to prepare_enable the aclk [%d]\n", ret); |
---|
813 | | - return ret; |
---|
| 808 | + DRM_DEV_ERROR(dev, "Failed to prepare_enable the aclk [%d]\n", |
---|
| 809 | + ret); |
---|
| 810 | + goto err_aclk_enable; |
---|
814 | 811 | } |
---|
815 | 812 | |
---|
816 | 813 | ret = clk_prepare_enable(ctx->eclk); |
---|
817 | 814 | if (ret < 0) { |
---|
818 | | - DRM_ERROR("Failed to prepare_enable the eclk [%d]\n", ret); |
---|
819 | | - return ret; |
---|
| 815 | + DRM_DEV_ERROR(dev, "Failed to prepare_enable the eclk [%d]\n", |
---|
| 816 | + ret); |
---|
| 817 | + goto err_eclk_enable; |
---|
820 | 818 | } |
---|
821 | 819 | |
---|
822 | 820 | ret = clk_prepare_enable(ctx->vclk); |
---|
823 | 821 | if (ret < 0) { |
---|
824 | | - DRM_ERROR("Failed to prepare_enable the vclk [%d]\n", ret); |
---|
825 | | - return ret; |
---|
| 822 | + DRM_DEV_ERROR(dev, "Failed to prepare_enable the vclk [%d]\n", |
---|
| 823 | + ret); |
---|
| 824 | + goto err_vclk_enable; |
---|
826 | 825 | } |
---|
827 | 826 | |
---|
828 | 827 | return 0; |
---|
| 828 | + |
---|
| 829 | +err_vclk_enable: |
---|
| 830 | + clk_disable_unprepare(ctx->eclk); |
---|
| 831 | +err_eclk_enable: |
---|
| 832 | + clk_disable_unprepare(ctx->aclk); |
---|
| 833 | +err_aclk_enable: |
---|
| 834 | + clk_disable_unprepare(ctx->pclk); |
---|
| 835 | +err_pclk_enable: |
---|
| 836 | + return ret; |
---|
829 | 837 | } |
---|
830 | 838 | #endif |
---|
831 | 839 | |
---|