diff options
Diffstat (limited to 'meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0983-drm-amd-display-separate-scl-functions-out-from-dcn1.patch')
-rw-r--r-- | meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0983-drm-amd-display-separate-scl-functions-out-from-dcn1.patch | 1493 |
1 files changed, 0 insertions, 1493 deletions
diff --git a/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0983-drm-amd-display-separate-scl-functions-out-from-dcn1.patch b/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0983-drm-amd-display-separate-scl-functions-out-from-dcn1.patch deleted file mode 100644 index aee5c2b5..00000000 --- a/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0983-drm-amd-display-separate-scl-functions-out-from-dcn1.patch +++ /dev/null @@ -1,1493 +0,0 @@ -From b08627c65cfbc2201fe5024bd3c05641b289fa94 Mon Sep 17 00:00:00 2001 -From: Yue Hin Lau <Yuehin.Lau@amd.com> -Date: Tue, 15 Aug 2017 17:44:19 -0400 -Subject: [PATCH 0983/4131] drm/amd/display: separate scl functions out from - dcn10_dpp - -Signed-off-by: Yue Hin Lau <Yuehin.Lau@amd.com> -Reviewed-by: Tony Cheng <Tony.Cheng@amd.com> -Acked-by: Harry Wentland <Harry.Wentland@amd.com> ---- - drivers/gpu/drm/amd/display/dc/dcn10/Makefile | 3 +- - drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c | 650 +----------------- - drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h | 5 + - .../gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c | 762 +++++++++++++++++++++ - 4 files changed, 770 insertions(+), 650 deletions(-) - create mode 100644 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c - -diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/Makefile b/drivers/gpu/drm/amd/display/dc/dcn10/Makefile -index 8af201a..83619e6 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn10/Makefile -+++ b/drivers/gpu/drm/amd/display/dc/dcn10/Makefile -@@ -3,7 +3,8 @@ - - DCN10 = dcn10_resource.o dcn10_ipp.o dcn10_hw_sequencer.o \ - dcn10_dpp.o dcn10_opp.o dcn10_timing_generator.o \ -- dcn10_mem_input.o dcn10_mpc.o dcn10_dwb.o -+ dcn10_mem_input.o dcn10_mpc.o dcn10_dwb.o \ -+ dcn10_dpp_dscl.o - - AMD_DAL_DCN10 = $(addprefix $(AMDDALPATH)/dc/dcn10/,$(DCN10)) - -diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c -index e52e1f4..a841ed3 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c -+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c -@@ -112,514 +112,6 @@ enum gamut_remap_select { - GAMUT_REMAP_COMB_COEFF - }; - --static void dpp_set_overscan( -- struct dcn10_dpp *xfm, -- const struct scaler_data *data) --{ -- uint32_t left = data->recout.x; -- uint32_t top = data->recout.y; -- -- int right = data->h_active - data->recout.x - data->recout.width; -- int bottom = data->v_active - data->recout.y - data->recout.height; -- -- if (right < 0) { -- BREAK_TO_DEBUGGER(); -- right = 0; -- } -- if (bottom < 0) { -- BREAK_TO_DEBUGGER(); -- bottom = 0; -- } -- -- REG_SET_2(DSCL_EXT_OVERSCAN_LEFT_RIGHT, 0, -- EXT_OVERSCAN_LEFT, left, -- EXT_OVERSCAN_RIGHT, right); -- -- REG_SET_2(DSCL_EXT_OVERSCAN_TOP_BOTTOM, 0, -- EXT_OVERSCAN_BOTTOM, bottom, -- EXT_OVERSCAN_TOP, top); --} -- --static void dpp_set_otg_blank( -- struct dcn10_dpp *xfm, const struct scaler_data *data) --{ -- uint32_t h_blank_start = data->h_active; -- uint32_t h_blank_end = 0; -- uint32_t v_blank_start = data->v_active; -- uint32_t v_blank_end = 0; -- -- REG_SET_2(OTG_H_BLANK, 0, -- OTG_H_BLANK_START, h_blank_start, -- OTG_H_BLANK_END, h_blank_end); -- -- REG_SET_2(OTG_V_BLANK, 0, -- OTG_V_BLANK_START, v_blank_start, -- OTG_V_BLANK_END, v_blank_end); --} -- --static enum dscl_mode_sel get_dscl_mode( -- const struct scaler_data *data, bool dbg_always_scale) --{ -- const long long one = dal_fixed31_32_one.value; -- bool ycbcr = false; -- bool format420 = false; -- -- if (data->format == PIXEL_FORMAT_FP16) -- return DSCL_MODE_DSCL_BYPASS; -- -- if (data->format >= PIXEL_FORMAT_VIDEO_BEGIN -- && data->format <= PIXEL_FORMAT_VIDEO_END) -- ycbcr = true; -- -- if (data->format == PIXEL_FORMAT_420BPP8 || -- data->format == PIXEL_FORMAT_420BPP10) -- format420 = true; -- -- if (data->ratios.horz.value == one -- && data->ratios.vert.value == one -- && data->ratios.horz_c.value == one -- && data->ratios.vert_c.value == one -- && !dbg_always_scale) -- return DSCL_MODE_SCALING_444_BYPASS; -- -- if (!format420) { -- if (ycbcr) -- return DSCL_MODE_SCALING_444_YCBCR_ENABLE; -- else -- return DSCL_MODE_SCALING_444_RGB_ENABLE; -- } -- if (data->ratios.horz.value == one && data->ratios.vert.value == one) -- return DSCL_MODE_SCALING_420_LUMA_BYPASS; -- if (data->ratios.horz_c.value == one && data->ratios.vert_c.value == one) -- return DSCL_MODE_SCALING_420_CHROMA_BYPASS; -- -- return DSCL_MODE_SCALING_420_YCBCR_ENABLE; --} -- --static int get_pixel_depth_val(enum lb_pixel_depth depth) --{ -- if (depth == LB_PIXEL_DEPTH_30BPP) -- return 0; /* 10 bpc */ -- else if (depth == LB_PIXEL_DEPTH_24BPP) -- return 1; /* 8 bpc */ -- else if (depth == LB_PIXEL_DEPTH_18BPP) -- return 2; /* 6 bpc */ -- else if (depth == LB_PIXEL_DEPTH_36BPP) -- return 3; /* 12 bpc */ -- else { -- ASSERT(0); -- return -1; /* Unsupported */ -- } --} -- --static void dpp_set_lb( -- struct dcn10_dpp *xfm, -- const struct line_buffer_params *lb_params, -- enum lb_memory_config mem_size_config) --{ -- uint32_t pixel_depth = get_pixel_depth_val(lb_params->depth); -- uint32_t dyn_pix_depth = lb_params->dynamic_pixel_depth; -- REG_SET_7(LB_DATA_FORMAT, 0, -- PIXEL_DEPTH, pixel_depth, /* Pixel depth stored in LB */ -- PIXEL_EXPAN_MODE, lb_params->pixel_expan_mode, /* Pixel expansion mode */ -- PIXEL_REDUCE_MODE, 1, /* Pixel reduction mode: Rounding */ -- DYNAMIC_PIXEL_DEPTH, dyn_pix_depth, /* Dynamic expansion pixel depth */ -- DITHER_EN, 0, /* Dithering enable: Disabled */ -- INTERLEAVE_EN, lb_params->interleave_en, /* Interleave source enable */ -- ALPHA_EN, lb_params->alpha_en); /* Alpha enable */ -- -- REG_SET_2(LB_MEMORY_CTRL, 0, -- MEMORY_CONFIG, mem_size_config, -- LB_MAX_PARTITIONS, 63); --} -- --static void dpp_set_scaler_filter( -- struct dcn10_dpp *xfm, -- uint32_t taps, -- enum dcn10_coef_filter_type_sel filter_type, -- const uint16_t *filter) --{ -- const int tap_pairs = (taps + 1) / 2; -- int phase; -- int pair; -- uint16_t odd_coef, even_coef; -- -- REG_SET_3(SCL_COEF_RAM_TAP_SELECT, 0, -- SCL_COEF_RAM_TAP_PAIR_IDX, 0, -- SCL_COEF_RAM_PHASE, 0, -- SCL_COEF_RAM_FILTER_TYPE, filter_type); -- -- for (phase = 0; phase < (NUM_PHASES / 2 + 1); phase++) { -- for (pair = 0; pair < tap_pairs; pair++) { -- even_coef = filter[phase * taps + 2 * pair]; -- if ((pair * 2 + 1) < taps) -- odd_coef = filter[phase * taps + 2 * pair + 1]; -- else -- odd_coef = 0; -- -- REG_SET_4(SCL_COEF_RAM_TAP_DATA, 0, -- /* Even tap coefficient (bits 1:0 fixed to 0) */ -- SCL_COEF_RAM_EVEN_TAP_COEF, even_coef, -- /* Write/read control for even coefficient */ -- SCL_COEF_RAM_EVEN_TAP_COEF_EN, 1, -- /* Odd tap coefficient (bits 1:0 fixed to 0) */ -- SCL_COEF_RAM_ODD_TAP_COEF, odd_coef, -- /* Write/read control for odd coefficient */ -- SCL_COEF_RAM_ODD_TAP_COEF_EN, 1); -- } -- } -- --} -- --#if 0 --bool dpp_set_pixel_storage_depth( -- struct dpp *xfm, -- enum lb_pixel_depth depth, -- const struct bit_depth_reduction_params *bit_depth_params) --{ -- struct dcn10_dpp *xfm110 = TO_DCN10_DPP(xfm); -- bool ret = true; -- uint32_t value; -- enum dc_color_depth color_depth; -- -- value = dm_read_reg(xfm->ctx, LB_REG(mmLB_DATA_FORMAT)); -- switch (depth) { -- case LB_PIXEL_DEPTH_18BPP: -- color_depth = COLOR_DEPTH_666; -- set_reg_field_value(value, 2, LB_DATA_FORMAT, PIXEL_DEPTH); -- set_reg_field_value(value, 1, LB_DATA_FORMAT, PIXEL_EXPAN_MODE); -- break; -- case LB_PIXEL_DEPTH_24BPP: -- color_depth = COLOR_DEPTH_888; -- set_reg_field_value(value, 1, LB_DATA_FORMAT, PIXEL_DEPTH); -- set_reg_field_value(value, 1, LB_DATA_FORMAT, PIXEL_EXPAN_MODE); -- break; -- case LB_PIXEL_DEPTH_30BPP: -- color_depth = COLOR_DEPTH_101010; -- set_reg_field_value(value, 0, LB_DATA_FORMAT, PIXEL_DEPTH); -- set_reg_field_value(value, 1, LB_DATA_FORMAT, PIXEL_EXPAN_MODE); -- break; -- case LB_PIXEL_DEPTH_36BPP: -- color_depth = COLOR_DEPTH_121212; -- set_reg_field_value(value, 3, LB_DATA_FORMAT, PIXEL_DEPTH); -- set_reg_field_value(value, 0, LB_DATA_FORMAT, PIXEL_EXPAN_MODE); -- break; -- default: -- ret = false; -- break; -- } -- -- if (ret == true) { -- set_denormalization(xfm110, color_depth); -- ret = program_bit_depth_reduction(xfm110, color_depth, -- bit_depth_params); -- -- set_reg_field_value(value, 0, LB_DATA_FORMAT, ALPHA_EN); -- dm_write_reg(xfm->ctx, LB_REG(mmLB_DATA_FORMAT), value); -- if (!(xfm110->lb_pixel_depth_supported & depth)) { -- /* We should use unsupported capabilities -- * unless it is required by w/a -- */ -- dm_logger_write(xfm->ctx->logger, LOG_WARNING, -- "%s: Capability not supported", -- __func__); -- } -- } -- -- return ret; --} --#endif -- --static const uint16_t *get_filter_coeffs_64p(int taps, struct fixed31_32 ratio) --{ -- if (taps == 8) -- return get_filter_8tap_64p(ratio); -- else if (taps == 7) -- return get_filter_7tap_64p(ratio); -- else if (taps == 6) -- return get_filter_6tap_64p(ratio); -- else if (taps == 5) -- return get_filter_5tap_64p(ratio); -- else if (taps == 4) -- return get_filter_4tap_64p(ratio); -- else if (taps == 3) -- return get_filter_3tap_64p(ratio); -- else if (taps == 2) -- return filter_2tap_64p; -- else if (taps == 1) -- return NULL; -- else { -- /* should never happen, bug */ -- BREAK_TO_DEBUGGER(); -- return NULL; -- } --} -- --static void dpp_set_scl_filter( -- struct dcn10_dpp *xfm, -- const struct scaler_data *scl_data, -- bool chroma_coef_mode) --{ -- bool h_2tap_hardcode_coef_en = false; -- bool v_2tap_hardcode_coef_en = false; -- bool h_2tap_sharp_en = false; -- bool v_2tap_sharp_en = false; -- uint32_t h_2tap_sharp_factor = scl_data->sharpness.horz; -- uint32_t v_2tap_sharp_factor = scl_data->sharpness.vert; -- bool coef_ram_current; -- const uint16_t *filter_h = NULL; -- const uint16_t *filter_v = NULL; -- const uint16_t *filter_h_c = NULL; -- const uint16_t *filter_v_c = NULL; -- -- h_2tap_hardcode_coef_en = scl_data->taps.h_taps < 3 -- && scl_data->taps.h_taps_c < 3 -- && (scl_data->taps.h_taps > 1 || scl_data->taps.h_taps_c > 1); -- v_2tap_hardcode_coef_en = scl_data->taps.v_taps < 3 -- && scl_data->taps.v_taps_c < 3 -- && (scl_data->taps.v_taps > 1 || scl_data->taps.v_taps_c > 1); -- -- h_2tap_sharp_en = h_2tap_hardcode_coef_en && h_2tap_sharp_factor != 0; -- v_2tap_sharp_en = v_2tap_hardcode_coef_en && v_2tap_sharp_factor != 0; -- -- REG_UPDATE_6(DSCL_2TAP_CONTROL, -- SCL_H_2TAP_HARDCODE_COEF_EN, h_2tap_hardcode_coef_en, -- SCL_H_2TAP_SHARP_EN, h_2tap_sharp_en, -- SCL_H_2TAP_SHARP_FACTOR, h_2tap_sharp_factor, -- SCL_V_2TAP_HARDCODE_COEF_EN, v_2tap_hardcode_coef_en, -- SCL_V_2TAP_SHARP_EN, v_2tap_sharp_en, -- SCL_V_2TAP_SHARP_FACTOR, v_2tap_sharp_factor); -- -- if (!v_2tap_hardcode_coef_en || !h_2tap_hardcode_coef_en) { -- bool filter_updated = false; -- -- filter_h = get_filter_coeffs_64p( -- scl_data->taps.h_taps, scl_data->ratios.horz); -- filter_v = get_filter_coeffs_64p( -- scl_data->taps.v_taps, scl_data->ratios.vert); -- -- filter_updated = (filter_h && (filter_h != xfm->filter_h)) -- || (filter_v && (filter_v != xfm->filter_v)); -- -- if (chroma_coef_mode) { -- filter_h_c = get_filter_coeffs_64p( -- scl_data->taps.h_taps_c, scl_data->ratios.horz_c); -- filter_v_c = get_filter_coeffs_64p( -- scl_data->taps.v_taps_c, scl_data->ratios.vert_c); -- filter_updated = filter_updated || (filter_h_c && (filter_h_c != xfm->filter_h_c)) -- || (filter_v_c && (filter_v_c != xfm->filter_v_c)); -- } -- -- if (filter_updated) { -- uint32_t scl_mode = REG_READ(SCL_MODE); -- -- if (!h_2tap_hardcode_coef_en && filter_h) { -- dpp_set_scaler_filter( -- xfm, scl_data->taps.h_taps, -- SCL_COEF_LUMA_HORZ_FILTER, filter_h); -- } -- xfm->filter_h = filter_h; -- if (!v_2tap_hardcode_coef_en && filter_v) { -- dpp_set_scaler_filter( -- xfm, scl_data->taps.v_taps, -- SCL_COEF_LUMA_VERT_FILTER, filter_v); -- } -- xfm->filter_v = filter_v; -- if (chroma_coef_mode) { -- if (!h_2tap_hardcode_coef_en && filter_h_c) { -- dpp_set_scaler_filter( -- xfm, scl_data->taps.h_taps_c, -- SCL_COEF_CHROMA_HORZ_FILTER, filter_h_c); -- } -- if (!v_2tap_hardcode_coef_en && filter_v_c) { -- dpp_set_scaler_filter( -- xfm, scl_data->taps.v_taps_c, -- SCL_COEF_CHROMA_VERT_FILTER, filter_v_c); -- } -- } -- xfm->filter_h_c = filter_h_c; -- xfm->filter_v_c = filter_v_c; -- -- coef_ram_current = get_reg_field_value_ex( -- scl_mode, xfm->tf_mask->SCL_COEF_RAM_SELECT_CURRENT, -- xfm->tf_shift->SCL_COEF_RAM_SELECT_CURRENT); -- -- /* Swap coefficient RAM and set chroma coefficient mode */ -- REG_SET_2(SCL_MODE, scl_mode, -- SCL_COEF_RAM_SELECT, !coef_ram_current, -- SCL_CHROMA_COEF_MODE, chroma_coef_mode); -- } -- } --} -- -- --static int get_lb_depth_bpc(enum lb_pixel_depth depth) --{ -- if (depth == LB_PIXEL_DEPTH_30BPP) -- return 10; -- else if (depth == LB_PIXEL_DEPTH_24BPP) -- return 8; -- else if (depth == LB_PIXEL_DEPTH_18BPP) -- return 6; -- else if (depth == LB_PIXEL_DEPTH_36BPP) -- return 12; -- else { -- BREAK_TO_DEBUGGER(); -- return -1; /* Unsupported */ -- } --} -- --static void calc_lb_num_partitions( -- const struct scaler_data *scl_data, -- enum lb_memory_config lb_config, -- int *num_part_y, -- int *num_part_c) --{ -- int line_size = scl_data->viewport.width < scl_data->recout.width ? -- scl_data->viewport.width : scl_data->recout.width; -- int line_size_c = scl_data->viewport_c.width < scl_data->recout.width ? -- scl_data->viewport_c.width : scl_data->recout.width; -- int lb_bpc = get_lb_depth_bpc(scl_data->lb_params.depth); -- int memory_line_size_y = (line_size * lb_bpc + 71) / 72; /* +71 to ceil */ -- int memory_line_size_c = (line_size_c * lb_bpc + 71) / 72; /* +71 to ceil */ -- int memory_line_size_a = (line_size + 5) / 6; /* +5 to ceil */ -- int lb_memory_size, lb_memory_size_c, lb_memory_size_a, num_partitions_a; -- -- if (lb_config == LB_MEMORY_CONFIG_1) { -- lb_memory_size = 816; -- lb_memory_size_c = 816; -- lb_memory_size_a = 984; -- } else if (lb_config == LB_MEMORY_CONFIG_2) { -- lb_memory_size = 1088; -- lb_memory_size_c = 1088; -- lb_memory_size_a = 1312; -- } else if (lb_config == LB_MEMORY_CONFIG_3) { -- lb_memory_size = 816 + 1088 + 848 + 848 + 848; -- lb_memory_size_c = 816 + 1088; -- lb_memory_size_a = 984 + 1312 + 456; -- } else { -- lb_memory_size = 816 + 1088 + 848; -- lb_memory_size_c = 816 + 1088 + 848; -- lb_memory_size_a = 984 + 1312 + 456; -- } -- *num_part_y = lb_memory_size / memory_line_size_y; -- *num_part_c = lb_memory_size_c / memory_line_size_c; -- num_partitions_a = lb_memory_size_a / memory_line_size_a; -- -- if (scl_data->lb_params.alpha_en -- && (num_partitions_a < *num_part_y)) -- *num_part_y = num_partitions_a; -- -- if (*num_part_y > 64) -- *num_part_y = 64; -- if (*num_part_c > 64) -- *num_part_c = 64; -- --} -- --static bool is_lb_conf_valid(int ceil_vratio, int num_partitions, int vtaps) --{ -- if (ceil_vratio > 2) -- return vtaps <= (num_partitions - ceil_vratio + 2); -- else -- return vtaps <= num_partitions; --} -- --/*find first match configuration which meets the min required lb size*/ --static enum lb_memory_config find_lb_memory_config(const struct scaler_data *scl_data) --{ -- int num_part_y, num_part_c; -- int vtaps = scl_data->taps.v_taps; -- int vtaps_c = scl_data->taps.v_taps_c; -- int ceil_vratio = dal_fixed31_32_ceil(scl_data->ratios.vert); -- int ceil_vratio_c = dal_fixed31_32_ceil(scl_data->ratios.vert_c); -- -- calc_lb_num_partitions( -- scl_data, LB_MEMORY_CONFIG_1, &num_part_y, &num_part_c); -- -- if (is_lb_conf_valid(ceil_vratio, num_part_y, vtaps) -- && is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c)) -- return LB_MEMORY_CONFIG_1; -- -- calc_lb_num_partitions( -- scl_data, LB_MEMORY_CONFIG_2, &num_part_y, &num_part_c); -- -- if (is_lb_conf_valid(ceil_vratio, num_part_y, vtaps) -- && is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c)) -- return LB_MEMORY_CONFIG_2; -- -- if (scl_data->format == PIXEL_FORMAT_420BPP8 -- || scl_data->format == PIXEL_FORMAT_420BPP10) { -- calc_lb_num_partitions( -- scl_data, LB_MEMORY_CONFIG_3, &num_part_y, &num_part_c); -- -- if (is_lb_conf_valid(ceil_vratio, num_part_y, vtaps) -- && is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c)) -- return LB_MEMORY_CONFIG_3; -- } -- -- calc_lb_num_partitions( -- scl_data, LB_MEMORY_CONFIG_0, &num_part_y, &num_part_c); -- -- /*Ensure we can support the requested number of vtaps*/ -- ASSERT(is_lb_conf_valid(ceil_vratio, num_part_y, vtaps) -- && is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c)); -- -- return LB_MEMORY_CONFIG_0; --} -- --void dpp_set_scaler_auto_scale( -- struct transform *xfm_base, -- const struct scaler_data *scl_data) --{ -- enum lb_memory_config lb_config; -- struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); -- enum dscl_mode_sel dscl_mode = get_dscl_mode( -- scl_data, xfm_base->ctx->dc->debug.always_scale); -- bool ycbcr = scl_data->format >= PIXEL_FORMAT_VIDEO_BEGIN -- && scl_data->format <= PIXEL_FORMAT_VIDEO_END; -- -- dpp_set_overscan(xfm, scl_data); -- -- dpp_set_otg_blank(xfm, scl_data); -- -- REG_UPDATE(SCL_MODE, DSCL_MODE, dscl_mode); -- -- if (dscl_mode == DSCL_MODE_DSCL_BYPASS) -- return; -- -- lb_config = find_lb_memory_config(scl_data); -- dpp_set_lb(xfm, &scl_data->lb_params, lb_config); -- -- if (dscl_mode == DSCL_MODE_SCALING_444_BYPASS) -- return; -- -- /* TODO: v_min */ -- REG_SET_3(DSCL_AUTOCAL, 0, -- AUTOCAL_MODE, AUTOCAL_MODE_AUTOSCALE, -- AUTOCAL_NUM_PIPE, 0, -- AUTOCAL_PIPE_ID, 0); -- -- /* Black offsets */ -- if (ycbcr) -- REG_SET_2(SCL_BLACK_OFFSET, 0, -- SCL_BLACK_OFFSET_RGB_Y, BLACK_OFFSET_RGB_Y, -- SCL_BLACK_OFFSET_CBCR, BLACK_OFFSET_CBCR); -- else -- -- REG_SET_2(SCL_BLACK_OFFSET, 0, -- SCL_BLACK_OFFSET_RGB_Y, BLACK_OFFSET_RGB_Y, -- SCL_BLACK_OFFSET_CBCR, BLACK_OFFSET_RGB_Y); -- -- REG_SET_4(SCL_TAP_CONTROL, 0, -- SCL_V_NUM_TAPS, scl_data->taps.v_taps - 1, -- SCL_H_NUM_TAPS, scl_data->taps.h_taps - 1, -- SCL_V_NUM_TAPS_C, scl_data->taps.v_taps_c - 1, -- SCL_H_NUM_TAPS_C, scl_data->taps.h_taps_c - 1); -- -- dpp_set_scl_filter(xfm, scl_data, ycbcr); --} -- - /* Program gamut remap in bypass mode */ - void dpp_set_gamut_remap_bypass(struct dcn10_dpp *xfm) - { -@@ -628,146 +120,6 @@ void dpp_set_gamut_remap_bypass(struct dcn10_dpp *xfm) - /* Gamut remap in bypass */ - } - --static void dpp_set_recout( -- struct dcn10_dpp *xfm, const struct rect *recout) --{ -- REG_SET_2(RECOUT_START, 0, -- /* First pixel of RECOUT */ -- RECOUT_START_X, recout->x, -- /* First line of RECOUT */ -- RECOUT_START_Y, recout->y); -- -- REG_SET_2(RECOUT_SIZE, 0, -- /* Number of RECOUT horizontal pixels */ -- RECOUT_WIDTH, recout->width, -- /* Number of RECOUT vertical lines */ -- RECOUT_HEIGHT, recout->height -- - xfm->base.ctx->dc->debug.surface_visual_confirm * 4 * -- (xfm->base.inst + 1)); --} -- --static void dpp_set_manual_ratio_init( -- struct dcn10_dpp *xfm, const struct scaler_data *data) --{ -- uint32_t init_frac = 0; -- uint32_t init_int = 0; -- -- REG_SET(SCL_HORZ_FILTER_SCALE_RATIO, 0, -- SCL_H_SCALE_RATIO, dal_fixed31_32_u2d19(data->ratios.horz) << 5); -- -- REG_SET(SCL_VERT_FILTER_SCALE_RATIO, 0, -- SCL_V_SCALE_RATIO, dal_fixed31_32_u2d19(data->ratios.vert) << 5); -- -- REG_SET(SCL_HORZ_FILTER_SCALE_RATIO_C, 0, -- SCL_H_SCALE_RATIO_C, dal_fixed31_32_u2d19(data->ratios.horz_c) << 5); -- -- REG_SET(SCL_VERT_FILTER_SCALE_RATIO_C, 0, -- SCL_V_SCALE_RATIO_C, dal_fixed31_32_u2d19(data->ratios.vert_c) << 5); -- -- /* -- * 0.24 format for fraction, first five bits zeroed -- */ -- init_frac = dal_fixed31_32_u0d19(data->inits.h) << 5; -- init_int = dal_fixed31_32_floor(data->inits.h); -- REG_SET_2(SCL_HORZ_FILTER_INIT, 0, -- SCL_H_INIT_FRAC, init_frac, -- SCL_H_INIT_INT, init_int); -- -- init_frac = dal_fixed31_32_u0d19(data->inits.h_c) << 5; -- init_int = dal_fixed31_32_floor(data->inits.h_c); -- REG_SET_2(SCL_HORZ_FILTER_INIT_C, 0, -- SCL_H_INIT_FRAC_C, init_frac, -- SCL_H_INIT_INT_C, init_int); -- -- init_frac = dal_fixed31_32_u0d19(data->inits.v) << 5; -- init_int = dal_fixed31_32_floor(data->inits.v); -- REG_SET_2(SCL_VERT_FILTER_INIT, 0, -- SCL_V_INIT_FRAC, init_frac, -- SCL_V_INIT_INT, init_int); -- -- init_frac = dal_fixed31_32_u0d19(data->inits.v_bot) << 5; -- init_int = dal_fixed31_32_floor(data->inits.v_bot); -- REG_SET_2(SCL_VERT_FILTER_INIT_BOT, 0, -- SCL_V_INIT_FRAC_BOT, init_frac, -- SCL_V_INIT_INT_BOT, init_int); -- -- init_frac = dal_fixed31_32_u0d19(data->inits.v_c) << 5; -- init_int = dal_fixed31_32_floor(data->inits.v_c); -- REG_SET_2(SCL_VERT_FILTER_INIT_C, 0, -- SCL_V_INIT_FRAC_C, init_frac, -- SCL_V_INIT_INT_C, init_int); -- -- init_frac = dal_fixed31_32_u0d19(data->inits.v_c_bot) << 5; -- init_int = dal_fixed31_32_floor(data->inits.v_c_bot); -- REG_SET_2(SCL_VERT_FILTER_INIT_BOT_C, 0, -- SCL_V_INIT_FRAC_BOT_C, init_frac, -- SCL_V_INIT_INT_BOT_C, init_int); --} -- --/* Main function to program scaler and line buffer in manual scaling mode */ --static void dpp_set_scaler_manual_scale( -- struct transform *xfm_base, -- const struct scaler_data *scl_data) --{ -- enum lb_memory_config lb_config; -- struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); -- enum dscl_mode_sel dscl_mode = get_dscl_mode( -- scl_data, xfm_base->ctx->dc->debug.always_scale); -- bool ycbcr = scl_data->format >= PIXEL_FORMAT_VIDEO_BEGIN -- && scl_data->format <= PIXEL_FORMAT_VIDEO_END; -- -- /* Recout */ -- dpp_set_recout(xfm, &scl_data->recout); -- -- /* MPC Size */ -- REG_SET_2(MPC_SIZE, 0, -- /* Number of horizontal pixels of MPC */ -- MPC_WIDTH, scl_data->h_active, -- /* Number of vertical lines of MPC */ -- MPC_HEIGHT, scl_data->v_active); -- -- /* SCL mode */ -- REG_UPDATE(SCL_MODE, DSCL_MODE, dscl_mode); -- -- if (dscl_mode == DSCL_MODE_DSCL_BYPASS) -- return; -- /* LB */ -- lb_config = find_lb_memory_config(scl_data); -- dpp_set_lb(xfm, &scl_data->lb_params, lb_config); -- -- if (dscl_mode == DSCL_MODE_SCALING_444_BYPASS) -- return; -- -- /* Autocal off */ -- REG_SET_3(DSCL_AUTOCAL, 0, -- AUTOCAL_MODE, AUTOCAL_MODE_OFF, -- AUTOCAL_NUM_PIPE, 0, -- AUTOCAL_PIPE_ID, 0); -- -- /* Black offsets */ -- if (ycbcr) -- REG_SET_2(SCL_BLACK_OFFSET, 0, -- SCL_BLACK_OFFSET_RGB_Y, BLACK_OFFSET_RGB_Y, -- SCL_BLACK_OFFSET_CBCR, BLACK_OFFSET_CBCR); -- else -- -- REG_SET_2(SCL_BLACK_OFFSET, 0, -- SCL_BLACK_OFFSET_RGB_Y, BLACK_OFFSET_RGB_Y, -- SCL_BLACK_OFFSET_CBCR, BLACK_OFFSET_RGB_Y); -- -- /* Manually calculate scale ratio and init values */ -- dpp_set_manual_ratio_init(xfm, scl_data); -- -- /* HTaps/VTaps */ -- REG_SET_4(SCL_TAP_CONTROL, 0, -- SCL_V_NUM_TAPS, scl_data->taps.v_taps - 1, -- SCL_H_NUM_TAPS, scl_data->taps.h_taps - 1, -- SCL_V_NUM_TAPS_C, scl_data->taps.v_taps_c - 1, -- SCL_H_NUM_TAPS_C, scl_data->taps.h_taps_c - 1); -- -- dpp_set_scl_filter(xfm, scl_data, ycbcr); --} -- - #define IDENTITY_RATIO(ratio) (dal_fixed31_32_u2d19(ratio) == (1 << 19)) - - -@@ -1561,7 +913,7 @@ static void oppn10_set_regamma_mode( - - static struct transform_funcs dcn10_dpp_funcs = { - .transform_reset = dpp_reset, -- .transform_set_scaler = dpp_set_scaler_manual_scale, -+ .transform_set_scaler = dcn10_dpp_set_scaler_manual_scale, - .transform_get_optimal_number_of_taps = dpp_get_optimal_number_of_taps, - .transform_set_gamut_remap = dcn_dpp_set_gamut_remap, - .opp_set_csc_adjustment = oppn10_set_output_csc_adjustment, -diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h -index 1c9d332..496df1f 100644 ---- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h -+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h -@@ -1386,6 +1386,11 @@ struct dcn10_dpp { - int lb_bits_per_entry; - bool is_write_to_ram_a_safe; - }; -+ -+void dcn10_dpp_set_scaler_manual_scale( -+ struct transform *xfm_base, -+ const struct scaler_data *scl_data); -+ - bool dcn10_dpp_construct(struct dcn10_dpp *xfm110, - struct dc_context *ctx, - uint32_t inst, -diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c -new file mode 100644 -index 0000000..95f014b ---- /dev/null -+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c -@@ -0,0 +1,762 @@ -+/* -+ * Copyright 2016 Advanced Micro Devices, Inc. -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ * -+ * Authors: AMD -+ * -+ */ -+ -+#include "dm_services.h" -+ -+#include "core_types.h" -+ -+#include "reg_helper.h" -+#include "dcn10_dpp.h" -+#include "basics/conversion.h" -+ -+#define NUM_PHASES 64 -+#define HORZ_MAX_TAPS 8 -+#define VERT_MAX_TAPS 8 -+ -+#define BLACK_OFFSET_RGB_Y 0x0 -+#define BLACK_OFFSET_CBCR 0x8000 -+ -+#define REG(reg)\ -+ xfm->tf_regs->reg -+ -+#define CTX \ -+ xfm->base.ctx -+ -+#undef FN -+#define FN(reg_name, field_name) \ -+ xfm->tf_shift->field_name, xfm->tf_mask->field_name -+ -+enum dcn10_coef_filter_type_sel { -+ SCL_COEF_LUMA_VERT_FILTER = 0, -+ SCL_COEF_LUMA_HORZ_FILTER = 1, -+ SCL_COEF_CHROMA_VERT_FILTER = 2, -+ SCL_COEF_CHROMA_HORZ_FILTER = 3, -+ SCL_COEF_ALPHA_VERT_FILTER = 4, -+ SCL_COEF_ALPHA_HORZ_FILTER = 5 -+}; -+ -+enum lb_memory_config { -+ /* Enable all 3 pieces of memory */ -+ LB_MEMORY_CONFIG_0 = 0, -+ -+ /* Enable only the first piece of memory */ -+ LB_MEMORY_CONFIG_1 = 1, -+ -+ /* Enable only the second piece of memory */ -+ LB_MEMORY_CONFIG_2 = 2, -+ -+ /* Only applicable in 4:2:0 mode, enable all 3 pieces of memory and the -+ * last piece of chroma memory used for the luma storage -+ */ -+ LB_MEMORY_CONFIG_3 = 3 -+}; -+ -+enum dscl_autocal_mode { -+ AUTOCAL_MODE_OFF = 0, -+ -+ /* Autocal calculate the scaling ratio and initial phase and the -+ * DSCL_MODE_SEL must be set to 1 -+ */ -+ AUTOCAL_MODE_AUTOSCALE = 1, -+ /* Autocal perform auto centering without replication and the -+ * DSCL_MODE_SEL must be set to 0 -+ */ -+ AUTOCAL_MODE_AUTOCENTER = 2, -+ /* Autocal perform auto centering and auto replication and the -+ * DSCL_MODE_SEL must be set to 0 -+ */ -+ AUTOCAL_MODE_AUTOREPLICATE = 3 -+}; -+ -+enum dscl_mode_sel { -+ DSCL_MODE_SCALING_444_BYPASS = 0, -+ DSCL_MODE_SCALING_444_RGB_ENABLE = 1, -+ DSCL_MODE_SCALING_444_YCBCR_ENABLE = 2, -+ DSCL_MODE_SCALING_420_YCBCR_ENABLE = 3, -+ DSCL_MODE_SCALING_420_LUMA_BYPASS = 4, -+ DSCL_MODE_SCALING_420_CHROMA_BYPASS = 5, -+ DSCL_MODE_DSCL_BYPASS = 6 -+}; -+ -+enum gamut_remap_select { -+ GAMUT_REMAP_BYPASS = 0, -+ GAMUT_REMAP_COEFF, -+ GAMUT_REMAP_COMA_COEFF, -+ GAMUT_REMAP_COMB_COEFF -+}; -+ -+ -+static void dpp_set_overscan( -+ struct dcn10_dpp *xfm, -+ const struct scaler_data *data) -+{ -+ uint32_t left = data->recout.x; -+ uint32_t top = data->recout.y; -+ -+ int right = data->h_active - data->recout.x - data->recout.width; -+ int bottom = data->v_active - data->recout.y - data->recout.height; -+ -+ if (right < 0) { -+ BREAK_TO_DEBUGGER(); -+ right = 0; -+ } -+ if (bottom < 0) { -+ BREAK_TO_DEBUGGER(); -+ bottom = 0; -+ } -+ -+ REG_SET_2(DSCL_EXT_OVERSCAN_LEFT_RIGHT, 0, -+ EXT_OVERSCAN_LEFT, left, -+ EXT_OVERSCAN_RIGHT, right); -+ -+ REG_SET_2(DSCL_EXT_OVERSCAN_TOP_BOTTOM, 0, -+ EXT_OVERSCAN_BOTTOM, bottom, -+ EXT_OVERSCAN_TOP, top); -+} -+ -+static void dpp_set_otg_blank( -+ struct dcn10_dpp *xfm, const struct scaler_data *data) -+{ -+ uint32_t h_blank_start = data->h_active; -+ uint32_t h_blank_end = 0; -+ uint32_t v_blank_start = data->v_active; -+ uint32_t v_blank_end = 0; -+ -+ REG_SET_2(OTG_H_BLANK, 0, -+ OTG_H_BLANK_START, h_blank_start, -+ OTG_H_BLANK_END, h_blank_end); -+ -+ REG_SET_2(OTG_V_BLANK, 0, -+ OTG_V_BLANK_START, v_blank_start, -+ OTG_V_BLANK_END, v_blank_end); -+} -+ -+static int get_pixel_depth_val(enum lb_pixel_depth depth) -+{ -+ if (depth == LB_PIXEL_DEPTH_30BPP) -+ return 0; /* 10 bpc */ -+ else if (depth == LB_PIXEL_DEPTH_24BPP) -+ return 1; /* 8 bpc */ -+ else if (depth == LB_PIXEL_DEPTH_18BPP) -+ return 2; /* 6 bpc */ -+ else if (depth == LB_PIXEL_DEPTH_36BPP) -+ return 3; /* 12 bpc */ -+ else { -+ ASSERT(0); -+ return -1; /* Unsupported */ -+ } -+} -+ -+static enum dscl_mode_sel get_dscl_mode( -+ const struct scaler_data *data, bool dbg_always_scale) -+{ -+ const long long one = dal_fixed31_32_one.value; -+ bool ycbcr = false; -+ bool format420 = false; -+ -+ if (data->format == PIXEL_FORMAT_FP16) -+ return DSCL_MODE_DSCL_BYPASS; -+ -+ if (data->format >= PIXEL_FORMAT_VIDEO_BEGIN -+ && data->format <= PIXEL_FORMAT_VIDEO_END) -+ ycbcr = true; -+ -+ if (data->format == PIXEL_FORMAT_420BPP8 || -+ data->format == PIXEL_FORMAT_420BPP10) -+ format420 = true; -+ -+ if (data->ratios.horz.value == one -+ && data->ratios.vert.value == one -+ && data->ratios.horz_c.value == one -+ && data->ratios.vert_c.value == one -+ && !dbg_always_scale) -+ return DSCL_MODE_SCALING_444_BYPASS; -+ -+ if (!format420) { -+ if (ycbcr) -+ return DSCL_MODE_SCALING_444_YCBCR_ENABLE; -+ else -+ return DSCL_MODE_SCALING_444_RGB_ENABLE; -+ } -+ if (data->ratios.horz.value == one && data->ratios.vert.value == one) -+ return DSCL_MODE_SCALING_420_LUMA_BYPASS; -+ if (data->ratios.horz_c.value == one && data->ratios.vert_c.value == one) -+ return DSCL_MODE_SCALING_420_CHROMA_BYPASS; -+ -+ return DSCL_MODE_SCALING_420_YCBCR_ENABLE; -+} -+ -+static void dpp_set_lb( -+ struct dcn10_dpp *xfm, -+ const struct line_buffer_params *lb_params, -+ enum lb_memory_config mem_size_config) -+{ -+ uint32_t pixel_depth = get_pixel_depth_val(lb_params->depth); -+ uint32_t dyn_pix_depth = lb_params->dynamic_pixel_depth; -+ REG_SET_7(LB_DATA_FORMAT, 0, -+ PIXEL_DEPTH, pixel_depth, /* Pixel depth stored in LB */ -+ PIXEL_EXPAN_MODE, lb_params->pixel_expan_mode, /* Pixel expansion mode */ -+ PIXEL_REDUCE_MODE, 1, /* Pixel reduction mode: Rounding */ -+ DYNAMIC_PIXEL_DEPTH, dyn_pix_depth, /* Dynamic expansion pixel depth */ -+ DITHER_EN, 0, /* Dithering enable: Disabled */ -+ INTERLEAVE_EN, lb_params->interleave_en, /* Interleave source enable */ -+ ALPHA_EN, lb_params->alpha_en); /* Alpha enable */ -+ -+ REG_SET_2(LB_MEMORY_CTRL, 0, -+ MEMORY_CONFIG, mem_size_config, -+ LB_MAX_PARTITIONS, 63); -+} -+ -+static const uint16_t *get_filter_coeffs_64p(int taps, struct fixed31_32 ratio) -+{ -+ if (taps == 8) -+ return get_filter_8tap_64p(ratio); -+ else if (taps == 7) -+ return get_filter_7tap_64p(ratio); -+ else if (taps == 6) -+ return get_filter_6tap_64p(ratio); -+ else if (taps == 5) -+ return get_filter_5tap_64p(ratio); -+ else if (taps == 4) -+ return get_filter_4tap_64p(ratio); -+ else if (taps == 3) -+ return get_filter_3tap_64p(ratio); -+ else if (taps == 2) -+ return filter_2tap_64p; -+ else if (taps == 1) -+ return NULL; -+ else { -+ /* should never happen, bug */ -+ BREAK_TO_DEBUGGER(); -+ return NULL; -+ } -+} -+ -+static void dpp_set_scaler_filter( -+ struct dcn10_dpp *xfm, -+ uint32_t taps, -+ enum dcn10_coef_filter_type_sel filter_type, -+ const uint16_t *filter) -+{ -+ const int tap_pairs = (taps + 1) / 2; -+ int phase; -+ int pair; -+ uint16_t odd_coef, even_coef; -+ -+ REG_SET_3(SCL_COEF_RAM_TAP_SELECT, 0, -+ SCL_COEF_RAM_TAP_PAIR_IDX, 0, -+ SCL_COEF_RAM_PHASE, 0, -+ SCL_COEF_RAM_FILTER_TYPE, filter_type); -+ -+ for (phase = 0; phase < (NUM_PHASES / 2 + 1); phase++) { -+ for (pair = 0; pair < tap_pairs; pair++) { -+ even_coef = filter[phase * taps + 2 * pair]; -+ if ((pair * 2 + 1) < taps) -+ odd_coef = filter[phase * taps + 2 * pair + 1]; -+ else -+ odd_coef = 0; -+ -+ REG_SET_4(SCL_COEF_RAM_TAP_DATA, 0, -+ /* Even tap coefficient (bits 1:0 fixed to 0) */ -+ SCL_COEF_RAM_EVEN_TAP_COEF, even_coef, -+ /* Write/read control for even coefficient */ -+ SCL_COEF_RAM_EVEN_TAP_COEF_EN, 1, -+ /* Odd tap coefficient (bits 1:0 fixed to 0) */ -+ SCL_COEF_RAM_ODD_TAP_COEF, odd_coef, -+ /* Write/read control for odd coefficient */ -+ SCL_COEF_RAM_ODD_TAP_COEF_EN, 1); -+ } -+ } -+ -+} -+ -+static void dpp_set_scl_filter( -+ struct dcn10_dpp *xfm, -+ const struct scaler_data *scl_data, -+ bool chroma_coef_mode) -+{ -+ bool h_2tap_hardcode_coef_en = false; -+ bool v_2tap_hardcode_coef_en = false; -+ bool h_2tap_sharp_en = false; -+ bool v_2tap_sharp_en = false; -+ uint32_t h_2tap_sharp_factor = scl_data->sharpness.horz; -+ uint32_t v_2tap_sharp_factor = scl_data->sharpness.vert; -+ bool coef_ram_current; -+ const uint16_t *filter_h = NULL; -+ const uint16_t *filter_v = NULL; -+ const uint16_t *filter_h_c = NULL; -+ const uint16_t *filter_v_c = NULL; -+ -+ h_2tap_hardcode_coef_en = scl_data->taps.h_taps < 3 -+ && scl_data->taps.h_taps_c < 3 -+ && (scl_data->taps.h_taps > 1 || scl_data->taps.h_taps_c > 1); -+ v_2tap_hardcode_coef_en = scl_data->taps.v_taps < 3 -+ && scl_data->taps.v_taps_c < 3 -+ && (scl_data->taps.v_taps > 1 || scl_data->taps.v_taps_c > 1); -+ -+ h_2tap_sharp_en = h_2tap_hardcode_coef_en && h_2tap_sharp_factor != 0; -+ v_2tap_sharp_en = v_2tap_hardcode_coef_en && v_2tap_sharp_factor != 0; -+ -+ REG_UPDATE_6(DSCL_2TAP_CONTROL, -+ SCL_H_2TAP_HARDCODE_COEF_EN, h_2tap_hardcode_coef_en, -+ SCL_H_2TAP_SHARP_EN, h_2tap_sharp_en, -+ SCL_H_2TAP_SHARP_FACTOR, h_2tap_sharp_factor, -+ SCL_V_2TAP_HARDCODE_COEF_EN, v_2tap_hardcode_coef_en, -+ SCL_V_2TAP_SHARP_EN, v_2tap_sharp_en, -+ SCL_V_2TAP_SHARP_FACTOR, v_2tap_sharp_factor); -+ -+ if (!v_2tap_hardcode_coef_en || !h_2tap_hardcode_coef_en) { -+ bool filter_updated = false; -+ -+ filter_h = get_filter_coeffs_64p( -+ scl_data->taps.h_taps, scl_data->ratios.horz); -+ filter_v = get_filter_coeffs_64p( -+ scl_data->taps.v_taps, scl_data->ratios.vert); -+ -+ filter_updated = (filter_h && (filter_h != xfm->filter_h)) -+ || (filter_v && (filter_v != xfm->filter_v)); -+ -+ if (chroma_coef_mode) { -+ filter_h_c = get_filter_coeffs_64p( -+ scl_data->taps.h_taps_c, scl_data->ratios.horz_c); -+ filter_v_c = get_filter_coeffs_64p( -+ scl_data->taps.v_taps_c, scl_data->ratios.vert_c); -+ filter_updated = filter_updated || (filter_h_c && (filter_h_c != xfm->filter_h_c)) -+ || (filter_v_c && (filter_v_c != xfm->filter_v_c)); -+ } -+ -+ if (filter_updated) { -+ uint32_t scl_mode = REG_READ(SCL_MODE); -+ -+ if (!h_2tap_hardcode_coef_en && filter_h) { -+ dpp_set_scaler_filter( -+ xfm, scl_data->taps.h_taps, -+ SCL_COEF_LUMA_HORZ_FILTER, filter_h); -+ } -+ xfm->filter_h = filter_h; -+ if (!v_2tap_hardcode_coef_en && filter_v) { -+ dpp_set_scaler_filter( -+ xfm, scl_data->taps.v_taps, -+ SCL_COEF_LUMA_VERT_FILTER, filter_v); -+ } -+ xfm->filter_v = filter_v; -+ if (chroma_coef_mode) { -+ if (!h_2tap_hardcode_coef_en && filter_h_c) { -+ dpp_set_scaler_filter( -+ xfm, scl_data->taps.h_taps_c, -+ SCL_COEF_CHROMA_HORZ_FILTER, filter_h_c); -+ } -+ if (!v_2tap_hardcode_coef_en && filter_v_c) { -+ dpp_set_scaler_filter( -+ xfm, scl_data->taps.v_taps_c, -+ SCL_COEF_CHROMA_VERT_FILTER, filter_v_c); -+ } -+ } -+ xfm->filter_h_c = filter_h_c; -+ xfm->filter_v_c = filter_v_c; -+ -+ coef_ram_current = get_reg_field_value_ex( -+ scl_mode, xfm->tf_mask->SCL_COEF_RAM_SELECT_CURRENT, -+ xfm->tf_shift->SCL_COEF_RAM_SELECT_CURRENT); -+ -+ /* Swap coefficient RAM and set chroma coefficient mode */ -+ REG_SET_2(SCL_MODE, scl_mode, -+ SCL_COEF_RAM_SELECT, !coef_ram_current, -+ SCL_CHROMA_COEF_MODE, chroma_coef_mode); -+ } -+ } -+} -+ -+static int get_lb_depth_bpc(enum lb_pixel_depth depth) -+{ -+ if (depth == LB_PIXEL_DEPTH_30BPP) -+ return 10; -+ else if (depth == LB_PIXEL_DEPTH_24BPP) -+ return 8; -+ else if (depth == LB_PIXEL_DEPTH_18BPP) -+ return 6; -+ else if (depth == LB_PIXEL_DEPTH_36BPP) -+ return 12; -+ else { -+ BREAK_TO_DEBUGGER(); -+ return -1; /* Unsupported */ -+ } -+} -+ -+static void calc_lb_num_partitions( -+ const struct scaler_data *scl_data, -+ enum lb_memory_config lb_config, -+ int *num_part_y, -+ int *num_part_c) -+{ -+ int line_size = scl_data->viewport.width < scl_data->recout.width ? -+ scl_data->viewport.width : scl_data->recout.width; -+ int line_size_c = scl_data->viewport_c.width < scl_data->recout.width ? -+ scl_data->viewport_c.width : scl_data->recout.width; -+ int lb_bpc = get_lb_depth_bpc(scl_data->lb_params.depth); -+ int memory_line_size_y = (line_size * lb_bpc + 71) / 72; /* +71 to ceil */ -+ int memory_line_size_c = (line_size_c * lb_bpc + 71) / 72; /* +71 to ceil */ -+ int memory_line_size_a = (line_size + 5) / 6; /* +5 to ceil */ -+ int lb_memory_size, lb_memory_size_c, lb_memory_size_a, num_partitions_a; -+ -+ if (lb_config == LB_MEMORY_CONFIG_1) { -+ lb_memory_size = 816; -+ lb_memory_size_c = 816; -+ lb_memory_size_a = 984; -+ } else if (lb_config == LB_MEMORY_CONFIG_2) { -+ lb_memory_size = 1088; -+ lb_memory_size_c = 1088; -+ lb_memory_size_a = 1312; -+ } else if (lb_config == LB_MEMORY_CONFIG_3) { -+ lb_memory_size = 816 + 1088 + 848 + 848 + 848; -+ lb_memory_size_c = 816 + 1088; -+ lb_memory_size_a = 984 + 1312 + 456; -+ } else { -+ lb_memory_size = 816 + 1088 + 848; -+ lb_memory_size_c = 816 + 1088 + 848; -+ lb_memory_size_a = 984 + 1312 + 456; -+ } -+ *num_part_y = lb_memory_size / memory_line_size_y; -+ *num_part_c = lb_memory_size_c / memory_line_size_c; -+ num_partitions_a = lb_memory_size_a / memory_line_size_a; -+ -+ if (scl_data->lb_params.alpha_en -+ && (num_partitions_a < *num_part_y)) -+ *num_part_y = num_partitions_a; -+ -+ if (*num_part_y > 64) -+ *num_part_y = 64; -+ if (*num_part_c > 64) -+ *num_part_c = 64; -+ -+} -+ -+static bool is_lb_conf_valid(int ceil_vratio, int num_partitions, int vtaps) -+{ -+ if (ceil_vratio > 2) -+ return vtaps <= (num_partitions - ceil_vratio + 2); -+ else -+ return vtaps <= num_partitions; -+} -+ -+/*find first match configuration which meets the min required lb size*/ -+static enum lb_memory_config find_lb_memory_config(const struct scaler_data *scl_data) -+{ -+ int num_part_y, num_part_c; -+ int vtaps = scl_data->taps.v_taps; -+ int vtaps_c = scl_data->taps.v_taps_c; -+ int ceil_vratio = dal_fixed31_32_ceil(scl_data->ratios.vert); -+ int ceil_vratio_c = dal_fixed31_32_ceil(scl_data->ratios.vert_c); -+ -+ calc_lb_num_partitions( -+ scl_data, LB_MEMORY_CONFIG_1, &num_part_y, &num_part_c); -+ -+ if (is_lb_conf_valid(ceil_vratio, num_part_y, vtaps) -+ && is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c)) -+ return LB_MEMORY_CONFIG_1; -+ -+ calc_lb_num_partitions( -+ scl_data, LB_MEMORY_CONFIG_2, &num_part_y, &num_part_c); -+ -+ if (is_lb_conf_valid(ceil_vratio, num_part_y, vtaps) -+ && is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c)) -+ return LB_MEMORY_CONFIG_2; -+ -+ if (scl_data->format == PIXEL_FORMAT_420BPP8 -+ || scl_data->format == PIXEL_FORMAT_420BPP10) { -+ calc_lb_num_partitions( -+ scl_data, LB_MEMORY_CONFIG_3, &num_part_y, &num_part_c); -+ -+ if (is_lb_conf_valid(ceil_vratio, num_part_y, vtaps) -+ && is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c)) -+ return LB_MEMORY_CONFIG_3; -+ } -+ -+ calc_lb_num_partitions( -+ scl_data, LB_MEMORY_CONFIG_0, &num_part_y, &num_part_c); -+ -+ /*Ensure we can support the requested number of vtaps*/ -+ ASSERT(is_lb_conf_valid(ceil_vratio, num_part_y, vtaps) -+ && is_lb_conf_valid(ceil_vratio_c, num_part_c, vtaps_c)); -+ -+ return LB_MEMORY_CONFIG_0; -+} -+ -+void dpp_set_scaler_auto_scale( -+ struct transform *xfm_base, -+ const struct scaler_data *scl_data) -+{ -+ enum lb_memory_config lb_config; -+ struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); -+ enum dscl_mode_sel dscl_mode = get_dscl_mode( -+ scl_data, xfm_base->ctx->dc->debug.always_scale); -+ bool ycbcr = scl_data->format >= PIXEL_FORMAT_VIDEO_BEGIN -+ && scl_data->format <= PIXEL_FORMAT_VIDEO_END; -+ -+ dpp_set_overscan(xfm, scl_data); -+ -+ dpp_set_otg_blank(xfm, scl_data); -+ -+ REG_UPDATE(SCL_MODE, DSCL_MODE, dscl_mode); -+ -+ if (dscl_mode == DSCL_MODE_DSCL_BYPASS) -+ return; -+ -+ lb_config = find_lb_memory_config(scl_data); -+ dpp_set_lb(xfm, &scl_data->lb_params, lb_config); -+ -+ if (dscl_mode == DSCL_MODE_SCALING_444_BYPASS) -+ return; -+ -+ /* TODO: v_min */ -+ REG_SET_3(DSCL_AUTOCAL, 0, -+ AUTOCAL_MODE, AUTOCAL_MODE_AUTOSCALE, -+ AUTOCAL_NUM_PIPE, 0, -+ AUTOCAL_PIPE_ID, 0); -+ -+ /* Black offsets */ -+ if (ycbcr) -+ REG_SET_2(SCL_BLACK_OFFSET, 0, -+ SCL_BLACK_OFFSET_RGB_Y, BLACK_OFFSET_RGB_Y, -+ SCL_BLACK_OFFSET_CBCR, BLACK_OFFSET_CBCR); -+ else -+ -+ REG_SET_2(SCL_BLACK_OFFSET, 0, -+ SCL_BLACK_OFFSET_RGB_Y, BLACK_OFFSET_RGB_Y, -+ SCL_BLACK_OFFSET_CBCR, BLACK_OFFSET_RGB_Y); -+ -+ REG_SET_4(SCL_TAP_CONTROL, 0, -+ SCL_V_NUM_TAPS, scl_data->taps.v_taps - 1, -+ SCL_H_NUM_TAPS, scl_data->taps.h_taps - 1, -+ SCL_V_NUM_TAPS_C, scl_data->taps.v_taps_c - 1, -+ SCL_H_NUM_TAPS_C, scl_data->taps.h_taps_c - 1); -+ -+ dpp_set_scl_filter(xfm, scl_data, ycbcr); -+} -+ -+ -+static void dpp_set_manual_ratio_init( -+ struct dcn10_dpp *xfm, const struct scaler_data *data) -+{ -+ uint32_t init_frac = 0; -+ uint32_t init_int = 0; -+ -+ REG_SET(SCL_HORZ_FILTER_SCALE_RATIO, 0, -+ SCL_H_SCALE_RATIO, dal_fixed31_32_u2d19(data->ratios.horz) << 5); -+ -+ REG_SET(SCL_VERT_FILTER_SCALE_RATIO, 0, -+ SCL_V_SCALE_RATIO, dal_fixed31_32_u2d19(data->ratios.vert) << 5); -+ -+ REG_SET(SCL_HORZ_FILTER_SCALE_RATIO_C, 0, -+ SCL_H_SCALE_RATIO_C, dal_fixed31_32_u2d19(data->ratios.horz_c) << 5); -+ -+ REG_SET(SCL_VERT_FILTER_SCALE_RATIO_C, 0, -+ SCL_V_SCALE_RATIO_C, dal_fixed31_32_u2d19(data->ratios.vert_c) << 5); -+ -+ /* -+ * 0.24 format for fraction, first five bits zeroed -+ */ -+ init_frac = dal_fixed31_32_u0d19(data->inits.h) << 5; -+ init_int = dal_fixed31_32_floor(data->inits.h); -+ REG_SET_2(SCL_HORZ_FILTER_INIT, 0, -+ SCL_H_INIT_FRAC, init_frac, -+ SCL_H_INIT_INT, init_int); -+ -+ init_frac = dal_fixed31_32_u0d19(data->inits.h_c) << 5; -+ init_int = dal_fixed31_32_floor(data->inits.h_c); -+ REG_SET_2(SCL_HORZ_FILTER_INIT_C, 0, -+ SCL_H_INIT_FRAC_C, init_frac, -+ SCL_H_INIT_INT_C, init_int); -+ -+ init_frac = dal_fixed31_32_u0d19(data->inits.v) << 5; -+ init_int = dal_fixed31_32_floor(data->inits.v); -+ REG_SET_2(SCL_VERT_FILTER_INIT, 0, -+ SCL_V_INIT_FRAC, init_frac, -+ SCL_V_INIT_INT, init_int); -+ -+ init_frac = dal_fixed31_32_u0d19(data->inits.v_bot) << 5; -+ init_int = dal_fixed31_32_floor(data->inits.v_bot); -+ REG_SET_2(SCL_VERT_FILTER_INIT_BOT, 0, -+ SCL_V_INIT_FRAC_BOT, init_frac, -+ SCL_V_INIT_INT_BOT, init_int); -+ -+ init_frac = dal_fixed31_32_u0d19(data->inits.v_c) << 5; -+ init_int = dal_fixed31_32_floor(data->inits.v_c); -+ REG_SET_2(SCL_VERT_FILTER_INIT_C, 0, -+ SCL_V_INIT_FRAC_C, init_frac, -+ SCL_V_INIT_INT_C, init_int); -+ -+ init_frac = dal_fixed31_32_u0d19(data->inits.v_c_bot) << 5; -+ init_int = dal_fixed31_32_floor(data->inits.v_c_bot); -+ REG_SET_2(SCL_VERT_FILTER_INIT_BOT_C, 0, -+ SCL_V_INIT_FRAC_BOT_C, init_frac, -+ SCL_V_INIT_INT_BOT_C, init_int); -+} -+ -+ -+ -+static void dpp_set_recout( -+ struct dcn10_dpp *xfm, const struct rect *recout) -+{ -+ REG_SET_2(RECOUT_START, 0, -+ /* First pixel of RECOUT */ -+ RECOUT_START_X, recout->x, -+ /* First line of RECOUT */ -+ RECOUT_START_Y, recout->y); -+ -+ REG_SET_2(RECOUT_SIZE, 0, -+ /* Number of RECOUT horizontal pixels */ -+ RECOUT_WIDTH, recout->width, -+ /* Number of RECOUT vertical lines */ -+ RECOUT_HEIGHT, recout->height -+ - xfm->base.ctx->dc->debug.surface_visual_confirm * 4 * -+ (xfm->base.inst + 1)); -+} -+ -+/* Main function to program scaler and line buffer in manual scaling mode */ -+void dcn10_dpp_set_scaler_manual_scale( -+ struct transform *xfm_base, -+ const struct scaler_data *scl_data) -+{ -+ enum lb_memory_config lb_config; -+ struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base); -+ enum dscl_mode_sel dscl_mode = get_dscl_mode( -+ scl_data, xfm_base->ctx->dc->debug.always_scale); -+ bool ycbcr = scl_data->format >= PIXEL_FORMAT_VIDEO_BEGIN -+ && scl_data->format <= PIXEL_FORMAT_VIDEO_END; -+ -+ /* Recout */ -+ dpp_set_recout(xfm, &scl_data->recout); -+ -+ /* MPC Size */ -+ REG_SET_2(MPC_SIZE, 0, -+ /* Number of horizontal pixels of MPC */ -+ MPC_WIDTH, scl_data->h_active, -+ /* Number of vertical lines of MPC */ -+ MPC_HEIGHT, scl_data->v_active); -+ -+ /* SCL mode */ -+ REG_UPDATE(SCL_MODE, DSCL_MODE, dscl_mode); -+ -+ if (dscl_mode == DSCL_MODE_DSCL_BYPASS) -+ return; -+ /* LB */ -+ lb_config = find_lb_memory_config(scl_data); -+ dpp_set_lb(xfm, &scl_data->lb_params, lb_config); -+ -+ if (dscl_mode == DSCL_MODE_SCALING_444_BYPASS) -+ return; -+ -+ /* Autocal off */ -+ REG_SET_3(DSCL_AUTOCAL, 0, -+ AUTOCAL_MODE, AUTOCAL_MODE_OFF, -+ AUTOCAL_NUM_PIPE, 0, -+ AUTOCAL_PIPE_ID, 0); -+ -+ /* Black offsets */ -+ if (ycbcr) -+ REG_SET_2(SCL_BLACK_OFFSET, 0, -+ SCL_BLACK_OFFSET_RGB_Y, BLACK_OFFSET_RGB_Y, -+ SCL_BLACK_OFFSET_CBCR, BLACK_OFFSET_CBCR); -+ else -+ -+ REG_SET_2(SCL_BLACK_OFFSET, 0, -+ SCL_BLACK_OFFSET_RGB_Y, BLACK_OFFSET_RGB_Y, -+ SCL_BLACK_OFFSET_CBCR, BLACK_OFFSET_RGB_Y); -+ -+ /* Manually calculate scale ratio and init values */ -+ dpp_set_manual_ratio_init(xfm, scl_data); -+ -+ /* HTaps/VTaps */ -+ REG_SET_4(SCL_TAP_CONTROL, 0, -+ SCL_V_NUM_TAPS, scl_data->taps.v_taps - 1, -+ SCL_H_NUM_TAPS, scl_data->taps.h_taps - 1, -+ SCL_V_NUM_TAPS_C, scl_data->taps.v_taps_c - 1, -+ SCL_H_NUM_TAPS_C, scl_data->taps.h_taps_c - 1); -+ -+ dpp_set_scl_filter(xfm, scl_data, ycbcr); -+} -+ -+ -+#if 0 -+bool dpp_set_pixel_storage_depth( -+ struct dpp *xfm, -+ enum lb_pixel_depth depth, -+ const struct bit_depth_reduction_params *bit_depth_params) -+{ -+ struct dcn10_dpp *xfm110 = TO_DCN10_DPP(xfm); -+ bool ret = true; -+ uint32_t value; -+ enum dc_color_depth color_depth; -+ -+ value = dm_read_reg(xfm->ctx, LB_REG(mmLB_DATA_FORMAT)); -+ switch (depth) { -+ case LB_PIXEL_DEPTH_18BPP: -+ color_depth = COLOR_DEPTH_666; -+ set_reg_field_value(value, 2, LB_DATA_FORMAT, PIXEL_DEPTH); -+ set_reg_field_value(value, 1, LB_DATA_FORMAT, PIXEL_EXPAN_MODE); -+ break; -+ case LB_PIXEL_DEPTH_24BPP: -+ color_depth = COLOR_DEPTH_888; -+ set_reg_field_value(value, 1, LB_DATA_FORMAT, PIXEL_DEPTH); -+ set_reg_field_value(value, 1, LB_DATA_FORMAT, PIXEL_EXPAN_MODE); -+ break; -+ case LB_PIXEL_DEPTH_30BPP: -+ color_depth = COLOR_DEPTH_101010; -+ set_reg_field_value(value, 0, LB_DATA_FORMAT, PIXEL_DEPTH); -+ set_reg_field_value(value, 1, LB_DATA_FORMAT, PIXEL_EXPAN_MODE); -+ break; -+ case LB_PIXEL_DEPTH_36BPP: -+ color_depth = COLOR_DEPTH_121212; -+ set_reg_field_value(value, 3, LB_DATA_FORMAT, PIXEL_DEPTH); -+ set_reg_field_value(value, 0, LB_DATA_FORMAT, PIXEL_EXPAN_MODE); -+ break; -+ default: -+ ret = false; -+ break; -+ } -+ -+ if (ret == true) { -+ set_denormalization(xfm110, color_depth); -+ ret = program_bit_depth_reduction(xfm110, color_depth, -+ bit_depth_params); -+ -+ set_reg_field_value(value, 0, LB_DATA_FORMAT, ALPHA_EN); -+ dm_write_reg(xfm->ctx, LB_REG(mmLB_DATA_FORMAT), value); -+ if (!(xfm110->lb_pixel_depth_supported & depth)) { -+ /* We should use unsupported capabilities -+ * unless it is required by w/a -+ */ -+ dm_logger_write(xfm->ctx->logger, LOG_WARNING, -+ "%s: Capability not supported", -+ __func__); -+ } -+ } -+ -+ return ret; -+} -+#endif -+ -+ --- -2.7.4 - |