LCOV - code coverage report
Current view: top level - drivers/gpu/drm/amd/display/dc/dce110 - dce110_transform_v.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 273 0.0 %
Date: 2022-12-09 01:23:36 Functions: 0 15 0.0 %

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

Generated by: LCOV version 1.14