dcn30_cm_common.c (20417B)
1/* 2 * Copyright 2020 Advanced Micro Devices, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * Authors: AMD 23 * 24 */ 25 26#include "dm_services.h" 27#include "core_types.h" 28#include "reg_helper.h" 29#include "dcn30_dpp.h" 30#include "basics/conversion.h" 31#include "dcn30_cm_common.h" 32#include "custom_float.h" 33 34#define REG(reg) reg 35 36#define CTX \ 37 ctx //dpp->base.ctx 38 39#undef FN 40#define FN(reg_name, field_name) \ 41 reg->shifts.field_name, reg->masks.field_name 42 43void cm_helper_program_gamcor_xfer_func( 44 struct dc_context *ctx, 45 const struct pwl_params *params, 46 const struct dcn3_xfer_func_reg *reg) 47{ 48 uint32_t reg_region_cur; 49 unsigned int i = 0; 50 51 REG_SET_2(reg->start_cntl_b, 0, 52 exp_region_start, params->corner_points[0].blue.custom_float_x, 53 exp_resion_start_segment, 0); 54 REG_SET_2(reg->start_cntl_g, 0, 55 exp_region_start, params->corner_points[0].green.custom_float_x, 56 exp_resion_start_segment, 0); 57 REG_SET_2(reg->start_cntl_r, 0, 58 exp_region_start, params->corner_points[0].red.custom_float_x, 59 exp_resion_start_segment, 0); 60 61 REG_SET(reg->start_slope_cntl_b, 0, //linear slope at start of curve 62 field_region_linear_slope, params->corner_points[0].blue.custom_float_slope); 63 REG_SET(reg->start_slope_cntl_g, 0, 64 field_region_linear_slope, params->corner_points[0].green.custom_float_slope); 65 REG_SET(reg->start_slope_cntl_r, 0, 66 field_region_linear_slope, params->corner_points[0].red.custom_float_slope); 67 68 REG_SET(reg->start_end_cntl1_b, 0, 69 field_region_end_base, params->corner_points[1].blue.custom_float_y); 70 REG_SET(reg->start_end_cntl1_g, 0, 71 field_region_end_base, params->corner_points[1].green.custom_float_y); 72 REG_SET(reg->start_end_cntl1_r, 0, 73 field_region_end_base, params->corner_points[1].red.custom_float_y); 74 75 REG_SET_2(reg->start_end_cntl2_b, 0, 76 field_region_end_slope, params->corner_points[1].blue.custom_float_slope, 77 field_region_end, params->corner_points[1].blue.custom_float_x); 78 REG_SET_2(reg->start_end_cntl2_g, 0, 79 field_region_end_slope, params->corner_points[1].green.custom_float_slope, 80 field_region_end, params->corner_points[1].green.custom_float_x); 81 REG_SET_2(reg->start_end_cntl2_r, 0, 82 field_region_end_slope, params->corner_points[1].red.custom_float_slope, 83 field_region_end, params->corner_points[1].red.custom_float_x); 84 85 for (reg_region_cur = reg->region_start; 86 reg_region_cur <= reg->region_end; 87 reg_region_cur++) { 88 89 const struct gamma_curve *curve0 = &(params->arr_curve_points[2 * i]); 90 const struct gamma_curve *curve1 = &(params->arr_curve_points[(2 * i) + 1]); 91 92 REG_SET_4(reg_region_cur, 0, 93 exp_region0_lut_offset, curve0->offset, 94 exp_region0_num_segments, curve0->segments_num, 95 exp_region1_lut_offset, curve1->offset, 96 exp_region1_num_segments, curve1->segments_num); 97 98 i++; 99 } 100} 101 102/* driver uses 32 regions or less, but DCN HW has 34, extra 2 are set to 0 */ 103#define MAX_REGIONS_NUMBER 34 104#define MAX_LOW_POINT 25 105#define NUMBER_REGIONS 32 106#define NUMBER_SW_SEGMENTS 16 107 108bool cm3_helper_translate_curve_to_hw_format( 109 const struct dc_transfer_func *output_tf, 110 struct pwl_params *lut_params, bool fixpoint) 111{ 112 struct curve_points3 *corner_points; 113 struct pwl_result_data *rgb_resulted; 114 struct pwl_result_data *rgb; 115 struct pwl_result_data *rgb_plus_1; 116 struct pwl_result_data *rgb_minus_1; 117 struct fixed31_32 end_value; 118 119 int32_t region_start, region_end; 120 int32_t i; 121 uint32_t j, k, seg_distr[MAX_REGIONS_NUMBER], increment, start_index, hw_points; 122 123 if (output_tf == NULL || lut_params == NULL || output_tf->type == TF_TYPE_BYPASS) 124 return false; 125 126 corner_points = lut_params->corner_points; 127 rgb_resulted = lut_params->rgb_resulted; 128 hw_points = 0; 129 130 memset(lut_params, 0, sizeof(struct pwl_params)); 131 memset(seg_distr, 0, sizeof(seg_distr)); 132 133 if (output_tf->tf == TRANSFER_FUNCTION_PQ || output_tf->tf == TRANSFER_FUNCTION_GAMMA22 || 134 output_tf->tf == TRANSFER_FUNCTION_HLG) { 135 /* 32 segments 136 * segments are from 2^-25 to 2^7 137 */ 138 for (i = 0; i < NUMBER_REGIONS ; i++) 139 seg_distr[i] = 3; 140 141 region_start = -MAX_LOW_POINT; 142 region_end = NUMBER_REGIONS - MAX_LOW_POINT; 143 } else { 144 /* 11 segments 145 * segment is from 2^-10 to 2^0 146 * There are less than 256 points, for optimization 147 */ 148 seg_distr[0] = 3; 149 seg_distr[1] = 4; 150 seg_distr[2] = 4; 151 seg_distr[3] = 4; 152 seg_distr[4] = 4; 153 seg_distr[5] = 4; 154 seg_distr[6] = 4; 155 seg_distr[7] = 4; 156 seg_distr[8] = 4; 157 seg_distr[9] = 4; 158 seg_distr[10] = 1; 159 160 region_start = -10; 161 region_end = 1; 162 } 163 164 for (i = region_end - region_start; i < MAX_REGIONS_NUMBER ; i++) 165 seg_distr[i] = -1; 166 167 for (k = 0; k < MAX_REGIONS_NUMBER; k++) { 168 if (seg_distr[k] != -1) 169 hw_points += (1 << seg_distr[k]); 170 } 171 172 j = 0; 173 for (k = 0; k < (region_end - region_start); k++) { 174 increment = NUMBER_SW_SEGMENTS / (1 << seg_distr[k]); 175 start_index = (region_start + k + MAX_LOW_POINT) * 176 NUMBER_SW_SEGMENTS; 177 for (i = start_index; i < start_index + NUMBER_SW_SEGMENTS; 178 i += increment) { 179 if (j == hw_points - 1) 180 break; 181 rgb_resulted[j].red = output_tf->tf_pts.red[i]; 182 rgb_resulted[j].green = output_tf->tf_pts.green[i]; 183 rgb_resulted[j].blue = output_tf->tf_pts.blue[i]; 184 j++; 185 } 186 } 187 188 /* last point */ 189 start_index = (region_end + MAX_LOW_POINT) * NUMBER_SW_SEGMENTS; 190 rgb_resulted[hw_points - 1].red = output_tf->tf_pts.red[start_index]; 191 rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index]; 192 rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index]; 193 194 rgb_resulted[hw_points].red = rgb_resulted[hw_points - 1].red; 195 rgb_resulted[hw_points].green = rgb_resulted[hw_points - 1].green; 196 rgb_resulted[hw_points].blue = rgb_resulted[hw_points - 1].blue; 197 198 // All 3 color channels have same x 199 corner_points[0].red.x = dc_fixpt_pow(dc_fixpt_from_int(2), 200 dc_fixpt_from_int(region_start)); 201 corner_points[0].green.x = corner_points[0].red.x; 202 corner_points[0].blue.x = corner_points[0].red.x; 203 204 corner_points[1].red.x = dc_fixpt_pow(dc_fixpt_from_int(2), 205 dc_fixpt_from_int(region_end)); 206 corner_points[1].green.x = corner_points[1].red.x; 207 corner_points[1].blue.x = corner_points[1].red.x; 208 209 corner_points[0].red.y = rgb_resulted[0].red; 210 corner_points[0].green.y = rgb_resulted[0].green; 211 corner_points[0].blue.y = rgb_resulted[0].blue; 212 213 corner_points[0].red.slope = dc_fixpt_div(corner_points[0].red.y, 214 corner_points[0].red.x); 215 corner_points[0].green.slope = dc_fixpt_div(corner_points[0].green.y, 216 corner_points[0].green.x); 217 corner_points[0].blue.slope = dc_fixpt_div(corner_points[0].blue.y, 218 corner_points[0].blue.x); 219 220 /* see comment above, m_arrPoints[1].y should be the Y value for the 221 * region end (m_numOfHwPoints), not last HW point(m_numOfHwPoints - 1) 222 */ 223 corner_points[1].red.y = rgb_resulted[hw_points - 1].red; 224 corner_points[1].green.y = rgb_resulted[hw_points - 1].green; 225 corner_points[1].blue.y = rgb_resulted[hw_points - 1].blue; 226 corner_points[1].red.slope = dc_fixpt_zero; 227 corner_points[1].green.slope = dc_fixpt_zero; 228 corner_points[1].blue.slope = dc_fixpt_zero; 229 230 if (output_tf->tf == TRANSFER_FUNCTION_PQ || output_tf->tf == TRANSFER_FUNCTION_HLG) { 231 /* for PQ/HLG, we want to have a straight line from last HW X point, 232 * and the slope to be such that we hit 1.0 at 10000/1000 nits. 233 */ 234 235 if (output_tf->tf == TRANSFER_FUNCTION_PQ) 236 end_value = dc_fixpt_from_int(125); 237 else 238 end_value = dc_fixpt_from_fraction(125, 10); 239 240 corner_points[1].red.slope = dc_fixpt_div( 241 dc_fixpt_sub(dc_fixpt_one, corner_points[1].red.y), 242 dc_fixpt_sub(end_value, corner_points[1].red.x)); 243 corner_points[1].green.slope = dc_fixpt_div( 244 dc_fixpt_sub(dc_fixpt_one, corner_points[1].green.y), 245 dc_fixpt_sub(end_value, corner_points[1].green.x)); 246 corner_points[1].blue.slope = dc_fixpt_div( 247 dc_fixpt_sub(dc_fixpt_one, corner_points[1].blue.y), 248 dc_fixpt_sub(end_value, corner_points[1].blue.x)); 249 } 250 lut_params->hw_points_num = hw_points; 251 252 k = 0; 253 for (i = 1; i < MAX_REGIONS_NUMBER; i++) { 254 if (seg_distr[k] != -1) { 255 lut_params->arr_curve_points[k].segments_num = 256 seg_distr[k]; 257 lut_params->arr_curve_points[i].offset = 258 lut_params->arr_curve_points[k].offset + (1 << seg_distr[k]); 259 } 260 k++; 261 } 262 263 if (seg_distr[k] != -1) 264 lut_params->arr_curve_points[k].segments_num = seg_distr[k]; 265 266 rgb = rgb_resulted; 267 rgb_plus_1 = rgb_resulted + 1; 268 rgb_minus_1 = rgb; 269 270 i = 1; 271 while (i != hw_points + 1) { 272 if (i >= hw_points - 1) { 273 if (dc_fixpt_lt(rgb_plus_1->red, rgb->red)) 274 rgb_plus_1->red = dc_fixpt_add(rgb->red, rgb_minus_1->delta_red); 275 if (dc_fixpt_lt(rgb_plus_1->green, rgb->green)) 276 rgb_plus_1->green = dc_fixpt_add(rgb->green, rgb_minus_1->delta_green); 277 if (dc_fixpt_lt(rgb_plus_1->blue, rgb->blue)) 278 rgb_plus_1->blue = dc_fixpt_add(rgb->blue, rgb_minus_1->delta_blue); 279 } 280 281 rgb->delta_red = dc_fixpt_sub(rgb_plus_1->red, rgb->red); 282 rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green); 283 rgb->delta_blue = dc_fixpt_sub(rgb_plus_1->blue, rgb->blue); 284 285 if (fixpoint == true) { 286 rgb->delta_red_reg = dc_fixpt_clamp_u0d10(rgb->delta_red); 287 rgb->delta_green_reg = dc_fixpt_clamp_u0d10(rgb->delta_green); 288 rgb->delta_blue_reg = dc_fixpt_clamp_u0d10(rgb->delta_blue); 289 rgb->red_reg = dc_fixpt_clamp_u0d14(rgb->red); 290 rgb->green_reg = dc_fixpt_clamp_u0d14(rgb->green); 291 rgb->blue_reg = dc_fixpt_clamp_u0d14(rgb->blue); 292 } 293 294 ++rgb_plus_1; 295 rgb_minus_1 = rgb; 296 ++rgb; 297 ++i; 298 } 299 cm3_helper_convert_to_custom_float(rgb_resulted, 300 lut_params->corner_points, 301 hw_points, fixpoint); 302 303 return true; 304} 305 306#define NUM_DEGAMMA_REGIONS 12 307 308 309bool cm3_helper_translate_curve_to_degamma_hw_format( 310 const struct dc_transfer_func *output_tf, 311 struct pwl_params *lut_params) 312{ 313 struct curve_points3 *corner_points; 314 struct pwl_result_data *rgb_resulted; 315 struct pwl_result_data *rgb; 316 struct pwl_result_data *rgb_plus_1; 317 318 int32_t region_start, region_end; 319 int32_t i; 320 uint32_t j, k, seg_distr[MAX_REGIONS_NUMBER], increment, start_index, hw_points; 321 322 if (output_tf == NULL || lut_params == NULL || output_tf->type == TF_TYPE_BYPASS) 323 return false; 324 325 corner_points = lut_params->corner_points; 326 rgb_resulted = lut_params->rgb_resulted; 327 hw_points = 0; 328 329 memset(lut_params, 0, sizeof(struct pwl_params)); 330 memset(seg_distr, 0, sizeof(seg_distr)); 331 332 region_start = -NUM_DEGAMMA_REGIONS; 333 region_end = 0; 334 335 336 for (i = region_end - region_start; i < MAX_REGIONS_NUMBER ; i++) 337 seg_distr[i] = -1; 338 /* 12 segments 339 * segments are from 2^-12 to 0 340 */ 341 for (i = 0; i < NUM_DEGAMMA_REGIONS ; i++) 342 seg_distr[i] = 4; 343 344 for (k = 0; k < MAX_REGIONS_NUMBER; k++) { 345 if (seg_distr[k] != -1) 346 hw_points += (1 << seg_distr[k]); 347 } 348 349 j = 0; 350 for (k = 0; k < (region_end - region_start); k++) { 351 increment = NUMBER_SW_SEGMENTS / (1 << seg_distr[k]); 352 start_index = (region_start + k + MAX_LOW_POINT) * 353 NUMBER_SW_SEGMENTS; 354 for (i = start_index; i < start_index + NUMBER_SW_SEGMENTS; 355 i += increment) { 356 if (j == hw_points - 1) 357 break; 358 rgb_resulted[j].red = output_tf->tf_pts.red[i]; 359 rgb_resulted[j].green = output_tf->tf_pts.green[i]; 360 rgb_resulted[j].blue = output_tf->tf_pts.blue[i]; 361 j++; 362 } 363 } 364 365 /* last point */ 366 start_index = (region_end + MAX_LOW_POINT) * NUMBER_SW_SEGMENTS; 367 rgb_resulted[hw_points - 1].red = output_tf->tf_pts.red[start_index]; 368 rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index]; 369 rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index]; 370 371 corner_points[0].red.x = dc_fixpt_pow(dc_fixpt_from_int(2), 372 dc_fixpt_from_int(region_start)); 373 corner_points[0].green.x = corner_points[0].red.x; 374 corner_points[0].blue.x = corner_points[0].red.x; 375 corner_points[1].red.x = dc_fixpt_pow(dc_fixpt_from_int(2), 376 dc_fixpt_from_int(region_end)); 377 corner_points[1].green.x = corner_points[1].red.x; 378 corner_points[1].blue.x = corner_points[1].red.x; 379 380 corner_points[0].red.y = rgb_resulted[0].red; 381 corner_points[0].green.y = rgb_resulted[0].green; 382 corner_points[0].blue.y = rgb_resulted[0].blue; 383 384 /* see comment above, m_arrPoints[1].y should be the Y value for the 385 * region end (m_numOfHwPoints), not last HW point(m_numOfHwPoints - 1) 386 */ 387 corner_points[1].red.y = rgb_resulted[hw_points - 1].red; 388 corner_points[1].green.y = rgb_resulted[hw_points - 1].green; 389 corner_points[1].blue.y = rgb_resulted[hw_points - 1].blue; 390 corner_points[1].red.slope = dc_fixpt_zero; 391 corner_points[1].green.slope = dc_fixpt_zero; 392 corner_points[1].blue.slope = dc_fixpt_zero; 393 394 if (output_tf->tf == TRANSFER_FUNCTION_PQ) { 395 /* for PQ, we want to have a straight line from last HW X point, 396 * and the slope to be such that we hit 1.0 at 10000 nits. 397 */ 398 const struct fixed31_32 end_value = 399 dc_fixpt_from_int(125); 400 401 corner_points[1].red.slope = dc_fixpt_div( 402 dc_fixpt_sub(dc_fixpt_one, corner_points[1].red.y), 403 dc_fixpt_sub(end_value, corner_points[1].red.x)); 404 corner_points[1].green.slope = dc_fixpt_div( 405 dc_fixpt_sub(dc_fixpt_one, corner_points[1].green.y), 406 dc_fixpt_sub(end_value, corner_points[1].green.x)); 407 corner_points[1].blue.slope = dc_fixpt_div( 408 dc_fixpt_sub(dc_fixpt_one, corner_points[1].blue.y), 409 dc_fixpt_sub(end_value, corner_points[1].blue.x)); 410 } 411 412 lut_params->hw_points_num = hw_points; 413 414 k = 0; 415 for (i = 1; i < MAX_REGIONS_NUMBER; i++) { 416 if (seg_distr[k] != -1) { 417 lut_params->arr_curve_points[k].segments_num = 418 seg_distr[k]; 419 lut_params->arr_curve_points[i].offset = 420 lut_params->arr_curve_points[k].offset + (1 << seg_distr[k]); 421 } 422 k++; 423 } 424 425 if (seg_distr[k] != -1) 426 lut_params->arr_curve_points[k].segments_num = seg_distr[k]; 427 428 rgb = rgb_resulted; 429 rgb_plus_1 = rgb_resulted + 1; 430 431 i = 1; 432 while (i != hw_points + 1) { 433 if (dc_fixpt_lt(rgb_plus_1->red, rgb->red)) 434 rgb_plus_1->red = rgb->red; 435 if (dc_fixpt_lt(rgb_plus_1->green, rgb->green)) 436 rgb_plus_1->green = rgb->green; 437 if (dc_fixpt_lt(rgb_plus_1->blue, rgb->blue)) 438 rgb_plus_1->blue = rgb->blue; 439 440 rgb->delta_red = dc_fixpt_sub(rgb_plus_1->red, rgb->red); 441 rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green); 442 rgb->delta_blue = dc_fixpt_sub(rgb_plus_1->blue, rgb->blue); 443 444 ++rgb_plus_1; 445 ++rgb; 446 ++i; 447 } 448 cm3_helper_convert_to_custom_float(rgb_resulted, 449 lut_params->corner_points, 450 hw_points, false); 451 452 return true; 453} 454 455bool cm3_helper_convert_to_custom_float( 456 struct pwl_result_data *rgb_resulted, 457 struct curve_points3 *corner_points, 458 uint32_t hw_points_num, 459 bool fixpoint) 460{ 461 struct custom_float_format fmt; 462 463 struct pwl_result_data *rgb = rgb_resulted; 464 465 uint32_t i = 0; 466 467 fmt.exponenta_bits = 6; 468 fmt.mantissa_bits = 12; 469 fmt.sign = false; 470 471 /* corner_points[0] - beginning base, slope offset for R,G,B 472 * corner_points[1] - end base, slope offset for R,G,B 473 */ 474 if (!convert_to_custom_float_format(corner_points[0].red.x, &fmt, 475 &corner_points[0].red.custom_float_x)) { 476 BREAK_TO_DEBUGGER(); 477 return false; 478 } 479 if (!convert_to_custom_float_format(corner_points[0].green.x, &fmt, 480 &corner_points[0].green.custom_float_x)) { 481 BREAK_TO_DEBUGGER(); 482 return false; 483 } 484 if (!convert_to_custom_float_format(corner_points[0].blue.x, &fmt, 485 &corner_points[0].blue.custom_float_x)) { 486 BREAK_TO_DEBUGGER(); 487 return false; 488 } 489 490 if (!convert_to_custom_float_format(corner_points[0].red.offset, &fmt, 491 &corner_points[0].red.custom_float_offset)) { 492 BREAK_TO_DEBUGGER(); 493 return false; 494 } 495 if (!convert_to_custom_float_format(corner_points[0].green.offset, &fmt, 496 &corner_points[0].green.custom_float_offset)) { 497 BREAK_TO_DEBUGGER(); 498 return false; 499 } 500 if (!convert_to_custom_float_format(corner_points[0].blue.offset, &fmt, 501 &corner_points[0].blue.custom_float_offset)) { 502 BREAK_TO_DEBUGGER(); 503 return false; 504 } 505 506 if (!convert_to_custom_float_format(corner_points[0].red.slope, &fmt, 507 &corner_points[0].red.custom_float_slope)) { 508 BREAK_TO_DEBUGGER(); 509 return false; 510 } 511 if (!convert_to_custom_float_format(corner_points[0].green.slope, &fmt, 512 &corner_points[0].green.custom_float_slope)) { 513 BREAK_TO_DEBUGGER(); 514 return false; 515 } 516 if (!convert_to_custom_float_format(corner_points[0].blue.slope, &fmt, 517 &corner_points[0].blue.custom_float_slope)) { 518 BREAK_TO_DEBUGGER(); 519 return false; 520 } 521 522 if (fixpoint == true) { 523 corner_points[1].red.custom_float_y = 524 dc_fixpt_clamp_u0d14(corner_points[1].red.y); 525 corner_points[1].green.custom_float_y = 526 dc_fixpt_clamp_u0d14(corner_points[1].green.y); 527 corner_points[1].blue.custom_float_y = 528 dc_fixpt_clamp_u0d14(corner_points[1].blue.y); 529 } else { 530 if (!convert_to_custom_float_format(corner_points[1].red.y, 531 &fmt, &corner_points[1].red.custom_float_y)) { 532 BREAK_TO_DEBUGGER(); 533 return false; 534 } 535 if (!convert_to_custom_float_format(corner_points[1].green.y, 536 &fmt, &corner_points[1].green.custom_float_y)) { 537 BREAK_TO_DEBUGGER(); 538 return false; 539 } 540 if (!convert_to_custom_float_format(corner_points[1].blue.y, 541 &fmt, &corner_points[1].blue.custom_float_y)) { 542 BREAK_TO_DEBUGGER(); 543 return false; 544 } 545 } 546 547 fmt.mantissa_bits = 10; 548 fmt.sign = false; 549 550 if (!convert_to_custom_float_format(corner_points[1].red.x, &fmt, 551 &corner_points[1].red.custom_float_x)) { 552 BREAK_TO_DEBUGGER(); 553 return false; 554 } 555 if (!convert_to_custom_float_format(corner_points[1].green.x, &fmt, 556 &corner_points[1].green.custom_float_x)) { 557 BREAK_TO_DEBUGGER(); 558 return false; 559 } 560 if (!convert_to_custom_float_format(corner_points[1].blue.x, &fmt, 561 &corner_points[1].blue.custom_float_x)) { 562 BREAK_TO_DEBUGGER(); 563 return false; 564 } 565 566 if (!convert_to_custom_float_format(corner_points[1].red.slope, &fmt, 567 &corner_points[1].red.custom_float_slope)) { 568 BREAK_TO_DEBUGGER(); 569 return false; 570 } 571 if (!convert_to_custom_float_format(corner_points[1].green.slope, &fmt, 572 &corner_points[1].green.custom_float_slope)) { 573 BREAK_TO_DEBUGGER(); 574 return false; 575 } 576 if (!convert_to_custom_float_format(corner_points[1].blue.slope, &fmt, 577 &corner_points[1].blue.custom_float_slope)) { 578 BREAK_TO_DEBUGGER(); 579 return false; 580 } 581 582 if (hw_points_num == 0 || rgb_resulted == NULL || fixpoint == true) 583 return true; 584 585 fmt.mantissa_bits = 12; 586 587 while (i != hw_points_num) { 588 if (!convert_to_custom_float_format(rgb->red, &fmt, 589 &rgb->red_reg)) { 590 BREAK_TO_DEBUGGER(); 591 return false; 592 } 593 594 if (!convert_to_custom_float_format(rgb->green, &fmt, 595 &rgb->green_reg)) { 596 BREAK_TO_DEBUGGER(); 597 return false; 598 } 599 600 if (!convert_to_custom_float_format(rgb->blue, &fmt, 601 &rgb->blue_reg)) { 602 BREAK_TO_DEBUGGER(); 603 return false; 604 } 605 606 if (!convert_to_custom_float_format(rgb->delta_red, &fmt, 607 &rgb->delta_red_reg)) { 608 BREAK_TO_DEBUGGER(); 609 return false; 610 } 611 612 if (!convert_to_custom_float_format(rgb->delta_green, &fmt, 613 &rgb->delta_green_reg)) { 614 BREAK_TO_DEBUGGER(); 615 return false; 616 } 617 618 if (!convert_to_custom_float_format(rgb->delta_blue, &fmt, 619 &rgb->delta_blue_reg)) { 620 BREAK_TO_DEBUGGER(); 621 return false; 622 } 623 624 ++rgb; 625 ++i; 626 } 627 628 return true; 629} 630 631bool is_rgb_equal(const struct pwl_result_data *rgb, uint32_t num) 632{ 633 uint32_t i; 634 bool ret = true; 635 636 for (i = 0 ; i < num; i++) { 637 if (rgb[i].red_reg != rgb[i].green_reg || 638 rgb[i].blue_reg != rgb[i].red_reg || 639 rgb[i].blue_reg != rgb[i].green_reg) { 640 ret = false; 641 break; 642 } 643 } 644 return ret; 645} 646