hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/gpu/ipu-v3/ipu-cpmem.c
....@@ -1,13 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Copyright (C) 2012 Mentor Graphics Inc.
34 * 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
115 */
126 #include <linux/types.h>
137 #include <linux/bitrev.h>
....@@ -188,9 +182,27 @@
188182 case V4L2_PIX_FMT_RGB32:
189183 /* R G B A <=> [32:0] A:B:G:R */
190184 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;
191188 case V4L2_PIX_FMT_XBGR32:
192189 /* B G R X <=> [32:0] X:R:G:B */
193190 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;
194206 case V4L2_PIX_FMT_XRGB32:
195207 /* X R G B <=> [32:0] B:G:R:X */
196208 return DRM_FORMAT_BGRX8888;
....@@ -259,6 +271,8 @@
259271
260272 void ipu_cpmem_set_buffer(struct ipuv3_channel *ch, int bufnum, dma_addr_t buf)
261273 {
274
+ WARN_ON_ONCE(buf & 0x7);
275
+
262276 if (bufnum)
263277 ipu_ch_param_write_field(ch, IPU_FIELD_EBA1, buf >> 3);
264278 else
....@@ -268,14 +282,17 @@
268282
269283 void ipu_cpmem_set_uv_offset(struct ipuv3_channel *ch, u32 u_off, u32 v_off)
270284 {
285
+ WARN_ON_ONCE((u_off & 0x7) || (v_off & 0x7));
286
+
271287 ipu_ch_param_write_field(ch, IPU_FIELD_UBO, u_off / 8);
272288 ipu_ch_param_write_field(ch, IPU_FIELD_VBO, v_off / 8);
273289 }
274290 EXPORT_SYMBOL_GPL(ipu_cpmem_set_uv_offset);
275291
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)
277294 {
278
- u32 ilo, sly;
295
+ u32 ilo, sly, sluv;
279296
280297 if (stride < 0) {
281298 stride = -stride;
....@@ -286,9 +303,30 @@
286303
287304 sly = (stride * 2) - 1;
288305
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
+
289325 ipu_ch_param_write_field(ch, IPU_FIELD_SO, 1);
290326 ipu_ch_param_write_field(ch, IPU_FIELD_ILO, ilo);
291327 ipu_ch_param_write_field(ch, IPU_FIELD_SLY, sly);
328
+ if (sluv)
329
+ ipu_ch_param_write_field(ch, IPU_FIELD_SLUV, sluv);
292330 };
293331 EXPORT_SYMBOL_GPL(ipu_cpmem_interlaced_scan);
294332
....@@ -435,6 +473,8 @@
435473 unsigned int uv_stride,
436474 unsigned int u_offset, unsigned int v_offset)
437475 {
476
+ WARN_ON_ONCE((u_offset & 0x7) || (v_offset & 0x7));
477
+
438478 ipu_ch_param_write_field(ch, IPU_FIELD_SLUV, uv_stride - 1);
439479 ipu_ch_param_write_field(ch, IPU_FIELD_UBO, u_offset / 8);
440480 ipu_ch_param_write_field(ch, IPU_FIELD_VBO, v_offset / 8);
....@@ -739,48 +779,56 @@
739779 switch (pix->pixelformat) {
740780 case V4L2_PIX_FMT_YUV420:
741781 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;
746788
747789 ipu_cpmem_set_yuv_planar_full(ch, pix->bytesperline / 2,
748790 u_offset, v_offset);
749791 break;
750792 case V4L2_PIX_FMT_YVU420:
751793 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;
756800
757801 ipu_cpmem_set_yuv_planar_full(ch, pix->bytesperline / 2,
758
- v_offset, u_offset);
802
+ u_offset, v_offset);
759803 break;
760804 case V4L2_PIX_FMT_YUV422P:
761805 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;
766812
767813 ipu_cpmem_set_yuv_planar_full(ch, pix->bytesperline / 2,
768814 u_offset, v_offset);
769815 break;
770816 case V4L2_PIX_FMT_NV12:
771817 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;
775822
776823 ipu_cpmem_set_yuv_planar_full(ch, pix->bytesperline,
777824 u_offset, v_offset);
778825 break;
779826 case V4L2_PIX_FMT_NV16:
780827 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;
784832
785833 ipu_cpmem_set_yuv_planar_full(ch, pix->bytesperline,
786834 u_offset, v_offset);
....@@ -793,8 +841,14 @@
793841 break;
794842 case V4L2_PIX_FMT_RGB32:
795843 case V4L2_PIX_FMT_BGR32:
796
- case V4L2_PIX_FMT_XRGB32:
844
+ case V4L2_PIX_FMT_ABGR32:
797845 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:
798852 offset = image->rect.left * 4 +
799853 image->rect.top * pix->bytesperline;
800854 break;