root/drivers/gpu/drm/amd/display/dc/dce110/dce110_transform_v.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. calculate_viewport
  2. program_viewport
  3. setup_scaling_configuration
  4. program_overscan
  5. set_coeff_update_complete
  6. program_multi_taps_filter
  7. calculate_inits
  8. program_scl_ratios_inits
  9. get_filter_coeffs_64p
  10. dce110_xfmv_power_up_line_buffer
  11. dce110_xfmv_set_scaler
  12. dce110_xfmv_reset
  13. dce110_xfmv_set_gamut_remap
  14. dce110_xfmv_set_pixel_storage_depth
  15. dce110_transform_v_construct

   1 /*
   2  * Copyright 2012-15 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 <linux/delay.h>
  27 
  28 #include "dce110_transform_v.h"
  29 #include "dm_services.h"
  30 #include "dc.h"
  31 #include "dce/dce_11_0_d.h"
  32 #include "dce/dce_11_0_sh_mask.h"
  33 
  34 #define SCLV_PHASES 64
  35 #define DC_LOGGER \
  36         xfm->ctx->logger
  37 
  38 struct sclv_ratios_inits {
  39         uint32_t h_int_scale_ratio_luma;
  40         uint32_t h_int_scale_ratio_chroma;
  41         uint32_t v_int_scale_ratio_luma;
  42         uint32_t v_int_scale_ratio_chroma;
  43         struct init_int_and_frac h_init_luma;
  44         struct init_int_and_frac h_init_chroma;
  45         struct init_int_and_frac v_init_luma;
  46         struct init_int_and_frac v_init_chroma;
  47 };
  48 
  49 static void calculate_viewport(
  50                 const struct scaler_data *scl_data,
  51                 struct rect *luma_viewport,
  52                 struct rect *chroma_viewport)
  53 {
  54         /*Do not set chroma vp for rgb444 pixel format*/
  55         luma_viewport->x = scl_data->viewport.x - scl_data->viewport.x % 2;
  56         luma_viewport->y = scl_data->viewport.y - scl_data->viewport.y % 2;
  57         luma_viewport->width =
  58                 scl_data->viewport.width - scl_data->viewport.width % 2;
  59         luma_viewport->height =
  60                 scl_data->viewport.height - scl_data->viewport.height % 2;
  61         chroma_viewport->x = luma_viewport->x;
  62         chroma_viewport->y = luma_viewport->y;
  63         chroma_viewport->height = luma_viewport->height;
  64         chroma_viewport->width = luma_viewport->width;
  65 
  66         if (scl_data->format == PIXEL_FORMAT_420BPP8) {
  67                 luma_viewport->height += luma_viewport->height % 2;
  68                 luma_viewport->width += luma_viewport->width % 2;
  69                 /*for 420 video chroma is 1/4 the area of luma, scaled
  70                  *vertically and horizontally
  71                  */
  72                 chroma_viewport->x = luma_viewport->x / 2;
  73                 chroma_viewport->y = luma_viewport->y / 2;
  74                 chroma_viewport->height = luma_viewport->height / 2;
  75                 chroma_viewport->width = luma_viewport->width / 2;
  76         }
  77 }
  78 
  79 static void program_viewport(
  80         struct dce_transform *xfm_dce,
  81         struct rect *luma_view_port,
  82         struct rect *chroma_view_port)
  83 {
  84         struct dc_context *ctx = xfm_dce->base.ctx;
  85         uint32_t value = 0;
  86         uint32_t addr = 0;
  87 
  88         if (luma_view_port->width != 0 && luma_view_port->height != 0) {
  89                 addr = mmSCLV_VIEWPORT_START;
  90                 value = 0;
  91                 set_reg_field_value(
  92                         value,
  93                         luma_view_port->x,
  94                         SCLV_VIEWPORT_START,
  95                         VIEWPORT_X_START);
  96                 set_reg_field_value(
  97                         value,
  98                         luma_view_port->y,
  99                         SCLV_VIEWPORT_START,
 100                         VIEWPORT_Y_START);
 101                 dm_write_reg(ctx, addr, value);
 102 
 103                 addr = mmSCLV_VIEWPORT_SIZE;
 104                 value = 0;
 105                 set_reg_field_value(
 106                         value,
 107                         luma_view_port->height,
 108                         SCLV_VIEWPORT_SIZE,
 109                         VIEWPORT_HEIGHT);
 110                 set_reg_field_value(
 111                         value,
 112                         luma_view_port->width,
 113                         SCLV_VIEWPORT_SIZE,
 114                         VIEWPORT_WIDTH);
 115                 dm_write_reg(ctx, addr, value);
 116         }
 117 
 118         if (chroma_view_port->width != 0 && chroma_view_port->height != 0) {
 119                 addr = mmSCLV_VIEWPORT_START_C;
 120                 value = 0;
 121                 set_reg_field_value(
 122                         value,
 123                         chroma_view_port->x,
 124                         SCLV_VIEWPORT_START_C,
 125                         VIEWPORT_X_START_C);
 126                 set_reg_field_value(
 127                         value,
 128                         chroma_view_port->y,
 129                         SCLV_VIEWPORT_START_C,
 130                         VIEWPORT_Y_START_C);
 131                 dm_write_reg(ctx, addr, value);
 132 
 133                 addr = mmSCLV_VIEWPORT_SIZE_C;
 134                 value = 0;
 135                 set_reg_field_value(
 136                         value,
 137                         chroma_view_port->height,
 138                         SCLV_VIEWPORT_SIZE_C,
 139                         VIEWPORT_HEIGHT_C);
 140                 set_reg_field_value(
 141                         value,
 142                         chroma_view_port->width,
 143                         SCLV_VIEWPORT_SIZE_C,
 144                         VIEWPORT_WIDTH_C);
 145                 dm_write_reg(ctx, addr, value);
 146         }
 147 }
 148 
 149 /*
 150  * Function:
 151  * void setup_scaling_configuration
 152  *
 153  * Purpose: setup scaling mode : bypass, RGb, YCbCr and nummber of taps
 154  * Input:   data
 155  *
 156  * Output:
 157  *  void
 158  */
 159 static bool setup_scaling_configuration(
 160         struct dce_transform *xfm_dce,
 161         const struct scaler_data *data)
 162 {
 163         bool is_scaling_needed = false;
 164         struct dc_context *ctx = xfm_dce->base.ctx;
 165         uint32_t value = 0;
 166 
 167         set_reg_field_value(value, data->taps.h_taps - 1,
 168                         SCLV_TAP_CONTROL, SCL_H_NUM_OF_TAPS);
 169         set_reg_field_value(value, data->taps.v_taps - 1,
 170                         SCLV_TAP_CONTROL, SCL_V_NUM_OF_TAPS);
 171         set_reg_field_value(value, data->taps.h_taps_c - 1,
 172                         SCLV_TAP_CONTROL, SCL_H_NUM_OF_TAPS_C);
 173         set_reg_field_value(value, data->taps.v_taps_c - 1,
 174                         SCLV_TAP_CONTROL, SCL_V_NUM_OF_TAPS_C);
 175         dm_write_reg(ctx, mmSCLV_TAP_CONTROL, value);
 176 
 177         value = 0;
 178         if (data->taps.h_taps + data->taps.v_taps > 2) {
 179                 set_reg_field_value(value, 1, SCLV_MODE, SCL_MODE);
 180                 set_reg_field_value(value, 1, SCLV_MODE, SCL_PSCL_EN);
 181                 is_scaling_needed = true;
 182         } else {
 183                 set_reg_field_value(value, 0, SCLV_MODE, SCL_MODE);
 184                 set_reg_field_value(value, 0, SCLV_MODE, SCL_PSCL_EN);
 185         }
 186 
 187         if (data->taps.h_taps_c + data->taps.v_taps_c > 2) {
 188                 set_reg_field_value(value, 1, SCLV_MODE, SCL_MODE_C);
 189                 set_reg_field_value(value, 1, SCLV_MODE, SCL_PSCL_EN_C);
 190                 is_scaling_needed = true;
 191         } else if (data->format != PIXEL_FORMAT_420BPP8) {
 192                 set_reg_field_value(
 193                         value,
 194                         get_reg_field_value(value, SCLV_MODE, SCL_MODE),
 195                         SCLV_MODE,
 196                         SCL_MODE_C);
 197                 set_reg_field_value(
 198                         value,
 199                         get_reg_field_value(value, SCLV_MODE, SCL_PSCL_EN),
 200                         SCLV_MODE,
 201                         SCL_PSCL_EN_C);
 202         } else {
 203                 set_reg_field_value(value, 0, SCLV_MODE, SCL_MODE_C);
 204                 set_reg_field_value(value, 0, SCLV_MODE, SCL_PSCL_EN_C);
 205         }
 206         dm_write_reg(ctx, mmSCLV_MODE, value);
 207 
 208         value = 0;
 209         /*
 210          * 0 - Replaced out of bound pixels with black pixel
 211          * (or any other required color)
 212          * 1 - Replaced out of bound pixels with the edge pixel
 213          */
 214         set_reg_field_value(value, 1, SCLV_CONTROL, SCL_BOUNDARY_MODE);
 215         dm_write_reg(ctx, mmSCLV_CONTROL, value);
 216 
 217         return is_scaling_needed;
 218 }
 219 
 220 /**
 221 * Function:
 222 * void program_overscan
 223 *
 224 * Purpose: Programs overscan border
 225 * Input:   overscan
 226 *
 227 * Output:
 228    void
 229 */
 230 static void program_overscan(
 231                 struct dce_transform *xfm_dce,
 232                 const struct scaler_data *data)
 233 {
 234         uint32_t overscan_left_right = 0;
 235         uint32_t overscan_top_bottom = 0;
 236 
 237         int overscan_right = data->h_active - data->recout.x - data->recout.width;
 238         int overscan_bottom = data->v_active - data->recout.y - data->recout.height;
 239 
 240         if (xfm_dce->base.ctx->dc->debug.visual_confirm != VISUAL_CONFIRM_DISABLE) {
 241                 overscan_bottom += 2;
 242                 overscan_right += 2;
 243         }
 244 
 245         if (overscan_right < 0) {
 246                 BREAK_TO_DEBUGGER();
 247                 overscan_right = 0;
 248         }
 249         if (overscan_bottom < 0) {
 250                 BREAK_TO_DEBUGGER();
 251                 overscan_bottom = 0;
 252         }
 253 
 254         set_reg_field_value(overscan_left_right, data->recout.x,
 255                         EXT_OVERSCAN_LEFT_RIGHT, EXT_OVERSCAN_LEFT);
 256 
 257         set_reg_field_value(overscan_left_right, overscan_right,
 258                         EXT_OVERSCAN_LEFT_RIGHT, EXT_OVERSCAN_RIGHT);
 259 
 260         set_reg_field_value(overscan_top_bottom, data->recout.y,
 261                         EXT_OVERSCAN_TOP_BOTTOM, EXT_OVERSCAN_TOP);
 262 
 263         set_reg_field_value(overscan_top_bottom, overscan_bottom,
 264                         EXT_OVERSCAN_TOP_BOTTOM, EXT_OVERSCAN_BOTTOM);
 265 
 266         dm_write_reg(xfm_dce->base.ctx,
 267                         mmSCLV_EXT_OVERSCAN_LEFT_RIGHT,
 268                         overscan_left_right);
 269 
 270         dm_write_reg(xfm_dce->base.ctx,
 271                         mmSCLV_EXT_OVERSCAN_TOP_BOTTOM,
 272                         overscan_top_bottom);
 273 }
 274 
 275 static void set_coeff_update_complete(
 276                 struct dce_transform *xfm_dce)
 277 {
 278         uint32_t value;
 279 
 280         value = dm_read_reg(xfm_dce->base.ctx, mmSCLV_UPDATE);
 281         set_reg_field_value(value, 1, SCLV_UPDATE, SCL_COEF_UPDATE_COMPLETE);
 282         dm_write_reg(xfm_dce->base.ctx, mmSCLV_UPDATE, value);
 283 }
 284 
 285 static void program_multi_taps_filter(
 286         struct dce_transform *xfm_dce,
 287         int taps,
 288         const uint16_t *coeffs,
 289         enum ram_filter_type filter_type)
 290 {
 291         struct dc_context *ctx = xfm_dce->base.ctx;
 292         int i, phase, pair;
 293         int array_idx = 0;
 294         int taps_pairs = (taps + 1) / 2;
 295         int phases_to_program = SCLV_PHASES / 2 + 1;
 296 
 297         uint32_t select = 0;
 298         uint32_t power_ctl, power_ctl_off;
 299 
 300         if (!coeffs)
 301                 return;
 302 
 303         /*We need to disable power gating on coeff memory to do programming*/
 304         power_ctl = dm_read_reg(ctx, mmDCFEV_MEM_PWR_CTRL);
 305         power_ctl_off = power_ctl;
 306         set_reg_field_value(power_ctl_off, 1, DCFEV_MEM_PWR_CTRL, SCLV_COEFF_MEM_PWR_DIS);
 307         dm_write_reg(ctx, mmDCFEV_MEM_PWR_CTRL, power_ctl_off);
 308 
 309         /*Wait to disable gating:*/
 310         for (i = 0; i < 10; i++) {
 311                 if (get_reg_field_value(
 312                                 dm_read_reg(ctx, mmDCFEV_MEM_PWR_STATUS),
 313                                 DCFEV_MEM_PWR_STATUS,
 314                                 SCLV_COEFF_MEM_PWR_STATE) == 0)
 315                         break;
 316 
 317                 udelay(1);
 318         }
 319 
 320         set_reg_field_value(select, filter_type, SCLV_COEF_RAM_SELECT, SCL_C_RAM_FILTER_TYPE);
 321 
 322         for (phase = 0; phase < phases_to_program; phase++) {
 323                 /*we always program N/2 + 1 phases, total phases N, but N/2-1 are just mirror
 324                 phase 0 is unique and phase N/2 is unique if N is even*/
 325                 set_reg_field_value(select, phase, SCLV_COEF_RAM_SELECT, SCL_C_RAM_PHASE);
 326                 for (pair = 0; pair < taps_pairs; pair++) {
 327                         uint32_t data = 0;
 328 
 329                         set_reg_field_value(select, pair,
 330                                         SCLV_COEF_RAM_SELECT, SCL_C_RAM_TAP_PAIR_IDX);
 331 
 332                         dm_write_reg(ctx, mmSCLV_COEF_RAM_SELECT, select);
 333 
 334                         set_reg_field_value(
 335                                         data, 1,
 336                                         SCLV_COEF_RAM_TAP_DATA,
 337                                         SCL_C_RAM_EVEN_TAP_COEF_EN);
 338                         set_reg_field_value(
 339                                         data, coeffs[array_idx],
 340                                         SCLV_COEF_RAM_TAP_DATA,
 341                                         SCL_C_RAM_EVEN_TAP_COEF);
 342 
 343                         if (taps % 2 && pair == taps_pairs - 1) {
 344                                 set_reg_field_value(
 345                                                 data, 0,
 346                                                 SCLV_COEF_RAM_TAP_DATA,
 347                                                 SCL_C_RAM_ODD_TAP_COEF_EN);
 348                                 array_idx++;
 349                         } else {
 350                                 set_reg_field_value(
 351                                                 data, 1,
 352                                                 SCLV_COEF_RAM_TAP_DATA,
 353                                                 SCL_C_RAM_ODD_TAP_COEF_EN);
 354                                 set_reg_field_value(
 355                                                 data, coeffs[array_idx + 1],
 356                                                 SCLV_COEF_RAM_TAP_DATA,
 357                                                 SCL_C_RAM_ODD_TAP_COEF);
 358 
 359                                 array_idx += 2;
 360                         }
 361 
 362                         dm_write_reg(ctx, mmSCLV_COEF_RAM_TAP_DATA, data);
 363                 }
 364         }
 365 
 366         /*We need to restore power gating on coeff memory to initial state*/
 367         dm_write_reg(ctx, mmDCFEV_MEM_PWR_CTRL, power_ctl);
 368 }
 369 
 370 static void calculate_inits(
 371         struct dce_transform *xfm_dce,
 372         const struct scaler_data *data,
 373         struct sclv_ratios_inits *inits,
 374         struct rect *luma_viewport,
 375         struct rect *chroma_viewport)
 376 {
 377         inits->h_int_scale_ratio_luma =
 378                 dc_fixpt_u2d19(data->ratios.horz) << 5;
 379         inits->v_int_scale_ratio_luma =
 380                 dc_fixpt_u2d19(data->ratios.vert) << 5;
 381         inits->h_int_scale_ratio_chroma =
 382                 dc_fixpt_u2d19(data->ratios.horz_c) << 5;
 383         inits->v_int_scale_ratio_chroma =
 384                 dc_fixpt_u2d19(data->ratios.vert_c) << 5;
 385 
 386         inits->h_init_luma.integer = 1;
 387         inits->v_init_luma.integer = 1;
 388         inits->h_init_chroma.integer = 1;
 389         inits->v_init_chroma.integer = 1;
 390 }
 391 
 392 static void program_scl_ratios_inits(
 393         struct dce_transform *xfm_dce,
 394         struct sclv_ratios_inits *inits)
 395 {
 396         struct dc_context *ctx = xfm_dce->base.ctx;
 397         uint32_t addr = mmSCLV_HORZ_FILTER_SCALE_RATIO;
 398         uint32_t value = 0;
 399 
 400         set_reg_field_value(
 401                 value,
 402                 inits->h_int_scale_ratio_luma,
 403                 SCLV_HORZ_FILTER_SCALE_RATIO,
 404                 SCL_H_SCALE_RATIO);
 405         dm_write_reg(ctx, addr, value);
 406 
 407         addr = mmSCLV_VERT_FILTER_SCALE_RATIO;
 408         value = 0;
 409         set_reg_field_value(
 410                 value,
 411                 inits->v_int_scale_ratio_luma,
 412                 SCLV_VERT_FILTER_SCALE_RATIO,
 413                 SCL_V_SCALE_RATIO);
 414         dm_write_reg(ctx, addr, value);
 415 
 416         addr = mmSCLV_HORZ_FILTER_SCALE_RATIO_C;
 417         value = 0;
 418         set_reg_field_value(
 419                 value,
 420                 inits->h_int_scale_ratio_chroma,
 421                 SCLV_HORZ_FILTER_SCALE_RATIO_C,
 422                 SCL_H_SCALE_RATIO_C);
 423         dm_write_reg(ctx, addr, value);
 424 
 425         addr = mmSCLV_VERT_FILTER_SCALE_RATIO_C;
 426         value = 0;
 427         set_reg_field_value(
 428                 value,
 429                 inits->v_int_scale_ratio_chroma,
 430                 SCLV_VERT_FILTER_SCALE_RATIO_C,
 431                 SCL_V_SCALE_RATIO_C);
 432         dm_write_reg(ctx, addr, value);
 433 
 434         addr = mmSCLV_HORZ_FILTER_INIT;
 435         value = 0;
 436         set_reg_field_value(
 437                 value,
 438                 inits->h_init_luma.fraction,
 439                 SCLV_HORZ_FILTER_INIT,
 440                 SCL_H_INIT_FRAC);
 441         set_reg_field_value(
 442                 value,
 443                 inits->h_init_luma.integer,
 444                 SCLV_HORZ_FILTER_INIT,
 445                 SCL_H_INIT_INT);
 446         dm_write_reg(ctx, addr, value);
 447 
 448         addr = mmSCLV_VERT_FILTER_INIT;
 449         value = 0;
 450         set_reg_field_value(
 451                 value,
 452                 inits->v_init_luma.fraction,
 453                 SCLV_VERT_FILTER_INIT,
 454                 SCL_V_INIT_FRAC);
 455         set_reg_field_value(
 456                 value,
 457                 inits->v_init_luma.integer,
 458                 SCLV_VERT_FILTER_INIT,
 459                 SCL_V_INIT_INT);
 460         dm_write_reg(ctx, addr, value);
 461 
 462         addr = mmSCLV_HORZ_FILTER_INIT_C;
 463         value = 0;
 464         set_reg_field_value(
 465                 value,
 466                 inits->h_init_chroma.fraction,
 467                 SCLV_HORZ_FILTER_INIT_C,
 468                 SCL_H_INIT_FRAC_C);
 469         set_reg_field_value(
 470                 value,
 471                 inits->h_init_chroma.integer,
 472                 SCLV_HORZ_FILTER_INIT_C,
 473                 SCL_H_INIT_INT_C);
 474         dm_write_reg(ctx, addr, value);
 475 
 476         addr = mmSCLV_VERT_FILTER_INIT_C;
 477         value = 0;
 478         set_reg_field_value(
 479                 value,
 480                 inits->v_init_chroma.fraction,
 481                 SCLV_VERT_FILTER_INIT_C,
 482                 SCL_V_INIT_FRAC_C);
 483         set_reg_field_value(
 484                 value,
 485                 inits->v_init_chroma.integer,
 486                 SCLV_VERT_FILTER_INIT_C,
 487                 SCL_V_INIT_INT_C);
 488         dm_write_reg(ctx, addr, value);
 489 }
 490 
 491 static const uint16_t *get_filter_coeffs_64p(int taps, struct fixed31_32 ratio)
 492 {
 493         if (taps == 4)
 494                 return get_filter_4tap_64p(ratio);
 495         else if (taps == 2)
 496                 return get_filter_2tap_64p();
 497         else if (taps == 1)
 498                 return NULL;
 499         else {
 500                 /* should never happen, bug */
 501                 BREAK_TO_DEBUGGER();
 502                 return NULL;
 503         }
 504 }
 505 
 506 static bool dce110_xfmv_power_up_line_buffer(struct transform *xfm)
 507 {
 508         struct dce_transform *xfm_dce = TO_DCE_TRANSFORM(xfm);
 509         uint32_t value;
 510 
 511         value = dm_read_reg(xfm_dce->base.ctx, mmLBV_MEMORY_CTRL);
 512 
 513         /*Use all three pieces of memory always*/
 514         set_reg_field_value(value, 0, LBV_MEMORY_CTRL, LB_MEMORY_CONFIG);
 515         /*hard coded number DCE11 1712(0x6B0) Partitions: 720/960/1712*/
 516         set_reg_field_value(value, xfm_dce->lb_memory_size, LBV_MEMORY_CTRL,
 517                         LB_MEMORY_SIZE);
 518 
 519         dm_write_reg(xfm_dce->base.ctx, mmLBV_MEMORY_CTRL, value);
 520 
 521         return true;
 522 }
 523 
 524 static void dce110_xfmv_set_scaler(
 525         struct transform *xfm,
 526         const struct scaler_data *data)
 527 {
 528         struct dce_transform *xfm_dce = TO_DCE_TRANSFORM(xfm);
 529         bool is_scaling_required = false;
 530         bool filter_updated = false;
 531         const uint16_t *coeffs_v, *coeffs_h, *coeffs_h_c, *coeffs_v_c;
 532         struct rect luma_viewport = {0};
 533         struct rect chroma_viewport = {0};
 534 
 535         dce110_xfmv_power_up_line_buffer(xfm);
 536         /* 1. Calculate viewport, viewport programming should happen after init
 537          * calculations as they may require an adjustment in the viewport.
 538          */
 539 
 540         calculate_viewport(data, &luma_viewport, &chroma_viewport);
 541 
 542         /* 2. Program overscan */
 543         program_overscan(xfm_dce, data);
 544 
 545         /* 3. Program taps and configuration */
 546         is_scaling_required = setup_scaling_configuration(xfm_dce, data);
 547 
 548         if (is_scaling_required) {
 549                 /* 4. Calculate and program ratio, filter initialization */
 550 
 551                 struct sclv_ratios_inits inits = { 0 };
 552 
 553                 calculate_inits(
 554                         xfm_dce,
 555                         data,
 556                         &inits,
 557                         &luma_viewport,
 558                         &chroma_viewport);
 559 
 560                 program_scl_ratios_inits(xfm_dce, &inits);
 561 
 562                 coeffs_v = get_filter_coeffs_64p(data->taps.v_taps, data->ratios.vert);
 563                 coeffs_h = get_filter_coeffs_64p(data->taps.h_taps, data->ratios.horz);
 564                 coeffs_v_c = get_filter_coeffs_64p(data->taps.v_taps_c, data->ratios.vert_c);
 565                 coeffs_h_c = get_filter_coeffs_64p(data->taps.h_taps_c, data->ratios.horz_c);
 566 
 567                 if (coeffs_v != xfm_dce->filter_v
 568                                 || coeffs_v_c != xfm_dce->filter_v_c
 569                                 || coeffs_h != xfm_dce->filter_h
 570                                 || coeffs_h_c != xfm_dce->filter_h_c) {
 571                 /* 5. Program vertical filters */
 572                         program_multi_taps_filter(
 573                                         xfm_dce,
 574                                         data->taps.v_taps,
 575                                         coeffs_v,
 576                                         FILTER_TYPE_RGB_Y_VERTICAL);
 577                         program_multi_taps_filter(
 578                                         xfm_dce,
 579                                         data->taps.v_taps_c,
 580                                         coeffs_v_c,
 581                                         FILTER_TYPE_CBCR_VERTICAL);
 582 
 583                 /* 6. Program horizontal filters */
 584                         program_multi_taps_filter(
 585                                         xfm_dce,
 586                                         data->taps.h_taps,
 587                                         coeffs_h,
 588                                         FILTER_TYPE_RGB_Y_HORIZONTAL);
 589                         program_multi_taps_filter(
 590                                         xfm_dce,
 591                                         data->taps.h_taps_c,
 592                                         coeffs_h_c,
 593                                         FILTER_TYPE_CBCR_HORIZONTAL);
 594 
 595                         xfm_dce->filter_v = coeffs_v;
 596                         xfm_dce->filter_v_c = coeffs_v_c;
 597                         xfm_dce->filter_h = coeffs_h;
 598                         xfm_dce->filter_h_c = coeffs_h_c;
 599                         filter_updated = true;
 600                 }
 601         }
 602 
 603         /* 7. Program the viewport */
 604         program_viewport(xfm_dce, &luma_viewport, &chroma_viewport);
 605 
 606         /* 8. Set bit to flip to new coefficient memory */
 607         if (filter_updated)
 608                 set_coeff_update_complete(xfm_dce);
 609 }
 610 
 611 static void dce110_xfmv_reset(struct transform *xfm)
 612 {
 613         struct dce_transform *xfm_dce = TO_DCE_TRANSFORM(xfm);
 614 
 615         xfm_dce->filter_h = NULL;
 616         xfm_dce->filter_v = NULL;
 617         xfm_dce->filter_h_c = NULL;
 618         xfm_dce->filter_v_c = NULL;
 619 }
 620 
 621 static void dce110_xfmv_set_gamut_remap(
 622         struct transform *xfm,
 623         const struct xfm_grph_csc_adjustment *adjust)
 624 {
 625         /* DO NOTHING*/
 626 }
 627 
 628 static void dce110_xfmv_set_pixel_storage_depth(
 629         struct transform *xfm,
 630         enum lb_pixel_depth depth,
 631         const struct bit_depth_reduction_params *bit_depth_params)
 632 {
 633         struct dce_transform *xfm_dce = TO_DCE_TRANSFORM(xfm);
 634         int pixel_depth = 0;
 635         int expan_mode = 0;
 636         uint32_t reg_data = 0;
 637 
 638         switch (depth) {
 639         case LB_PIXEL_DEPTH_18BPP:
 640                 pixel_depth = 2;
 641                 expan_mode  = 1;
 642                 break;
 643         case LB_PIXEL_DEPTH_24BPP:
 644                 pixel_depth = 1;
 645                 expan_mode  = 1;
 646                 break;
 647         case LB_PIXEL_DEPTH_30BPP:
 648                 pixel_depth = 0;
 649                 expan_mode  = 1;
 650                 break;
 651         case LB_PIXEL_DEPTH_36BPP:
 652                 pixel_depth = 3;
 653                 expan_mode  = 0;
 654                 break;
 655         default:
 656                 BREAK_TO_DEBUGGER();
 657                 break;
 658         }
 659 
 660         set_reg_field_value(
 661                 reg_data,
 662                 expan_mode,
 663                 LBV_DATA_FORMAT,
 664                 PIXEL_EXPAN_MODE);
 665 
 666         set_reg_field_value(
 667                 reg_data,
 668                 pixel_depth,
 669                 LBV_DATA_FORMAT,
 670                 PIXEL_DEPTH);
 671 
 672         dm_write_reg(xfm->ctx, mmLBV_DATA_FORMAT, reg_data);
 673 
 674         if (!(xfm_dce->lb_pixel_depth_supported & depth)) {
 675                 /*we should use unsupported capabilities
 676                  *  unless it is required by w/a*/
 677                 DC_LOG_WARNING("%s: Capability not supported",
 678                         __func__);
 679         }
 680 }
 681 
 682 static const struct transform_funcs dce110_xfmv_funcs = {
 683         .transform_reset = dce110_xfmv_reset,
 684         .transform_set_scaler = dce110_xfmv_set_scaler,
 685         .transform_set_gamut_remap =
 686                 dce110_xfmv_set_gamut_remap,
 687         .opp_set_csc_default = dce110_opp_v_set_csc_default,
 688         .opp_set_csc_adjustment = dce110_opp_v_set_csc_adjustment,
 689         .opp_power_on_regamma_lut = dce110_opp_power_on_regamma_lut_v,
 690         .opp_program_regamma_pwl = dce110_opp_program_regamma_pwl_v,
 691         .opp_set_regamma_mode = dce110_opp_set_regamma_mode_v,
 692         .transform_set_pixel_storage_depth =
 693                         dce110_xfmv_set_pixel_storage_depth,
 694         .transform_get_optimal_number_of_taps =
 695                 dce_transform_get_optimal_number_of_taps
 696 };
 697 /*****************************************/
 698 /* Constructor, Destructor               */
 699 /*****************************************/
 700 
 701 bool dce110_transform_v_construct(
 702         struct dce_transform *xfm_dce,
 703         struct dc_context *ctx)
 704 {
 705         xfm_dce->base.ctx = ctx;
 706 
 707         xfm_dce->base.funcs = &dce110_xfmv_funcs;
 708 
 709         xfm_dce->lb_pixel_depth_supported =
 710                         LB_PIXEL_DEPTH_18BPP |
 711                         LB_PIXEL_DEPTH_24BPP |
 712                         LB_PIXEL_DEPTH_30BPP;
 713 
 714         xfm_dce->prescaler_on = true;
 715         xfm_dce->lb_bits_per_entry = LB_BITS_PER_ENTRY;
 716         xfm_dce->lb_memory_size = LB_TOTAL_NUMBER_OF_ENTRIES; /*0x6B0*/
 717 
 718         return true;
 719 }

/* [<][>][^][v][top][bottom][index][help] */