1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2022 Rockchip Electronics Co., Ltd 4 */ 5 6 #include <common.h> 7 #include <dm.h> 8 #include <errno.h> 9 #include <i2c.h> 10 #include <linux/iopoll.h> 11 12 #include "rk628.h" 13 #include "rk628_cru.h" 14 #include "rk628_post_process.h" 15 16 #define PQ_CSC_HUE_TABLE_NUM 256 17 #define PQ_CSC_MODE_COEF_COMMENT_LEN 32 18 #define PQ_CSC_SIMPLE_MAT_PARAM_FIX_BIT_WIDTH 10 19 #define PQ_CSC_SIMPLE_MAT_PARAM_FIX_NUM (1 << PQ_CSC_SIMPLE_MAT_PARAM_FIX_BIT_WIDTH) 20 21 #define PQ_CALC_ENHANCE_BIT 6 22 /* csc convert coef fixed-point num bit width */ 23 #define PQ_CSC_PARAM_FIX_BIT_WIDTH 10 24 /* csc convert coef half fixed-point num bit width */ 25 #define PQ_CSC_PARAM_HALF_FIX_BIT_WIDTH (PQ_CSC_PARAM_FIX_BIT_WIDTH - 1) 26 /* csc convert coef fixed-point num */ 27 #define PQ_CSC_PARAM_FIX_NUM (1 << PQ_CSC_PARAM_FIX_BIT_WIDTH) 28 #define PQ_CSC_PARAM_HALF_FIX_NUM (1 << PQ_CSC_PARAM_HALF_FIX_BIT_WIDTH) 29 /* csc input param bit width */ 30 #define PQ_CSC_IN_PARAM_NORM_BIT_WIDTH 9 31 /* csc input param normalization coef */ 32 #define PQ_CSC_IN_PARAM_NORM_COEF (1 << PQ_CSC_IN_PARAM_NORM_BIT_WIDTH) 33 34 /* csc hue table range [0,255] */ 35 #define PQ_CSC_HUE_TABLE_DIV_COEF 2 36 /* csc brightness offset */ 37 #define PQ_CSC_BRIGHTNESS_OFFSET 256 38 39 /* dc coef base bit width */ 40 #define PQ_CSC_DC_COEF_BASE_BIT_WIDTH 10 41 /* input dc coef offset for 10bit data */ 42 #define PQ_CSC_DC_IN_OFFSET 64 43 /* input and output dc coef offset for 10bit data u,v */ 44 #define PQ_CSC_DC_IN_OUT_DEFAULT 512 45 /* r,g,b color temp div coef, range [-128,128] for 10bit data */ 46 #define PQ_CSC_TEMP_OFFSET_DIV_COEF 2 47 48 #define MAX(a, b) ((a) > (b) ? (a) : (b)) 49 #define MIN(a, b) ((a) < (b) ? (a) : (b)) 50 #define CLIP(x, min_v, max_v) MIN(MAX(x, min_v), max_v) 51 52 #define V4L2_COLORSPACE_BT709F 0xfe 53 #define V4L2_COLORSPACE_BT2020F 0xff 54 55 enum vop_csc_bit_depth { 56 CSC_10BIT_DEPTH, 57 CSC_13BIT_DEPTH, 58 }; 59 60 enum rk_pq_csc_mode { 61 RK_PQ_CSC_YUV2RGB_601 = 0, /* YCbCr_601 LIMIT-> RGB FULL */ 62 RK_PQ_CSC_YUV2RGB_709, /* YCbCr_709 LIMIT-> RGB FULL */ 63 RK_PQ_CSC_RGB2YUV_601, /* RGB FULL->YCbCr_601 LIMIT */ 64 RK_PQ_CSC_RGB2YUV_709, /* RGB FULL->YCbCr_709 LIMIT */ 65 RK_PQ_CSC_YUV2YUV_709_601, /* YCbCr_709 LIMIT->YCbCr_601 LIMIT */ 66 RK_PQ_CSC_YUV2YUV_601_709, /* YCbCr_601 LIMIT->YCbCr_709 LIMIT */ 67 RK_PQ_CSC_YUV2YUV, /* YCbCr LIMIT->YCbCr LIMIT */ 68 RK_PQ_CSC_YUV2RGB_601_FULL, /* YCbCr_601 FULL-> RGB FULL */ 69 RK_PQ_CSC_YUV2RGB_709_FULL, /* YCbCr_709 FULL-> RGB FULL */ 70 RK_PQ_CSC_RGB2YUV_601_FULL, /* RGB FULL->YCbCr_601 FULL */ 71 RK_PQ_CSC_RGB2YUV_709_FULL, /* RGB FULL->YCbCr_709 FULL */ 72 RK_PQ_CSC_YUV2YUV_709_601_FULL, /* YCbCr_709 FULL->YCbCr_601 FULL */ 73 RK_PQ_CSC_YUV2YUV_601_709_FULL, /* YCbCr_601 FULL->YCbCr_709 FULL */ 74 RK_PQ_CSC_YUV2YUV_FULL, /* YCbCr FULL->YCbCr FULL */ 75 RK_PQ_CSC_YUV2YUV_LIMIT2FULL, /* YCbCr LIMIT->YCbCr FULL */ 76 RK_PQ_CSC_YUV2YUV_601_709_LIMIT2FULL, /* YCbCr 601 LIMIT->YCbCr 709 FULL */ 77 RK_PQ_CSC_YUV2YUV_709_601_LIMIT2FULL, /* YCbCr 709 LIMIT->YCbCr 601 FULL */ 78 RK_PQ_CSC_YUV2YUV_FULL2LIMIT, /* YCbCr FULL->YCbCr LIMIT */ 79 RK_PQ_CSC_YUV2YUV_601_709_FULL2LIMIT, /* YCbCr 601 FULL->YCbCr 709 LIMIT */ 80 RK_PQ_CSC_YUV2YUV_709_601_FULL2LIMIT, /* YCbCr 709 FULL->YCbCr 601 LIMIT */ 81 RK_PQ_CSC_YUV2RGBL_601, /* YCbCr_601 LIMIT-> RGB LIMIT */ 82 RK_PQ_CSC_YUV2RGBL_709, /* YCbCr_709 LIMIT-> RGB LIMIT */ 83 RK_PQ_CSC_RGBL2YUV_601, /* RGB LIMIT->YCbCr_601 LIMIT */ 84 RK_PQ_CSC_RGBL2YUV_709, /* RGB LIMIT->YCbCr_709 LIMIT */ 85 RK_PQ_CSC_YUV2RGBL_601_FULL, /* YCbCr_601 FULL-> RGB LIMIT */ 86 RK_PQ_CSC_YUV2RGBL_709_FULL, /* YCbCr_709 FULL-> RGB LIMIT */ 87 RK_PQ_CSC_RGBL2YUV_601_FULL, /* RGB LIMIT->YCbCr_601 FULL */ 88 RK_PQ_CSC_RGBL2YUV_709_FULL, /* RGB LIMIT->YCbCr_709 FULL */ 89 RK_PQ_CSC_RGB2RGBL, /* RGB FULL->RGB LIMIT */ 90 RK_PQ_CSC_RGBL2RGB, /* RGB LIMIT->RGB FULL */ 91 RK_PQ_CSC_RGBL2RGBL, /* RGB LIMIT->RGB LIMIT */ 92 RK_PQ_CSC_RGB2RGB, /* RGB FULL->RGB FULL */ 93 RK_PQ_CSC_YUV2RGB_2020, /* YUV 2020 FULL->RGB 2020 FULL */ 94 RK_PQ_CSC_RGB2YUV2020_LIMIT2FULL, /* BT2020RGBLIMIT -> BT2020YUVFULL */ 95 RK_PQ_CSC_RGB2YUV2020_LIMIT, /* BT2020RGBLIMIT -> BT2020YUVLIMIT */ 96 RK_PQ_CSC_RGB2YUV2020_FULL2LIMIT, /* BT2020RGBFULL -> BT2020YUVLIMIT */ 97 RK_PQ_CSC_RGB2YUV2020_FULL, /* BT2020RGBFULL -> BT2020YUVFULL */ 98 }; 99 100 enum color_space_type { 101 OPTM_CS_E_UNKNOWN = 0, 102 OPTM_CS_E_ITU_R_BT_709 = 1, 103 OPTM_CS_E_FCC = 4, 104 OPTM_CS_E_ITU_R_BT_470_2_BG = 5, 105 OPTM_CS_E_SMPTE_170_M = 6, 106 OPTM_CS_E_SMPTE_240_M = 7, 107 OPTM_CS_E_XV_YCC_709 = OPTM_CS_E_ITU_R_BT_709, 108 OPTM_CS_E_XV_YCC_601 = 8, 109 OPTM_CS_E_RGB = 9, 110 OPTM_CS_E_XV_YCC_2020 = 10, 111 OPTM_CS_E_RGB_2020 = 11, 112 }; 113 114 struct rk_pq_csc_coef { 115 s32 csc_coef00; 116 s32 csc_coef01; 117 s32 csc_coef02; 118 s32 csc_coef10; 119 s32 csc_coef11; 120 s32 csc_coef12; 121 s32 csc_coef20; 122 s32 csc_coef21; 123 s32 csc_coef22; 124 }; 125 126 struct rk_pq_csc_ventor { 127 s32 csc_offset0; 128 s32 csc_offset1; 129 s32 csc_offset2; 130 }; 131 132 struct rk_pq_csc_dc_coef { 133 s32 csc_in_dc0; 134 s32 csc_in_dc1; 135 s32 csc_in_dc2; 136 s32 csc_out_dc0; 137 s32 csc_out_dc1; 138 s32 csc_out_dc2; 139 }; 140 141 /* color space param */ 142 struct rk_csc_colorspace_info { 143 enum color_space_type input_color_space; 144 enum color_space_type output_color_space; 145 bool in_full_range; 146 bool out_full_range; 147 }; 148 149 struct rk_csc_mode_coef { 150 enum rk_pq_csc_mode csc_mode; 151 char c_csc_comment[PQ_CSC_MODE_COEF_COMMENT_LEN]; 152 const struct rk_pq_csc_coef *pst_csc_coef; 153 const struct rk_pq_csc_dc_coef *pst_csc_dc_coef; 154 struct rk_csc_colorspace_info st_csc_color_info; 155 }; 156 157 /* 158 *CSC matrix 159 */ 160 /* xv_ycc BT.601 limit(i.e. SD) -> RGB full */ 161 static const struct rk_pq_csc_coef rk_csc_table_xv_yccsdy_cb_cr_limit_to_rgb_full = { 162 1196, 0, 1639, 163 1196, -402, -835, 164 1196, 2072, 0 165 }; 166 167 static const struct rk_pq_csc_dc_coef rk_dc_csc_table_xv_yccsdy_cb_cr_limit_to_rgb_full = { 168 -64, -512, -512, 169 0, 0, 0 170 }; 171 172 /* BT.709 limit(i.e. HD) -> RGB full */ 173 static const struct rk_pq_csc_coef rk_csc_table_hdy_cb_cr_limit_to_rgb_full = { 174 1196, 0, 1841, 175 1196, -219, -547, 176 1196, 2169, 0 177 }; 178 179 static const struct rk_pq_csc_dc_coef rk_dc_csc_table_hdy_cb_cr_limit_to_rgb_full = { 180 -64, -512, -512, 181 0, 0, 0 182 }; 183 184 /* RGB full-> YUV601 (i.e. SD) limit */ 185 static const struct rk_pq_csc_coef rk_csc_table_rgb_to_xv_yccsdy_cb_cr = { 186 262, 515, 100, 187 -151, -297, 448, 188 448, -376, -73 189 }; 190 191 static const struct rk_pq_csc_dc_coef rk_dc_csc_table_rgb_to_xv_yccsdy_cb_cr = { 192 0, 0, 0, 193 64, 512, 512 194 }; 195 196 /* RGB full-> YUV709 (i.e. SD) limit */ 197 static const struct rk_pq_csc_coef rk_csc_table_rgb_to_hdy_cb_cr = { 198 186, 627, 63, 199 -103, -346, 448, 200 448, -407, -41 201 }; 202 203 static const struct rk_pq_csc_dc_coef rk_dc_csc_table_rgb_to_hdy_cb_cr = { 204 0, 0, 0, 205 64, 512, 512 206 }; 207 208 /* BT.709 (i.e. HD) -> to xv_ycc BT.601 (i.e. SD) */ 209 static const struct rk_pq_csc_coef rk_csc_table_hdy_cb_cr_to_xv_yccsdy_cb_cr = { 210 1024, 104, 201, 211 0, 1014, -113, 212 0, -74, 1007 213 }; 214 215 static const struct rk_pq_csc_dc_coef rk_dc_csc_table_hdy_cb_cr_to_xv_yccsdy_cb_cr = { 216 -64, -512, -512, 217 64, 512, 512 218 }; 219 220 static const struct rk_pq_csc_dc_coef rk_dc_csc_table_hdy_cb_cr_full_to_xv_yccsdy_cb_cr_full = { 221 0, -512, -512, 222 0, 512, 512 223 }; 224 225 /* xv_ycc BT.601 (i.e. SD) -> to BT.709 (i.e. HD) */ 226 static const struct rk_pq_csc_coef rk_csc_table_xv_yccsdy_cb_cr_to_hdy_cb_cr = { 227 1024, -121, -218, 228 0, 1043, 117, 229 0, 77, 1050 230 }; 231 232 static const struct rk_pq_csc_dc_coef rk_dc_csc_table_xv_yccsdy_cb_cr_to_hdy_cb_cr = { 233 -64, -512, -512, 234 64, 512, 512 235 }; 236 237 /* xv_ycc BT.601 full(i.e. SD) -> RGB full */ 238 static const struct rk_pq_csc_coef rk_csc_table_xv_yccsdy_cb_cr_to_rgb_full = { 239 1024, 0, 1436, 240 1024, -352, -731, 241 1024, 1815, 0 242 }; 243 244 static const struct rk_pq_csc_dc_coef rk_dc_csc_table_xv_yccsdy_cb_cr_to_rgb_full = { 245 0, -512, -512, 246 0, 0, 0 247 }; 248 249 /* BT.709 full(i.e. HD) -> RGB full */ 250 static const struct rk_pq_csc_coef rk_csc_table_hdy_cb_cr_to_rgb_full = { 251 1024, 0, 1613, 252 1024, -192, -479, 253 1024, 1900, 0 254 }; 255 256 static const struct rk_pq_csc_dc_coef rk_dc_csc_table_hdy_cb_cr_to_rgb_full = { 257 0, -512, -512, 258 0, 0, 0 259 }; 260 261 /* RGB full-> YUV601 full(i.e. SD) */ 262 static const struct rk_pq_csc_coef rk_csc_table_rgb_to_xv_yccsdy_cb_cr_full = { 263 306, 601, 117, 264 -173, -339, 512, 265 512, -429, -83 266 }; 267 268 static const struct rk_pq_csc_dc_coef rk_dc_csc_table_rgb_to_xv_yccsdy_cb_cr_full = { 269 0, 0, 0, 270 0, 512, 512 271 }; 272 273 /* RGB full-> YUV709 full (i.e. SD) */ 274 static const struct rk_pq_csc_coef rk_csc_table_rgb_to_hdy_cb_cr_full = { 275 218, 732, 74, 276 -117, -395, 512, 277 512, -465, -47 278 }; 279 280 static const struct rk_pq_csc_dc_coef rk_dc_csc_table_rgb_to_hdy_cb_cr_full = { 281 0, 0, 0, 282 0, 512, 512 283 }; 284 285 /* limit -> full */ 286 static const struct rk_pq_csc_coef rk_csc_table_identity_y_cb_cr_limit_to_y_cb_cr_full = { 287 1196, 0, 0, 288 0, 1169, 0, 289 0, 0, 1169 290 }; 291 292 static const struct rk_pq_csc_dc_coef rk_dc_csc_table_identity_y_cb_cr_limit_to_y_cb_cr_full = { 293 -64, -512, -512, 294 0, 512, 512 295 }; 296 297 /* 601 limit -> 709 full */ 298 static const struct rk_pq_csc_coef rk_csc_table_identity_601_limit_to_709_full = { 299 1196, -138, -249, 300 0, 1191, 134, 301 0, 88, 1199 302 }; 303 304 static const struct rk_pq_csc_dc_coef rk_dc_csc_table_identity_601_limit_to_709_full = { 305 -64, -512, -512, 306 0, 512, 512 307 }; 308 309 /* 709 limit -> 601 full */ 310 static const struct rk_pq_csc_coef rk_csc_table_identity_709_limit_to_601_full = { 311 1196, 119, 229, 312 0, 1157, -129, 313 0, -85, 1150 314 }; 315 316 static const struct rk_pq_csc_dc_coef rk_dc_csc_table_identity_709_limit_to_601_full = { 317 -64, -512, -512, 318 0, 512, 512 319 }; 320 321 /* full -> limit */ 322 static const struct rk_pq_csc_coef rk_csc_table_identity_y_cb_cr_full_to_y_cb_cr_limit = { 323 877, 0, 0, 324 0, 897, 0, 325 0, 0, 897 326 }; 327 328 static const struct rk_pq_csc_dc_coef rk_dc_csc_table_identity_y_cb_cr_full_to_y_cb_cr_limit = { 329 0, -512, -512, 330 64, 512, 512 331 }; 332 333 /* 601 full -> 709 limit */ 334 static const struct rk_pq_csc_coef rk_csc_table_identity_y_cb_cr_601_full_to_y_cb_cr_709_limit = { 335 877, -106, -191, 336 0, 914, 103, 337 0, 67, 920 338 }; 339 340 static const struct rk_pq_csc_dc_coef 341 rk_dc_csc_table_identity_y_cb_cr_601_full_to_y_cb_cr_709_limit = { 342 0, -512, -512, 343 64, 512, 512 344 }; 345 346 /* 709 full -> 601 limit */ 347 static const struct rk_pq_csc_coef rk_csc_table_identity_y_cb_cr_709_full_to_y_cb_cr_601_limit = { 348 877, 91, 176, 349 0, 888, -99, 350 0, -65, 882 351 }; 352 353 static const struct rk_pq_csc_dc_coef 354 rk_dc_csc_table_identity_y_cb_cr_709_full_to_y_cb_cr_601_limit = { 355 0, -512, -512, 356 64, 512, 512 357 }; 358 359 /* xv_ycc BT.601 limit(i.e. SD) -> RGB limit */ 360 static const struct rk_pq_csc_coef rk_csc_table_xv_yccsdy_cb_cr_limit_to_rgb_limit = { 361 1024, 0, 1404, 362 1024, -344, -715, 363 1024, 1774, 0 364 }; 365 366 static const struct rk_pq_csc_dc_coef rk_dc_csc_table_xv_yccsdy_cb_cr_limit_to_rgb_limit = { 367 -64, -512, -512, 368 64, 64, 64 369 }; 370 371 /* BT.709 limit(i.e. HD) -> RGB limit */ 372 static const struct rk_pq_csc_coef rk_csc_table_hdy_cb_cr_limit_to_rgb_limit = { 373 1024, 0, 1577, 374 1024, -188, -469, 375 1024, 1858, 0 376 }; 377 378 static const struct rk_pq_csc_dc_coef rk_dc_csc_table_hdy_cb_cr_limit_to_rgb_limit = { 379 -64, -512, -512, 380 64, 64, 64 381 }; 382 383 /* RGB limit-> YUV601 (i.e. SD) limit */ 384 static const struct rk_pq_csc_coef rk_csc_table_rgb_limit_to_xv_yccsdy_cb_cr = { 385 306, 601, 117, 386 -177, -347, 524, 387 524, -439, -85 388 }; 389 390 static const struct rk_pq_csc_dc_coef rk_dc_csc_table_rgb_limit_to_xv_yccsdy_cb_cr = { 391 -64, -64, -64, 392 64, 512, 512 393 }; 394 395 /* RGB limit -> YUV709 (i.e. SD) limit */ 396 static const struct rk_pq_csc_coef rk_csc_table_rgb_limit_to_hdy_cb_cr = { 397 218, 732, 74, 398 -120, -404, 524, 399 524, -476, -48 400 }; 401 402 static const struct rk_pq_csc_dc_coef rk_dc_csc_table_rgb_limit_to_hdy_cb_cr = { 403 -64, -64, -64, 404 64, 512, 512 405 }; 406 407 /* xv_ycc BT.601 full(i.e. SD) -> RGB limit */ 408 static const struct rk_pq_csc_coef rk_csc_table_xv_yccsdy_cb_cr_to_rgb_limit = { 409 877, 0, 1229, 410 877, -302, -626, 411 877, 1554, 0 412 }; 413 414 static const struct rk_pq_csc_dc_coef rk_dc_csc_table_xv_yccsdy_cb_cr_to_rgb_limit = { 415 0, -512, -512, 416 64, 64, 64 417 }; 418 419 /* BT.709 full(i.e. HD) -> RGB limit */ 420 static const struct rk_pq_csc_coef rk_csc_table_hdy_cb_cr_to_rgb_limit = { 421 877, 0, 1381, 422 877, -164, -410, 423 877, 1627, 0 424 }; 425 426 static const struct rk_pq_csc_dc_coef rk_dc_csc_table_hdy_cb_cr_to_rgb_limit = { 427 0, -512, -512, 428 64, 64, 64 429 }; 430 431 /* RGB limit-> YUV601 full(i.e. SD) */ 432 static const struct rk_pq_csc_coef rk_csc_table_rgb_limit_to_xv_yccsdy_cb_cr_full = { 433 358, 702, 136, 434 -202, -396, 598, 435 598, -501, -97 436 }; 437 438 static const struct rk_pq_csc_dc_coef rk_dc_csc_table_rgb_limit_to_xv_yccsdy_cb_cr_full = { 439 -64, -64, -64, 440 0, 512, 512 441 }; 442 443 /* RGB limit-> YUV709 full (i.e. SD) */ 444 static const struct rk_pq_csc_coef rk_csc_table_rgb_limit_to_hdy_cb_cr_full = { 445 254, 855, 86, 446 -137, -461, 598, 447 598, -543, -55 448 }; 449 450 static const struct rk_pq_csc_dc_coef rk_dc_csc_table_rgb_limit_to_hdy_cb_cr_full = { 451 -64, -64, -64, 452 0, 512, 512 453 }; 454 455 /* RGB full -> RGB limit */ 456 static const struct rk_pq_csc_coef rk_csc_table_identity_rgb_to_rgb_limit = { 457 877, 0, 0, 458 0, 877, 0, 459 0, 0, 877 460 }; 461 462 static const struct rk_pq_csc_dc_coef rk_dc_csc_table_identity_rgb_to_rgb_limit = { 463 0, 0, 0, 464 64, 64, 64 465 }; 466 467 /* RGB limit -> RGB full */ 468 static const struct rk_pq_csc_coef rk_csc_table_identity_rgb_limit_to_rgb = { 469 1196, 0, 0, 470 0, 1196, 0, 471 0, 0, 1196 472 }; 473 474 static const struct rk_pq_csc_dc_coef rk_dc_csc_table_identity_rgb_limit_to_rgb = { 475 -64, -64, -64, 476 0, 0, 0 477 }; 478 479 /* RGB limit/full -> RGB limit/full */ 480 static const struct rk_pq_csc_coef rk_csc_table_identity_rgb_to_rgb = { 481 1024, 0, 0, 482 0, 1024, 0, 483 0, 0, 1024 484 }; 485 486 static const struct rk_pq_csc_dc_coef rk_dc_csc_table_identity_rgb_to_rgb1 = { 487 -64, -64, -64, 488 64, 64, 64 489 }; 490 491 static const struct rk_pq_csc_dc_coef rk_dc_csc_table_identity_rgb_to_rgb2 = { 492 0, 0, 0, 493 0, 0, 0 494 }; 495 496 static const struct rk_pq_csc_coef rk_csc_table_identity_yuv_to_rgb_2020 = { 497 1024, 0, 1510, 498 1024, -169, -585, 499 1024, 1927, 0 500 }; 501 502 static const struct rk_pq_csc_dc_coef rk_dc_csc_table_identity_yuv_to_rgb_2020 = { 503 0, -512, -512, 504 0, 0, 0 505 }; 506 507 /* 2020 RGB LIMIT ->YUV LIMIT */ 508 static const struct rk_pq_csc_coef rk_csc_table_identity_rgb_limit_to_yuv_limit_2020 = { 509 269, 694, 61, 510 -146, -377, 524, 511 524, -482, -42 512 }; 513 514 static const struct rk_pq_csc_dc_coef rk_dc_csc_table_identity_rgb_limit_to_yuv_limit_2020 = { 515 -64, -64, -64, 516 64, 512, 512 517 }; 518 519 /* 2020 RGB LIMIT ->YUV FULL */ 520 static const struct rk_pq_csc_coef rk_csc_table_identity_rgb_limit_to_yuv_full_2020 = { 521 314, 811, 71, 522 -167, -431, 598, 523 598, -550, -48 524 }; 525 526 static const struct rk_pq_csc_dc_coef rk_dc_csc_table_identity_rgb_limit_to_yuv_full_2020 = { 527 -64, -64, -64, 528 0, 512, 512 529 }; 530 531 /* 2020 RGB FULL ->YUV LIMIT */ 532 static const struct rk_pq_csc_coef rk_csc_table_identity_rgb_full_to_yuv_limit_2020 = { 533 230, 595, 52, 534 -125, -323, 448, 535 448, -412, -36 536 }; 537 538 static const struct rk_pq_csc_dc_coef rk_dc_csc_table_identity_rgb_full_to_yuv_limit_2020 = { 539 0, 0, 0, 540 64, 512, 512 541 }; 542 543 /* 2020 RGB FULL ->YUV FULL */ 544 static const struct rk_pq_csc_coef rk_csc_table_identity_rgb_full_to_yuv_full_2020 = { 545 269, 694, 61, 546 -143, -369, 512, 547 512, -471, -41 548 }; 549 550 static const struct rk_pq_csc_dc_coef rk_dc_csc_table_identity_rgb_full_to_yuv_full_2020 = { 551 0, 0, 0, 552 0, 512, 512 553 }; 554 555 /* identity matrix */ 556 static const struct rk_pq_csc_coef rk_csc_table_identity_y_cb_cr_to_y_cb_cr = { 557 1024, 0, 0, 558 0, 1024, 0, 559 0, 0, 1024 560 }; 561 562 /* 563 *CSC Param Struct 564 */ 565 static const struct rk_csc_mode_coef g_mode_csc_coef[] = { 566 { 567 RK_PQ_CSC_YUV2RGB_601, "YUV601 L->RGB F", 568 &rk_csc_table_xv_yccsdy_cb_cr_limit_to_rgb_full, 569 &rk_dc_csc_table_xv_yccsdy_cb_cr_limit_to_rgb_full, 570 { 571 OPTM_CS_E_XV_YCC_601, OPTM_CS_E_RGB, false, true 572 } 573 }, 574 { 575 RK_PQ_CSC_YUV2RGB_709, "YUV709 L->RGB F", 576 &rk_csc_table_hdy_cb_cr_limit_to_rgb_full, 577 &rk_dc_csc_table_hdy_cb_cr_limit_to_rgb_full, 578 { 579 OPTM_CS_E_ITU_R_BT_709, OPTM_CS_E_RGB, false, true 580 } 581 }, 582 { 583 RK_PQ_CSC_RGB2YUV_601, "RGB F->YUV601 L", 584 &rk_csc_table_rgb_to_xv_yccsdy_cb_cr, 585 &rk_dc_csc_table_rgb_to_xv_yccsdy_cb_cr, 586 { 587 OPTM_CS_E_RGB, OPTM_CS_E_XV_YCC_601, true, false 588 } 589 }, 590 { 591 RK_PQ_CSC_RGB2YUV_709, "RGB F->YUV709 L", 592 &rk_csc_table_rgb_to_hdy_cb_cr, 593 &rk_dc_csc_table_rgb_to_hdy_cb_cr, 594 { 595 OPTM_CS_E_RGB, OPTM_CS_E_ITU_R_BT_709, true, false 596 } 597 }, 598 { 599 RK_PQ_CSC_YUV2YUV_709_601, "YUV709 L->YUV601 L", 600 &rk_csc_table_hdy_cb_cr_to_xv_yccsdy_cb_cr, 601 &rk_dc_csc_table_hdy_cb_cr_to_xv_yccsdy_cb_cr, 602 { 603 OPTM_CS_E_ITU_R_BT_709, OPTM_CS_E_XV_YCC_601, false, false 604 } 605 }, 606 { 607 RK_PQ_CSC_YUV2YUV_601_709, "YUV601 L->YUV709 L", 608 &rk_csc_table_xv_yccsdy_cb_cr_to_hdy_cb_cr, 609 &rk_dc_csc_table_xv_yccsdy_cb_cr_to_hdy_cb_cr, 610 { 611 OPTM_CS_E_XV_YCC_601, OPTM_CS_E_ITU_R_BT_709, false, false 612 } 613 }, 614 { 615 RK_PQ_CSC_YUV2YUV, "YUV L->YUV L", 616 &rk_csc_table_xv_yccsdy_cb_cr_to_hdy_cb_cr, 617 &rk_dc_csc_table_xv_yccsdy_cb_cr_to_hdy_cb_cr, 618 { 619 OPTM_CS_E_ITU_R_BT_709, OPTM_CS_E_ITU_R_BT_709, false, false 620 } 621 }, 622 { 623 RK_PQ_CSC_YUV2RGB_601_FULL, "YUV601 F->RGB F", 624 &rk_csc_table_xv_yccsdy_cb_cr_to_rgb_full, 625 &rk_dc_csc_table_xv_yccsdy_cb_cr_to_rgb_full, 626 { 627 OPTM_CS_E_XV_YCC_601, OPTM_CS_E_RGB, true, true 628 } 629 }, 630 { 631 RK_PQ_CSC_YUV2RGB_709_FULL, "YUV709 F->RGB F", 632 &rk_csc_table_hdy_cb_cr_to_rgb_full, 633 &rk_dc_csc_table_hdy_cb_cr_to_rgb_full, 634 { 635 OPTM_CS_E_ITU_R_BT_709, OPTM_CS_E_RGB, true, true 636 } 637 }, 638 { 639 RK_PQ_CSC_RGB2YUV_601_FULL, "RGB F->YUV601 F", 640 &rk_csc_table_rgb_to_xv_yccsdy_cb_cr_full, 641 &rk_dc_csc_table_rgb_to_xv_yccsdy_cb_cr_full, 642 { 643 OPTM_CS_E_RGB, OPTM_CS_E_XV_YCC_601, true, true 644 } 645 }, 646 { 647 RK_PQ_CSC_RGB2YUV_709_FULL, "RGB F->YUV709 F", 648 &rk_csc_table_rgb_to_hdy_cb_cr_full, 649 &rk_dc_csc_table_rgb_to_hdy_cb_cr_full, 650 { 651 OPTM_CS_E_RGB, OPTM_CS_E_ITU_R_BT_709, true, true 652 } 653 }, 654 { 655 RK_PQ_CSC_YUV2YUV_709_601_FULL, "YUV709 F->YUV601 F", 656 &rk_csc_table_hdy_cb_cr_to_xv_yccsdy_cb_cr, 657 &rk_dc_csc_table_hdy_cb_cr_full_to_xv_yccsdy_cb_cr_full, 658 { 659 OPTM_CS_E_ITU_R_BT_709, OPTM_CS_E_XV_YCC_601, true, true 660 } 661 }, 662 { 663 RK_PQ_CSC_YUV2YUV_601_709_FULL, "YUV601 F->YUV709 F", 664 &rk_csc_table_xv_yccsdy_cb_cr_to_hdy_cb_cr, 665 &rk_dc_csc_table_hdy_cb_cr_full_to_xv_yccsdy_cb_cr_full, 666 { 667 OPTM_CS_E_XV_YCC_601, OPTM_CS_E_ITU_R_BT_709, true, true 668 } 669 }, 670 { 671 RK_PQ_CSC_YUV2YUV_FULL, "YUV F->YUV F", 672 &rk_csc_table_identity_y_cb_cr_to_y_cb_cr, 673 &rk_dc_csc_table_hdy_cb_cr_full_to_xv_yccsdy_cb_cr_full, 674 { 675 OPTM_CS_E_ITU_R_BT_709, OPTM_CS_E_ITU_R_BT_709, true, true 676 } 677 }, 678 { 679 RK_PQ_CSC_YUV2YUV_LIMIT2FULL, "YUV L->YUV F", 680 &rk_csc_table_identity_y_cb_cr_limit_to_y_cb_cr_full, 681 &rk_dc_csc_table_identity_y_cb_cr_limit_to_y_cb_cr_full, 682 { 683 OPTM_CS_E_ITU_R_BT_709, OPTM_CS_E_ITU_R_BT_709, false, true 684 } 685 }, 686 { 687 RK_PQ_CSC_YUV2YUV_601_709_LIMIT2FULL, "YUV601 L->YUV709 F", 688 &rk_csc_table_identity_601_limit_to_709_full, 689 &rk_dc_csc_table_identity_601_limit_to_709_full, 690 { 691 OPTM_CS_E_XV_YCC_601, OPTM_CS_E_ITU_R_BT_709, false, true 692 } 693 }, 694 { 695 RK_PQ_CSC_YUV2YUV_709_601_LIMIT2FULL, "YUV709 L->YUV601 F", 696 &rk_csc_table_identity_709_limit_to_601_full, 697 &rk_dc_csc_table_identity_709_limit_to_601_full, 698 { 699 OPTM_CS_E_ITU_R_BT_709, OPTM_CS_E_XV_YCC_601, false, true 700 } 701 }, 702 { 703 RK_PQ_CSC_YUV2YUV_FULL2LIMIT, "YUV F->YUV L", 704 &rk_csc_table_identity_y_cb_cr_full_to_y_cb_cr_limit, 705 &rk_dc_csc_table_identity_y_cb_cr_full_to_y_cb_cr_limit, 706 { 707 OPTM_CS_E_ITU_R_BT_709, OPTM_CS_E_ITU_R_BT_709, true, false 708 } 709 }, 710 { 711 RK_PQ_CSC_YUV2YUV_601_709_FULL2LIMIT, "YUV601 F->YUV709 L", 712 &rk_csc_table_identity_y_cb_cr_601_full_to_y_cb_cr_709_limit, 713 &rk_dc_csc_table_identity_y_cb_cr_601_full_to_y_cb_cr_709_limit, 714 { 715 OPTM_CS_E_XV_YCC_601, OPTM_CS_E_ITU_R_BT_709, true, false 716 } 717 }, 718 { 719 RK_PQ_CSC_YUV2YUV_709_601_FULL2LIMIT, "YUV709 F->YUV601 L", 720 &rk_csc_table_identity_y_cb_cr_709_full_to_y_cb_cr_601_limit, 721 &rk_dc_csc_table_identity_y_cb_cr_709_full_to_y_cb_cr_601_limit, 722 { 723 OPTM_CS_E_ITU_R_BT_709, OPTM_CS_E_XV_YCC_601, true, false 724 } 725 }, 726 { 727 RK_PQ_CSC_YUV2RGBL_601, "YUV601 L->RGB L", 728 &rk_csc_table_xv_yccsdy_cb_cr_limit_to_rgb_limit, 729 &rk_dc_csc_table_xv_yccsdy_cb_cr_limit_to_rgb_limit, 730 { 731 OPTM_CS_E_XV_YCC_601, OPTM_CS_E_RGB, false, false 732 } 733 }, 734 { 735 RK_PQ_CSC_YUV2RGBL_709, "YUV709 L->RGB L", 736 &rk_csc_table_hdy_cb_cr_limit_to_rgb_limit, 737 &rk_dc_csc_table_hdy_cb_cr_limit_to_rgb_limit, 738 { 739 OPTM_CS_E_ITU_R_BT_709, OPTM_CS_E_RGB, false, false 740 } 741 }, 742 { 743 RK_PQ_CSC_RGBL2YUV_601, "RGB L->YUV601 L", 744 &rk_csc_table_rgb_limit_to_xv_yccsdy_cb_cr, 745 &rk_dc_csc_table_rgb_limit_to_xv_yccsdy_cb_cr, 746 { 747 OPTM_CS_E_RGB, OPTM_CS_E_XV_YCC_601, false, false 748 } 749 }, 750 { 751 RK_PQ_CSC_RGBL2YUV_709, "RGB L->YUV709 L", 752 &rk_csc_table_rgb_limit_to_hdy_cb_cr, 753 &rk_dc_csc_table_rgb_limit_to_hdy_cb_cr, 754 { 755 OPTM_CS_E_RGB, OPTM_CS_E_ITU_R_BT_709, false, false 756 } 757 }, 758 { 759 RK_PQ_CSC_YUV2RGBL_601_FULL, "YUV601 F->RGB L", 760 &rk_csc_table_xv_yccsdy_cb_cr_to_rgb_limit, 761 &rk_dc_csc_table_xv_yccsdy_cb_cr_to_rgb_limit, 762 { 763 OPTM_CS_E_XV_YCC_601, OPTM_CS_E_RGB, true, false 764 } 765 }, 766 { 767 RK_PQ_CSC_YUV2RGBL_709_FULL, "YUV709 F->RGB L", 768 &rk_csc_table_hdy_cb_cr_to_rgb_limit, 769 &rk_dc_csc_table_hdy_cb_cr_to_rgb_limit, 770 { 771 OPTM_CS_E_ITU_R_BT_709, OPTM_CS_E_RGB, true, false 772 } 773 }, 774 { 775 RK_PQ_CSC_RGBL2YUV_601_FULL, "RGB L->YUV601 F", 776 &rk_csc_table_rgb_limit_to_xv_yccsdy_cb_cr_full, 777 &rk_dc_csc_table_rgb_limit_to_xv_yccsdy_cb_cr_full, 778 { 779 OPTM_CS_E_RGB, OPTM_CS_E_XV_YCC_601, false, true 780 } 781 }, 782 { 783 RK_PQ_CSC_RGBL2YUV_709_FULL, "RGB L->YUV709 F", 784 &rk_csc_table_rgb_limit_to_hdy_cb_cr_full, 785 &rk_dc_csc_table_rgb_limit_to_hdy_cb_cr_full, 786 { 787 OPTM_CS_E_RGB, OPTM_CS_E_ITU_R_BT_709, false, true 788 } 789 }, 790 { 791 RK_PQ_CSC_RGB2RGBL, "RGB F->RGB L", 792 &rk_csc_table_identity_rgb_to_rgb_limit, 793 &rk_dc_csc_table_identity_rgb_to_rgb_limit, 794 { 795 OPTM_CS_E_RGB, OPTM_CS_E_RGB, true, false 796 } 797 }, 798 { 799 RK_PQ_CSC_RGBL2RGB, "RGB L->RGB F", 800 &rk_csc_table_identity_rgb_limit_to_rgb, 801 &rk_dc_csc_table_identity_rgb_limit_to_rgb, 802 { 803 OPTM_CS_E_RGB, OPTM_CS_E_RGB, false, true 804 } 805 }, 806 { 807 RK_PQ_CSC_RGBL2RGBL, "RGB L->RGB L", 808 &rk_csc_table_identity_rgb_to_rgb, 809 &rk_dc_csc_table_identity_rgb_to_rgb1, 810 { 811 OPTM_CS_E_RGB, OPTM_CS_E_RGB, false, false 812 } 813 }, 814 { 815 RK_PQ_CSC_RGB2RGB, "RGB F->RGB F", 816 &rk_csc_table_identity_rgb_to_rgb, 817 &rk_dc_csc_table_identity_rgb_to_rgb2, 818 { 819 OPTM_CS_E_RGB, OPTM_CS_E_RGB, true, true 820 } 821 }, 822 { 823 RK_PQ_CSC_YUV2RGB_2020, "YUV2020 F->RGB2020 F", 824 &rk_csc_table_identity_yuv_to_rgb_2020, 825 &rk_dc_csc_table_identity_yuv_to_rgb_2020, 826 { 827 OPTM_CS_E_XV_YCC_2020, OPTM_CS_E_RGB_2020, true, true 828 } 829 }, 830 { 831 RK_PQ_CSC_RGB2YUV2020_LIMIT2FULL, "RGB2020 L->YUV2020 F", 832 &rk_csc_table_identity_rgb_limit_to_yuv_full_2020, 833 &rk_dc_csc_table_identity_rgb_limit_to_yuv_full_2020, 834 { 835 OPTM_CS_E_RGB_2020, OPTM_CS_E_XV_YCC_2020, false, true 836 } 837 }, 838 { 839 RK_PQ_CSC_RGB2YUV2020_LIMIT, "RGB2020 L->YUV2020 L", 840 &rk_csc_table_identity_rgb_limit_to_yuv_limit_2020, 841 &rk_dc_csc_table_identity_rgb_limit_to_yuv_limit_2020, 842 { 843 OPTM_CS_E_RGB_2020, OPTM_CS_E_XV_YCC_2020, false, false 844 } 845 }, 846 { 847 RK_PQ_CSC_RGB2YUV2020_FULL2LIMIT, "RGB2020 F->YUV2020 L", 848 &rk_csc_table_identity_rgb_full_to_yuv_limit_2020, 849 &rk_dc_csc_table_identity_rgb_full_to_yuv_limit_2020, 850 { 851 OPTM_CS_E_RGB_2020, OPTM_CS_E_XV_YCC_2020, true, false 852 } 853 }, 854 { 855 RK_PQ_CSC_RGB2YUV2020_FULL, "RGB2020 F->YUV2020 F", 856 &rk_csc_table_identity_rgb_full_to_yuv_full_2020, 857 &rk_dc_csc_table_identity_rgb_full_to_yuv_full_2020, 858 { 859 OPTM_CS_E_RGB_2020, OPTM_CS_E_XV_YCC_2020, true, true 860 } 861 }, 862 { 863 RK_PQ_CSC_YUV2YUV, "YUV 601 L->YUV 601 L", 864 &rk_csc_table_xv_yccsdy_cb_cr_to_hdy_cb_cr, 865 &rk_dc_csc_table_xv_yccsdy_cb_cr_to_hdy_cb_cr, 866 { 867 OPTM_CS_E_XV_YCC_601, OPTM_CS_E_XV_YCC_601, false, false 868 } 869 }, 870 { 871 RK_PQ_CSC_YUV2YUV_FULL, "YUV 601 F->YUV 601 F", 872 &rk_csc_table_identity_y_cb_cr_to_y_cb_cr, 873 &rk_dc_csc_table_hdy_cb_cr_full_to_xv_yccsdy_cb_cr_full, 874 { 875 OPTM_CS_E_XV_YCC_601, OPTM_CS_E_XV_YCC_601, true, true 876 } 877 }, 878 { 879 RK_PQ_CSC_YUV2YUV_LIMIT2FULL, "YUV 601 L->YUV 601 F", 880 &rk_csc_table_identity_y_cb_cr_limit_to_y_cb_cr_full, 881 &rk_dc_csc_table_identity_y_cb_cr_limit_to_y_cb_cr_full, 882 { 883 OPTM_CS_E_XV_YCC_601, OPTM_CS_E_XV_YCC_601, false, true 884 } 885 }, 886 { 887 RK_PQ_CSC_YUV2YUV_FULL2LIMIT, "YUV 601 F->YUV 601 L", 888 &rk_csc_table_identity_y_cb_cr_full_to_y_cb_cr_limit, 889 &rk_dc_csc_table_identity_y_cb_cr_full_to_y_cb_cr_limit, 890 { 891 OPTM_CS_E_XV_YCC_601, OPTM_CS_E_XV_YCC_601, true, false 892 } 893 }, 894 { 895 RK_PQ_CSC_YUV2YUV, "YUV 2020 L->YUV 2020 L", 896 &rk_csc_table_xv_yccsdy_cb_cr_to_hdy_cb_cr, 897 &rk_dc_csc_table_xv_yccsdy_cb_cr_to_hdy_cb_cr, 898 { 899 OPTM_CS_E_XV_YCC_2020, OPTM_CS_E_XV_YCC_2020, false, false 900 } 901 }, 902 { 903 RK_PQ_CSC_YUV2YUV_FULL, "YUV 2020 F->YUV 2020 F", 904 &rk_csc_table_identity_y_cb_cr_to_y_cb_cr, 905 &rk_dc_csc_table_hdy_cb_cr_full_to_xv_yccsdy_cb_cr_full, 906 { 907 OPTM_CS_E_XV_YCC_2020, OPTM_CS_E_XV_YCC_2020, true, true 908 } 909 }, 910 { 911 RK_PQ_CSC_YUV2YUV_LIMIT2FULL, "YUV 2020 L->YUV 2020 F", 912 &rk_csc_table_identity_y_cb_cr_limit_to_y_cb_cr_full, 913 &rk_dc_csc_table_identity_y_cb_cr_limit_to_y_cb_cr_full, 914 { 915 OPTM_CS_E_XV_YCC_2020, OPTM_CS_E_XV_YCC_2020, false, true 916 } 917 }, 918 { 919 RK_PQ_CSC_YUV2YUV_FULL2LIMIT, "YUV 2020 F->YUV 2020 L", 920 &rk_csc_table_identity_y_cb_cr_full_to_y_cb_cr_limit, 921 &rk_dc_csc_table_identity_y_cb_cr_full_to_y_cb_cr_limit, 922 { 923 OPTM_CS_E_XV_YCC_2020, OPTM_CS_E_XV_YCC_2020, true, false 924 } 925 }, 926 { 927 RK_PQ_CSC_RGB2RGBL, "RGB 2020 F->RGB 2020 L", 928 &rk_csc_table_identity_rgb_to_rgb_limit, 929 &rk_dc_csc_table_identity_rgb_to_rgb_limit, 930 { 931 OPTM_CS_E_RGB_2020, OPTM_CS_E_RGB_2020, true, false 932 } 933 }, 934 { 935 RK_PQ_CSC_RGBL2RGB, "RGB 2020 L->RGB 2020 F", 936 &rk_csc_table_identity_rgb_limit_to_rgb, 937 &rk_dc_csc_table_identity_rgb_limit_to_rgb, 938 { 939 OPTM_CS_E_RGB_2020, OPTM_CS_E_RGB_2020, false, true 940 } 941 }, 942 { 943 RK_PQ_CSC_RGBL2RGBL, "RGB 2020 L->RGB 2020 L", 944 &rk_csc_table_identity_rgb_to_rgb, 945 &rk_dc_csc_table_identity_rgb_to_rgb1, 946 { 947 OPTM_CS_E_RGB_2020, OPTM_CS_E_RGB_2020, false, false 948 } 949 }, 950 { 951 RK_PQ_CSC_RGB2RGB, "RGB 2020 F->RGB 2020 F", 952 &rk_csc_table_identity_rgb_to_rgb, 953 &rk_dc_csc_table_identity_rgb_to_rgb2, 954 { 955 OPTM_CS_E_RGB_2020, OPTM_CS_E_RGB_2020, true, true 956 } 957 }, 958 }; 959 960 enum vop_csc_format { 961 CSC_BT601L, 962 CSC_BT709L, 963 CSC_BT601F, 964 CSC_BT2020, 965 CSC_BT709L_13BIT, 966 CSC_BT709F_13BIT, 967 CSC_BT2020L_13BIT, 968 CSC_BT2020F_13BIT, 969 }; 970 971 enum vop_csc_mode { 972 CSC_RGB, 973 CSC_YUV, 974 }; 975 976 struct csc_mapping { 977 enum vop_csc_format csc_format; 978 enum color_space_type rgb_color_space; 979 enum color_space_type yuv_color_space; 980 bool rgb_full_range; 981 bool yuv_full_range; 982 }; 983 984 static const struct csc_mapping csc_mapping_table[] = { 985 { 986 CSC_BT601L, 987 OPTM_CS_E_RGB, 988 OPTM_CS_E_XV_YCC_601, 989 true, 990 false, 991 }, 992 { 993 CSC_BT709L, 994 OPTM_CS_E_RGB, 995 OPTM_CS_E_XV_YCC_709, 996 true, 997 false, 998 }, 999 { 1000 CSC_BT601F, 1001 OPTM_CS_E_RGB, 1002 OPTM_CS_E_XV_YCC_601, 1003 true, 1004 true, 1005 }, 1006 { 1007 CSC_BT2020, 1008 OPTM_CS_E_RGB_2020, 1009 OPTM_CS_E_XV_YCC_2020, 1010 true, 1011 true, 1012 }, 1013 { 1014 CSC_BT709L_13BIT, 1015 OPTM_CS_E_RGB, 1016 OPTM_CS_E_XV_YCC_709, 1017 true, 1018 false, 1019 }, 1020 { 1021 CSC_BT709F_13BIT, 1022 OPTM_CS_E_RGB, 1023 OPTM_CS_E_XV_YCC_709, 1024 true, 1025 true, 1026 }, 1027 { 1028 CSC_BT2020L_13BIT, 1029 OPTM_CS_E_RGB_2020, 1030 OPTM_CS_E_XV_YCC_2020, 1031 true, 1032 false, 1033 }, 1034 { 1035 CSC_BT2020F_13BIT, 1036 OPTM_CS_E_RGB_2020, 1037 OPTM_CS_E_XV_YCC_2020, 1038 true, 1039 true, 1040 }, 1041 }; 1042 1043 static bool is_rgb_format(u64 format) 1044 { 1045 switch (format) { 1046 case BUS_FMT_YUV420: 1047 case BUS_FMT_YUV422: 1048 case BUS_FMT_YUV444: 1049 return false; 1050 case BUS_FMT_RGB: 1051 default: 1052 return true; 1053 } 1054 } 1055 1056 struct post_csc_coef { 1057 s32 csc_coef00; 1058 s32 csc_coef01; 1059 s32 csc_coef02; 1060 s32 csc_coef10; 1061 s32 csc_coef11; 1062 s32 csc_coef12; 1063 s32 csc_coef20; 1064 s32 csc_coef21; 1065 s32 csc_coef22; 1066 1067 s32 csc_dc0; 1068 s32 csc_dc1; 1069 s32 csc_dc2; 1070 1071 u32 range_type; 1072 }; 1073 1074 static int csc_get_mode_index(int post_csc_mode, bool is_input_yuv, bool is_output_yuv) 1075 { 1076 const struct rk_csc_colorspace_info *colorspace_info; 1077 enum color_space_type input_color_space; 1078 enum color_space_type output_color_space; 1079 bool is_input_full_range; 1080 bool is_output_full_range; 1081 int i; 1082 1083 for (i = 0; i < ARRAY_SIZE(csc_mapping_table); i++) { 1084 if (post_csc_mode == csc_mapping_table[i].csc_format) { 1085 input_color_space = is_input_yuv ? csc_mapping_table[i].yuv_color_space : 1086 csc_mapping_table[i].rgb_color_space; 1087 is_input_full_range = is_input_yuv ? csc_mapping_table[i].yuv_full_range : 1088 csc_mapping_table[i].rgb_full_range; 1089 output_color_space = is_output_yuv ? csc_mapping_table[i].yuv_color_space : 1090 csc_mapping_table[i].rgb_color_space; 1091 is_output_full_range = is_output_yuv ? csc_mapping_table[i].yuv_full_range : 1092 csc_mapping_table[i].rgb_full_range; 1093 break; 1094 } 1095 } 1096 if (i >= ARRAY_SIZE(csc_mapping_table)) 1097 return -EINVAL; 1098 1099 for (i = 0; i < ARRAY_SIZE(g_mode_csc_coef); i++) { 1100 colorspace_info = &g_mode_csc_coef[i].st_csc_color_info; 1101 if (colorspace_info->input_color_space == input_color_space && 1102 colorspace_info->output_color_space == output_color_space && 1103 colorspace_info->in_full_range == is_input_full_range && 1104 colorspace_info->out_full_range == is_output_full_range) 1105 return i; 1106 } 1107 1108 return -EINVAL; 1109 } 1110 1111 static void csc_matrix_ventor_multiply(struct rk_pq_csc_ventor *dst, 1112 const struct rk_pq_csc_coef *m0, 1113 const struct rk_pq_csc_ventor *v0) 1114 { 1115 dst->csc_offset0 = m0->csc_coef00 * v0->csc_offset0 + 1116 m0->csc_coef01 * v0->csc_offset1 + 1117 m0->csc_coef02 * v0->csc_offset2; 1118 1119 dst->csc_offset1 = m0->csc_coef10 * v0->csc_offset0 + 1120 m0->csc_coef11 * v0->csc_offset1 + 1121 m0->csc_coef12 * v0->csc_offset2; 1122 1123 dst->csc_offset2 = m0->csc_coef20 * v0->csc_offset0 + 1124 m0->csc_coef21 * v0->csc_offset1 + 1125 m0->csc_coef22 * v0->csc_offset2; 1126 } 1127 1128 static inline s32 pq_csc_simple_round(s32 x, s32 n) 1129 { 1130 s32 value = 0; 1131 1132 if (n == 0) 1133 return x; 1134 1135 value = (abs(x) + (1 << (n - 1))) >> (n); 1136 return (((x) >= 0) ? value : -value); 1137 } 1138 1139 static int csc_calc_default_output_coef(const struct rk_csc_mode_coef *csc_mode_cfg, 1140 struct rk_pq_csc_coef *out_matrix, 1141 struct rk_pq_csc_ventor *out_dc) 1142 { 1143 const struct rk_pq_csc_coef *csc_coef; 1144 const struct rk_pq_csc_dc_coef *csc_dc_coef; 1145 struct rk_pq_csc_ventor dc_in_ventor; 1146 struct rk_pq_csc_ventor dc_out_ventor; 1147 struct rk_pq_csc_ventor v; 1148 1149 csc_coef = csc_mode_cfg->pst_csc_coef; 1150 csc_dc_coef = csc_mode_cfg->pst_csc_dc_coef; 1151 1152 out_matrix->csc_coef00 = csc_coef->csc_coef00; 1153 out_matrix->csc_coef01 = csc_coef->csc_coef01; 1154 out_matrix->csc_coef02 = csc_coef->csc_coef02; 1155 out_matrix->csc_coef10 = csc_coef->csc_coef10; 1156 out_matrix->csc_coef11 = csc_coef->csc_coef11; 1157 out_matrix->csc_coef12 = csc_coef->csc_coef12; 1158 out_matrix->csc_coef20 = csc_coef->csc_coef20; 1159 out_matrix->csc_coef21 = csc_coef->csc_coef21; 1160 out_matrix->csc_coef22 = csc_coef->csc_coef22; 1161 1162 dc_in_ventor.csc_offset0 = csc_dc_coef->csc_in_dc0; 1163 dc_in_ventor.csc_offset1 = csc_dc_coef->csc_in_dc1; 1164 dc_in_ventor.csc_offset2 = csc_dc_coef->csc_in_dc2; 1165 dc_out_ventor.csc_offset0 = csc_dc_coef->csc_out_dc0; 1166 dc_out_ventor.csc_offset1 = csc_dc_coef->csc_out_dc1; 1167 dc_out_ventor.csc_offset2 = csc_dc_coef->csc_out_dc2; 1168 1169 csc_matrix_ventor_multiply(&v, csc_coef, &dc_in_ventor); 1170 out_dc->csc_offset0 = v.csc_offset0 + dc_out_ventor.csc_offset0 * 1171 PQ_CSC_SIMPLE_MAT_PARAM_FIX_NUM; 1172 out_dc->csc_offset1 = v.csc_offset1 + dc_out_ventor.csc_offset1 * 1173 PQ_CSC_SIMPLE_MAT_PARAM_FIX_NUM; 1174 out_dc->csc_offset2 = v.csc_offset2 + dc_out_ventor.csc_offset2 * 1175 PQ_CSC_SIMPLE_MAT_PARAM_FIX_NUM; 1176 1177 return 0; 1178 } 1179 1180 static int vop2_convert_csc_mode(int csc_mode, int bit_depth) 1181 { 1182 switch (csc_mode) { 1183 case V4L2_COLORSPACE_SMPTE170M: 1184 case V4L2_COLORSPACE_470_SYSTEM_M: 1185 case V4L2_COLORSPACE_470_SYSTEM_BG: 1186 return CSC_BT601L; 1187 case V4L2_COLORSPACE_REC709: 1188 case V4L2_COLORSPACE_SMPTE240M: 1189 case V4L2_COLORSPACE_DEFAULT: 1190 if (bit_depth == CSC_13BIT_DEPTH) 1191 return CSC_BT709L_13BIT; 1192 else 1193 return CSC_BT709L; 1194 case V4L2_COLORSPACE_JPEG: 1195 return CSC_BT601F; 1196 case V4L2_COLORSPACE_BT2020: 1197 if (bit_depth == CSC_13BIT_DEPTH) 1198 return CSC_BT2020L_13BIT; 1199 else 1200 return CSC_BT2020; 1201 case V4L2_COLORSPACE_BT709F: 1202 if (bit_depth == CSC_10BIT_DEPTH) 1203 return CSC_BT601F; 1204 else 1205 return CSC_BT709F_13BIT; 1206 case V4L2_COLORSPACE_BT2020F: 1207 if (bit_depth == CSC_10BIT_DEPTH) 1208 return CSC_BT601F; 1209 else 1210 return CSC_BT2020F_13BIT; 1211 default: 1212 return CSC_BT709L; 1213 } 1214 } 1215 1216 static int rockchip_calc_post_csc(struct post_csc_coef *csc_simple_coef, 1217 int csc_mode, bool is_input_yuv, bool is_output_yuv) 1218 { 1219 int ret = 0; 1220 struct rk_pq_csc_coef out_matrix; 1221 struct rk_pq_csc_ventor out_dc; 1222 const struct rk_csc_mode_coef *csc_mode_cfg; 1223 int bit_num = PQ_CSC_SIMPLE_MAT_PARAM_FIX_BIT_WIDTH; 1224 1225 ret = csc_get_mode_index(csc_mode, is_input_yuv, is_output_yuv); 1226 if (ret < 0) 1227 return ret; 1228 1229 csc_mode_cfg = &g_mode_csc_coef[ret]; 1230 1231 ret = csc_calc_default_output_coef(csc_mode_cfg, &out_matrix, &out_dc); 1232 1233 csc_simple_coef->csc_coef00 = out_matrix.csc_coef00; 1234 csc_simple_coef->csc_coef01 = out_matrix.csc_coef01; 1235 csc_simple_coef->csc_coef02 = out_matrix.csc_coef02; 1236 csc_simple_coef->csc_coef10 = out_matrix.csc_coef10; 1237 csc_simple_coef->csc_coef11 = out_matrix.csc_coef11; 1238 csc_simple_coef->csc_coef12 = out_matrix.csc_coef12; 1239 csc_simple_coef->csc_coef20 = out_matrix.csc_coef20; 1240 csc_simple_coef->csc_coef21 = out_matrix.csc_coef21; 1241 csc_simple_coef->csc_coef22 = out_matrix.csc_coef22; 1242 csc_simple_coef->csc_dc0 = out_dc.csc_offset0; 1243 csc_simple_coef->csc_dc1 = out_dc.csc_offset1; 1244 csc_simple_coef->csc_dc2 = out_dc.csc_offset2; 1245 1246 csc_simple_coef->csc_dc0 = pq_csc_simple_round(csc_simple_coef->csc_dc0, bit_num); 1247 csc_simple_coef->csc_dc1 = pq_csc_simple_round(csc_simple_coef->csc_dc1, bit_num); 1248 csc_simple_coef->csc_dc2 = pq_csc_simple_round(csc_simple_coef->csc_dc2, bit_num); 1249 csc_simple_coef->range_type = csc_mode_cfg->st_csc_color_info.out_full_range; 1250 1251 return ret; 1252 } 1253 1254 static void calc_dsp_frm_hst_vst(const struct drm_display_mode *src, 1255 const struct drm_display_mode *dst, 1256 u32 *dsp_frame_hst, 1257 u32 *dsp_frame_vst) 1258 { 1259 u32 bp_in, bp_out; 1260 u32 v_scale_ratio; 1261 u64 t_frm_st; 1262 u64 t_bp_in, t_bp_out, t_delta, tin; 1263 u32 src_pixclock, dst_pixclock; 1264 u32 dst_htotal, dst_hsync_len, dst_hback_porch; 1265 u32 dst_vsync_len, dst_vback_porch, dst_vactive; 1266 u32 src_htotal, src_hsync_len, src_hback_porch; 1267 u32 src_vtotal, src_vsync_len, src_vback_porch, src_vactive; 1268 u32 rem; 1269 u32 x; 1270 1271 src_pixclock = div_u64(1000000000llu, src->clock); 1272 dst_pixclock = div_u64(1000000000llu, dst->clock); 1273 1274 src_hsync_len = src->hsync_end - src->hsync_start; 1275 src_hback_porch = src->htotal - src->hsync_end; 1276 src_htotal = src->htotal; 1277 src_vsync_len = src->vsync_end - src->vsync_start; 1278 src_vback_porch = src->vtotal - src->vsync_end; 1279 src_vactive = src->vdisplay; 1280 src_vtotal = src->vtotal; 1281 1282 dst_hsync_len = dst->hsync_end - dst->hsync_start; 1283 dst_hback_porch = dst->htotal - dst->hsync_end; 1284 dst_htotal = dst->htotal; 1285 dst_vsync_len = dst->vsync_end - dst->vsync_start; 1286 dst_vback_porch = dst->vtotal - dst->vsync_end; 1287 dst_vactive = dst->vdisplay; 1288 1289 bp_in = (src_vback_porch + src_vsync_len) * src_htotal + 1290 src_hsync_len + src_hback_porch; 1291 bp_out = (dst_vback_porch + dst_vsync_len) * dst_htotal + 1292 dst_hsync_len + dst_hback_porch; 1293 1294 t_bp_in = bp_in * src_pixclock; 1295 t_bp_out = bp_out * dst_pixclock; 1296 tin = src_vtotal * src_htotal * src_pixclock; 1297 1298 v_scale_ratio = src_vactive / dst_vactive; 1299 x = 5; 1300 __retry: 1301 if (v_scale_ratio <= 2) 1302 t_delta = x * src_htotal * src_pixclock; 1303 else 1304 t_delta = 12 * src_htotal * src_pixclock; 1305 1306 if (t_bp_in + t_delta > t_bp_out) 1307 t_frm_st = (t_bp_in + t_delta - t_bp_out); 1308 else 1309 t_frm_st = tin - (t_bp_out - (t_bp_in + t_delta)); 1310 1311 do_div(t_frm_st, src_pixclock); 1312 rem = do_div(t_frm_st, src_htotal); 1313 if ((t_frm_st < 2 || t_frm_st > 14) && x < 12) { 1314 x++; 1315 goto __retry; 1316 } 1317 if (t_frm_st < 2 || t_frm_st > 14) 1318 t_frm_st = 4; 1319 1320 *dsp_frame_hst = rem; 1321 *dsp_frame_vst = t_frm_st; 1322 } 1323 1324 static void rk628_post_process_scaler_init(struct rk628 *rk628, 1325 struct drm_display_mode *src, 1326 const struct drm_display_mode *dst) 1327 { 1328 u32 dsp_frame_hst, dsp_frame_vst; 1329 u32 scl_hor_mode, scl_ver_mode; 1330 u32 scl_v_factor, scl_h_factor; 1331 u32 dsp_htotal, dsp_hs_end, dsp_hact_st, dsp_hact_end; 1332 u32 dsp_vtotal, dsp_vs_end, dsp_vact_st, dsp_vact_end; 1333 u32 dsp_hbor_end, dsp_hbor_st, dsp_vbor_end, dsp_vbor_st; 1334 u16 bor_right = 0, bor_left = 0, bor_up = 0, bor_down = 0; 1335 u8 hor_down_mode = 0, ver_down_mode = 0; 1336 u32 dst_hsync_len, dst_hback_porch, dst_hfront_porch, dst_hactive; 1337 u32 dst_vsync_len, dst_vback_porch, dst_vfront_porch, dst_vactive; 1338 u32 src_hactive; 1339 u32 src_vactive; 1340 int gvi_offset = 0; 1341 1342 if (rk628->version == RK628F_VERSION && rk628->gvi.division_mode) 1343 gvi_offset = 4; 1344 1345 src_hactive = src->hdisplay; 1346 src_vactive = src->vdisplay; 1347 1348 dst_hactive = dst->hdisplay; 1349 dst_hsync_len = dst->hsync_end - dst->hsync_start; 1350 dst_hback_porch = dst->htotal - dst->hsync_end; 1351 dst_hfront_porch = dst->hsync_start - dst->hdisplay; 1352 dst_vsync_len = dst->vsync_end - dst->vsync_start; 1353 dst_vback_porch = dst->vtotal - dst->vsync_end; 1354 dst_vfront_porch = dst->vsync_start - dst->vdisplay; 1355 dst_vactive = dst->vdisplay; 1356 1357 dsp_htotal = dst_hsync_len + dst_hback_porch + 1358 dst_hactive + dst_hfront_porch; 1359 dsp_vtotal = dst_vsync_len + dst_vback_porch + 1360 dst_vactive + dst_vfront_porch; 1361 dsp_hs_end = dst_hsync_len; 1362 dsp_vs_end = dst_vsync_len; 1363 dsp_hbor_end = dst_hsync_len + dst_hback_porch + dst_hactive - gvi_offset; 1364 dsp_hbor_st = dst_hsync_len + dst_hback_porch - gvi_offset; 1365 dsp_vbor_end = dst_vsync_len + dst_vback_porch + dst_vactive; 1366 dsp_vbor_st = dst_vsync_len + dst_vback_porch; 1367 dsp_hact_st = dsp_hbor_st + bor_left; 1368 dsp_hact_end = dsp_hbor_end - bor_right; 1369 dsp_vact_st = dsp_vbor_st + bor_up; 1370 dsp_vact_end = dsp_vbor_end - bor_down; 1371 1372 calc_dsp_frm_hst_vst(src, dst, &dsp_frame_hst, &dsp_frame_vst); 1373 printf("rk628 dsp_frame_vst:%d dsp_frame_hst:%d\n", 1374 dsp_frame_vst, dsp_frame_hst); 1375 1376 if (src_hactive > dst_hactive) { 1377 scl_hor_mode = 2; 1378 1379 if (hor_down_mode == 0) { 1380 if ((src_hactive - 1) / (dst_hactive - 1) > 2) 1381 scl_h_factor = ((src_hactive - 1) << 14) / 1382 (dst_hactive - 1); 1383 else 1384 scl_h_factor = ((src_hactive - 2) << 14) / 1385 (dst_hactive - 1); 1386 } else { 1387 scl_h_factor = (dst_hactive << 16) / (src_hactive - 1); 1388 } 1389 1390 } else if (src_hactive == dst_hactive) { 1391 scl_hor_mode = 0; 1392 scl_h_factor = 0; 1393 } else { 1394 scl_hor_mode = 1; 1395 scl_h_factor = ((src_hactive - 1) << 16) / (dst_hactive - 1); 1396 } 1397 1398 if (src_vactive > dst_vactive) { 1399 scl_ver_mode = 2; 1400 1401 if (ver_down_mode == 0) { 1402 if ((src_vactive - 1) / (dst_vactive - 1) > 2) 1403 scl_v_factor = ((src_vactive - 1) << 14) / 1404 (dst_vactive - 1); 1405 else 1406 scl_v_factor = ((src_vactive - 2) << 14) / 1407 (dst_vactive - 1); 1408 } else { 1409 scl_v_factor = (dst_vactive << 16) / (src_vactive - 1); 1410 } 1411 1412 } else if (src_vactive == dst_vactive) { 1413 scl_ver_mode = 0; 1414 scl_v_factor = 0; 1415 } else { 1416 scl_ver_mode = 1; 1417 scl_v_factor = ((src_vactive - 1) << 16) / (dst_vactive - 1); 1418 } 1419 1420 rk628_i2c_update_bits(rk628, GRF_RGB_DEC_CON0, SW_HRES_MASK, 1421 SW_HRES(src_hactive)); 1422 rk628_i2c_write(rk628, GRF_SCALER_CON0, SCL_VER_DOWN_MODE(ver_down_mode) | 1423 SCL_HOR_DOWN_MODE(hor_down_mode) | 1424 SCL_VER_MODE(scl_ver_mode) | 1425 SCL_HOR_MODE(scl_hor_mode)); 1426 rk628_i2c_write(rk628, GRF_SCALER_CON1, SCL_V_FACTOR(scl_v_factor) | 1427 SCL_H_FACTOR(scl_h_factor)); 1428 rk628_i2c_write(rk628, GRF_SCALER_CON2, DSP_FRAME_VST(dsp_frame_vst) | 1429 DSP_FRAME_HST(dsp_frame_hst)); 1430 rk628_i2c_write(rk628, GRF_SCALER_CON3, DSP_HS_END(dsp_hs_end) | 1431 DSP_HTOTAL(dsp_htotal)); 1432 rk628_i2c_write(rk628, GRF_SCALER_CON4, DSP_HACT_END(dsp_hact_end) | 1433 DSP_HACT_ST(dsp_hact_st)); 1434 rk628_i2c_write(rk628, GRF_SCALER_CON5, DSP_VS_END(dsp_vs_end) | 1435 DSP_VTOTAL(dsp_vtotal)); 1436 rk628_i2c_write(rk628, GRF_SCALER_CON6, DSP_VACT_END(dsp_vact_end) | 1437 DSP_VACT_ST(dsp_vact_st)); 1438 rk628_i2c_write(rk628, GRF_SCALER_CON7, DSP_HBOR_END(dsp_hbor_end) | 1439 DSP_HBOR_ST(dsp_hbor_st)); 1440 rk628_i2c_write(rk628, GRF_SCALER_CON8, DSP_VBOR_END(dsp_vbor_end) | 1441 DSP_VBOR_ST(dsp_vbor_st)); 1442 } 1443 1444 void rk628_post_process_init(struct rk628 *rk628) 1445 { 1446 struct drm_display_mode *src = &rk628->src_mode; 1447 const struct drm_display_mode *dst = &rk628->dst_mode; 1448 u64 dst_rate, src_rate; 1449 1450 src_rate = src->clock * 1000; 1451 dst_rate = src_rate * dst->vtotal * dst->htotal; 1452 do_div(dst_rate, (src->vtotal * src->htotal)); 1453 do_div(dst_rate, 1000); 1454 printf("rk628 src %dx%d clock:%d\n", 1455 src->hdisplay, src->vdisplay, src->clock); 1456 1457 printf("rk628 dst %dx%d clock:%llu\n", 1458 dst->hdisplay, dst->vdisplay, dst_rate); 1459 1460 rk628_cru_clk_set_rate(rk628, CGU_CLK_RX_READ, src->clock * 1000); 1461 rk628_cru_clk_set_rate(rk628, CGU_SCLK_VOP, dst_rate * 1000); 1462 1463 if (rk628_output_is_hdmi(rk628)) { 1464 rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0, SW_VSYNC_POL_MASK, 1465 SW_VSYNC_POL(rk628->sync_pol)); 1466 rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0, SW_HSYNC_POL_MASK, 1467 SW_HSYNC_POL(rk628->sync_pol)); 1468 } else { 1469 if (src->flags & DRM_MODE_FLAG_PVSYNC) 1470 rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0, 1471 SW_VSYNC_POL_MASK, SW_VSYNC_POL(1)); 1472 if (src->flags & DRM_MODE_FLAG_PHSYNC) 1473 rk628_i2c_update_bits(rk628, GRF_SYSTEM_CON0, 1474 SW_HSYNC_POL_MASK, 1475 SW_HSYNC_POL(1)); 1476 } 1477 1478 rk628_post_process_scaler_init(rk628, src, dst); 1479 } 1480 1481 static void rk628_post_process_csc(struct rk628 *rk628) 1482 { 1483 enum bus_format in_fmt, out_fmt; 1484 struct post_csc_coef csc_coef = {}; 1485 bool is_input_yuv, is_output_yuv; 1486 u32 color_space = V4L2_COLORSPACE_DEFAULT; 1487 u32 csc_mode; 1488 u32 val; 1489 int range_type; 1490 1491 in_fmt = rk628_get_input_bus_format(rk628); 1492 out_fmt = rk628_get_output_bus_format(rk628); 1493 1494 if (in_fmt == out_fmt) { 1495 if (out_fmt == BUS_FMT_YUV422) { 1496 rk628_i2c_write(rk628, GRF_CSC_CTRL_CON, 1497 SW_YUV2VYU_SWP(1) | 1498 SW_R2Y_EN(0)); 1499 return; 1500 } 1501 rk628_i2c_write(rk628, GRF_CSC_CTRL_CON, SW_R2Y_EN(0)); 1502 rk628_i2c_write(rk628, GRF_CSC_CTRL_CON, SW_Y2R_EN(0)); 1503 return; 1504 } 1505 1506 if (rk628->version == RK628D_VERSION) { 1507 if (in_fmt == BUS_FMT_RGB) 1508 rk628_i2c_write(rk628, GRF_CSC_CTRL_CON, SW_R2Y_EN(1)); 1509 else if (out_fmt == BUS_FMT_RGB) 1510 rk628_i2c_write(rk628, GRF_CSC_CTRL_CON, SW_Y2R_EN(1)); 1511 } else { 1512 csc_mode = vop2_convert_csc_mode(color_space, CSC_13BIT_DEPTH); 1513 1514 is_input_yuv = !is_rgb_format(in_fmt); 1515 is_output_yuv = !is_rgb_format(out_fmt); 1516 rockchip_calc_post_csc(&csc_coef, csc_mode, is_input_yuv, is_output_yuv); 1517 1518 val = ((csc_coef.csc_coef01 & 0xffff) << 16) | (csc_coef.csc_coef00 & 0xffff); 1519 rk628_i2c_write(rk628, GRF_CSC_MATRIX_COE01_COE00, val); 1520 1521 val = ((csc_coef.csc_coef10 & 0xffff) << 16) | (csc_coef.csc_coef02 & 0xffff); 1522 rk628_i2c_write(rk628, GRF_CSC_MATRIX_COE10_COE02, val); 1523 1524 val = ((csc_coef.csc_coef12 & 0xffff) << 16) | (csc_coef.csc_coef11 & 0xffff); 1525 rk628_i2c_write(rk628, GRF_CSC_MATRIX_COE12_COE11, val); 1526 1527 val = ((csc_coef.csc_coef21 & 0xffff) << 16) | (csc_coef.csc_coef20 & 0xffff); 1528 rk628_i2c_write(rk628, GRF_CSC_MATRIX_COE21_COE20, val); 1529 1530 rk628_i2c_write(rk628, GRF_CSC_MATRIX_COE22, csc_coef.csc_coef22); 1531 1532 rk628_i2c_write(rk628, GRF_CSC_MATRIX_OFFSET0, csc_coef.csc_dc0); 1533 rk628_i2c_write(rk628, GRF_CSC_MATRIX_OFFSET1, csc_coef.csc_dc1); 1534 rk628_i2c_write(rk628, GRF_CSC_MATRIX_OFFSET2, csc_coef.csc_dc2); 1535 1536 range_type = csc_coef.range_type ? 0 : 1; 1537 range_type <<= is_input_yuv ? 0 : 1; 1538 val = SW_Y2R_MODE(range_type) | SW_FROM_CSC_MATRIX_EN(1); 1539 rk628_i2c_write(rk628, GRF_CSC_CTRL_CON, val); 1540 1541 if (rk628_output_is_bt1120(rk628)) 1542 rk628_i2c_write(rk628, GRF_CSC_CTRL_CON, SW_YUV2VYU_SWP(1)); 1543 } 1544 } 1545 1546 void rk628_post_process_enable(struct rk628 *rk628) 1547 { 1548 #if 0 1549 /* 1550 * bt1120 needs to configure the timing register, but hdmitx will modify 1551 * the timing as needed, so the bt1120 enable process is moved here. 1552 */ 1553 if (rk628_input_is_bt1120(rk628)) 1554 rk628_bt1120_rx_enable(rk628); 1555 #endif 1556 rk628_post_process_csc(rk628); 1557 rk628_i2c_write(rk628, GRF_SCALER_CON0, SCL_EN(1)); 1558 } 1559 1560 void rk628_post_process_disable(struct rk628 *rk628) 1561 { 1562 rk628_i2c_write(rk628, GRF_SCALER_CON0, SCL_EN(0)); 1563 } 1564