14562236bSHarry Wentland /* 24562236bSHarry Wentland * Copyright 2012-15 Advanced Micro Devices, Inc. 34562236bSHarry Wentland * 44562236bSHarry Wentland * Permission is hereby granted, free of charge, to any person obtaining a 54562236bSHarry Wentland * copy of this software and associated documentation files (the "Software"), 64562236bSHarry Wentland * to deal in the Software without restriction, including without limitation 74562236bSHarry Wentland * the rights to use, copy, modify, merge, publish, distribute, sublicense, 84562236bSHarry Wentland * and/or sell copies of the Software, and to permit persons to whom the 94562236bSHarry Wentland * Software is furnished to do so, subject to the following conditions: 104562236bSHarry Wentland * 114562236bSHarry Wentland * The above copyright notice and this permission notice shall be included in 124562236bSHarry Wentland * all copies or substantial portions of the Software. 134562236bSHarry Wentland * 144562236bSHarry Wentland * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 154562236bSHarry Wentland * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 164562236bSHarry Wentland * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 174562236bSHarry Wentland * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 184562236bSHarry Wentland * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 194562236bSHarry Wentland * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 204562236bSHarry Wentland * OTHER DEALINGS IN THE SOFTWARE. 214562236bSHarry Wentland * 224562236bSHarry Wentland * Authors: AMD 234562236bSHarry Wentland * 244562236bSHarry Wentland */ 254562236bSHarry Wentland 264562236bSHarry Wentland #include "dce110_transform_v.h" 274562236bSHarry Wentland #include "dm_services.h" 28ce9c0880SDmytro Laktyushkin #include "dc.h" 294562236bSHarry Wentland #include "dce/dce_11_0_d.h" 304562236bSHarry Wentland #include "dce/dce_11_0_sh_mask.h" 314562236bSHarry Wentland 324562236bSHarry Wentland #define SCLV_PHASES 64 334562236bSHarry Wentland 344562236bSHarry Wentland struct sclv_ratios_inits { 354562236bSHarry Wentland uint32_t h_int_scale_ratio_luma; 364562236bSHarry Wentland uint32_t h_int_scale_ratio_chroma; 374562236bSHarry Wentland uint32_t v_int_scale_ratio_luma; 384562236bSHarry Wentland uint32_t v_int_scale_ratio_chroma; 394562236bSHarry Wentland struct init_int_and_frac h_init_luma; 404562236bSHarry Wentland struct init_int_and_frac h_init_chroma; 414562236bSHarry Wentland struct init_int_and_frac v_init_luma; 424562236bSHarry Wentland struct init_int_and_frac v_init_chroma; 434562236bSHarry Wentland }; 444562236bSHarry Wentland 454562236bSHarry Wentland static void calculate_viewport( 464562236bSHarry Wentland const struct scaler_data *scl_data, 474562236bSHarry Wentland struct rect *luma_viewport, 484562236bSHarry Wentland struct rect *chroma_viewport) 494562236bSHarry Wentland { 504562236bSHarry Wentland /*Do not set chroma vp for rgb444 pixel format*/ 514562236bSHarry Wentland luma_viewport->x = scl_data->viewport.x - scl_data->viewport.x % 2; 524562236bSHarry Wentland luma_viewport->y = scl_data->viewport.y - scl_data->viewport.y % 2; 534562236bSHarry Wentland luma_viewport->width = 544562236bSHarry Wentland scl_data->viewport.width - scl_data->viewport.width % 2; 554562236bSHarry Wentland luma_viewport->height = 564562236bSHarry Wentland scl_data->viewport.height - scl_data->viewport.height % 2; 574562236bSHarry Wentland chroma_viewport->x = luma_viewport->x; 584562236bSHarry Wentland chroma_viewport->y = luma_viewport->y; 594562236bSHarry Wentland chroma_viewport->height = luma_viewport->height; 604562236bSHarry Wentland chroma_viewport->width = luma_viewport->width; 614562236bSHarry Wentland 6287449a90SAnthony Koo if (scl_data->format == PIXEL_FORMAT_420BPP8) { 634562236bSHarry Wentland luma_viewport->height += luma_viewport->height % 2; 644562236bSHarry Wentland luma_viewport->width += luma_viewport->width % 2; 654562236bSHarry Wentland /*for 420 video chroma is 1/4 the area of luma, scaled 664562236bSHarry Wentland *vertically and horizontally 674562236bSHarry Wentland */ 684562236bSHarry Wentland chroma_viewport->x = luma_viewport->x / 2; 694562236bSHarry Wentland chroma_viewport->y = luma_viewport->y / 2; 704562236bSHarry Wentland chroma_viewport->height = luma_viewport->height / 2; 714562236bSHarry Wentland chroma_viewport->width = luma_viewport->width / 2; 724562236bSHarry Wentland } 734562236bSHarry Wentland } 744562236bSHarry Wentland 754562236bSHarry Wentland static void program_viewport( 764562236bSHarry Wentland struct dce_transform *xfm_dce, 774562236bSHarry Wentland struct rect *luma_view_port, 784562236bSHarry Wentland struct rect *chroma_view_port) 794562236bSHarry Wentland { 804562236bSHarry Wentland struct dc_context *ctx = xfm_dce->base.ctx; 814562236bSHarry Wentland uint32_t value = 0; 824562236bSHarry Wentland uint32_t addr = 0; 834562236bSHarry Wentland 844562236bSHarry Wentland if (luma_view_port->width != 0 && luma_view_port->height != 0) { 854562236bSHarry Wentland addr = mmSCLV_VIEWPORT_START; 864562236bSHarry Wentland value = 0; 874562236bSHarry Wentland set_reg_field_value( 884562236bSHarry Wentland value, 894562236bSHarry Wentland luma_view_port->x, 904562236bSHarry Wentland SCLV_VIEWPORT_START, 914562236bSHarry Wentland VIEWPORT_X_START); 924562236bSHarry Wentland set_reg_field_value( 934562236bSHarry Wentland value, 944562236bSHarry Wentland luma_view_port->y, 954562236bSHarry Wentland SCLV_VIEWPORT_START, 964562236bSHarry Wentland VIEWPORT_Y_START); 974562236bSHarry Wentland dm_write_reg(ctx, addr, value); 984562236bSHarry Wentland 994562236bSHarry Wentland addr = mmSCLV_VIEWPORT_SIZE; 1004562236bSHarry Wentland value = 0; 1014562236bSHarry Wentland set_reg_field_value( 1024562236bSHarry Wentland value, 1034562236bSHarry Wentland luma_view_port->height, 1044562236bSHarry Wentland SCLV_VIEWPORT_SIZE, 1054562236bSHarry Wentland VIEWPORT_HEIGHT); 1064562236bSHarry Wentland set_reg_field_value( 1074562236bSHarry Wentland value, 1084562236bSHarry Wentland luma_view_port->width, 1094562236bSHarry Wentland SCLV_VIEWPORT_SIZE, 1104562236bSHarry Wentland VIEWPORT_WIDTH); 1114562236bSHarry Wentland dm_write_reg(ctx, addr, value); 1124562236bSHarry Wentland } 1134562236bSHarry Wentland 1144562236bSHarry Wentland if (chroma_view_port->width != 0 && chroma_view_port->height != 0) { 1154562236bSHarry Wentland addr = mmSCLV_VIEWPORT_START_C; 1164562236bSHarry Wentland value = 0; 1174562236bSHarry Wentland set_reg_field_value( 1184562236bSHarry Wentland value, 1194562236bSHarry Wentland chroma_view_port->x, 1204562236bSHarry Wentland SCLV_VIEWPORT_START_C, 1214562236bSHarry Wentland VIEWPORT_X_START_C); 1224562236bSHarry Wentland set_reg_field_value( 1234562236bSHarry Wentland value, 1244562236bSHarry Wentland chroma_view_port->y, 1254562236bSHarry Wentland SCLV_VIEWPORT_START_C, 1264562236bSHarry Wentland VIEWPORT_Y_START_C); 1274562236bSHarry Wentland dm_write_reg(ctx, addr, value); 1284562236bSHarry Wentland 1294562236bSHarry Wentland addr = mmSCLV_VIEWPORT_SIZE_C; 1304562236bSHarry Wentland value = 0; 1314562236bSHarry Wentland set_reg_field_value( 1324562236bSHarry Wentland value, 1334562236bSHarry Wentland chroma_view_port->height, 1344562236bSHarry Wentland SCLV_VIEWPORT_SIZE_C, 1354562236bSHarry Wentland VIEWPORT_HEIGHT_C); 1364562236bSHarry Wentland set_reg_field_value( 1374562236bSHarry Wentland value, 1384562236bSHarry Wentland chroma_view_port->width, 1394562236bSHarry Wentland SCLV_VIEWPORT_SIZE_C, 1404562236bSHarry Wentland VIEWPORT_WIDTH_C); 1414562236bSHarry Wentland dm_write_reg(ctx, addr, value); 1424562236bSHarry Wentland } 1434562236bSHarry Wentland } 1444562236bSHarry Wentland 1454562236bSHarry Wentland /* 1464562236bSHarry Wentland * Function: 1474562236bSHarry Wentland * void setup_scaling_configuration 1484562236bSHarry Wentland * 1494562236bSHarry Wentland * Purpose: setup scaling mode : bypass, RGb, YCbCr and nummber of taps 1504562236bSHarry Wentland * Input: data 1514562236bSHarry Wentland * 1524562236bSHarry Wentland * Output: 1534562236bSHarry Wentland * void 1544562236bSHarry Wentland */ 1554562236bSHarry Wentland static bool setup_scaling_configuration( 1564562236bSHarry Wentland struct dce_transform *xfm_dce, 1574562236bSHarry Wentland const struct scaler_data *data) 1584562236bSHarry Wentland { 1594562236bSHarry Wentland bool is_scaling_needed = false; 1604562236bSHarry Wentland struct dc_context *ctx = xfm_dce->base.ctx; 1614562236bSHarry Wentland uint32_t value = 0; 1624562236bSHarry Wentland 1634562236bSHarry Wentland set_reg_field_value(value, data->taps.h_taps - 1, 1644562236bSHarry Wentland SCLV_TAP_CONTROL, SCL_H_NUM_OF_TAPS); 1654562236bSHarry Wentland set_reg_field_value(value, data->taps.v_taps - 1, 1664562236bSHarry Wentland SCLV_TAP_CONTROL, SCL_V_NUM_OF_TAPS); 1674562236bSHarry Wentland set_reg_field_value(value, data->taps.h_taps_c - 1, 1684562236bSHarry Wentland SCLV_TAP_CONTROL, SCL_H_NUM_OF_TAPS_C); 1694562236bSHarry Wentland set_reg_field_value(value, data->taps.v_taps_c - 1, 1704562236bSHarry Wentland SCLV_TAP_CONTROL, SCL_V_NUM_OF_TAPS_C); 1714562236bSHarry Wentland dm_write_reg(ctx, mmSCLV_TAP_CONTROL, value); 1724562236bSHarry Wentland 1734562236bSHarry Wentland value = 0; 1744562236bSHarry Wentland if (data->taps.h_taps + data->taps.v_taps > 2) { 1754562236bSHarry Wentland set_reg_field_value(value, 1, SCLV_MODE, SCL_MODE); 1764562236bSHarry Wentland set_reg_field_value(value, 1, SCLV_MODE, SCL_PSCL_EN); 1774562236bSHarry Wentland is_scaling_needed = true; 1784562236bSHarry Wentland } else { 1794562236bSHarry Wentland set_reg_field_value(value, 0, SCLV_MODE, SCL_MODE); 1804562236bSHarry Wentland set_reg_field_value(value, 0, SCLV_MODE, SCL_PSCL_EN); 1814562236bSHarry Wentland } 1824562236bSHarry Wentland 1834562236bSHarry Wentland if (data->taps.h_taps_c + data->taps.v_taps_c > 2) { 1844562236bSHarry Wentland set_reg_field_value(value, 1, SCLV_MODE, SCL_MODE_C); 1854562236bSHarry Wentland set_reg_field_value(value, 1, SCLV_MODE, SCL_PSCL_EN_C); 1864562236bSHarry Wentland is_scaling_needed = true; 18787449a90SAnthony Koo } else if (data->format != PIXEL_FORMAT_420BPP8) { 1884562236bSHarry Wentland set_reg_field_value( 1894562236bSHarry Wentland value, 1904562236bSHarry Wentland get_reg_field_value(value, SCLV_MODE, SCL_MODE), 1914562236bSHarry Wentland SCLV_MODE, 1924562236bSHarry Wentland SCL_MODE_C); 1934562236bSHarry Wentland set_reg_field_value( 1944562236bSHarry Wentland value, 1954562236bSHarry Wentland get_reg_field_value(value, SCLV_MODE, SCL_PSCL_EN), 1964562236bSHarry Wentland SCLV_MODE, 1974562236bSHarry Wentland SCL_PSCL_EN_C); 1984562236bSHarry Wentland } else { 1994562236bSHarry Wentland set_reg_field_value(value, 0, SCLV_MODE, SCL_MODE_C); 2004562236bSHarry Wentland set_reg_field_value(value, 0, SCLV_MODE, SCL_PSCL_EN_C); 2014562236bSHarry Wentland } 2024562236bSHarry Wentland dm_write_reg(ctx, mmSCLV_MODE, value); 2034562236bSHarry Wentland 2044562236bSHarry Wentland value = 0; 2054562236bSHarry Wentland /* 2064562236bSHarry Wentland * 0 - Replaced out of bound pixels with black pixel 2074562236bSHarry Wentland * (or any other required color) 2084562236bSHarry Wentland * 1 - Replaced out of bound pixels with the edge pixel 2094562236bSHarry Wentland */ 2104562236bSHarry Wentland set_reg_field_value(value, 1, SCLV_CONTROL, SCL_BOUNDARY_MODE); 2114562236bSHarry Wentland dm_write_reg(ctx, mmSCLV_CONTROL, value); 2124562236bSHarry Wentland 2134562236bSHarry Wentland return is_scaling_needed; 2144562236bSHarry Wentland } 2154562236bSHarry Wentland 2164562236bSHarry Wentland /** 2174562236bSHarry Wentland * Function: 2184562236bSHarry Wentland * void program_overscan 2194562236bSHarry Wentland * 2204562236bSHarry Wentland * Purpose: Programs overscan border 2214562236bSHarry Wentland * Input: overscan 2224562236bSHarry Wentland * 2234562236bSHarry Wentland * Output: 2244562236bSHarry Wentland void 2254562236bSHarry Wentland */ 2264562236bSHarry Wentland static void program_overscan( 2274562236bSHarry Wentland struct dce_transform *xfm_dce, 2284562236bSHarry Wentland const struct scaler_data *data) 2294562236bSHarry Wentland { 2304562236bSHarry Wentland uint32_t overscan_left_right = 0; 2314562236bSHarry Wentland uint32_t overscan_top_bottom = 0; 2324562236bSHarry Wentland 2334562236bSHarry Wentland int overscan_right = data->h_active - data->recout.x - data->recout.width; 2344562236bSHarry Wentland int overscan_bottom = data->v_active - data->recout.y - data->recout.height; 2354562236bSHarry Wentland 236ce9c0880SDmytro Laktyushkin if (xfm_dce->base.ctx->dc->debug.surface_visual_confirm) { 237ce9c0880SDmytro Laktyushkin overscan_bottom += 2; 238ce9c0880SDmytro Laktyushkin overscan_right += 2; 239ce9c0880SDmytro Laktyushkin } 240ce9c0880SDmytro Laktyushkin 2414562236bSHarry Wentland if (overscan_right < 0) { 2424562236bSHarry Wentland BREAK_TO_DEBUGGER(); 2434562236bSHarry Wentland overscan_right = 0; 2444562236bSHarry Wentland } 2454562236bSHarry Wentland if (overscan_bottom < 0) { 2464562236bSHarry Wentland BREAK_TO_DEBUGGER(); 2474562236bSHarry Wentland overscan_bottom = 0; 2484562236bSHarry Wentland } 2494562236bSHarry Wentland 2504562236bSHarry Wentland set_reg_field_value(overscan_left_right, data->recout.x, 2514562236bSHarry Wentland EXT_OVERSCAN_LEFT_RIGHT, EXT_OVERSCAN_LEFT); 2524562236bSHarry Wentland 2534562236bSHarry Wentland set_reg_field_value(overscan_left_right, overscan_right, 2544562236bSHarry Wentland EXT_OVERSCAN_LEFT_RIGHT, EXT_OVERSCAN_RIGHT); 2554562236bSHarry Wentland 2564562236bSHarry Wentland set_reg_field_value(overscan_top_bottom, data->recout.y, 2574562236bSHarry Wentland EXT_OVERSCAN_TOP_BOTTOM, EXT_OVERSCAN_TOP); 2584562236bSHarry Wentland 2594562236bSHarry Wentland set_reg_field_value(overscan_top_bottom, overscan_bottom, 2604562236bSHarry Wentland EXT_OVERSCAN_TOP_BOTTOM, EXT_OVERSCAN_BOTTOM); 2614562236bSHarry Wentland 2624562236bSHarry Wentland dm_write_reg(xfm_dce->base.ctx, 2634562236bSHarry Wentland mmSCLV_EXT_OVERSCAN_LEFT_RIGHT, 2644562236bSHarry Wentland overscan_left_right); 2654562236bSHarry Wentland 2664562236bSHarry Wentland dm_write_reg(xfm_dce->base.ctx, 2674562236bSHarry Wentland mmSCLV_EXT_OVERSCAN_TOP_BOTTOM, 2684562236bSHarry Wentland overscan_top_bottom); 2694562236bSHarry Wentland } 2704562236bSHarry Wentland 2714562236bSHarry Wentland static void set_coeff_update_complete( 2724562236bSHarry Wentland struct dce_transform *xfm_dce) 2734562236bSHarry Wentland { 2744562236bSHarry Wentland uint32_t value; 2754562236bSHarry Wentland 2764562236bSHarry Wentland value = dm_read_reg(xfm_dce->base.ctx, mmSCLV_UPDATE); 2774562236bSHarry Wentland set_reg_field_value(value, 1, SCLV_UPDATE, SCL_COEF_UPDATE_COMPLETE); 2784562236bSHarry Wentland dm_write_reg(xfm_dce->base.ctx, mmSCLV_UPDATE, value); 2794562236bSHarry Wentland } 2804562236bSHarry Wentland 2814562236bSHarry Wentland static void program_multi_taps_filter( 2824562236bSHarry Wentland struct dce_transform *xfm_dce, 2834562236bSHarry Wentland int taps, 2844562236bSHarry Wentland const uint16_t *coeffs, 2854562236bSHarry Wentland enum ram_filter_type filter_type) 2864562236bSHarry Wentland { 2874562236bSHarry Wentland struct dc_context *ctx = xfm_dce->base.ctx; 2884562236bSHarry Wentland int i, phase, pair; 2894562236bSHarry Wentland int array_idx = 0; 2904562236bSHarry Wentland int taps_pairs = (taps + 1) / 2; 2914562236bSHarry Wentland int phases_to_program = SCLV_PHASES / 2 + 1; 2924562236bSHarry Wentland 2934562236bSHarry Wentland uint32_t select = 0; 2944562236bSHarry Wentland uint32_t power_ctl, power_ctl_off; 2954562236bSHarry Wentland 2964562236bSHarry Wentland if (!coeffs) 2974562236bSHarry Wentland return; 2984562236bSHarry Wentland 2994562236bSHarry Wentland /*We need to disable power gating on coeff memory to do programming*/ 3004562236bSHarry Wentland power_ctl = dm_read_reg(ctx, mmDCFEV_MEM_PWR_CTRL); 3014562236bSHarry Wentland power_ctl_off = power_ctl; 3024562236bSHarry Wentland set_reg_field_value(power_ctl_off, 1, DCFEV_MEM_PWR_CTRL, SCLV_COEFF_MEM_PWR_DIS); 3034562236bSHarry Wentland dm_write_reg(ctx, mmDCFEV_MEM_PWR_CTRL, power_ctl_off); 3044562236bSHarry Wentland 3054562236bSHarry Wentland /*Wait to disable gating:*/ 3064562236bSHarry Wentland for (i = 0; i < 10; i++) { 3074562236bSHarry Wentland if (get_reg_field_value( 3084562236bSHarry Wentland dm_read_reg(ctx, mmDCFEV_MEM_PWR_STATUS), 3094562236bSHarry Wentland DCFEV_MEM_PWR_STATUS, 3104562236bSHarry Wentland SCLV_COEFF_MEM_PWR_STATE) == 0) 3114562236bSHarry Wentland break; 3124562236bSHarry Wentland 3134562236bSHarry Wentland udelay(1); 3144562236bSHarry Wentland } 3154562236bSHarry Wentland 3164562236bSHarry Wentland set_reg_field_value(select, filter_type, SCLV_COEF_RAM_SELECT, SCL_C_RAM_FILTER_TYPE); 3174562236bSHarry Wentland 3184562236bSHarry Wentland for (phase = 0; phase < phases_to_program; phase++) { 3194562236bSHarry Wentland /*we always program N/2 + 1 phases, total phases N, but N/2-1 are just mirror 3204562236bSHarry Wentland phase 0 is unique and phase N/2 is unique if N is even*/ 3214562236bSHarry Wentland set_reg_field_value(select, phase, SCLV_COEF_RAM_SELECT, SCL_C_RAM_PHASE); 3224562236bSHarry Wentland for (pair = 0; pair < taps_pairs; pair++) { 3234562236bSHarry Wentland uint32_t data = 0; 3244562236bSHarry Wentland 3254562236bSHarry Wentland set_reg_field_value(select, pair, 3264562236bSHarry Wentland SCLV_COEF_RAM_SELECT, SCL_C_RAM_TAP_PAIR_IDX); 3274562236bSHarry Wentland 3284562236bSHarry Wentland dm_write_reg(ctx, mmSCLV_COEF_RAM_SELECT, select); 3294562236bSHarry Wentland 3304562236bSHarry Wentland set_reg_field_value( 3314562236bSHarry Wentland data, 1, 3324562236bSHarry Wentland SCLV_COEF_RAM_TAP_DATA, 3334562236bSHarry Wentland SCL_C_RAM_EVEN_TAP_COEF_EN); 3344562236bSHarry Wentland set_reg_field_value( 3354562236bSHarry Wentland data, coeffs[array_idx], 3364562236bSHarry Wentland SCLV_COEF_RAM_TAP_DATA, 3374562236bSHarry Wentland SCL_C_RAM_EVEN_TAP_COEF); 3384562236bSHarry Wentland 3394562236bSHarry Wentland if (taps % 2 && pair == taps_pairs - 1) { 3404562236bSHarry Wentland set_reg_field_value( 3414562236bSHarry Wentland data, 0, 3424562236bSHarry Wentland SCLV_COEF_RAM_TAP_DATA, 3434562236bSHarry Wentland SCL_C_RAM_ODD_TAP_COEF_EN); 3444562236bSHarry Wentland array_idx++; 3454562236bSHarry Wentland } else { 3464562236bSHarry Wentland set_reg_field_value( 3474562236bSHarry Wentland data, 1, 3484562236bSHarry Wentland SCLV_COEF_RAM_TAP_DATA, 3494562236bSHarry Wentland SCL_C_RAM_ODD_TAP_COEF_EN); 3504562236bSHarry Wentland set_reg_field_value( 3514562236bSHarry Wentland data, coeffs[array_idx + 1], 3524562236bSHarry Wentland SCLV_COEF_RAM_TAP_DATA, 3534562236bSHarry Wentland SCL_C_RAM_ODD_TAP_COEF); 3544562236bSHarry Wentland 3554562236bSHarry Wentland array_idx += 2; 3564562236bSHarry Wentland } 3574562236bSHarry Wentland 3584562236bSHarry Wentland dm_write_reg(ctx, mmSCLV_COEF_RAM_TAP_DATA, data); 3594562236bSHarry Wentland } 3604562236bSHarry Wentland } 3614562236bSHarry Wentland 3624562236bSHarry Wentland /*We need to restore power gating on coeff memory to initial state*/ 3634562236bSHarry Wentland dm_write_reg(ctx, mmDCFEV_MEM_PWR_CTRL, power_ctl); 3644562236bSHarry Wentland } 3654562236bSHarry Wentland 3664562236bSHarry Wentland static void calculate_inits( 3674562236bSHarry Wentland struct dce_transform *xfm_dce, 3684562236bSHarry Wentland const struct scaler_data *data, 3694562236bSHarry Wentland struct sclv_ratios_inits *inits, 3704562236bSHarry Wentland struct rect *luma_viewport, 3714562236bSHarry Wentland struct rect *chroma_viewport) 3724562236bSHarry Wentland { 3734562236bSHarry Wentland inits->h_int_scale_ratio_luma = 3744562236bSHarry Wentland dal_fixed31_32_u2d19(data->ratios.horz) << 5; 3754562236bSHarry Wentland inits->v_int_scale_ratio_luma = 3764562236bSHarry Wentland dal_fixed31_32_u2d19(data->ratios.vert) << 5; 3774562236bSHarry Wentland inits->h_int_scale_ratio_chroma = 3784562236bSHarry Wentland dal_fixed31_32_u2d19(data->ratios.horz_c) << 5; 3794562236bSHarry Wentland inits->v_int_scale_ratio_chroma = 3804562236bSHarry Wentland dal_fixed31_32_u2d19(data->ratios.vert_c) << 5; 3814562236bSHarry Wentland 3824562236bSHarry Wentland inits->h_init_luma.integer = 1; 3834562236bSHarry Wentland inits->v_init_luma.integer = 1; 3844562236bSHarry Wentland inits->h_init_chroma.integer = 1; 3854562236bSHarry Wentland inits->v_init_chroma.integer = 1; 3864562236bSHarry Wentland } 3874562236bSHarry Wentland 3884562236bSHarry Wentland static void program_scl_ratios_inits( 3894562236bSHarry Wentland struct dce_transform *xfm_dce, 3904562236bSHarry Wentland struct sclv_ratios_inits *inits) 3914562236bSHarry Wentland { 3924562236bSHarry Wentland struct dc_context *ctx = xfm_dce->base.ctx; 3934562236bSHarry Wentland uint32_t addr = mmSCLV_HORZ_FILTER_SCALE_RATIO; 3944562236bSHarry Wentland uint32_t value = 0; 3954562236bSHarry Wentland 3964562236bSHarry Wentland set_reg_field_value( 3974562236bSHarry Wentland value, 3984562236bSHarry Wentland inits->h_int_scale_ratio_luma, 3994562236bSHarry Wentland SCLV_HORZ_FILTER_SCALE_RATIO, 4004562236bSHarry Wentland SCL_H_SCALE_RATIO); 4014562236bSHarry Wentland dm_write_reg(ctx, addr, value); 4024562236bSHarry Wentland 4034562236bSHarry Wentland addr = mmSCLV_VERT_FILTER_SCALE_RATIO; 4044562236bSHarry Wentland value = 0; 4054562236bSHarry Wentland set_reg_field_value( 4064562236bSHarry Wentland value, 4074562236bSHarry Wentland inits->v_int_scale_ratio_luma, 4084562236bSHarry Wentland SCLV_VERT_FILTER_SCALE_RATIO, 4094562236bSHarry Wentland SCL_V_SCALE_RATIO); 4104562236bSHarry Wentland dm_write_reg(ctx, addr, value); 4114562236bSHarry Wentland 4124562236bSHarry Wentland addr = mmSCLV_HORZ_FILTER_SCALE_RATIO_C; 4134562236bSHarry Wentland value = 0; 4144562236bSHarry Wentland set_reg_field_value( 4154562236bSHarry Wentland value, 4164562236bSHarry Wentland inits->h_int_scale_ratio_chroma, 4174562236bSHarry Wentland SCLV_HORZ_FILTER_SCALE_RATIO_C, 4184562236bSHarry Wentland SCL_H_SCALE_RATIO_C); 4194562236bSHarry Wentland dm_write_reg(ctx, addr, value); 4204562236bSHarry Wentland 4214562236bSHarry Wentland addr = mmSCLV_VERT_FILTER_SCALE_RATIO_C; 4224562236bSHarry Wentland value = 0; 4234562236bSHarry Wentland set_reg_field_value( 4244562236bSHarry Wentland value, 4254562236bSHarry Wentland inits->v_int_scale_ratio_chroma, 4264562236bSHarry Wentland SCLV_VERT_FILTER_SCALE_RATIO_C, 4274562236bSHarry Wentland SCL_V_SCALE_RATIO_C); 4284562236bSHarry Wentland dm_write_reg(ctx, addr, value); 4294562236bSHarry Wentland 4304562236bSHarry Wentland addr = mmSCLV_HORZ_FILTER_INIT; 4314562236bSHarry Wentland value = 0; 4324562236bSHarry Wentland set_reg_field_value( 4334562236bSHarry Wentland value, 4344562236bSHarry Wentland inits->h_init_luma.fraction, 4354562236bSHarry Wentland SCLV_HORZ_FILTER_INIT, 4364562236bSHarry Wentland SCL_H_INIT_FRAC); 4374562236bSHarry Wentland set_reg_field_value( 4384562236bSHarry Wentland value, 4394562236bSHarry Wentland inits->h_init_luma.integer, 4404562236bSHarry Wentland SCLV_HORZ_FILTER_INIT, 4414562236bSHarry Wentland SCL_H_INIT_INT); 4424562236bSHarry Wentland dm_write_reg(ctx, addr, value); 4434562236bSHarry Wentland 4444562236bSHarry Wentland addr = mmSCLV_VERT_FILTER_INIT; 4454562236bSHarry Wentland value = 0; 4464562236bSHarry Wentland set_reg_field_value( 4474562236bSHarry Wentland value, 4484562236bSHarry Wentland inits->v_init_luma.fraction, 4494562236bSHarry Wentland SCLV_VERT_FILTER_INIT, 4504562236bSHarry Wentland SCL_V_INIT_FRAC); 4514562236bSHarry Wentland set_reg_field_value( 4524562236bSHarry Wentland value, 4534562236bSHarry Wentland inits->v_init_luma.integer, 4544562236bSHarry Wentland SCLV_VERT_FILTER_INIT, 4554562236bSHarry Wentland SCL_V_INIT_INT); 4564562236bSHarry Wentland dm_write_reg(ctx, addr, value); 4574562236bSHarry Wentland 4584562236bSHarry Wentland addr = mmSCLV_HORZ_FILTER_INIT_C; 4594562236bSHarry Wentland value = 0; 4604562236bSHarry Wentland set_reg_field_value( 4614562236bSHarry Wentland value, 4624562236bSHarry Wentland inits->h_init_chroma.fraction, 4634562236bSHarry Wentland SCLV_HORZ_FILTER_INIT_C, 4644562236bSHarry Wentland SCL_H_INIT_FRAC_C); 4654562236bSHarry Wentland set_reg_field_value( 4664562236bSHarry Wentland value, 4674562236bSHarry Wentland inits->h_init_chroma.integer, 4684562236bSHarry Wentland SCLV_HORZ_FILTER_INIT_C, 4694562236bSHarry Wentland SCL_H_INIT_INT_C); 4704562236bSHarry Wentland dm_write_reg(ctx, addr, value); 4714562236bSHarry Wentland 4724562236bSHarry Wentland addr = mmSCLV_VERT_FILTER_INIT_C; 4734562236bSHarry Wentland value = 0; 4744562236bSHarry Wentland set_reg_field_value( 4754562236bSHarry Wentland value, 4764562236bSHarry Wentland inits->v_init_chroma.fraction, 4774562236bSHarry Wentland SCLV_VERT_FILTER_INIT_C, 4784562236bSHarry Wentland SCL_V_INIT_FRAC_C); 4794562236bSHarry Wentland set_reg_field_value( 4804562236bSHarry Wentland value, 4814562236bSHarry Wentland inits->v_init_chroma.integer, 4824562236bSHarry Wentland SCLV_VERT_FILTER_INIT_C, 4834562236bSHarry Wentland SCL_V_INIT_INT_C); 4844562236bSHarry Wentland dm_write_reg(ctx, addr, value); 4854562236bSHarry Wentland } 4864562236bSHarry Wentland 4874562236bSHarry Wentland static const uint16_t *get_filter_coeffs_64p(int taps, struct fixed31_32 ratio) 4884562236bSHarry Wentland { 4894562236bSHarry Wentland if (taps == 4) 4904562236bSHarry Wentland return get_filter_4tap_64p(ratio); 4914562236bSHarry Wentland else if (taps == 2) 4928c0dc2b9SDave Airlie return get_filter_2tap_64p(); 4934562236bSHarry Wentland else if (taps == 1) 4944562236bSHarry Wentland return NULL; 4954562236bSHarry Wentland else { 4964562236bSHarry Wentland /* should never happen, bug */ 4974562236bSHarry Wentland BREAK_TO_DEBUGGER(); 4984562236bSHarry Wentland return NULL; 4994562236bSHarry Wentland } 5004562236bSHarry Wentland } 5014562236bSHarry Wentland 5024562236bSHarry Wentland static bool dce110_xfmv_power_up_line_buffer(struct transform *xfm) 5034562236bSHarry Wentland { 5044562236bSHarry Wentland struct dce_transform *xfm_dce = TO_DCE_TRANSFORM(xfm); 5054562236bSHarry Wentland uint32_t value; 5064562236bSHarry Wentland 5074562236bSHarry Wentland value = dm_read_reg(xfm_dce->base.ctx, mmLBV_MEMORY_CTRL); 5084562236bSHarry Wentland 5094562236bSHarry Wentland /*Use all three pieces of memory always*/ 5104562236bSHarry Wentland set_reg_field_value(value, 0, LBV_MEMORY_CTRL, LB_MEMORY_CONFIG); 5114562236bSHarry Wentland /*hard coded number DCE11 1712(0x6B0) Partitions: 720/960/1712*/ 5124562236bSHarry Wentland set_reg_field_value(value, xfm_dce->lb_memory_size, LBV_MEMORY_CTRL, 5134562236bSHarry Wentland LB_MEMORY_SIZE); 5144562236bSHarry Wentland 5154562236bSHarry Wentland dm_write_reg(xfm_dce->base.ctx, mmLBV_MEMORY_CTRL, value); 5164562236bSHarry Wentland 5174562236bSHarry Wentland return true; 5184562236bSHarry Wentland } 5194562236bSHarry Wentland 5204562236bSHarry Wentland static void dce110_xfmv_set_scaler( 5214562236bSHarry Wentland struct transform *xfm, 5224562236bSHarry Wentland const struct scaler_data *data) 5234562236bSHarry Wentland { 5244562236bSHarry Wentland struct dce_transform *xfm_dce = TO_DCE_TRANSFORM(xfm); 5254562236bSHarry Wentland bool is_scaling_required = false; 5264562236bSHarry Wentland bool filter_updated = false; 5274562236bSHarry Wentland const uint16_t *coeffs_v, *coeffs_h, *coeffs_h_c, *coeffs_v_c; 5284562236bSHarry Wentland struct rect luma_viewport = {0}; 5294562236bSHarry Wentland struct rect chroma_viewport = {0}; 5304562236bSHarry Wentland 5314562236bSHarry Wentland dce110_xfmv_power_up_line_buffer(xfm); 5324562236bSHarry Wentland /* 1. Calculate viewport, viewport programming should happen after init 5334562236bSHarry Wentland * calculations as they may require an adjustment in the viewport. 5344562236bSHarry Wentland */ 5354562236bSHarry Wentland 5364562236bSHarry Wentland calculate_viewport(data, &luma_viewport, &chroma_viewport); 5374562236bSHarry Wentland 5384562236bSHarry Wentland /* 2. Program overscan */ 5394562236bSHarry Wentland program_overscan(xfm_dce, data); 5404562236bSHarry Wentland 5414562236bSHarry Wentland /* 3. Program taps and configuration */ 5424562236bSHarry Wentland is_scaling_required = setup_scaling_configuration(xfm_dce, data); 5434562236bSHarry Wentland 5444562236bSHarry Wentland if (is_scaling_required) { 5454562236bSHarry Wentland /* 4. Calculate and program ratio, filter initialization */ 5464562236bSHarry Wentland 5474562236bSHarry Wentland struct sclv_ratios_inits inits = { 0 }; 5484562236bSHarry Wentland 5494562236bSHarry Wentland calculate_inits( 5504562236bSHarry Wentland xfm_dce, 5514562236bSHarry Wentland data, 5524562236bSHarry Wentland &inits, 5534562236bSHarry Wentland &luma_viewport, 5544562236bSHarry Wentland &chroma_viewport); 5554562236bSHarry Wentland 5564562236bSHarry Wentland program_scl_ratios_inits(xfm_dce, &inits); 5574562236bSHarry Wentland 5584562236bSHarry Wentland coeffs_v = get_filter_coeffs_64p(data->taps.v_taps, data->ratios.vert); 5594562236bSHarry Wentland coeffs_h = get_filter_coeffs_64p(data->taps.h_taps, data->ratios.horz); 5604562236bSHarry Wentland coeffs_v_c = get_filter_coeffs_64p(data->taps.v_taps_c, data->ratios.vert_c); 5614562236bSHarry Wentland coeffs_h_c = get_filter_coeffs_64p(data->taps.h_taps_c, data->ratios.horz_c); 5624562236bSHarry Wentland 5634562236bSHarry Wentland if (coeffs_v != xfm_dce->filter_v 5644562236bSHarry Wentland || coeffs_v_c != xfm_dce->filter_v_c 5654562236bSHarry Wentland || coeffs_h != xfm_dce->filter_h 5664562236bSHarry Wentland || coeffs_h_c != xfm_dce->filter_h_c) { 5674562236bSHarry Wentland /* 5. Program vertical filters */ 5684562236bSHarry Wentland program_multi_taps_filter( 5694562236bSHarry Wentland xfm_dce, 5704562236bSHarry Wentland data->taps.v_taps, 5714562236bSHarry Wentland coeffs_v, 5724562236bSHarry Wentland FILTER_TYPE_RGB_Y_VERTICAL); 5734562236bSHarry Wentland program_multi_taps_filter( 5744562236bSHarry Wentland xfm_dce, 5754562236bSHarry Wentland data->taps.v_taps_c, 5764562236bSHarry Wentland coeffs_v_c, 5774562236bSHarry Wentland FILTER_TYPE_CBCR_VERTICAL); 5784562236bSHarry Wentland 5794562236bSHarry Wentland /* 6. Program horizontal filters */ 5804562236bSHarry Wentland program_multi_taps_filter( 5814562236bSHarry Wentland xfm_dce, 5824562236bSHarry Wentland data->taps.h_taps, 5834562236bSHarry Wentland coeffs_h, 5844562236bSHarry Wentland FILTER_TYPE_RGB_Y_HORIZONTAL); 5854562236bSHarry Wentland program_multi_taps_filter( 5864562236bSHarry Wentland xfm_dce, 5874562236bSHarry Wentland data->taps.h_taps_c, 5884562236bSHarry Wentland coeffs_h_c, 5894562236bSHarry Wentland FILTER_TYPE_CBCR_HORIZONTAL); 5904562236bSHarry Wentland 5914562236bSHarry Wentland xfm_dce->filter_v = coeffs_v; 5924562236bSHarry Wentland xfm_dce->filter_v_c = coeffs_v_c; 5934562236bSHarry Wentland xfm_dce->filter_h = coeffs_h; 5944562236bSHarry Wentland xfm_dce->filter_h_c = coeffs_h_c; 5954562236bSHarry Wentland filter_updated = true; 5964562236bSHarry Wentland } 5974562236bSHarry Wentland } 5984562236bSHarry Wentland 5994562236bSHarry Wentland /* 7. Program the viewport */ 6004562236bSHarry Wentland program_viewport(xfm_dce, &luma_viewport, &chroma_viewport); 6014562236bSHarry Wentland 6024562236bSHarry Wentland /* 8. Set bit to flip to new coefficient memory */ 6034562236bSHarry Wentland if (filter_updated) 6044562236bSHarry Wentland set_coeff_update_complete(xfm_dce); 6054562236bSHarry Wentland } 6064562236bSHarry Wentland 6074562236bSHarry Wentland static void dce110_xfmv_reset(struct transform *xfm) 6084562236bSHarry Wentland { 6094562236bSHarry Wentland struct dce_transform *xfm_dce = TO_DCE_TRANSFORM(xfm); 6104562236bSHarry Wentland 6114562236bSHarry Wentland xfm_dce->filter_h = NULL; 6124562236bSHarry Wentland xfm_dce->filter_v = NULL; 6134562236bSHarry Wentland xfm_dce->filter_h_c = NULL; 6144562236bSHarry Wentland xfm_dce->filter_v_c = NULL; 6154562236bSHarry Wentland } 6164562236bSHarry Wentland 6174562236bSHarry Wentland static void dce110_xfmv_set_gamut_remap( 6184562236bSHarry Wentland struct transform *xfm, 6194562236bSHarry Wentland const struct xfm_grph_csc_adjustment *adjust) 6204562236bSHarry Wentland { 6214562236bSHarry Wentland /* DO NOTHING*/ 6224562236bSHarry Wentland } 6234562236bSHarry Wentland 6244562236bSHarry Wentland static void dce110_xfmv_set_pixel_storage_depth( 6254562236bSHarry Wentland struct transform *xfm, 6264562236bSHarry Wentland enum lb_pixel_depth depth, 6274562236bSHarry Wentland const struct bit_depth_reduction_params *bit_depth_params) 6284562236bSHarry Wentland { 6294562236bSHarry Wentland struct dce_transform *xfm_dce = TO_DCE_TRANSFORM(xfm); 630a33fa99dSHarry Wentland int pixel_depth = 0; 631a33fa99dSHarry Wentland int expan_mode = 0; 6324562236bSHarry Wentland uint32_t reg_data = 0; 6334562236bSHarry Wentland 6344562236bSHarry Wentland switch (depth) { 6354562236bSHarry Wentland case LB_PIXEL_DEPTH_18BPP: 6364562236bSHarry Wentland pixel_depth = 2; 6374562236bSHarry Wentland expan_mode = 1; 6384562236bSHarry Wentland break; 6394562236bSHarry Wentland case LB_PIXEL_DEPTH_24BPP: 6404562236bSHarry Wentland pixel_depth = 1; 6414562236bSHarry Wentland expan_mode = 1; 6424562236bSHarry Wentland break; 6434562236bSHarry Wentland case LB_PIXEL_DEPTH_30BPP: 6444562236bSHarry Wentland pixel_depth = 0; 6454562236bSHarry Wentland expan_mode = 1; 6464562236bSHarry Wentland break; 6474562236bSHarry Wentland case LB_PIXEL_DEPTH_36BPP: 6484562236bSHarry Wentland pixel_depth = 3; 6494562236bSHarry Wentland expan_mode = 0; 6504562236bSHarry Wentland break; 6514562236bSHarry Wentland default: 6524562236bSHarry Wentland BREAK_TO_DEBUGGER(); 6534562236bSHarry Wentland break; 6544562236bSHarry Wentland } 6554562236bSHarry Wentland 6564562236bSHarry Wentland set_reg_field_value( 6574562236bSHarry Wentland reg_data, 6584562236bSHarry Wentland expan_mode, 6594562236bSHarry Wentland LBV_DATA_FORMAT, 6604562236bSHarry Wentland PIXEL_EXPAN_MODE); 6614562236bSHarry Wentland 6624562236bSHarry Wentland set_reg_field_value( 6634562236bSHarry Wentland reg_data, 6644562236bSHarry Wentland pixel_depth, 6654562236bSHarry Wentland LBV_DATA_FORMAT, 6664562236bSHarry Wentland PIXEL_DEPTH); 6674562236bSHarry Wentland 6684562236bSHarry Wentland dm_write_reg(xfm->ctx, mmLBV_DATA_FORMAT, reg_data); 6694562236bSHarry Wentland 6704562236bSHarry Wentland if (!(xfm_dce->lb_pixel_depth_supported & depth)) { 6714562236bSHarry Wentland /*we should use unsupported capabilities 6724562236bSHarry Wentland * unless it is required by w/a*/ 6734562236bSHarry Wentland dm_logger_write(xfm->ctx->logger, LOG_WARNING, 6744562236bSHarry Wentland "%s: Capability not supported", 6754562236bSHarry Wentland __func__); 6764562236bSHarry Wentland } 6774562236bSHarry Wentland } 6784562236bSHarry Wentland 6794562236bSHarry Wentland static const struct transform_funcs dce110_xfmv_funcs = { 6804562236bSHarry Wentland .transform_reset = dce110_xfmv_reset, 6814562236bSHarry Wentland .transform_set_scaler = dce110_xfmv_set_scaler, 6824562236bSHarry Wentland .transform_set_gamut_remap = 6834562236bSHarry Wentland dce110_xfmv_set_gamut_remap, 684bdf9a1a0SYue Hin Lau .opp_set_csc_default = dce110_opp_v_set_csc_default, 685bdf9a1a0SYue Hin Lau .opp_set_csc_adjustment = dce110_opp_v_set_csc_adjustment, 6867a09f5beSYue Hin Lau .opp_power_on_regamma_lut = dce110_opp_power_on_regamma_lut_v, 6877a09f5beSYue Hin Lau .opp_program_regamma_pwl = dce110_opp_program_regamma_pwl_v, 6887a09f5beSYue Hin Lau .opp_set_regamma_mode = dce110_opp_set_regamma_mode_v, 6894562236bSHarry Wentland .transform_set_pixel_storage_depth = 6904562236bSHarry Wentland dce110_xfmv_set_pixel_storage_depth, 6914562236bSHarry Wentland .transform_get_optimal_number_of_taps = 6924562236bSHarry Wentland dce_transform_get_optimal_number_of_taps 6934562236bSHarry Wentland }; 6944562236bSHarry Wentland /*****************************************/ 6954562236bSHarry Wentland /* Constructor, Destructor */ 6964562236bSHarry Wentland /*****************************************/ 6974562236bSHarry Wentland 6984562236bSHarry Wentland bool dce110_transform_v_construct( 6994562236bSHarry Wentland struct dce_transform *xfm_dce, 7004562236bSHarry Wentland struct dc_context *ctx) 7014562236bSHarry Wentland { 7024562236bSHarry Wentland xfm_dce->base.ctx = ctx; 7034562236bSHarry Wentland 7044562236bSHarry Wentland xfm_dce->base.funcs = &dce110_xfmv_funcs; 7054562236bSHarry Wentland 7064562236bSHarry Wentland xfm_dce->lb_pixel_depth_supported = 7074562236bSHarry Wentland LB_PIXEL_DEPTH_18BPP | 7084562236bSHarry Wentland LB_PIXEL_DEPTH_24BPP | 7094562236bSHarry Wentland LB_PIXEL_DEPTH_30BPP; 7104562236bSHarry Wentland 7114562236bSHarry Wentland xfm_dce->prescaler_on = true; 7124562236bSHarry Wentland xfm_dce->lb_bits_per_entry = LB_BITS_PER_ENTRY; 7134562236bSHarry Wentland xfm_dce->lb_memory_size = LB_TOTAL_NUMBER_OF_ENTRIES; /*0x6B0*/ 7144562236bSHarry Wentland 7154562236bSHarry Wentland return true; 7164562236bSHarry Wentland } 717