@@ -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+
149176static 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+
667838static 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+
8001024static 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