xref: /openbmc/linux/drivers/media/platform/amphion/vpu_color.c (revision 9a87ffc99ec8eb8d35eed7c4f816d75f5cc9662e)
1  // SPDX-License-Identifier: GPL-2.0
2  /*
3   * Copyright 2020-2021 NXP
4   */
5  
6  #include <linux/init.h>
7  #include <linux/device.h>
8  #include <linux/ioctl.h>
9  #include <linux/list.h>
10  #include <linux/module.h>
11  #include <linux/kernel.h>
12  #include <linux/slab.h>
13  #include <linux/delay.h>
14  #include <linux/types.h>
15  #include <media/v4l2-device.h>
16  #include "vpu.h"
17  #include "vpu_helpers.h"
18  
19  static const u8 colorprimaries[] = {
20  	V4L2_COLORSPACE_LAST,
21  	V4L2_COLORSPACE_REC709,         /*Rec. ITU-R BT.709-6*/
22  	0,
23  	0,
24  	V4L2_COLORSPACE_470_SYSTEM_M,   /*Rec. ITU-R BT.470-6 System M*/
25  	V4L2_COLORSPACE_470_SYSTEM_BG,  /*Rec. ITU-R BT.470-6 System B, G*/
26  	V4L2_COLORSPACE_SMPTE170M,      /*SMPTE170M*/
27  	V4L2_COLORSPACE_SMPTE240M,      /*SMPTE240M*/
28  	0,                              /*Generic film*/
29  	V4L2_COLORSPACE_BT2020,         /*Rec. ITU-R BT.2020-2*/
30  	0,                              /*SMPTE ST 428-1*/
31  };
32  
33  static const u8 colortransfers[] = {
34  	V4L2_XFER_FUNC_LAST,
35  	V4L2_XFER_FUNC_709,             /*Rec. ITU-R BT.709-6*/
36  	0,
37  	0,
38  	0,                              /*Rec. ITU-R BT.470-6 System M*/
39  	0,                              /*Rec. ITU-R BT.470-6 System B, G*/
40  	V4L2_XFER_FUNC_709,             /*SMPTE170M*/
41  	V4L2_XFER_FUNC_SMPTE240M,       /*SMPTE240M*/
42  	V4L2_XFER_FUNC_NONE,            /*Linear transfer characteristics*/
43  	0,
44  	0,
45  	0,                              /*IEC 61966-2-4*/
46  	0,                              /*Rec. ITU-R BT.1361-0 extended colour gamut*/
47  	V4L2_XFER_FUNC_SRGB,            /*IEC 61966-2-1 sRGB or sYCC*/
48  	V4L2_XFER_FUNC_709,             /*Rec. ITU-R BT.2020-2 (10 bit system)*/
49  	V4L2_XFER_FUNC_709,             /*Rec. ITU-R BT.2020-2 (12 bit system)*/
50  	V4L2_XFER_FUNC_SMPTE2084,       /*SMPTE ST 2084*/
51  	0,                              /*SMPTE ST 428-1*/
52  	0                               /*Rec. ITU-R BT.2100-0 hybrid log-gamma (HLG)*/
53  };
54  
55  static const u8 colormatrixcoefs[] = {
56  	V4L2_YCBCR_ENC_LAST,
57  	V4L2_YCBCR_ENC_709,              /*Rec. ITU-R BT.709-6*/
58  	0,
59  	0,
60  	0,                               /*Title 47 Code of Federal Regulations*/
61  	V4L2_YCBCR_ENC_601,              /*Rec. ITU-R BT.601-7 625*/
62  	V4L2_YCBCR_ENC_601,              /*Rec. ITU-R BT.601-7 525*/
63  	V4L2_YCBCR_ENC_SMPTE240M,        /*SMPTE240M*/
64  	0,
65  	V4L2_YCBCR_ENC_BT2020,           /*Rec. ITU-R BT.2020-2*/
66  	V4L2_YCBCR_ENC_BT2020_CONST_LUM  /*Rec. ITU-R BT.2020-2 constant*/
67  };
68  
vpu_color_cvrt_primaries_v2i(u32 primaries)69  u32 vpu_color_cvrt_primaries_v2i(u32 primaries)
70  {
71  	return vpu_helper_find_in_array_u8(colorprimaries, ARRAY_SIZE(colorprimaries), primaries);
72  }
73  
vpu_color_cvrt_primaries_i2v(u32 primaries)74  u32 vpu_color_cvrt_primaries_i2v(u32 primaries)
75  {
76  	return primaries < ARRAY_SIZE(colorprimaries) ? colorprimaries[primaries] : 0;
77  }
78  
vpu_color_cvrt_transfers_v2i(u32 transfers)79  u32 vpu_color_cvrt_transfers_v2i(u32 transfers)
80  {
81  	return vpu_helper_find_in_array_u8(colortransfers, ARRAY_SIZE(colortransfers), transfers);
82  }
83  
vpu_color_cvrt_transfers_i2v(u32 transfers)84  u32 vpu_color_cvrt_transfers_i2v(u32 transfers)
85  {
86  	return transfers < ARRAY_SIZE(colortransfers) ? colortransfers[transfers] : 0;
87  }
88  
vpu_color_cvrt_matrix_v2i(u32 matrix)89  u32 vpu_color_cvrt_matrix_v2i(u32 matrix)
90  {
91  	return vpu_helper_find_in_array_u8(colormatrixcoefs, ARRAY_SIZE(colormatrixcoefs), matrix);
92  }
93  
vpu_color_cvrt_matrix_i2v(u32 matrix)94  u32 vpu_color_cvrt_matrix_i2v(u32 matrix)
95  {
96  	return matrix < ARRAY_SIZE(colormatrixcoefs) ? colormatrixcoefs[matrix] : 0;
97  }
98  
vpu_color_cvrt_full_range_v2i(u32 full_range)99  u32 vpu_color_cvrt_full_range_v2i(u32 full_range)
100  {
101  	return (full_range == V4L2_QUANTIZATION_FULL_RANGE);
102  }
103  
vpu_color_cvrt_full_range_i2v(u32 full_range)104  u32 vpu_color_cvrt_full_range_i2v(u32 full_range)
105  {
106  	if (full_range)
107  		return V4L2_QUANTIZATION_FULL_RANGE;
108  
109  	return V4L2_QUANTIZATION_LIM_RANGE;
110  }
111  
vpu_color_check_primaries(u32 primaries)112  int vpu_color_check_primaries(u32 primaries)
113  {
114  	return vpu_color_cvrt_primaries_v2i(primaries) ? 0 : -EINVAL;
115  }
116  
vpu_color_check_transfers(u32 transfers)117  int vpu_color_check_transfers(u32 transfers)
118  {
119  	return vpu_color_cvrt_transfers_v2i(transfers) ? 0 : -EINVAL;
120  }
121  
vpu_color_check_matrix(u32 matrix)122  int vpu_color_check_matrix(u32 matrix)
123  {
124  	return vpu_color_cvrt_matrix_v2i(matrix) ? 0 : -EINVAL;
125  }
126  
vpu_color_check_full_range(u32 full_range)127  int vpu_color_check_full_range(u32 full_range)
128  {
129  	int ret = -EINVAL;
130  
131  	switch (full_range) {
132  	case V4L2_QUANTIZATION_FULL_RANGE:
133  	case V4L2_QUANTIZATION_LIM_RANGE:
134  		ret = 0;
135  		break;
136  	default:
137  		break;
138  	}
139  
140  	return ret;
141  }
142  
vpu_color_get_default(u32 primaries,u32 * ptransfers,u32 * pmatrix,u32 * pfull_range)143  int vpu_color_get_default(u32 primaries, u32 *ptransfers, u32 *pmatrix, u32 *pfull_range)
144  {
145  	u32 transfers;
146  	u32 matrix;
147  	u32 full_range;
148  
149  	switch (primaries) {
150  	case V4L2_COLORSPACE_REC709:
151  		transfers = V4L2_XFER_FUNC_709;
152  		matrix = V4L2_YCBCR_ENC_709;
153  		break;
154  	case V4L2_COLORSPACE_470_SYSTEM_M:
155  	case V4L2_COLORSPACE_470_SYSTEM_BG:
156  	case V4L2_COLORSPACE_SMPTE170M:
157  		transfers = V4L2_XFER_FUNC_709;
158  		matrix = V4L2_YCBCR_ENC_601;
159  		break;
160  	case V4L2_COLORSPACE_SMPTE240M:
161  		transfers = V4L2_XFER_FUNC_SMPTE240M;
162  		matrix = V4L2_YCBCR_ENC_SMPTE240M;
163  		break;
164  	case V4L2_COLORSPACE_BT2020:
165  		transfers = V4L2_XFER_FUNC_709;
166  		matrix = V4L2_YCBCR_ENC_BT2020;
167  		break;
168  	default:
169  		transfers = V4L2_XFER_FUNC_DEFAULT;
170  		matrix = V4L2_YCBCR_ENC_DEFAULT;
171  		break;
172  	}
173  	full_range = V4L2_QUANTIZATION_LIM_RANGE;
174  
175  	if (ptransfers)
176  		*ptransfers = transfers;
177  	if (pmatrix)
178  		*pmatrix = matrix;
179  	if (pfull_range)
180  		*pfull_range = full_range;
181  
182  	return 0;
183  }
184