.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * (C) COPYRIGHT 2016 ARM Limited. All rights reserved. |
---|
3 | 4 | * Author: Liviu Dudau <Liviu.Dudau@arm.com> |
---|
4 | | - * |
---|
5 | | - * This program is free software and is provided to you under the terms of the |
---|
6 | | - * GNU General Public License version 2 as published by the Free Software |
---|
7 | | - * Foundation, and any use by you of this program is subject to the terms |
---|
8 | | - * of such GNU licence. |
---|
9 | 5 | * |
---|
10 | 6 | * ARM Mali DP500/DP550/DP650 hardware manipulation routines. This is where |
---|
11 | 7 | * the difference between various versions of the hardware is being dealt with |
---|
.. | .. |
---|
13 | 9 | */ |
---|
14 | 10 | |
---|
15 | 11 | #include <linux/clk.h> |
---|
| 12 | +#include <linux/delay.h> |
---|
16 | 13 | #include <linux/types.h> |
---|
17 | 14 | #include <linux/io.h> |
---|
18 | | -#include <drm/drmP.h> |
---|
| 15 | + |
---|
19 | 16 | #include <video/videomode.h> |
---|
20 | 17 | #include <video/display_timing.h> |
---|
| 18 | + |
---|
| 19 | +#include <drm/drm_fourcc.h> |
---|
| 20 | +#include <drm/drm_vblank.h> |
---|
| 21 | +#include <drm/drm_print.h> |
---|
21 | 22 | |
---|
22 | 23 | #include "malidp_drv.h" |
---|
23 | 24 | #include "malidp_hw.h" |
---|
.. | .. |
---|
49 | 50 | { DRM_FORMAT_YUYV, DE_VIDEO1, 13 }, |
---|
50 | 51 | { DRM_FORMAT_NV12, DE_VIDEO1 | SE_MEMWRITE, 14 }, |
---|
51 | 52 | { DRM_FORMAT_YUV420, DE_VIDEO1, 15 }, |
---|
| 53 | + { DRM_FORMAT_XYUV8888, DE_VIDEO1, 16 }, |
---|
| 54 | + /* These are supported with AFBC only */ |
---|
| 55 | + { DRM_FORMAT_YUV420_8BIT, DE_VIDEO1, 14 }, |
---|
| 56 | + { DRM_FORMAT_VUY888, DE_VIDEO1, 16 }, |
---|
| 57 | + { DRM_FORMAT_VUY101010, DE_VIDEO1, 17 }, |
---|
| 58 | + { DRM_FORMAT_YUV420_10BIT, DE_VIDEO1, 18 } |
---|
52 | 59 | }; |
---|
53 | 60 | |
---|
54 | 61 | #define MALIDP_ID(__group, __format) \ |
---|
55 | 62 | ((((__group) & 0x7) << 3) | ((__format) & 0x7)) |
---|
| 63 | + |
---|
| 64 | +#define AFBC_YUV_422_FORMAT_ID MALIDP_ID(5, 1) |
---|
56 | 65 | |
---|
57 | 66 | #define MALIDP_COMMON_FORMATS \ |
---|
58 | 67 | /* fourcc, layers supporting the format, internal id */ \ |
---|
.. | .. |
---|
74 | 83 | { DRM_FORMAT_ABGR1555, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2, MALIDP_ID(4, 1) }, \ |
---|
75 | 84 | { DRM_FORMAT_RGB565, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2, MALIDP_ID(4, 2) }, \ |
---|
76 | 85 | { DRM_FORMAT_BGR565, DE_VIDEO1 | DE_GRAPHICS1 | DE_VIDEO2, MALIDP_ID(4, 3) }, \ |
---|
| 86 | + /* This is only supported with linear modifier */ \ |
---|
| 87 | + { DRM_FORMAT_XYUV8888, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 0) },\ |
---|
| 88 | + /* This is only supported with AFBC modifier */ \ |
---|
| 89 | + { DRM_FORMAT_VUY888, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 0) }, \ |
---|
77 | 90 | { DRM_FORMAT_YUYV, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 2) }, \ |
---|
| 91 | + /* This is only supported with linear modifier */ \ |
---|
78 | 92 | { DRM_FORMAT_UYVY, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 3) }, \ |
---|
79 | 93 | { DRM_FORMAT_NV12, DE_VIDEO1 | DE_VIDEO2 | SE_MEMWRITE, MALIDP_ID(5, 6) }, \ |
---|
80 | | - { DRM_FORMAT_YUV420, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 7) } |
---|
| 94 | + /* This is only supported with AFBC modifier */ \ |
---|
| 95 | + { DRM_FORMAT_YUV420_8BIT, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 6) }, \ |
---|
| 96 | + { DRM_FORMAT_YUV420, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 7) }, \ |
---|
| 97 | + /* This is only supported with linear modifier */ \ |
---|
| 98 | + { DRM_FORMAT_XVYU2101010, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(6, 0)}, \ |
---|
| 99 | + /* This is only supported with AFBC modifier */ \ |
---|
| 100 | + { DRM_FORMAT_VUY101010, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(6, 0)}, \ |
---|
| 101 | + { DRM_FORMAT_X0L2, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(6, 6)}, \ |
---|
| 102 | + /* This is only supported with AFBC modifier */ \ |
---|
| 103 | + { DRM_FORMAT_YUV420_10BIT, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(6, 7)}, \ |
---|
| 104 | + { DRM_FORMAT_P010, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(6, 7)} |
---|
81 | 105 | |
---|
82 | 106 | static const struct malidp_format_id malidp550_de_formats[] = { |
---|
83 | 107 | MALIDP_COMMON_FORMATS, |
---|
84 | 108 | }; |
---|
85 | 109 | |
---|
| 110 | +static const struct malidp_format_id malidp650_de_formats[] = { |
---|
| 111 | + MALIDP_COMMON_FORMATS, |
---|
| 112 | + { DRM_FORMAT_X0L0, DE_VIDEO1 | DE_VIDEO2, MALIDP_ID(5, 4)}, |
---|
| 113 | +}; |
---|
| 114 | + |
---|
86 | 115 | static const struct malidp_layer malidp500_layers[] = { |
---|
87 | | - { DE_VIDEO1, MALIDP500_DE_LV_BASE, MALIDP500_DE_LV_PTR_BASE, MALIDP_DE_LV_STRIDE0, MALIDP500_LV_YUV2RGB }, |
---|
88 | | - { DE_GRAPHICS1, MALIDP500_DE_LG1_BASE, MALIDP500_DE_LG1_PTR_BASE, MALIDP_DE_LG_STRIDE, 0 }, |
---|
89 | | - { DE_GRAPHICS2, MALIDP500_DE_LG2_BASE, MALIDP500_DE_LG2_PTR_BASE, MALIDP_DE_LG_STRIDE, 0 }, |
---|
| 116 | + /* id, base address, fb pointer address base, stride offset, |
---|
| 117 | + * yuv2rgb matrix offset, mmu control register offset, rotation_features |
---|
| 118 | + */ |
---|
| 119 | + { DE_VIDEO1, MALIDP500_DE_LV_BASE, MALIDP500_DE_LV_PTR_BASE, |
---|
| 120 | + MALIDP_DE_LV_STRIDE0, MALIDP500_LV_YUV2RGB, 0, ROTATE_ANY, |
---|
| 121 | + MALIDP500_DE_LV_AD_CTRL }, |
---|
| 122 | + { DE_GRAPHICS1, MALIDP500_DE_LG1_BASE, MALIDP500_DE_LG1_PTR_BASE, |
---|
| 123 | + MALIDP_DE_LG_STRIDE, 0, 0, ROTATE_ANY, |
---|
| 124 | + MALIDP500_DE_LG1_AD_CTRL }, |
---|
| 125 | + { DE_GRAPHICS2, MALIDP500_DE_LG2_BASE, MALIDP500_DE_LG2_PTR_BASE, |
---|
| 126 | + MALIDP_DE_LG_STRIDE, 0, 0, ROTATE_ANY, |
---|
| 127 | + MALIDP500_DE_LG2_AD_CTRL }, |
---|
90 | 128 | }; |
---|
91 | 129 | |
---|
92 | 130 | static const struct malidp_layer malidp550_layers[] = { |
---|
93 | | - { DE_VIDEO1, MALIDP550_DE_LV1_BASE, MALIDP550_DE_LV1_PTR_BASE, MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB }, |
---|
94 | | - { DE_GRAPHICS1, MALIDP550_DE_LG_BASE, MALIDP550_DE_LG_PTR_BASE, MALIDP_DE_LG_STRIDE, 0 }, |
---|
95 | | - { DE_VIDEO2, MALIDP550_DE_LV2_BASE, MALIDP550_DE_LV2_PTR_BASE, MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB }, |
---|
96 | | - { DE_SMART, MALIDP550_DE_LS_BASE, MALIDP550_DE_LS_PTR_BASE, MALIDP550_DE_LS_R1_STRIDE, 0 }, |
---|
| 131 | + /* id, base address, fb pointer address base, stride offset, |
---|
| 132 | + * yuv2rgb matrix offset, mmu control register offset, rotation_features |
---|
| 133 | + */ |
---|
| 134 | + { DE_VIDEO1, MALIDP550_DE_LV1_BASE, MALIDP550_DE_LV1_PTR_BASE, |
---|
| 135 | + MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB, 0, ROTATE_ANY, |
---|
| 136 | + MALIDP550_DE_LV1_AD_CTRL }, |
---|
| 137 | + { DE_GRAPHICS1, MALIDP550_DE_LG_BASE, MALIDP550_DE_LG_PTR_BASE, |
---|
| 138 | + MALIDP_DE_LG_STRIDE, 0, 0, ROTATE_ANY, |
---|
| 139 | + MALIDP550_DE_LG_AD_CTRL }, |
---|
| 140 | + { DE_VIDEO2, MALIDP550_DE_LV2_BASE, MALIDP550_DE_LV2_PTR_BASE, |
---|
| 141 | + MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB, 0, ROTATE_ANY, |
---|
| 142 | + MALIDP550_DE_LV2_AD_CTRL }, |
---|
| 143 | + { DE_SMART, MALIDP550_DE_LS_BASE, MALIDP550_DE_LS_PTR_BASE, |
---|
| 144 | + MALIDP550_DE_LS_R1_STRIDE, 0, 0, ROTATE_NONE, 0 }, |
---|
| 145 | +}; |
---|
| 146 | + |
---|
| 147 | +static const struct malidp_layer malidp650_layers[] = { |
---|
| 148 | + /* id, base address, fb pointer address base, stride offset, |
---|
| 149 | + * yuv2rgb matrix offset, mmu control register offset, |
---|
| 150 | + * rotation_features |
---|
| 151 | + */ |
---|
| 152 | + { DE_VIDEO1, MALIDP550_DE_LV1_BASE, MALIDP550_DE_LV1_PTR_BASE, |
---|
| 153 | + MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB, |
---|
| 154 | + MALIDP650_DE_LV_MMU_CTRL, ROTATE_ANY, |
---|
| 155 | + MALIDP550_DE_LV1_AD_CTRL }, |
---|
| 156 | + { DE_GRAPHICS1, MALIDP550_DE_LG_BASE, MALIDP550_DE_LG_PTR_BASE, |
---|
| 157 | + MALIDP_DE_LG_STRIDE, 0, MALIDP650_DE_LG_MMU_CTRL, |
---|
| 158 | + ROTATE_COMPRESSED, MALIDP550_DE_LG_AD_CTRL }, |
---|
| 159 | + { DE_VIDEO2, MALIDP550_DE_LV2_BASE, MALIDP550_DE_LV2_PTR_BASE, |
---|
| 160 | + MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB, |
---|
| 161 | + MALIDP650_DE_LV_MMU_CTRL, ROTATE_ANY, |
---|
| 162 | + MALIDP550_DE_LV2_AD_CTRL }, |
---|
| 163 | + { DE_SMART, MALIDP550_DE_LS_BASE, MALIDP550_DE_LS_PTR_BASE, |
---|
| 164 | + MALIDP550_DE_LS_R1_STRIDE, 0, MALIDP650_DE_LS_MMU_CTRL, |
---|
| 165 | + ROTATE_NONE, 0 }, |
---|
| 166 | +}; |
---|
| 167 | + |
---|
| 168 | +const u64 malidp_format_modifiers[] = { |
---|
| 169 | + /* All RGB formats (except XRGB, RGBX, XBGR, BGRX) */ |
---|
| 170 | + DRM_FORMAT_MOD_ARM_AFBC(AFBC_SIZE_16X16 | AFBC_YTR | AFBC_SPARSE), |
---|
| 171 | + DRM_FORMAT_MOD_ARM_AFBC(AFBC_SIZE_16X16 | AFBC_YTR), |
---|
| 172 | + |
---|
| 173 | + /* All RGB formats > 16bpp (except XRGB, RGBX, XBGR, BGRX) */ |
---|
| 174 | + DRM_FORMAT_MOD_ARM_AFBC(AFBC_SIZE_16X16 | AFBC_YTR | AFBC_SPARSE | AFBC_SPLIT), |
---|
| 175 | + |
---|
| 176 | + /* All 8 or 10 bit YUV 444 formats. */ |
---|
| 177 | + /* In DP550, 10 bit YUV 420 format also supported */ |
---|
| 178 | + DRM_FORMAT_MOD_ARM_AFBC(AFBC_SIZE_16X16 | AFBC_SPARSE | AFBC_SPLIT), |
---|
| 179 | + |
---|
| 180 | + /* YUV 420, 422 P1 8 bit and YUV 444 8 bit/10 bit formats */ |
---|
| 181 | + DRM_FORMAT_MOD_ARM_AFBC(AFBC_SIZE_16X16 | AFBC_SPARSE), |
---|
| 182 | + DRM_FORMAT_MOD_ARM_AFBC(AFBC_SIZE_16X16), |
---|
| 183 | + |
---|
| 184 | + /* YUV 420, 422 P1 8, 10 bit formats */ |
---|
| 185 | + DRM_FORMAT_MOD_ARM_AFBC(AFBC_SIZE_16X16 | AFBC_CBR | AFBC_SPARSE), |
---|
| 186 | + DRM_FORMAT_MOD_ARM_AFBC(AFBC_SIZE_16X16 | AFBC_CBR), |
---|
| 187 | + |
---|
| 188 | + /* All formats */ |
---|
| 189 | + DRM_FORMAT_MOD_LINEAR, |
---|
| 190 | + |
---|
| 191 | + DRM_FORMAT_MOD_INVALID |
---|
97 | 192 | }; |
---|
98 | 193 | |
---|
99 | 194 | #define SE_N_SCALING_COEFFS 96 |
---|
.. | .. |
---|
284 | 379 | malidp_hw_setbits(hwdev, MALIDP_DISP_FUNC_ILACED, MALIDP_DE_DISPLAY_FUNC); |
---|
285 | 380 | else |
---|
286 | 381 | malidp_hw_clearbits(hwdev, MALIDP_DISP_FUNC_ILACED, MALIDP_DE_DISPLAY_FUNC); |
---|
| 382 | + |
---|
| 383 | + /* |
---|
| 384 | + * Program the RQoS register to avoid high resolutions flicker |
---|
| 385 | + * issue on the LS1028A. |
---|
| 386 | + */ |
---|
| 387 | + if (hwdev->arqos_value) { |
---|
| 388 | + val = hwdev->arqos_value; |
---|
| 389 | + malidp_hw_setbits(hwdev, val, MALIDP500_RQOS_QUALITY); |
---|
| 390 | + } |
---|
287 | 391 | } |
---|
288 | 392 | |
---|
289 | | -static int malidp500_rotmem_required(struct malidp_hw_device *hwdev, u16 w, u16 h, u32 fmt) |
---|
| 393 | +int malidp_format_get_bpp(u32 fmt) |
---|
290 | 394 | { |
---|
291 | | - /* RGB888 or BGR888 can't be rotated */ |
---|
292 | | - if ((fmt == DRM_FORMAT_RGB888) || (fmt == DRM_FORMAT_BGR888)) |
---|
293 | | - return -EINVAL; |
---|
| 395 | + const struct drm_format_info *info = drm_format_info(fmt); |
---|
| 396 | + int bpp = info->cpp[0] * 8; |
---|
294 | 397 | |
---|
| 398 | + if (bpp == 0) { |
---|
| 399 | + switch (fmt) { |
---|
| 400 | + case DRM_FORMAT_VUY101010: |
---|
| 401 | + bpp = 30; |
---|
| 402 | + break; |
---|
| 403 | + case DRM_FORMAT_YUV420_10BIT: |
---|
| 404 | + bpp = 15; |
---|
| 405 | + break; |
---|
| 406 | + case DRM_FORMAT_YUV420_8BIT: |
---|
| 407 | + bpp = 12; |
---|
| 408 | + break; |
---|
| 409 | + default: |
---|
| 410 | + bpp = 0; |
---|
| 411 | + } |
---|
| 412 | + } |
---|
| 413 | + |
---|
| 414 | + return bpp; |
---|
| 415 | +} |
---|
| 416 | + |
---|
| 417 | +static int malidp500_rotmem_required(struct malidp_hw_device *hwdev, u16 w, |
---|
| 418 | + u16 h, u32 fmt, bool has_modifier) |
---|
| 419 | +{ |
---|
295 | 420 | /* |
---|
296 | 421 | * Each layer needs enough rotation memory to fit 8 lines |
---|
297 | 422 | * worth of pixel data. Required size is then: |
---|
298 | 423 | * size = rotated_width * (bpp / 8) * 8; |
---|
299 | 424 | */ |
---|
300 | | - return w * drm_format_plane_cpp(fmt, 0) * 8; |
---|
| 425 | + int bpp = malidp_format_get_bpp(fmt); |
---|
| 426 | + |
---|
| 427 | + return w * bpp; |
---|
301 | 428 | } |
---|
302 | 429 | |
---|
303 | 430 | static void malidp500_se_write_pp_coefftab(struct malidp_hw_device *hwdev, |
---|
.. | .. |
---|
405 | 532 | malidp_hw_write(hwdev, lower_32_bits(addrs[1]), base + MALIDP_MW_P2_PTR_LOW); |
---|
406 | 533 | malidp_hw_write(hwdev, upper_32_bits(addrs[1]), base + MALIDP_MW_P2_PTR_HIGH); |
---|
407 | 534 | malidp_hw_write(hwdev, pitches[1], base + MALIDP_MW_P2_STRIDE); |
---|
408 | | - /* fall through */ |
---|
| 535 | + fallthrough; |
---|
409 | 536 | case 1: |
---|
410 | 537 | malidp_hw_write(hwdev, lower_32_bits(addrs[0]), base + MALIDP_MW_P1_PTR_LOW); |
---|
411 | 538 | malidp_hw_write(hwdev, upper_32_bits(addrs[0]), base + MALIDP_MW_P1_PTR_HIGH); |
---|
.. | .. |
---|
575 | 702 | malidp_hw_clearbits(hwdev, MALIDP_DISP_FUNC_ILACED, MALIDP_DE_DISPLAY_FUNC); |
---|
576 | 703 | } |
---|
577 | 704 | |
---|
578 | | -static int malidp550_rotmem_required(struct malidp_hw_device *hwdev, u16 w, u16 h, u32 fmt) |
---|
| 705 | +static int malidpx50_get_bytes_per_column(u32 fmt) |
---|
579 | 706 | { |
---|
580 | | - u32 bytes_per_col; |
---|
581 | | - |
---|
582 | | - /* raw RGB888 or BGR888 can't be rotated */ |
---|
583 | | - if ((fmt == DRM_FORMAT_RGB888) || (fmt == DRM_FORMAT_BGR888)) |
---|
584 | | - return -EINVAL; |
---|
| 707 | + u32 bytes_per_column; |
---|
585 | 708 | |
---|
586 | 709 | switch (fmt) { |
---|
587 | 710 | /* 8 lines at 4 bytes per pixel */ |
---|
.. | .. |
---|
606 | 729 | case DRM_FORMAT_BGR565: |
---|
607 | 730 | case DRM_FORMAT_UYVY: |
---|
608 | 731 | case DRM_FORMAT_YUYV: |
---|
609 | | - bytes_per_col = 32; |
---|
| 732 | + case DRM_FORMAT_X0L0: |
---|
| 733 | + bytes_per_column = 32; |
---|
610 | 734 | break; |
---|
611 | 735 | /* 16 lines at 1.5 bytes per pixel */ |
---|
612 | 736 | case DRM_FORMAT_NV12: |
---|
613 | 737 | case DRM_FORMAT_YUV420: |
---|
614 | | - bytes_per_col = 24; |
---|
| 738 | + /* 8 lines at 3 bytes per pixel */ |
---|
| 739 | + case DRM_FORMAT_VUY888: |
---|
| 740 | + /* 16 lines at 12 bits per pixel */ |
---|
| 741 | + case DRM_FORMAT_YUV420_8BIT: |
---|
| 742 | + /* 8 lines at 3 bytes per pixel */ |
---|
| 743 | + case DRM_FORMAT_P010: |
---|
| 744 | + bytes_per_column = 24; |
---|
| 745 | + break; |
---|
| 746 | + /* 8 lines at 30 bits per pixel */ |
---|
| 747 | + case DRM_FORMAT_VUY101010: |
---|
| 748 | + /* 16 lines at 15 bits per pixel */ |
---|
| 749 | + case DRM_FORMAT_YUV420_10BIT: |
---|
| 750 | + bytes_per_column = 30; |
---|
615 | 751 | break; |
---|
616 | 752 | default: |
---|
617 | 753 | return -EINVAL; |
---|
618 | 754 | } |
---|
619 | 755 | |
---|
620 | | - return w * bytes_per_col; |
---|
| 756 | + return bytes_per_column; |
---|
| 757 | +} |
---|
| 758 | + |
---|
| 759 | +static int malidp550_rotmem_required(struct malidp_hw_device *hwdev, u16 w, |
---|
| 760 | + u16 h, u32 fmt, bool has_modifier) |
---|
| 761 | +{ |
---|
| 762 | + int bytes_per_column = 0; |
---|
| 763 | + |
---|
| 764 | + switch (fmt) { |
---|
| 765 | + /* 8 lines at 15 bits per pixel */ |
---|
| 766 | + case DRM_FORMAT_YUV420_10BIT: |
---|
| 767 | + bytes_per_column = 15; |
---|
| 768 | + break; |
---|
| 769 | + /* Uncompressed YUV 420 10 bit single plane cannot be rotated */ |
---|
| 770 | + case DRM_FORMAT_X0L2: |
---|
| 771 | + if (has_modifier) |
---|
| 772 | + bytes_per_column = 8; |
---|
| 773 | + else |
---|
| 774 | + return -EINVAL; |
---|
| 775 | + break; |
---|
| 776 | + default: |
---|
| 777 | + bytes_per_column = malidpx50_get_bytes_per_column(fmt); |
---|
| 778 | + } |
---|
| 779 | + |
---|
| 780 | + if (bytes_per_column == -EINVAL) |
---|
| 781 | + return bytes_per_column; |
---|
| 782 | + |
---|
| 783 | + return w * bytes_per_column; |
---|
| 784 | +} |
---|
| 785 | + |
---|
| 786 | +static int malidp650_rotmem_required(struct malidp_hw_device *hwdev, u16 w, |
---|
| 787 | + u16 h, u32 fmt, bool has_modifier) |
---|
| 788 | +{ |
---|
| 789 | + int bytes_per_column = 0; |
---|
| 790 | + |
---|
| 791 | + switch (fmt) { |
---|
| 792 | + /* 16 lines at 2 bytes per pixel */ |
---|
| 793 | + case DRM_FORMAT_X0L2: |
---|
| 794 | + bytes_per_column = 32; |
---|
| 795 | + break; |
---|
| 796 | + default: |
---|
| 797 | + bytes_per_column = malidpx50_get_bytes_per_column(fmt); |
---|
| 798 | + } |
---|
| 799 | + |
---|
| 800 | + if (bytes_per_column == -EINVAL) |
---|
| 801 | + return bytes_per_column; |
---|
| 802 | + |
---|
| 803 | + return w * bytes_per_column; |
---|
621 | 804 | } |
---|
622 | 805 | |
---|
623 | 806 | static int malidp550_se_set_scaling_coeffs(struct malidp_hw_device *hwdev, |
---|
.. | .. |
---|
686 | 869 | malidp_hw_write(hwdev, lower_32_bits(addrs[1]), base + MALIDP_MW_P2_PTR_LOW); |
---|
687 | 870 | malidp_hw_write(hwdev, upper_32_bits(addrs[1]), base + MALIDP_MW_P2_PTR_HIGH); |
---|
688 | 871 | malidp_hw_write(hwdev, pitches[1], base + MALIDP_MW_P2_STRIDE); |
---|
689 | | - /* fall through */ |
---|
| 872 | + fallthrough; |
---|
690 | 873 | case 1: |
---|
691 | 874 | malidp_hw_write(hwdev, lower_32_bits(addrs[0]), base + MALIDP_MW_P1_PTR_LOW); |
---|
692 | 875 | malidp_hw_write(hwdev, upper_32_bits(addrs[0]), base + MALIDP_MW_P1_PTR_HIGH); |
---|
.. | .. |
---|
806 | 989 | .se_base = MALIDP550_SE_BASE, |
---|
807 | 990 | .dc_base = MALIDP550_DC_BASE, |
---|
808 | 991 | .out_depth_base = MALIDP550_DE_OUTPUT_DEPTH, |
---|
809 | | - .features = MALIDP_REGMAP_HAS_CLEARIRQ, |
---|
| 992 | + .features = MALIDP_REGMAP_HAS_CLEARIRQ | |
---|
| 993 | + MALIDP_DEVICE_AFBC_SUPPORT_SPLIT | |
---|
| 994 | + MALIDP_DEVICE_AFBC_YUV_420_10_SUPPORT_SPLIT | |
---|
| 995 | + MALIDP_DEVICE_AFBC_YUYV_USE_422_P2, |
---|
810 | 996 | .n_layers = ARRAY_SIZE(malidp550_layers), |
---|
811 | 997 | .layers = malidp550_layers, |
---|
812 | 998 | .de_irq_map = { |
---|
.. | .. |
---|
852 | 1038 | .se_base = MALIDP550_SE_BASE, |
---|
853 | 1039 | .dc_base = MALIDP550_DC_BASE, |
---|
854 | 1040 | .out_depth_base = MALIDP550_DE_OUTPUT_DEPTH, |
---|
855 | | - .features = MALIDP_REGMAP_HAS_CLEARIRQ, |
---|
856 | | - .n_layers = ARRAY_SIZE(malidp550_layers), |
---|
857 | | - .layers = malidp550_layers, |
---|
| 1041 | + .features = MALIDP_REGMAP_HAS_CLEARIRQ | |
---|
| 1042 | + MALIDP_DEVICE_AFBC_SUPPORT_SPLIT | |
---|
| 1043 | + MALIDP_DEVICE_AFBC_YUYV_USE_422_P2, |
---|
| 1044 | + .n_layers = ARRAY_SIZE(malidp650_layers), |
---|
| 1045 | + .layers = malidp650_layers, |
---|
858 | 1046 | .de_irq_map = { |
---|
859 | 1047 | .irq_mask = MALIDP_DE_IRQ_UNDERRUN | |
---|
860 | 1048 | MALIDP650_DE_IRQ_DRIFT | |
---|
.. | .. |
---|
881 | 1069 | MALIDP550_DC_IRQ_SE, |
---|
882 | 1070 | .vsync_irq = MALIDP550_DC_IRQ_CONF_VALID, |
---|
883 | 1071 | }, |
---|
884 | | - .pixel_formats = malidp550_de_formats, |
---|
885 | | - .n_pixel_formats = ARRAY_SIZE(malidp550_de_formats), |
---|
| 1072 | + .pixel_formats = malidp650_de_formats, |
---|
| 1073 | + .n_pixel_formats = ARRAY_SIZE(malidp650_de_formats), |
---|
886 | 1074 | .bus_align_bytes = 16, |
---|
887 | 1075 | }, |
---|
888 | 1076 | .query_hw = malidp650_query_hw, |
---|
.. | .. |
---|
891 | 1079 | .in_config_mode = malidp550_in_config_mode, |
---|
892 | 1080 | .set_config_valid = malidp550_set_config_valid, |
---|
893 | 1081 | .modeset = malidp550_modeset, |
---|
894 | | - .rotmem_required = malidp550_rotmem_required, |
---|
| 1082 | + .rotmem_required = malidp650_rotmem_required, |
---|
895 | 1083 | .se_set_scaling_coeffs = malidp550_se_set_scaling_coeffs, |
---|
896 | 1084 | .se_calc_mclk = malidp550_se_calc_mclk, |
---|
897 | 1085 | .enable_memwrite = malidp550_enable_memwrite, |
---|
.. | .. |
---|
901 | 1089 | }; |
---|
902 | 1090 | |
---|
903 | 1091 | u8 malidp_hw_get_format_id(const struct malidp_hw_regmap *map, |
---|
904 | | - u8 layer_id, u32 format) |
---|
| 1092 | + u8 layer_id, u32 format, bool has_modifier) |
---|
905 | 1093 | { |
---|
906 | 1094 | unsigned int i; |
---|
907 | 1095 | |
---|
908 | 1096 | for (i = 0; i < map->n_pixel_formats; i++) { |
---|
909 | 1097 | if (((map->pixel_formats[i].layer & layer_id) == layer_id) && |
---|
910 | | - (map->pixel_formats[i].format == format)) |
---|
911 | | - return map->pixel_formats[i].id; |
---|
| 1098 | + (map->pixel_formats[i].format == format)) { |
---|
| 1099 | + /* |
---|
| 1100 | + * In some DP550 and DP650, DRM_FORMAT_YUYV + AFBC modifier |
---|
| 1101 | + * is supported by a different h/w format id than |
---|
| 1102 | + * DRM_FORMAT_YUYV (only). |
---|
| 1103 | + */ |
---|
| 1104 | + if (format == DRM_FORMAT_YUYV && |
---|
| 1105 | + (has_modifier) && |
---|
| 1106 | + (map->features & MALIDP_DEVICE_AFBC_YUYV_USE_422_P2)) |
---|
| 1107 | + return AFBC_YUV_422_FORMAT_ID; |
---|
| 1108 | + else |
---|
| 1109 | + return map->pixel_formats[i].id; |
---|
| 1110 | + } |
---|
912 | 1111 | } |
---|
913 | 1112 | |
---|
914 | 1113 | return MALIDP_INVALID_FORMAT_ID; |
---|
| 1114 | +} |
---|
| 1115 | + |
---|
| 1116 | +bool malidp_hw_format_is_linear_only(u32 format) |
---|
| 1117 | +{ |
---|
| 1118 | + switch (format) { |
---|
| 1119 | + case DRM_FORMAT_ARGB2101010: |
---|
| 1120 | + case DRM_FORMAT_RGBA1010102: |
---|
| 1121 | + case DRM_FORMAT_BGRA1010102: |
---|
| 1122 | + case DRM_FORMAT_ARGB8888: |
---|
| 1123 | + case DRM_FORMAT_RGBA8888: |
---|
| 1124 | + case DRM_FORMAT_BGRA8888: |
---|
| 1125 | + case DRM_FORMAT_XBGR8888: |
---|
| 1126 | + case DRM_FORMAT_XRGB8888: |
---|
| 1127 | + case DRM_FORMAT_RGBX8888: |
---|
| 1128 | + case DRM_FORMAT_BGRX8888: |
---|
| 1129 | + case DRM_FORMAT_RGB888: |
---|
| 1130 | + case DRM_FORMAT_RGB565: |
---|
| 1131 | + case DRM_FORMAT_ARGB1555: |
---|
| 1132 | + case DRM_FORMAT_RGBA5551: |
---|
| 1133 | + case DRM_FORMAT_BGRA5551: |
---|
| 1134 | + case DRM_FORMAT_UYVY: |
---|
| 1135 | + case DRM_FORMAT_XYUV8888: |
---|
| 1136 | + case DRM_FORMAT_XVYU2101010: |
---|
| 1137 | + case DRM_FORMAT_X0L2: |
---|
| 1138 | + case DRM_FORMAT_X0L0: |
---|
| 1139 | + return true; |
---|
| 1140 | + default: |
---|
| 1141 | + return false; |
---|
| 1142 | + } |
---|
| 1143 | +} |
---|
| 1144 | + |
---|
| 1145 | +bool malidp_hw_format_is_afbc_only(u32 format) |
---|
| 1146 | +{ |
---|
| 1147 | + switch (format) { |
---|
| 1148 | + case DRM_FORMAT_VUY888: |
---|
| 1149 | + case DRM_FORMAT_VUY101010: |
---|
| 1150 | + case DRM_FORMAT_YUV420_8BIT: |
---|
| 1151 | + case DRM_FORMAT_YUV420_10BIT: |
---|
| 1152 | + return true; |
---|
| 1153 | + default: |
---|
| 1154 | + return false; |
---|
| 1155 | + } |
---|
915 | 1156 | } |
---|
916 | 1157 | |
---|
917 | 1158 | static void malidp_hw_clear_irq(struct malidp_hw_device *hwdev, u8 block, u32 irq) |
---|
.. | .. |
---|
1083 | 1324 | break; |
---|
1084 | 1325 | case MW_RESTART: |
---|
1085 | 1326 | drm_writeback_signal_completion(&malidp->mw_connector, 0); |
---|
1086 | | - /* fall through to a new start */ |
---|
| 1327 | + fallthrough; /* to a new start */ |
---|
1087 | 1328 | case MW_START: |
---|
1088 | 1329 | /* writeback started, need to emulate one-shot mode */ |
---|
1089 | 1330 | hw->disable_memwrite(hwdev); |
---|