Skip to content

Commit b70aaf5

Browse files
maurossialexdeucher
authored andcommitted
drm/amd/display: dce_transform: add DCE6 specific macros,functions
[Why] DCE6 has no SCL_MODE and no SCL_{HORZ,VERT}_FILTER_INIT registers DCE6 has no SCL_BOUNDARY_MODE bit in SCL_CONTROL register DCE6 has Line Buffer programming registers (DC_LB_MEMORY_SPLIT,DC_LB_MEM_SIZE) DCE6 DATA_FORMAT register has only INTERLEAVE_EN bit DCE6 has no Out Clamp Control programming registers (OUT_CLAMP_CONTROL_*) [How] Add DCE6 specific macros definitions for XFM registers and masks Add DCE6 specific registers to dce_transform_registers struct Add DCE6 specific masks to dce_transform_mask struct DCE6 XFM macros/structs changes will avoid buiding errors when using DCE6 headers Add dce60_setup_scaling_configuration() w/o missing Scaling registers/bit programming Add dce60_transform_set_scaler() using DCE6 Line Buffer programming registers Add dce60_program_bit_depth_reduction() w/o Out Clamp Control programming Add dce60_transform_set_pixel_storage_depth() use dce60_program_bit_depth_reduction() Use dce60_transform_set_scaler() in dce60_transform_funcs Use dce60_transform_set_pixel_storage_depth() in dce60_transform_funcs Add DCE6 specific dce60_transform_construct Reviewed-by: Alex Deucher <[email protected]> Signed-off-by: Mauro Rossi <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent d85a1e5 commit b70aaf5

File tree

2 files changed

+418
-0
lines changed

2 files changed

+418
-0
lines changed

drivers/gpu/drm/amd/display/dc/dce/dce_transform.c

Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,33 @@ static bool setup_scaling_configuration(
146146
return true;
147147
}
148148

149+
#if defined(CONFIG_DRM_AMD_DC_SI)
150+
static bool dce60_setup_scaling_configuration(
151+
struct dce_transform *xfm_dce,
152+
const struct scaler_data *data)
153+
{
154+
REG_SET(SCL_BYPASS_CONTROL, 0, SCL_BYPASS_MODE, 0);
155+
156+
if (data->taps.h_taps + data->taps.v_taps <= 2) {
157+
/* Set bypass */
158+
159+
/* DCE6 has no SCL_MODE register, skip scale mode programming */
160+
161+
return false;
162+
}
163+
164+
REG_SET_2(SCL_TAP_CONTROL, 0,
165+
SCL_H_NUM_OF_TAPS, data->taps.h_taps - 1,
166+
SCL_V_NUM_OF_TAPS, data->taps.v_taps - 1);
167+
168+
/* DCE6 has no SCL_MODE register, skip scale mode programming */
169+
170+
/* DCE6 has no SCL_BOUNDARY_MODE bit, skip replace out of bound pixels */
171+
172+
return true;
173+
}
174+
#endif
175+
149176
static void program_overscan(
150177
struct dce_transform *xfm_dce,
151178
const struct scaler_data *data)
@@ -399,6 +426,89 @@ static void dce_transform_set_scaler(
399426
REG_UPDATE(LB_DATA_FORMAT, ALPHA_EN, data->lb_params.alpha_en);
400427
}
401428

429+
#if defined(CONFIG_DRM_AMD_DC_SI)
430+
static void dce60_transform_set_scaler(
431+
struct transform *xfm,
432+
const struct scaler_data *data)
433+
{
434+
struct dce_transform *xfm_dce = TO_DCE_TRANSFORM(xfm);
435+
bool is_scaling_required;
436+
bool filter_updated = false;
437+
const uint16_t *coeffs_v, *coeffs_h;
438+
439+
/*Use whole line buffer memory always*/
440+
REG_SET(DC_LB_MEMORY_SPLIT, 0,
441+
DC_LB_MEMORY_CONFIG, 0);
442+
443+
REG_SET(DC_LB_MEM_SIZE, 0,
444+
DC_LB_MEM_SIZE, xfm_dce->lb_memory_size);
445+
446+
/* Clear SCL_F_SHARP_CONTROL value to 0 */
447+
REG_WRITE(SCL_F_SHARP_CONTROL, 0);
448+
449+
/* 1. Program overscan */
450+
program_overscan(xfm_dce, data);
451+
452+
/* 2. Program taps and configuration */
453+
is_scaling_required = dce60_setup_scaling_configuration(xfm_dce, data);
454+
455+
if (is_scaling_required) {
456+
/* 3. Calculate and program ratio, filter initialization */
457+
struct scl_ratios_inits inits = { 0 };
458+
459+
calculate_inits(xfm_dce, data, &inits);
460+
461+
program_scl_ratios_inits(xfm_dce, &inits);
462+
463+
coeffs_v = get_filter_coeffs_16p(data->taps.v_taps, data->ratios.vert);
464+
coeffs_h = get_filter_coeffs_16p(data->taps.h_taps, data->ratios.horz);
465+
466+
if (coeffs_v != xfm_dce->filter_v || coeffs_h != xfm_dce->filter_h) {
467+
/* 4. Program vertical filters */
468+
if (xfm_dce->filter_v == NULL)
469+
REG_SET(SCL_VERT_FILTER_CONTROL, 0,
470+
SCL_V_2TAP_HARDCODE_COEF_EN, 0);
471+
program_multi_taps_filter(
472+
xfm_dce,
473+
data->taps.v_taps,
474+
coeffs_v,
475+
FILTER_TYPE_RGB_Y_VERTICAL);
476+
program_multi_taps_filter(
477+
xfm_dce,
478+
data->taps.v_taps,
479+
coeffs_v,
480+
FILTER_TYPE_ALPHA_VERTICAL);
481+
482+
/* 5. Program horizontal filters */
483+
if (xfm_dce->filter_h == NULL)
484+
REG_SET(SCL_HORZ_FILTER_CONTROL, 0,
485+
SCL_H_2TAP_HARDCODE_COEF_EN, 0);
486+
program_multi_taps_filter(
487+
xfm_dce,
488+
data->taps.h_taps,
489+
coeffs_h,
490+
FILTER_TYPE_RGB_Y_HORIZONTAL);
491+
program_multi_taps_filter(
492+
xfm_dce,
493+
data->taps.h_taps,
494+
coeffs_h,
495+
FILTER_TYPE_ALPHA_HORIZONTAL);
496+
497+
xfm_dce->filter_v = coeffs_v;
498+
xfm_dce->filter_h = coeffs_h;
499+
filter_updated = true;
500+
}
501+
}
502+
503+
/* 6. Program the viewport */
504+
program_viewport(xfm_dce, &data->viewport);
505+
506+
/* DCE6 does not have bit to flip to new coefficient memory */
507+
508+
/* DCE6 DATA_FORMAT register does not support ALPHA_EN */
509+
}
510+
#endif
511+
402512
/*****************************************************************************
403513
* set_clamp
404514
*
@@ -664,6 +774,67 @@ static void program_bit_depth_reduction(
664774
bit_depth_params->flags.HIGHPASS_RANDOM);
665775
}
666776

777+
#if defined(CONFIG_DRM_AMD_DC_SI)
778+
/*****************************************************************************
779+
* dce60_transform_bit_depth_reduction program
780+
*
781+
* @brief
782+
* Programs the DCP bit depth reduction registers (Clamp, Round/Truncate,
783+
* Dither) for dce
784+
*
785+
* @param depth : bit depth to set the clamp to (should match denorm)
786+
*
787+
******************************************************************************/
788+
static void dce60_program_bit_depth_reduction(
789+
struct dce_transform *xfm_dce,
790+
enum dc_color_depth depth,
791+
const struct bit_depth_reduction_params *bit_depth_params)
792+
{
793+
enum dcp_out_trunc_round_depth trunc_round_depth;
794+
enum dcp_out_trunc_round_mode trunc_mode;
795+
bool spatial_dither_enable;
796+
797+
ASSERT(depth < COLOR_DEPTH_121212); /* Invalid clamp bit depth */
798+
799+
spatial_dither_enable = bit_depth_params->flags.SPATIAL_DITHER_ENABLED;
800+
/* Default to 12 bit truncation without rounding */
801+
trunc_round_depth = DCP_OUT_TRUNC_ROUND_DEPTH_12BIT;
802+
trunc_mode = DCP_OUT_TRUNC_ROUND_MODE_TRUNCATE;
803+
804+
if (bit_depth_params->flags.TRUNCATE_ENABLED) {
805+
/* Don't enable dithering if truncation is enabled */
806+
spatial_dither_enable = false;
807+
trunc_mode = bit_depth_params->flags.TRUNCATE_MODE ?
808+
DCP_OUT_TRUNC_ROUND_MODE_ROUND :
809+
DCP_OUT_TRUNC_ROUND_MODE_TRUNCATE;
810+
811+
if (bit_depth_params->flags.TRUNCATE_DEPTH == 0 ||
812+
bit_depth_params->flags.TRUNCATE_DEPTH == 1)
813+
trunc_round_depth = DCP_OUT_TRUNC_ROUND_DEPTH_8BIT;
814+
else if (bit_depth_params->flags.TRUNCATE_DEPTH == 2)
815+
trunc_round_depth = DCP_OUT_TRUNC_ROUND_DEPTH_10BIT;
816+
else {
817+
/*
818+
* Invalid truncate/round depth. Setting here to 12bit
819+
* to prevent use-before-initialize errors.
820+
*/
821+
trunc_round_depth = DCP_OUT_TRUNC_ROUND_DEPTH_12BIT;
822+
BREAK_TO_DEBUGGER();
823+
}
824+
}
825+
826+
/* DCE6 has no OUT_CLAMP_CONTROL_* registers - set_clamp() is skipped */
827+
set_round(xfm_dce, trunc_mode, trunc_round_depth);
828+
set_dither(xfm_dce,
829+
spatial_dither_enable,
830+
DCP_SPATIAL_DITHER_MODE_A_AA_A,
831+
DCP_SPATIAL_DITHER_DEPTH_30BPP,
832+
bit_depth_params->flags.FRAME_RANDOM,
833+
bit_depth_params->flags.RGB_RANDOM,
834+
bit_depth_params->flags.HIGHPASS_RANDOM);
835+
}
836+
#endif
837+
667838
static int dce_transform_get_max_num_of_supported_lines(
668839
struct dce_transform *xfm_dce,
669840
enum lb_pixel_depth depth,
@@ -797,6 +968,59 @@ static void dce_transform_set_pixel_storage_depth(
797968
}
798969
}
799970

971+
#if defined(CONFIG_DRM_AMD_DC_SI)
972+
static void dce60_transform_set_pixel_storage_depth(
973+
struct transform *xfm,
974+
enum lb_pixel_depth depth,
975+
const struct bit_depth_reduction_params *bit_depth_params)
976+
{
977+
struct dce_transform *xfm_dce = TO_DCE_TRANSFORM(xfm);
978+
int pixel_depth, expan_mode;
979+
enum dc_color_depth color_depth;
980+
981+
switch (depth) {
982+
case LB_PIXEL_DEPTH_18BPP:
983+
color_depth = COLOR_DEPTH_666;
984+
pixel_depth = 2;
985+
expan_mode = 1;
986+
break;
987+
case LB_PIXEL_DEPTH_24BPP:
988+
color_depth = COLOR_DEPTH_888;
989+
pixel_depth = 1;
990+
expan_mode = 1;
991+
break;
992+
case LB_PIXEL_DEPTH_30BPP:
993+
color_depth = COLOR_DEPTH_101010;
994+
pixel_depth = 0;
995+
expan_mode = 1;
996+
break;
997+
case LB_PIXEL_DEPTH_36BPP:
998+
color_depth = COLOR_DEPTH_121212;
999+
pixel_depth = 3;
1000+
expan_mode = 0;
1001+
break;
1002+
default:
1003+
color_depth = COLOR_DEPTH_101010;
1004+
pixel_depth = 0;
1005+
expan_mode = 1;
1006+
BREAK_TO_DEBUGGER();
1007+
break;
1008+
}
1009+
1010+
set_denormalization(xfm_dce, color_depth);
1011+
dce60_program_bit_depth_reduction(xfm_dce, color_depth, bit_depth_params);
1012+
1013+
/* DATA_FORMAT in DCE6 does not have PIXEL_DEPTH and PIXEL_EXPAN_MODE masks */
1014+
1015+
if (!(xfm_dce->lb_pixel_depth_supported & depth)) {
1016+
/*we should use unsupported capabilities
1017+
* unless it is required by w/a*/
1018+
DC_LOG_WARNING("%s: Capability not supported",
1019+
__func__);
1020+
}
1021+
}
1022+
#endif
1023+
8001024
static void program_gamut_remap(
8011025
struct dce_transform *xfm_dce,
8021026
const uint16_t *reg_val)
@@ -1335,6 +1559,21 @@ static const struct transform_funcs dce_transform_funcs = {
13351559
.transform_get_optimal_number_of_taps = dce_transform_get_optimal_number_of_taps
13361560
};
13371561

1562+
#if defined(CONFIG_DRM_AMD_DC_SI)
1563+
static const struct transform_funcs dce60_transform_funcs = {
1564+
.transform_reset = dce_transform_reset,
1565+
.transform_set_scaler = dce60_transform_set_scaler,
1566+
.transform_set_gamut_remap = dce_transform_set_gamut_remap,
1567+
.opp_set_csc_adjustment = dce110_opp_set_csc_adjustment,
1568+
.opp_set_csc_default = dce110_opp_set_csc_default,
1569+
.opp_power_on_regamma_lut = dce110_opp_power_on_regamma_lut,
1570+
.opp_program_regamma_pwl = dce110_opp_program_regamma_pwl,
1571+
.opp_set_regamma_mode = dce110_opp_set_regamma_mode,
1572+
.transform_set_pixel_storage_depth = dce60_transform_set_pixel_storage_depth,
1573+
.transform_get_optimal_number_of_taps = dce_transform_get_optimal_number_of_taps
1574+
};
1575+
#endif
1576+
13381577
/*****************************************/
13391578
/* Constructor, Destructor */
13401579
/*****************************************/
@@ -1365,3 +1604,32 @@ void dce_transform_construct(
13651604
xfm_dce->lb_bits_per_entry = LB_BITS_PER_ENTRY;
13661605
xfm_dce->lb_memory_size = LB_TOTAL_NUMBER_OF_ENTRIES; /*0x6B0*/
13671606
}
1607+
1608+
#if defined(CONFIG_DRM_AMD_DC_SI)
1609+
void dce60_transform_construct(
1610+
struct dce_transform *xfm_dce,
1611+
struct dc_context *ctx,
1612+
uint32_t inst,
1613+
const struct dce_transform_registers *regs,
1614+
const struct dce_transform_shift *xfm_shift,
1615+
const struct dce_transform_mask *xfm_mask)
1616+
{
1617+
xfm_dce->base.ctx = ctx;
1618+
1619+
xfm_dce->base.inst = inst;
1620+
xfm_dce->base.funcs = &dce60_transform_funcs;
1621+
1622+
xfm_dce->regs = regs;
1623+
xfm_dce->xfm_shift = xfm_shift;
1624+
xfm_dce->xfm_mask = xfm_mask;
1625+
1626+
xfm_dce->prescaler_on = true;
1627+
xfm_dce->lb_pixel_depth_supported =
1628+
LB_PIXEL_DEPTH_18BPP |
1629+
LB_PIXEL_DEPTH_24BPP |
1630+
LB_PIXEL_DEPTH_30BPP;
1631+
1632+
xfm_dce->lb_bits_per_entry = LB_BITS_PER_ENTRY;
1633+
xfm_dce->lb_memory_size = LB_TOTAL_NUMBER_OF_ENTRIES; /*0x6B0*/
1634+
}
1635+
#endif

0 commit comments

Comments
 (0)