| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (C) 2012 Texas Instruments |
|---|
| 3 | 4 | * Author: Rob Clark <robdclark@gmail.com> |
|---|
| 4 | | - * |
|---|
| 5 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 6 | | - * under the terms of the GNU General Public License version 2 as published by |
|---|
| 7 | | - * the Free Software Foundation. |
|---|
| 8 | | - * |
|---|
| 9 | | - * This program is distributed in the hope that it will be useful, but WITHOUT |
|---|
| 10 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|---|
| 11 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
|---|
| 12 | | - * more details. |
|---|
| 13 | | - * |
|---|
| 14 | | - * You should have received a copy of the GNU General Public License along with |
|---|
| 15 | | - * this program. If not, see <http://www.gnu.org/licenses/>. |
|---|
| 16 | 5 | */ |
|---|
| 6 | + |
|---|
| 7 | +#include <linux/delay.h> |
|---|
| 8 | +#include <linux/dma-mapping.h> |
|---|
| 9 | +#include <linux/of_graph.h> |
|---|
| 10 | +#include <linux/pm_runtime.h> |
|---|
| 17 | 11 | |
|---|
| 18 | 12 | #include <drm/drm_atomic.h> |
|---|
| 19 | 13 | #include <drm/drm_atomic_helper.h> |
|---|
| 20 | 14 | #include <drm/drm_crtc.h> |
|---|
| 21 | | -#include <drm/drm_flip_work.h> |
|---|
| 22 | | -#include <drm/drm_plane_helper.h> |
|---|
| 23 | | -#include <linux/workqueue.h> |
|---|
| 24 | | -#include <linux/completion.h> |
|---|
| 25 | | -#include <linux/dma-mapping.h> |
|---|
| 26 | | -#include <linux/of_graph.h> |
|---|
| 27 | | -#include <linux/math64.h> |
|---|
| 15 | +#include <drm/drm_fb_cma_helper.h> |
|---|
| 16 | +#include <drm/drm_fourcc.h> |
|---|
| 17 | +#include <drm/drm_gem_cma_helper.h> |
|---|
| 18 | +#include <drm/drm_modeset_helper_vtables.h> |
|---|
| 19 | +#include <drm/drm_print.h> |
|---|
| 20 | +#include <drm/drm_vblank.h> |
|---|
| 28 | 21 | |
|---|
| 29 | 22 | #include "tilcdc_drv.h" |
|---|
| 30 | 23 | #include "tilcdc_regs.h" |
|---|
| .. | .. |
|---|
| 393 | 386 | case DRM_FORMAT_XBGR8888: |
|---|
| 394 | 387 | case DRM_FORMAT_XRGB8888: |
|---|
| 395 | 388 | reg |= LCDC_V2_TFT_24BPP_UNPACK; |
|---|
| 396 | | - /* fallthrough */ |
|---|
| 389 | + fallthrough; |
|---|
| 397 | 390 | case DRM_FORMAT_BGR888: |
|---|
| 398 | 391 | case DRM_FORMAT_RGB888: |
|---|
| 399 | 392 | reg |= LCDC_V2_TFT_24BPP_MODE; |
|---|
| .. | .. |
|---|
| 525 | 518 | |
|---|
| 526 | 519 | drm_crtc_vblank_off(crtc); |
|---|
| 527 | 520 | |
|---|
| 521 | + spin_lock_irq(&crtc->dev->event_lock); |
|---|
| 522 | + |
|---|
| 523 | + if (crtc->state->event) { |
|---|
| 524 | + drm_crtc_send_vblank_event(crtc, crtc->state->event); |
|---|
| 525 | + crtc->state->event = NULL; |
|---|
| 526 | + } |
|---|
| 527 | + |
|---|
| 528 | + spin_unlock_irq(&crtc->dev->event_lock); |
|---|
| 529 | + |
|---|
| 528 | 530 | tilcdc_crtc_disable_irqs(dev); |
|---|
| 529 | 531 | |
|---|
| 530 | 532 | pm_runtime_put_sync(dev->dev); |
|---|
| .. | .. |
|---|
| 542 | 544 | struct drm_crtc_state *old_state) |
|---|
| 543 | 545 | { |
|---|
| 544 | 546 | tilcdc_crtc_disable(crtc); |
|---|
| 547 | +} |
|---|
| 548 | + |
|---|
| 549 | +static void tilcdc_crtc_atomic_flush(struct drm_crtc *crtc, |
|---|
| 550 | + struct drm_crtc_state *old_state) |
|---|
| 551 | +{ |
|---|
| 552 | + if (!crtc->state->event) |
|---|
| 553 | + return; |
|---|
| 554 | + |
|---|
| 555 | + spin_lock_irq(&crtc->dev->event_lock); |
|---|
| 556 | + drm_crtc_send_vblank_event(crtc, crtc->state->event); |
|---|
| 557 | + crtc->state->event = NULL; |
|---|
| 558 | + spin_unlock_irq(&crtc->dev->event_lock); |
|---|
| 545 | 559 | } |
|---|
| 546 | 560 | |
|---|
| 547 | 561 | void tilcdc_crtc_shutdown(struct drm_crtc *crtc) |
|---|
| .. | .. |
|---|
| 657 | 671 | static int tilcdc_crtc_atomic_check(struct drm_crtc *crtc, |
|---|
| 658 | 672 | struct drm_crtc_state *state) |
|---|
| 659 | 673 | { |
|---|
| 660 | | - struct drm_display_mode *mode = &state->mode; |
|---|
| 661 | | - int ret; |
|---|
| 662 | | - |
|---|
| 663 | 674 | /* If we are not active we don't care */ |
|---|
| 664 | 675 | if (!state->active) |
|---|
| 665 | 676 | return 0; |
|---|
| .. | .. |
|---|
| 668 | 679 | state->state->planes[0].state == NULL || |
|---|
| 669 | 680 | state->state->planes[0].state->crtc != crtc) { |
|---|
| 670 | 681 | dev_dbg(crtc->dev->dev, "CRTC primary plane must be present"); |
|---|
| 671 | | - return -EINVAL; |
|---|
| 672 | | - } |
|---|
| 673 | | - |
|---|
| 674 | | - ret = tilcdc_crtc_mode_valid(crtc, mode); |
|---|
| 675 | | - if (ret) { |
|---|
| 676 | | - dev_dbg(crtc->dev->dev, "Mode \"%s\" not valid", mode->name); |
|---|
| 677 | 682 | return -EINVAL; |
|---|
| 678 | 683 | } |
|---|
| 679 | 684 | |
|---|
| .. | .. |
|---|
| 728 | 733 | .disable_vblank = tilcdc_crtc_disable_vblank, |
|---|
| 729 | 734 | }; |
|---|
| 730 | 735 | |
|---|
| 731 | | -static const struct drm_crtc_helper_funcs tilcdc_crtc_helper_funcs = { |
|---|
| 732 | | - .mode_fixup = tilcdc_crtc_mode_fixup, |
|---|
| 733 | | - .atomic_check = tilcdc_crtc_atomic_check, |
|---|
| 734 | | - .atomic_enable = tilcdc_crtc_atomic_enable, |
|---|
| 735 | | - .atomic_disable = tilcdc_crtc_atomic_disable, |
|---|
| 736 | | -}; |
|---|
| 737 | | - |
|---|
| 738 | 736 | int tilcdc_crtc_max_width(struct drm_crtc *crtc) |
|---|
| 739 | 737 | { |
|---|
| 740 | 738 | struct drm_device *dev = crtc->dev; |
|---|
| .. | .. |
|---|
| 749 | 747 | return max_width; |
|---|
| 750 | 748 | } |
|---|
| 751 | 749 | |
|---|
| 752 | | -int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode) |
|---|
| 750 | +static enum drm_mode_status |
|---|
| 751 | +tilcdc_crtc_mode_valid(struct drm_crtc *crtc, |
|---|
| 752 | + const struct drm_display_mode *mode) |
|---|
| 753 | 753 | { |
|---|
| 754 | 754 | struct tilcdc_drm_private *priv = crtc->dev->dev_private; |
|---|
| 755 | 755 | unsigned int bandwidth; |
|---|
| .. | .. |
|---|
| 837 | 837 | return MODE_OK; |
|---|
| 838 | 838 | } |
|---|
| 839 | 839 | |
|---|
| 840 | +static const struct drm_crtc_helper_funcs tilcdc_crtc_helper_funcs = { |
|---|
| 841 | + .mode_valid = tilcdc_crtc_mode_valid, |
|---|
| 842 | + .mode_fixup = tilcdc_crtc_mode_fixup, |
|---|
| 843 | + .atomic_check = tilcdc_crtc_atomic_check, |
|---|
| 844 | + .atomic_enable = tilcdc_crtc_atomic_enable, |
|---|
| 845 | + .atomic_disable = tilcdc_crtc_atomic_disable, |
|---|
| 846 | + .atomic_flush = tilcdc_crtc_atomic_flush, |
|---|
| 847 | +}; |
|---|
| 848 | + |
|---|
| 840 | 849 | void tilcdc_crtc_set_panel_info(struct drm_crtc *crtc, |
|---|
| 841 | 850 | const struct tilcdc_panel_info *info) |
|---|
| 842 | 851 | { |
|---|