| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (C) 2012 Mentor Graphics Inc. |
|---|
| 3 | 4 | * Copyright 2005-2012 Freescale Semiconductor, Inc. All Rights Reserved. |
|---|
| 4 | | - * |
|---|
| 5 | | - * The code contained herein is licensed under the GNU General Public |
|---|
| 6 | | - * License. You may obtain a copy of the GNU General Public License |
|---|
| 7 | | - * Version 2 or later at the following locations: |
|---|
| 8 | | - * |
|---|
| 9 | | - * http://www.opensource.org/licenses/gpl-license.html |
|---|
| 10 | | - * http://www.gnu.org/copyleft/gpl.html |
|---|
| 11 | 5 | */ |
|---|
| 12 | 6 | #include <linux/types.h> |
|---|
| 13 | 7 | #include <linux/bitrev.h> |
|---|
| .. | .. |
|---|
| 188 | 182 | case V4L2_PIX_FMT_RGB32: |
|---|
| 189 | 183 | /* R G B A <=> [32:0] A:B:G:R */ |
|---|
| 190 | 184 | return DRM_FORMAT_XBGR8888; |
|---|
| 185 | + case V4L2_PIX_FMT_ABGR32: |
|---|
| 186 | + /* B G R A <=> [32:0] A:R:G:B */ |
|---|
| 187 | + return DRM_FORMAT_ARGB8888; |
|---|
| 191 | 188 | case V4L2_PIX_FMT_XBGR32: |
|---|
| 192 | 189 | /* B G R X <=> [32:0] X:R:G:B */ |
|---|
| 193 | 190 | return DRM_FORMAT_XRGB8888; |
|---|
| 191 | + case V4L2_PIX_FMT_BGRA32: |
|---|
| 192 | + /* A B G R <=> [32:0] R:G:B:A */ |
|---|
| 193 | + return DRM_FORMAT_RGBA8888; |
|---|
| 194 | + case V4L2_PIX_FMT_BGRX32: |
|---|
| 195 | + /* X B G R <=> [32:0] R:G:B:X */ |
|---|
| 196 | + return DRM_FORMAT_RGBX8888; |
|---|
| 197 | + case V4L2_PIX_FMT_RGBA32: |
|---|
| 198 | + /* R G B A <=> [32:0] A:B:G:R */ |
|---|
| 199 | + return DRM_FORMAT_ABGR8888; |
|---|
| 200 | + case V4L2_PIX_FMT_RGBX32: |
|---|
| 201 | + /* R G B X <=> [32:0] X:B:G:R */ |
|---|
| 202 | + return DRM_FORMAT_XBGR8888; |
|---|
| 203 | + case V4L2_PIX_FMT_ARGB32: |
|---|
| 204 | + /* A R G B <=> [32:0] B:G:R:A */ |
|---|
| 205 | + return DRM_FORMAT_BGRA8888; |
|---|
| 194 | 206 | case V4L2_PIX_FMT_XRGB32: |
|---|
| 195 | 207 | /* X R G B <=> [32:0] B:G:R:X */ |
|---|
| 196 | 208 | return DRM_FORMAT_BGRX8888; |
|---|
| .. | .. |
|---|
| 259 | 271 | |
|---|
| 260 | 272 | void ipu_cpmem_set_buffer(struct ipuv3_channel *ch, int bufnum, dma_addr_t buf) |
|---|
| 261 | 273 | { |
|---|
| 274 | + WARN_ON_ONCE(buf & 0x7); |
|---|
| 275 | + |
|---|
| 262 | 276 | if (bufnum) |
|---|
| 263 | 277 | ipu_ch_param_write_field(ch, IPU_FIELD_EBA1, buf >> 3); |
|---|
| 264 | 278 | else |
|---|
| .. | .. |
|---|
| 268 | 282 | |
|---|
| 269 | 283 | void ipu_cpmem_set_uv_offset(struct ipuv3_channel *ch, u32 u_off, u32 v_off) |
|---|
| 270 | 284 | { |
|---|
| 285 | + WARN_ON_ONCE((u_off & 0x7) || (v_off & 0x7)); |
|---|
| 286 | + |
|---|
| 271 | 287 | ipu_ch_param_write_field(ch, IPU_FIELD_UBO, u_off / 8); |
|---|
| 272 | 288 | ipu_ch_param_write_field(ch, IPU_FIELD_VBO, v_off / 8); |
|---|
| 273 | 289 | } |
|---|
| 274 | 290 | EXPORT_SYMBOL_GPL(ipu_cpmem_set_uv_offset); |
|---|
| 275 | 291 | |
|---|
| 276 | | -void ipu_cpmem_interlaced_scan(struct ipuv3_channel *ch, int stride) |
|---|
| 292 | +void ipu_cpmem_interlaced_scan(struct ipuv3_channel *ch, int stride, |
|---|
| 293 | + u32 pixelformat) |
|---|
| 277 | 294 | { |
|---|
| 278 | | - u32 ilo, sly; |
|---|
| 295 | + u32 ilo, sly, sluv; |
|---|
| 279 | 296 | |
|---|
| 280 | 297 | if (stride < 0) { |
|---|
| 281 | 298 | stride = -stride; |
|---|
| .. | .. |
|---|
| 286 | 303 | |
|---|
| 287 | 304 | sly = (stride * 2) - 1; |
|---|
| 288 | 305 | |
|---|
| 306 | + switch (pixelformat) { |
|---|
| 307 | + case V4L2_PIX_FMT_YUV420: |
|---|
| 308 | + case V4L2_PIX_FMT_YVU420: |
|---|
| 309 | + sluv = stride / 2 - 1; |
|---|
| 310 | + break; |
|---|
| 311 | + case V4L2_PIX_FMT_NV12: |
|---|
| 312 | + sluv = stride - 1; |
|---|
| 313 | + break; |
|---|
| 314 | + case V4L2_PIX_FMT_YUV422P: |
|---|
| 315 | + sluv = stride - 1; |
|---|
| 316 | + break; |
|---|
| 317 | + case V4L2_PIX_FMT_NV16: |
|---|
| 318 | + sluv = stride * 2 - 1; |
|---|
| 319 | + break; |
|---|
| 320 | + default: |
|---|
| 321 | + sluv = 0; |
|---|
| 322 | + break; |
|---|
| 323 | + } |
|---|
| 324 | + |
|---|
| 289 | 325 | ipu_ch_param_write_field(ch, IPU_FIELD_SO, 1); |
|---|
| 290 | 326 | ipu_ch_param_write_field(ch, IPU_FIELD_ILO, ilo); |
|---|
| 291 | 327 | ipu_ch_param_write_field(ch, IPU_FIELD_SLY, sly); |
|---|
| 328 | + if (sluv) |
|---|
| 329 | + ipu_ch_param_write_field(ch, IPU_FIELD_SLUV, sluv); |
|---|
| 292 | 330 | }; |
|---|
| 293 | 331 | EXPORT_SYMBOL_GPL(ipu_cpmem_interlaced_scan); |
|---|
| 294 | 332 | |
|---|
| .. | .. |
|---|
| 435 | 473 | unsigned int uv_stride, |
|---|
| 436 | 474 | unsigned int u_offset, unsigned int v_offset) |
|---|
| 437 | 475 | { |
|---|
| 476 | + WARN_ON_ONCE((u_offset & 0x7) || (v_offset & 0x7)); |
|---|
| 477 | + |
|---|
| 438 | 478 | ipu_ch_param_write_field(ch, IPU_FIELD_SLUV, uv_stride - 1); |
|---|
| 439 | 479 | ipu_ch_param_write_field(ch, IPU_FIELD_UBO, u_offset / 8); |
|---|
| 440 | 480 | ipu_ch_param_write_field(ch, IPU_FIELD_VBO, v_offset / 8); |
|---|
| .. | .. |
|---|
| 739 | 779 | switch (pix->pixelformat) { |
|---|
| 740 | 780 | case V4L2_PIX_FMT_YUV420: |
|---|
| 741 | 781 | offset = Y_OFFSET(pix, image->rect.left, image->rect.top); |
|---|
| 742 | | - u_offset = U_OFFSET(pix, image->rect.left, |
|---|
| 743 | | - image->rect.top) - offset; |
|---|
| 744 | | - v_offset = V_OFFSET(pix, image->rect.left, |
|---|
| 745 | | - image->rect.top) - offset; |
|---|
| 782 | + u_offset = image->u_offset ? |
|---|
| 783 | + image->u_offset : U_OFFSET(pix, image->rect.left, |
|---|
| 784 | + image->rect.top) - offset; |
|---|
| 785 | + v_offset = image->v_offset ? |
|---|
| 786 | + image->v_offset : V_OFFSET(pix, image->rect.left, |
|---|
| 787 | + image->rect.top) - offset; |
|---|
| 746 | 788 | |
|---|
| 747 | 789 | ipu_cpmem_set_yuv_planar_full(ch, pix->bytesperline / 2, |
|---|
| 748 | 790 | u_offset, v_offset); |
|---|
| 749 | 791 | break; |
|---|
| 750 | 792 | case V4L2_PIX_FMT_YVU420: |
|---|
| 751 | 793 | offset = Y_OFFSET(pix, image->rect.left, image->rect.top); |
|---|
| 752 | | - u_offset = U_OFFSET(pix, image->rect.left, |
|---|
| 753 | | - image->rect.top) - offset; |
|---|
| 754 | | - v_offset = V_OFFSET(pix, image->rect.left, |
|---|
| 755 | | - image->rect.top) - offset; |
|---|
| 794 | + u_offset = image->u_offset ? |
|---|
| 795 | + image->u_offset : V_OFFSET(pix, image->rect.left, |
|---|
| 796 | + image->rect.top) - offset; |
|---|
| 797 | + v_offset = image->v_offset ? |
|---|
| 798 | + image->v_offset : U_OFFSET(pix, image->rect.left, |
|---|
| 799 | + image->rect.top) - offset; |
|---|
| 756 | 800 | |
|---|
| 757 | 801 | ipu_cpmem_set_yuv_planar_full(ch, pix->bytesperline / 2, |
|---|
| 758 | | - v_offset, u_offset); |
|---|
| 802 | + u_offset, v_offset); |
|---|
| 759 | 803 | break; |
|---|
| 760 | 804 | case V4L2_PIX_FMT_YUV422P: |
|---|
| 761 | 805 | offset = Y_OFFSET(pix, image->rect.left, image->rect.top); |
|---|
| 762 | | - u_offset = U2_OFFSET(pix, image->rect.left, |
|---|
| 763 | | - image->rect.top) - offset; |
|---|
| 764 | | - v_offset = V2_OFFSET(pix, image->rect.left, |
|---|
| 765 | | - image->rect.top) - offset; |
|---|
| 806 | + u_offset = image->u_offset ? |
|---|
| 807 | + image->u_offset : U2_OFFSET(pix, image->rect.left, |
|---|
| 808 | + image->rect.top) - offset; |
|---|
| 809 | + v_offset = image->v_offset ? |
|---|
| 810 | + image->v_offset : V2_OFFSET(pix, image->rect.left, |
|---|
| 811 | + image->rect.top) - offset; |
|---|
| 766 | 812 | |
|---|
| 767 | 813 | ipu_cpmem_set_yuv_planar_full(ch, pix->bytesperline / 2, |
|---|
| 768 | 814 | u_offset, v_offset); |
|---|
| 769 | 815 | break; |
|---|
| 770 | 816 | case V4L2_PIX_FMT_NV12: |
|---|
| 771 | 817 | offset = Y_OFFSET(pix, image->rect.left, image->rect.top); |
|---|
| 772 | | - u_offset = UV_OFFSET(pix, image->rect.left, |
|---|
| 773 | | - image->rect.top) - offset; |
|---|
| 774 | | - v_offset = 0; |
|---|
| 818 | + u_offset = image->u_offset ? |
|---|
| 819 | + image->u_offset : UV_OFFSET(pix, image->rect.left, |
|---|
| 820 | + image->rect.top) - offset; |
|---|
| 821 | + v_offset = image->v_offset ? image->v_offset : 0; |
|---|
| 775 | 822 | |
|---|
| 776 | 823 | ipu_cpmem_set_yuv_planar_full(ch, pix->bytesperline, |
|---|
| 777 | 824 | u_offset, v_offset); |
|---|
| 778 | 825 | break; |
|---|
| 779 | 826 | case V4L2_PIX_FMT_NV16: |
|---|
| 780 | 827 | offset = Y_OFFSET(pix, image->rect.left, image->rect.top); |
|---|
| 781 | | - u_offset = UV2_OFFSET(pix, image->rect.left, |
|---|
| 782 | | - image->rect.top) - offset; |
|---|
| 783 | | - v_offset = 0; |
|---|
| 828 | + u_offset = image->u_offset ? |
|---|
| 829 | + image->u_offset : UV2_OFFSET(pix, image->rect.left, |
|---|
| 830 | + image->rect.top) - offset; |
|---|
| 831 | + v_offset = image->v_offset ? image->v_offset : 0; |
|---|
| 784 | 832 | |
|---|
| 785 | 833 | ipu_cpmem_set_yuv_planar_full(ch, pix->bytesperline, |
|---|
| 786 | 834 | u_offset, v_offset); |
|---|
| .. | .. |
|---|
| 793 | 841 | break; |
|---|
| 794 | 842 | case V4L2_PIX_FMT_RGB32: |
|---|
| 795 | 843 | case V4L2_PIX_FMT_BGR32: |
|---|
| 796 | | - case V4L2_PIX_FMT_XRGB32: |
|---|
| 844 | + case V4L2_PIX_FMT_ABGR32: |
|---|
| 797 | 845 | case V4L2_PIX_FMT_XBGR32: |
|---|
| 846 | + case V4L2_PIX_FMT_BGRA32: |
|---|
| 847 | + case V4L2_PIX_FMT_BGRX32: |
|---|
| 848 | + case V4L2_PIX_FMT_RGBA32: |
|---|
| 849 | + case V4L2_PIX_FMT_RGBX32: |
|---|
| 850 | + case V4L2_PIX_FMT_ARGB32: |
|---|
| 851 | + case V4L2_PIX_FMT_XRGB32: |
|---|
| 798 | 852 | offset = image->rect.left * 4 + |
|---|
| 799 | 853 | image->rect.top * pix->bytesperline; |
|---|
| 800 | 854 | break; |
|---|