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