162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2019 Mentor Graphics Inc.
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#include <linux/types.h>
762306a36Sopenharmony_ci#include <linux/init.h>
862306a36Sopenharmony_ci#include <linux/errno.h>
962306a36Sopenharmony_ci#include <linux/err.h>
1062306a36Sopenharmony_ci#include <linux/sizes.h>
1162306a36Sopenharmony_ci#include "ipu-prv.h"
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#define QUANT_MAP(q)					\
1462306a36Sopenharmony_ci	((q) == V4L2_QUANTIZATION_FULL_RANGE ||		\
1562306a36Sopenharmony_ci	 (q) == V4L2_QUANTIZATION_DEFAULT ? 0 : 1)
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci/* identity matrix */
1862306a36Sopenharmony_cistatic const struct ipu_ic_csc_params identity = {
1962306a36Sopenharmony_ci	.coeff = {
2062306a36Sopenharmony_ci		{  128,    0,    0, },
2162306a36Sopenharmony_ci		{    0,  128,    0, },
2262306a36Sopenharmony_ci		{    0,    0,  128, },
2362306a36Sopenharmony_ci	},
2462306a36Sopenharmony_ci	.offset = { 0, 0, 0, },
2562306a36Sopenharmony_ci	.scale = 2,
2662306a36Sopenharmony_ci};
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci/*
2962306a36Sopenharmony_ci * RGB full-range to RGB limited-range
3062306a36Sopenharmony_ci *
3162306a36Sopenharmony_ci * R_lim = 0.8588 * R_full + 16
3262306a36Sopenharmony_ci * G_lim = 0.8588 * G_full + 16
3362306a36Sopenharmony_ci * B_lim = 0.8588 * B_full + 16
3462306a36Sopenharmony_ci */
3562306a36Sopenharmony_cistatic const struct ipu_ic_csc_params rgbf2rgbl = {
3662306a36Sopenharmony_ci	.coeff = {
3762306a36Sopenharmony_ci		{  220,    0,    0, },
3862306a36Sopenharmony_ci		{    0,  220,    0, },
3962306a36Sopenharmony_ci		{    0,    0,  220, },
4062306a36Sopenharmony_ci	},
4162306a36Sopenharmony_ci	.offset = { 64, 64, 64, },
4262306a36Sopenharmony_ci	.scale = 1,
4362306a36Sopenharmony_ci};
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci/*
4662306a36Sopenharmony_ci * RGB limited-range to RGB full-range
4762306a36Sopenharmony_ci *
4862306a36Sopenharmony_ci * R_full = 1.1644 * (R_lim - 16)
4962306a36Sopenharmony_ci * G_full = 1.1644 * (G_lim - 16)
5062306a36Sopenharmony_ci * B_full = 1.1644 * (B_lim - 16)
5162306a36Sopenharmony_ci */
5262306a36Sopenharmony_cistatic const struct ipu_ic_csc_params rgbl2rgbf = {
5362306a36Sopenharmony_ci	.coeff = {
5462306a36Sopenharmony_ci		{  149,    0,    0, },
5562306a36Sopenharmony_ci		{    0,  149,    0, },
5662306a36Sopenharmony_ci		{    0,    0,  149, },
5762306a36Sopenharmony_ci	},
5862306a36Sopenharmony_ci	.offset = { -37, -37, -37, },
5962306a36Sopenharmony_ci	.scale = 2,
6062306a36Sopenharmony_ci};
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci/*
6362306a36Sopenharmony_ci * YUV full-range to YUV limited-range
6462306a36Sopenharmony_ci *
6562306a36Sopenharmony_ci * Y_lim  = 0.8588 * Y_full + 16
6662306a36Sopenharmony_ci * Cb_lim = 0.8784 * (Cb_full - 128) + 128
6762306a36Sopenharmony_ci * Cr_lim = 0.8784 * (Cr_full - 128) + 128
6862306a36Sopenharmony_ci */
6962306a36Sopenharmony_cistatic const struct ipu_ic_csc_params yuvf2yuvl = {
7062306a36Sopenharmony_ci	.coeff = {
7162306a36Sopenharmony_ci		{  220,    0,    0, },
7262306a36Sopenharmony_ci		{    0,  225,    0, },
7362306a36Sopenharmony_ci		{    0,    0,  225, },
7462306a36Sopenharmony_ci	},
7562306a36Sopenharmony_ci	.offset = { 64, 62, 62, },
7662306a36Sopenharmony_ci	.scale = 1,
7762306a36Sopenharmony_ci	.sat = true,
7862306a36Sopenharmony_ci};
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci/*
8162306a36Sopenharmony_ci * YUV limited-range to YUV full-range
8262306a36Sopenharmony_ci *
8362306a36Sopenharmony_ci * Y_full  = 1.1644 * (Y_lim - 16)
8462306a36Sopenharmony_ci * Cb_full = 1.1384 * (Cb_lim - 128) + 128
8562306a36Sopenharmony_ci * Cr_full = 1.1384 * (Cr_lim - 128) + 128
8662306a36Sopenharmony_ci */
8762306a36Sopenharmony_cistatic const struct ipu_ic_csc_params yuvl2yuvf = {
8862306a36Sopenharmony_ci	.coeff = {
8962306a36Sopenharmony_ci		{  149,    0,    0, },
9062306a36Sopenharmony_ci		{    0,  146,    0, },
9162306a36Sopenharmony_ci		{    0,    0,  146, },
9262306a36Sopenharmony_ci	},
9362306a36Sopenharmony_ci	.offset = { -37, -35, -35, },
9462306a36Sopenharmony_ci	.scale = 2,
9562306a36Sopenharmony_ci};
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_cistatic const struct ipu_ic_csc_params *rgb2rgb[] = {
9862306a36Sopenharmony_ci	&identity,
9962306a36Sopenharmony_ci	&rgbf2rgbl,
10062306a36Sopenharmony_ci	&rgbl2rgbf,
10162306a36Sopenharmony_ci	&identity,
10262306a36Sopenharmony_ci};
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_cistatic const struct ipu_ic_csc_params *yuv2yuv[] = {
10562306a36Sopenharmony_ci	&identity,
10662306a36Sopenharmony_ci	&yuvf2yuvl,
10762306a36Sopenharmony_ci	&yuvl2yuvf,
10862306a36Sopenharmony_ci	&identity,
10962306a36Sopenharmony_ci};
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci/*
11262306a36Sopenharmony_ci * BT.601 RGB full-range to YUV full-range
11362306a36Sopenharmony_ci *
11462306a36Sopenharmony_ci * Y =  .2990 * R + .5870 * G + .1140 * B
11562306a36Sopenharmony_ci * U = -.1687 * R - .3313 * G + .5000 * B + 128
11662306a36Sopenharmony_ci * V =  .5000 * R - .4187 * G - .0813 * B + 128
11762306a36Sopenharmony_ci */
11862306a36Sopenharmony_cistatic const struct ipu_ic_csc_params rgbf2yuvf_601 = {
11962306a36Sopenharmony_ci	.coeff = {
12062306a36Sopenharmony_ci		{   77,  150,   29, },
12162306a36Sopenharmony_ci		{  -43,  -85,  128, },
12262306a36Sopenharmony_ci		{  128, -107,  -21, },
12362306a36Sopenharmony_ci	},
12462306a36Sopenharmony_ci	.offset = { 0, 512, 512, },
12562306a36Sopenharmony_ci	.scale = 1,
12662306a36Sopenharmony_ci};
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ci/* BT.601 RGB full-range to YUV limited-range */
12962306a36Sopenharmony_cistatic const struct ipu_ic_csc_params rgbf2yuvl_601 = {
13062306a36Sopenharmony_ci	.coeff = {
13162306a36Sopenharmony_ci		{   66,  129,   25, },
13262306a36Sopenharmony_ci		{  -38,  -74,  112, },
13362306a36Sopenharmony_ci		{  112,  -94,  -18, },
13462306a36Sopenharmony_ci	},
13562306a36Sopenharmony_ci	.offset = { 64, 512, 512, },
13662306a36Sopenharmony_ci	.scale = 1,
13762306a36Sopenharmony_ci	.sat = true,
13862306a36Sopenharmony_ci};
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci/* BT.601 RGB limited-range to YUV full-range */
14162306a36Sopenharmony_cistatic const struct ipu_ic_csc_params rgbl2yuvf_601 = {
14262306a36Sopenharmony_ci	.coeff = {
14362306a36Sopenharmony_ci		{   89,  175,   34, },
14462306a36Sopenharmony_ci		{  -50,  -99,  149, },
14562306a36Sopenharmony_ci		{  149, -125,  -24, },
14662306a36Sopenharmony_ci	},
14762306a36Sopenharmony_ci	.offset = { -75, 512, 512, },
14862306a36Sopenharmony_ci	.scale = 1,
14962306a36Sopenharmony_ci};
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ci/* BT.601 RGB limited-range to YUV limited-range */
15262306a36Sopenharmony_cistatic const struct ipu_ic_csc_params rgbl2yuvl_601 = {
15362306a36Sopenharmony_ci	.coeff = {
15462306a36Sopenharmony_ci		{   77,  150,   29, },
15562306a36Sopenharmony_ci		{  -44,  -87,  131, },
15662306a36Sopenharmony_ci		{  131, -110,  -21, },
15762306a36Sopenharmony_ci	},
15862306a36Sopenharmony_ci	.offset = { 0, 512, 512, },
15962306a36Sopenharmony_ci	.scale = 1,
16062306a36Sopenharmony_ci	.sat = true,
16162306a36Sopenharmony_ci};
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ci/*
16462306a36Sopenharmony_ci * BT.601 YUV full-range to RGB full-range
16562306a36Sopenharmony_ci *
16662306a36Sopenharmony_ci * R = 1. * Y +      0 * (Cb - 128) + 1.4020 * (Cr - 128)
16762306a36Sopenharmony_ci * G = 1. * Y -  .3441 * (Cb - 128) -  .7141 * (Cr - 128)
16862306a36Sopenharmony_ci * B = 1. * Y + 1.7720 * (Cb - 128) +      0 * (Cr - 128)
16962306a36Sopenharmony_ci *
17062306a36Sopenharmony_ci * equivalently (factoring out the offsets):
17162306a36Sopenharmony_ci *
17262306a36Sopenharmony_ci * R = 1. * Y  +      0 * Cb + 1.4020 * Cr - 179.456
17362306a36Sopenharmony_ci * G = 1. * Y  -  .3441 * Cb -  .7141 * Cr + 135.450
17462306a36Sopenharmony_ci * B = 1. * Y  + 1.7720 * Cb +      0 * Cr - 226.816
17562306a36Sopenharmony_ci */
17662306a36Sopenharmony_cistatic const struct ipu_ic_csc_params yuvf2rgbf_601 = {
17762306a36Sopenharmony_ci	.coeff = {
17862306a36Sopenharmony_ci		{  128,    0,  179, },
17962306a36Sopenharmony_ci		{  128,  -44,  -91, },
18062306a36Sopenharmony_ci		{  128,  227,    0, },
18162306a36Sopenharmony_ci	},
18262306a36Sopenharmony_ci	.offset = { -359, 271, -454, },
18362306a36Sopenharmony_ci	.scale = 2,
18462306a36Sopenharmony_ci};
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_ci/* BT.601 YUV full-range to RGB limited-range */
18762306a36Sopenharmony_cistatic const struct ipu_ic_csc_params yuvf2rgbl_601 = {
18862306a36Sopenharmony_ci	.coeff = {
18962306a36Sopenharmony_ci		{  110,    0,  154, },
19062306a36Sopenharmony_ci		{  110,  -38,  -78, },
19162306a36Sopenharmony_ci		{  110,  195,    0, },
19262306a36Sopenharmony_ci	},
19362306a36Sopenharmony_ci	.offset = { -276, 265, -358, },
19462306a36Sopenharmony_ci	.scale = 2,
19562306a36Sopenharmony_ci};
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ci/* BT.601 YUV limited-range to RGB full-range */
19862306a36Sopenharmony_cistatic const struct ipu_ic_csc_params yuvl2rgbf_601 = {
19962306a36Sopenharmony_ci	.coeff = {
20062306a36Sopenharmony_ci		{   75,    0,  102, },
20162306a36Sopenharmony_ci		{   75,  -25,  -52, },
20262306a36Sopenharmony_ci		{   75,  129,    0, },
20362306a36Sopenharmony_ci	},
20462306a36Sopenharmony_ci	.offset = { -223, 136, -277, },
20562306a36Sopenharmony_ci	.scale = 3,
20662306a36Sopenharmony_ci};
20762306a36Sopenharmony_ci
20862306a36Sopenharmony_ci/* BT.601 YUV limited-range to RGB limited-range */
20962306a36Sopenharmony_cistatic const struct ipu_ic_csc_params yuvl2rgbl_601 = {
21062306a36Sopenharmony_ci	.coeff = {
21162306a36Sopenharmony_ci		{  128,    0,  175, },
21262306a36Sopenharmony_ci		{  128,  -43,  -89, },
21362306a36Sopenharmony_ci		{  128,  222,    0, },
21462306a36Sopenharmony_ci	},
21562306a36Sopenharmony_ci	.offset = { -351, 265, -443, },
21662306a36Sopenharmony_ci	.scale = 2,
21762306a36Sopenharmony_ci};
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_cistatic const struct ipu_ic_csc_params *rgb2yuv_601[] = {
22062306a36Sopenharmony_ci	&rgbf2yuvf_601,
22162306a36Sopenharmony_ci	&rgbf2yuvl_601,
22262306a36Sopenharmony_ci	&rgbl2yuvf_601,
22362306a36Sopenharmony_ci	&rgbl2yuvl_601,
22462306a36Sopenharmony_ci};
22562306a36Sopenharmony_ci
22662306a36Sopenharmony_cistatic const struct ipu_ic_csc_params *yuv2rgb_601[] = {
22762306a36Sopenharmony_ci	&yuvf2rgbf_601,
22862306a36Sopenharmony_ci	&yuvf2rgbl_601,
22962306a36Sopenharmony_ci	&yuvl2rgbf_601,
23062306a36Sopenharmony_ci	&yuvl2rgbl_601,
23162306a36Sopenharmony_ci};
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_ci/*
23462306a36Sopenharmony_ci * REC.709 encoding from RGB full range to YUV full range:
23562306a36Sopenharmony_ci *
23662306a36Sopenharmony_ci * Y =  .2126 * R + .7152 * G + .0722 * B
23762306a36Sopenharmony_ci * U = -.1146 * R - .3854 * G + .5000 * B + 128
23862306a36Sopenharmony_ci * V =  .5000 * R - .4542 * G - .0458 * B + 128
23962306a36Sopenharmony_ci */
24062306a36Sopenharmony_cistatic const struct ipu_ic_csc_params rgbf2yuvf_709 = {
24162306a36Sopenharmony_ci	.coeff = {
24262306a36Sopenharmony_ci		{  54,  183,  19 },
24362306a36Sopenharmony_ci		{ -29,  -99, 128 },
24462306a36Sopenharmony_ci		{ 128, -116, -12 },
24562306a36Sopenharmony_ci	},
24662306a36Sopenharmony_ci	.offset = { 0, 512, 512 },
24762306a36Sopenharmony_ci	.scale = 1,
24862306a36Sopenharmony_ci};
24962306a36Sopenharmony_ci
25062306a36Sopenharmony_ci/* Rec.709 RGB full-range to YUV limited-range */
25162306a36Sopenharmony_cistatic const struct ipu_ic_csc_params rgbf2yuvl_709 = {
25262306a36Sopenharmony_ci	.coeff = {
25362306a36Sopenharmony_ci		{   47,  157,   16, },
25462306a36Sopenharmony_ci		{  -26,  -87,  112, },
25562306a36Sopenharmony_ci		{  112, -102,  -10, },
25662306a36Sopenharmony_ci	},
25762306a36Sopenharmony_ci	.offset = { 64, 512, 512, },
25862306a36Sopenharmony_ci	.scale = 1,
25962306a36Sopenharmony_ci	.sat = true,
26062306a36Sopenharmony_ci};
26162306a36Sopenharmony_ci
26262306a36Sopenharmony_ci/* Rec.709 RGB limited-range to YUV full-range */
26362306a36Sopenharmony_cistatic const struct ipu_ic_csc_params rgbl2yuvf_709 = {
26462306a36Sopenharmony_ci	.coeff = {
26562306a36Sopenharmony_ci		{   63,  213,   22, },
26662306a36Sopenharmony_ci		{  -34, -115,  149, },
26762306a36Sopenharmony_ci		{  149, -135,  -14, },
26862306a36Sopenharmony_ci	},
26962306a36Sopenharmony_ci	.offset = { -75, 512, 512, },
27062306a36Sopenharmony_ci	.scale = 1,
27162306a36Sopenharmony_ci};
27262306a36Sopenharmony_ci
27362306a36Sopenharmony_ci/* Rec.709 RGB limited-range to YUV limited-range */
27462306a36Sopenharmony_cistatic const struct ipu_ic_csc_params rgbl2yuvl_709 = {
27562306a36Sopenharmony_ci	.coeff = {
27662306a36Sopenharmony_ci		{   54,  183,   18, },
27762306a36Sopenharmony_ci		{  -30, -101,  131, },
27862306a36Sopenharmony_ci		{  131, -119,  -12, },
27962306a36Sopenharmony_ci	},
28062306a36Sopenharmony_ci	.offset = { 0, 512, 512, },
28162306a36Sopenharmony_ci	.scale = 1,
28262306a36Sopenharmony_ci	.sat = true,
28362306a36Sopenharmony_ci};
28462306a36Sopenharmony_ci
28562306a36Sopenharmony_ci/*
28662306a36Sopenharmony_ci * Inverse REC.709 encoding from YUV full range to RGB full range:
28762306a36Sopenharmony_ci *
28862306a36Sopenharmony_ci * R = 1. * Y +      0 * (Cb - 128) + 1.5748 * (Cr - 128)
28962306a36Sopenharmony_ci * G = 1. * Y -  .1873 * (Cb - 128) -  .4681 * (Cr - 128)
29062306a36Sopenharmony_ci * B = 1. * Y + 1.8556 * (Cb - 128) +      0 * (Cr - 128)
29162306a36Sopenharmony_ci *
29262306a36Sopenharmony_ci * equivalently (factoring out the offsets):
29362306a36Sopenharmony_ci *
29462306a36Sopenharmony_ci * R = 1. * Y  +      0 * Cb + 1.5748 * Cr - 201.574
29562306a36Sopenharmony_ci * G = 1. * Y  -  .1873 * Cb -  .4681 * Cr +  83.891
29662306a36Sopenharmony_ci * B = 1. * Y  + 1.8556 * Cb +      0 * Cr - 237.517
29762306a36Sopenharmony_ci */
29862306a36Sopenharmony_cistatic const struct ipu_ic_csc_params yuvf2rgbf_709 = {
29962306a36Sopenharmony_ci	.coeff = {
30062306a36Sopenharmony_ci		{  128,   0, 202 },
30162306a36Sopenharmony_ci		{  128, -24, -60 },
30262306a36Sopenharmony_ci		{  128, 238,   0 },
30362306a36Sopenharmony_ci	},
30462306a36Sopenharmony_ci	.offset = { -403, 168, -475 },
30562306a36Sopenharmony_ci	.scale = 2,
30662306a36Sopenharmony_ci};
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_ci/* Rec.709 YUV full-range to RGB limited-range */
30962306a36Sopenharmony_cistatic const struct ipu_ic_csc_params yuvf2rgbl_709 = {
31062306a36Sopenharmony_ci	.coeff = {
31162306a36Sopenharmony_ci		{  110,    0,  173, },
31262306a36Sopenharmony_ci		{  110,  -21,  -51, },
31362306a36Sopenharmony_ci		{  110,  204,    0, },
31462306a36Sopenharmony_ci	},
31562306a36Sopenharmony_ci	.offset = { -314, 176, -376, },
31662306a36Sopenharmony_ci	.scale = 2,
31762306a36Sopenharmony_ci};
31862306a36Sopenharmony_ci
31962306a36Sopenharmony_ci/* Rec.709 YUV limited-range to RGB full-range */
32062306a36Sopenharmony_cistatic const struct ipu_ic_csc_params yuvl2rgbf_709 = {
32162306a36Sopenharmony_ci	.coeff = {
32262306a36Sopenharmony_ci		{   75,    0,  115, },
32362306a36Sopenharmony_ci		{   75,  -14,  -34, },
32462306a36Sopenharmony_ci		{   75,  135,    0, },
32562306a36Sopenharmony_ci	},
32662306a36Sopenharmony_ci	.offset = { -248, 77, -289, },
32762306a36Sopenharmony_ci	.scale = 3,
32862306a36Sopenharmony_ci};
32962306a36Sopenharmony_ci
33062306a36Sopenharmony_ci/* Rec.709 YUV limited-range to RGB limited-range */
33162306a36Sopenharmony_cistatic const struct ipu_ic_csc_params yuvl2rgbl_709 = {
33262306a36Sopenharmony_ci	.coeff = {
33362306a36Sopenharmony_ci		{  128,    0,  197, },
33462306a36Sopenharmony_ci		{  128,  -23,  -59, },
33562306a36Sopenharmony_ci		{  128,  232,    0, },
33662306a36Sopenharmony_ci	},
33762306a36Sopenharmony_ci	.offset = { -394, 164, -464, },
33862306a36Sopenharmony_ci	.scale = 2,
33962306a36Sopenharmony_ci};
34062306a36Sopenharmony_ci
34162306a36Sopenharmony_cistatic const struct ipu_ic_csc_params *rgb2yuv_709[] = {
34262306a36Sopenharmony_ci	&rgbf2yuvf_709,
34362306a36Sopenharmony_ci	&rgbf2yuvl_709,
34462306a36Sopenharmony_ci	&rgbl2yuvf_709,
34562306a36Sopenharmony_ci	&rgbl2yuvl_709,
34662306a36Sopenharmony_ci};
34762306a36Sopenharmony_ci
34862306a36Sopenharmony_cistatic const struct ipu_ic_csc_params *yuv2rgb_709[] = {
34962306a36Sopenharmony_ci	&yuvf2rgbf_709,
35062306a36Sopenharmony_ci	&yuvf2rgbl_709,
35162306a36Sopenharmony_ci	&yuvl2rgbf_709,
35262306a36Sopenharmony_ci	&yuvl2rgbl_709,
35362306a36Sopenharmony_ci};
35462306a36Sopenharmony_ci
35562306a36Sopenharmony_cistatic int calc_csc_coeffs(struct ipu_ic_csc *csc)
35662306a36Sopenharmony_ci{
35762306a36Sopenharmony_ci	const struct ipu_ic_csc_params **params_tbl;
35862306a36Sopenharmony_ci	int tbl_idx;
35962306a36Sopenharmony_ci
36062306a36Sopenharmony_ci	tbl_idx = (QUANT_MAP(csc->in_cs.quant) << 1) |
36162306a36Sopenharmony_ci		QUANT_MAP(csc->out_cs.quant);
36262306a36Sopenharmony_ci
36362306a36Sopenharmony_ci	if (csc->in_cs.cs == csc->out_cs.cs) {
36462306a36Sopenharmony_ci		csc->params = (csc->in_cs.cs == IPUV3_COLORSPACE_YUV) ?
36562306a36Sopenharmony_ci			*yuv2yuv[tbl_idx] : *rgb2rgb[tbl_idx];
36662306a36Sopenharmony_ci
36762306a36Sopenharmony_ci		return 0;
36862306a36Sopenharmony_ci	}
36962306a36Sopenharmony_ci
37062306a36Sopenharmony_ci	/* YUV <-> RGB encoding is required */
37162306a36Sopenharmony_ci
37262306a36Sopenharmony_ci	switch (csc->out_cs.enc) {
37362306a36Sopenharmony_ci	case V4L2_YCBCR_ENC_601:
37462306a36Sopenharmony_ci		params_tbl = (csc->in_cs.cs == IPUV3_COLORSPACE_YUV) ?
37562306a36Sopenharmony_ci			yuv2rgb_601 : rgb2yuv_601;
37662306a36Sopenharmony_ci		break;
37762306a36Sopenharmony_ci	case V4L2_YCBCR_ENC_709:
37862306a36Sopenharmony_ci		params_tbl = (csc->in_cs.cs == IPUV3_COLORSPACE_YUV) ?
37962306a36Sopenharmony_ci			yuv2rgb_709 : rgb2yuv_709;
38062306a36Sopenharmony_ci		break;
38162306a36Sopenharmony_ci	default:
38262306a36Sopenharmony_ci		return -ENOTSUPP;
38362306a36Sopenharmony_ci	}
38462306a36Sopenharmony_ci
38562306a36Sopenharmony_ci	csc->params = *params_tbl[tbl_idx];
38662306a36Sopenharmony_ci
38762306a36Sopenharmony_ci	return 0;
38862306a36Sopenharmony_ci}
38962306a36Sopenharmony_ci
39062306a36Sopenharmony_ciint __ipu_ic_calc_csc(struct ipu_ic_csc *csc)
39162306a36Sopenharmony_ci{
39262306a36Sopenharmony_ci	return calc_csc_coeffs(csc);
39362306a36Sopenharmony_ci}
39462306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(__ipu_ic_calc_csc);
39562306a36Sopenharmony_ci
39662306a36Sopenharmony_ciint ipu_ic_calc_csc(struct ipu_ic_csc *csc,
39762306a36Sopenharmony_ci		    enum v4l2_ycbcr_encoding in_enc,
39862306a36Sopenharmony_ci		    enum v4l2_quantization in_quant,
39962306a36Sopenharmony_ci		    enum ipu_color_space in_cs,
40062306a36Sopenharmony_ci		    enum v4l2_ycbcr_encoding out_enc,
40162306a36Sopenharmony_ci		    enum v4l2_quantization out_quant,
40262306a36Sopenharmony_ci		    enum ipu_color_space out_cs)
40362306a36Sopenharmony_ci{
40462306a36Sopenharmony_ci	ipu_ic_fill_colorspace(&csc->in_cs, in_enc, in_quant, in_cs);
40562306a36Sopenharmony_ci	ipu_ic_fill_colorspace(&csc->out_cs, out_enc, out_quant, out_cs);
40662306a36Sopenharmony_ci
40762306a36Sopenharmony_ci	return __ipu_ic_calc_csc(csc);
40862306a36Sopenharmony_ci}
40962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ipu_ic_calc_csc);
410