| .. | .. |
|---|
| 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 | |
|---|