| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (C) 2014-2015 The Linux Foundation. All rights reserved. |
|---|
| 3 | 4 | * Copyright (C) 2013 Red Hat |
|---|
| 4 | 5 | * Author: Rob Clark <robdclark@gmail.com> |
|---|
| 5 | | - * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 7 | | - * under the terms of the GNU General Public License version 2 as published by |
|---|
| 8 | | - * the Free Software Foundation. |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is distributed in the hope that it will be useful, but WITHOUT |
|---|
| 11 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|---|
| 12 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
|---|
| 13 | | - * more details. |
|---|
| 14 | | - * |
|---|
| 15 | | - * You should have received a copy of the GNU General Public License along with |
|---|
| 16 | | - * this program. If not, see <http://www.gnu.org/licenses/>. |
|---|
| 17 | 6 | */ |
|---|
| 18 | 7 | |
|---|
| 8 | +#include <drm/drm_damage_helper.h> |
|---|
| 9 | +#include <drm/drm_fourcc.h> |
|---|
| 19 | 10 | #include <drm/drm_print.h> |
|---|
| 11 | + |
|---|
| 20 | 12 | #include "mdp5_kms.h" |
|---|
| 21 | 13 | |
|---|
| 22 | 14 | struct mdp5_plane { |
|---|
| .. | .. |
|---|
| 46 | 38 | { |
|---|
| 47 | 39 | struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); |
|---|
| 48 | 40 | |
|---|
| 49 | | - drm_plane_helper_disable(plane, NULL); |
|---|
| 50 | 41 | drm_plane_cleanup(plane); |
|---|
| 51 | 42 | |
|---|
| 52 | 43 | kfree(mdp5_plane); |
|---|
| .. | .. |
|---|
| 126 | 117 | |
|---|
| 127 | 118 | SET_PROPERTY(zpos, ZPOS, uint8_t); |
|---|
| 128 | 119 | |
|---|
| 129 | | - dev_err(dev->dev, "Invalid property\n"); |
|---|
| 120 | + DRM_DEV_ERROR(dev->dev, "Invalid property\n"); |
|---|
| 130 | 121 | ret = -EINVAL; |
|---|
| 131 | 122 | done: |
|---|
| 132 | 123 | return ret; |
|---|
| .. | .. |
|---|
| 154 | 145 | |
|---|
| 155 | 146 | GET_PROPERTY(zpos, ZPOS, uint8_t); |
|---|
| 156 | 147 | |
|---|
| 157 | | - dev_err(dev->dev, "Invalid property\n"); |
|---|
| 148 | + DRM_DEV_ERROR(dev->dev, "Invalid property\n"); |
|---|
| 158 | 149 | ret = -EINVAL; |
|---|
| 159 | 150 | done: |
|---|
| 160 | 151 | return ret; |
|---|
| .. | .. |
|---|
| 185 | 176 | struct mdp5_plane_state *mdp5_state; |
|---|
| 186 | 177 | |
|---|
| 187 | 178 | if (plane->state && plane->state->fb) |
|---|
| 188 | | - drm_framebuffer_unreference(plane->state->fb); |
|---|
| 179 | + drm_framebuffer_put(plane->state->fb); |
|---|
| 189 | 180 | |
|---|
| 190 | 181 | kfree(to_mdp5_plane_state(plane->state)); |
|---|
| 182 | + plane->state = NULL; |
|---|
| 191 | 183 | mdp5_state = kzalloc(sizeof(*mdp5_state), GFP_KERNEL); |
|---|
| 184 | + if (!mdp5_state) |
|---|
| 185 | + return; |
|---|
| 192 | 186 | |
|---|
| 193 | 187 | /* assign default blend parameters */ |
|---|
| 194 | 188 | mdp5_state->alpha = 255; |
|---|
| .. | .. |
|---|
| 227 | 221 | { |
|---|
| 228 | 222 | struct mdp5_plane_state *pstate = to_mdp5_plane_state(state); |
|---|
| 229 | 223 | |
|---|
| 230 | | - if (state->fb) |
|---|
| 231 | | - drm_framebuffer_unreference(state->fb); |
|---|
| 224 | + __drm_atomic_helper_plane_destroy_state(state); |
|---|
| 232 | 225 | |
|---|
| 233 | 226 | kfree(pstate); |
|---|
| 234 | 227 | } |
|---|
| .. | .. |
|---|
| 399 | 392 | mdp5_state->r_hwpipe = NULL; |
|---|
| 400 | 393 | |
|---|
| 401 | 394 | |
|---|
| 402 | | - mdp5_pipe_release(state->state, old_hwpipe); |
|---|
| 403 | | - mdp5_pipe_release(state->state, old_right_hwpipe); |
|---|
| 395 | + ret = mdp5_pipe_release(state->state, old_hwpipe); |
|---|
| 396 | + if (ret) |
|---|
| 397 | + return ret; |
|---|
| 398 | + |
|---|
| 399 | + ret = mdp5_pipe_release(state->state, old_right_hwpipe); |
|---|
| 400 | + if (ret) |
|---|
| 401 | + return ret; |
|---|
| 402 | + |
|---|
| 404 | 403 | } |
|---|
| 405 | 404 | } else { |
|---|
| 406 | | - mdp5_pipe_release(state->state, mdp5_state->hwpipe); |
|---|
| 407 | | - mdp5_pipe_release(state->state, mdp5_state->r_hwpipe); |
|---|
| 405 | + ret = mdp5_pipe_release(state->state, mdp5_state->hwpipe); |
|---|
| 406 | + if (ret) |
|---|
| 407 | + return ret; |
|---|
| 408 | + |
|---|
| 409 | + ret = mdp5_pipe_release(state->state, mdp5_state->r_hwpipe); |
|---|
| 410 | + if (ret) |
|---|
| 411 | + return ret; |
|---|
| 412 | + |
|---|
| 408 | 413 | mdp5_state->hwpipe = mdp5_state->r_hwpipe = NULL; |
|---|
| 409 | 414 | } |
|---|
| 410 | 415 | |
|---|
| .. | .. |
|---|
| 655 | 660 | uint32_t pixel_format, uint32_t src, uint32_t dest, |
|---|
| 656 | 661 | uint32_t phasex_steps[COMP_MAX]) |
|---|
| 657 | 662 | { |
|---|
| 663 | + const struct drm_format_info *info = drm_format_info(pixel_format); |
|---|
| 658 | 664 | struct mdp5_kms *mdp5_kms = get_kms(plane); |
|---|
| 659 | 665 | struct device *dev = mdp5_kms->dev->dev; |
|---|
| 660 | 666 | uint32_t phasex_step; |
|---|
| 661 | | - unsigned int hsub; |
|---|
| 662 | 667 | int ret; |
|---|
| 663 | 668 | |
|---|
| 664 | 669 | ret = calc_phase_step(src, dest, &phasex_step); |
|---|
| 665 | 670 | if (ret) { |
|---|
| 666 | | - dev_err(dev, "X scaling (%d->%d) failed: %d\n", src, dest, ret); |
|---|
| 671 | + DRM_DEV_ERROR(dev, "X scaling (%d->%d) failed: %d\n", src, dest, ret); |
|---|
| 667 | 672 | return ret; |
|---|
| 668 | 673 | } |
|---|
| 669 | 674 | |
|---|
| 670 | | - hsub = drm_format_horz_chroma_subsampling(pixel_format); |
|---|
| 671 | | - |
|---|
| 672 | 675 | phasex_steps[COMP_0] = phasex_step; |
|---|
| 673 | 676 | phasex_steps[COMP_3] = phasex_step; |
|---|
| 674 | | - phasex_steps[COMP_1_2] = phasex_step / hsub; |
|---|
| 677 | + phasex_steps[COMP_1_2] = phasex_step / info->hsub; |
|---|
| 675 | 678 | |
|---|
| 676 | 679 | return 0; |
|---|
| 677 | 680 | } |
|---|
| .. | .. |
|---|
| 680 | 683 | uint32_t pixel_format, uint32_t src, uint32_t dest, |
|---|
| 681 | 684 | uint32_t phasey_steps[COMP_MAX]) |
|---|
| 682 | 685 | { |
|---|
| 686 | + const struct drm_format_info *info = drm_format_info(pixel_format); |
|---|
| 683 | 687 | struct mdp5_kms *mdp5_kms = get_kms(plane); |
|---|
| 684 | 688 | struct device *dev = mdp5_kms->dev->dev; |
|---|
| 685 | 689 | uint32_t phasey_step; |
|---|
| 686 | | - unsigned int vsub; |
|---|
| 687 | 690 | int ret; |
|---|
| 688 | 691 | |
|---|
| 689 | 692 | ret = calc_phase_step(src, dest, &phasey_step); |
|---|
| 690 | 693 | if (ret) { |
|---|
| 691 | | - dev_err(dev, "Y scaling (%d->%d) failed: %d\n", src, dest, ret); |
|---|
| 694 | + DRM_DEV_ERROR(dev, "Y scaling (%d->%d) failed: %d\n", src, dest, ret); |
|---|
| 692 | 695 | return ret; |
|---|
| 693 | 696 | } |
|---|
| 694 | 697 | |
|---|
| 695 | | - vsub = drm_format_vert_chroma_subsampling(pixel_format); |
|---|
| 696 | | - |
|---|
| 697 | 698 | phasey_steps[COMP_0] = phasey_step; |
|---|
| 698 | 699 | phasey_steps[COMP_3] = phasey_step; |
|---|
| 699 | | - phasey_steps[COMP_1_2] = phasey_step / vsub; |
|---|
| 700 | + phasey_steps[COMP_1_2] = phasey_step / info->vsub; |
|---|
| 700 | 701 | |
|---|
| 701 | 702 | return 0; |
|---|
| 702 | 703 | } |
|---|
| .. | .. |
|---|
| 704 | 705 | static uint32_t get_scale_config(const struct mdp_format *format, |
|---|
| 705 | 706 | uint32_t src, uint32_t dst, bool horz) |
|---|
| 706 | 707 | { |
|---|
| 708 | + const struct drm_format_info *info = drm_format_info(format->base.pixel_format); |
|---|
| 707 | 709 | bool scaling = format->is_yuv ? true : (src != dst); |
|---|
| 708 | | - uint32_t sub, pix_fmt = format->base.pixel_format; |
|---|
| 710 | + uint32_t sub; |
|---|
| 709 | 711 | uint32_t ya_filter, uv_filter; |
|---|
| 710 | 712 | bool yuv = format->is_yuv; |
|---|
| 711 | 713 | |
|---|
| .. | .. |
|---|
| 713 | 715 | return 0; |
|---|
| 714 | 716 | |
|---|
| 715 | 717 | if (yuv) { |
|---|
| 716 | | - sub = horz ? drm_format_horz_chroma_subsampling(pix_fmt) : |
|---|
| 717 | | - drm_format_vert_chroma_subsampling(pix_fmt); |
|---|
| 718 | + sub = horz ? info->hsub : info->vsub; |
|---|
| 718 | 719 | uv_filter = ((src / sub) <= dst) ? |
|---|
| 719 | 720 | SCALE_FILTER_BIL : SCALE_FILTER_PCMN; |
|---|
| 720 | 721 | } |
|---|
| .. | .. |
|---|
| 759 | 760 | uint32_t src_w, int pe_left[COMP_MAX], int pe_right[COMP_MAX], |
|---|
| 760 | 761 | uint32_t src_h, int pe_top[COMP_MAX], int pe_bottom[COMP_MAX]) |
|---|
| 761 | 762 | { |
|---|
| 762 | | - uint32_t pix_fmt = format->base.pixel_format; |
|---|
| 763 | + const struct drm_format_info *info = drm_format_info(format->base.pixel_format); |
|---|
| 763 | 764 | uint32_t lr, tb, req; |
|---|
| 764 | 765 | int i; |
|---|
| 765 | 766 | |
|---|
| .. | .. |
|---|
| 768 | 769 | uint32_t roi_h = src_h; |
|---|
| 769 | 770 | |
|---|
| 770 | 771 | if (format->is_yuv && i == COMP_1_2) { |
|---|
| 771 | | - roi_w /= drm_format_horz_chroma_subsampling(pix_fmt); |
|---|
| 772 | | - roi_h /= drm_format_vert_chroma_subsampling(pix_fmt); |
|---|
| 772 | + roi_w /= info->hsub; |
|---|
| 773 | + roi_h /= info->vsub; |
|---|
| 773 | 774 | } |
|---|
| 774 | 775 | |
|---|
| 775 | 776 | lr = (pe_left[i] >= 0) ? |
|---|
| .. | .. |
|---|
| 1104 | 1105 | |
|---|
| 1105 | 1106 | mdp5_plane_install_properties(plane, &plane->base); |
|---|
| 1106 | 1107 | |
|---|
| 1108 | + drm_plane_enable_fb_damage_clips(plane); |
|---|
| 1109 | + |
|---|
| 1107 | 1110 | return plane; |
|---|
| 1108 | 1111 | |
|---|
| 1109 | 1112 | fail: |
|---|