- Add YUV422/YUV444 pixel format definitions
- Handle YUV422 chroma scaling ratios
- Use separate horizontal and vertical viewport divisors
- Add UPSP upsampling register programming
- Refine tap selection for horizontally and vertically subsampled formats

Reviewed-by: Tom Chung <[email protected]>
Signed-off-by: Aurabindo Pillai <[email protected]>
Signed-off-by: Wayne Lin <[email protected]>
---
 drivers/gpu/drm/amd/display/dc/sspl/dc_spl.c  | 202 ++++++++++++++++--
 .../drm/amd/display/dc/sspl/dc_spl_types.h    |  58 ++++-
 2 files changed, 234 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl.c 
b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl.c
index d8aebaff7c3f..1f1318769d5b 100644
--- a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl.c
+++ b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl.c
@@ -9,7 +9,6 @@
 
 #define IDENTITY_RATIO(ratio) (SPL_NAMESPACE(spl_fixpt_u3d19(ratio)) == (1 << 
19))
 #define MIN_VIEWPORT_SIZE 12
-
 static bool spl_is_yuv420(enum spl_pixel_format format)
 {
        if ((format >= SPL_PIXEL_FORMAT_420BPP8) &&
@@ -19,6 +18,15 @@ static bool spl_is_yuv420(enum spl_pixel_format format)
        return false;
 }
 
+static bool spl_is_yuv422(enum spl_pixel_format format)
+{
+       if ((format >= SPL_PIXEL_FORMAT_422BPP8) &&
+               (format <= SPL_PIXEL_FORMAT_422BPP12))
+               return true;
+
+       return false;
+}
+
 static bool spl_is_rgb8(enum spl_pixel_format format)
 {
        if (format == SPL_PIXEL_FORMAT_ARGB8888)
@@ -468,6 +476,12 @@ static void spl_calculate_scaling_ratios(struct spl_in 
*spl_in,
        if (spl_is_yuv420(spl_in->basic_in.format)) {
                spl_scratch->scl_data.ratios.horz_c.value /= 2;
                spl_scratch->scl_data.ratios.vert_c.value /= 2;
+       } else if (spl_is_yuv422(spl_in->basic_in.format)) {
+               if (spl_in->basic_in.rotation == SPL_ROTATION_ANGLE_90 ||
+                       spl_in->basic_in.rotation == SPL_ROTATION_ANGLE_270)
+                       spl_scratch->scl_data.ratios.vert_c.value /= 2;
+               else
+                       spl_scratch->scl_data.ratios.horz_c.value /= 2;
        }
        spl_scratch->scl_data.ratios.horz = spl_fixpt_truncate(
                        spl_scratch->scl_data.ratios.horz, 19);
@@ -612,7 +626,8 @@ static void spl_calculate_inits_and_viewports(struct spl_in 
*spl_in,
        struct spl_rect recout_clip_in_recout_dst;
        struct spl_rect overlap_in_active_timing;
        struct spl_rect odm_slice = 
calculate_odm_slice_in_timing_active(spl_in);
-       int vpc_div = spl_is_subsampled_format(spl_in->basic_in.format) ? 2 : 1;
+       int vp_hc_div = spl_is_subsampled_format(spl_in->basic_in.format) ? 2 : 
1;
+       int vp_vc_div = spl_is_yuv420(spl_in->basic_in.format) ? 2 : 1;
        bool orthogonal_rotation, flip_vert_scan_dir, flip_horz_scan_dir;
        struct spl_fixed31_32 init_adj_h = spl_fixpt_zero;
        struct spl_fixed31_32 init_adj_v = spl_fixpt_zero;
@@ -667,6 +682,7 @@ static void spl_calculate_inits_and_viewports(struct spl_in 
*spl_in,
        if (orthogonal_rotation) {
                spl_swap(src.width, src.height);
                spl_swap(flip_vert_scan_dir, flip_horz_scan_dir);
+               spl_swap(vp_hc_div, vp_vc_div);
                spl_swap(init_adj_h, init_adj_v);
        }
 
@@ -685,7 +701,7 @@ static void spl_calculate_inits_and_viewports(struct spl_in 
*spl_in,
                        flip_horz_scan_dir,
                        recout_clip_in_recout_dst.x,
                        spl_scratch->scl_data.recout.width,
-                       src.width / vpc_div,
+                       src.width / vp_hc_div,
                        spl_scratch->scl_data.taps.h_taps_c,
                        spl_scratch->scl_data.ratios.horz_c,
                        init_adj_h,
@@ -707,7 +723,7 @@ static void spl_calculate_inits_and_viewports(struct spl_in 
*spl_in,
                        flip_vert_scan_dir,
                        recout_clip_in_recout_dst.y,
                        spl_scratch->scl_data.recout.height,
-                       src.height / vpc_div,
+                       src.height / vp_vc_div,
                        spl_scratch->scl_data.taps.v_taps_c,
                        spl_scratch->scl_data.ratios.vert_c,
                        init_adj_v,
@@ -719,12 +735,13 @@ static void spl_calculate_inits_and_viewports(struct 
spl_in *spl_in,
                spl_swap(spl_scratch->scl_data.viewport.width, 
spl_scratch->scl_data.viewport.height);
                spl_swap(spl_scratch->scl_data.viewport_c.x, 
spl_scratch->scl_data.viewport_c.y);
                spl_swap(spl_scratch->scl_data.viewport_c.width, 
spl_scratch->scl_data.viewport_c.height);
+               spl_swap(vp_hc_div, vp_vc_div);
        }
        spl_scratch->scl_data.viewport.x += src.x;
        spl_scratch->scl_data.viewport.y += src.y;
-       SPL_ASSERT(src.x % vpc_div == 0 && src.y % vpc_div == 0);
-       spl_scratch->scl_data.viewport_c.x += src.x / vpc_div;
-       spl_scratch->scl_data.viewport_c.y += src.y / vpc_div;
+       SPL_ASSERT(src.x % vp_hc_div == 0 && src.y % vp_vc_div == 0);
+       spl_scratch->scl_data.viewport_c.x += src.x / vp_hc_div;
+       spl_scratch->scl_data.viewport_c.y += src.y / vp_vc_div;
 }
 
 static void spl_handle_3d_recout(struct spl_in *spl_in, struct spl_rect 
*recout)
@@ -760,6 +777,7 @@ static enum scl_mode spl_get_dscl_mode(const struct spl_in 
*spl_in,
                                const struct spl_scaler_data *data,
                                bool enable_isharp, bool enable_easf)
 {
+       (void)enable_easf;
        const long long one = spl_fixpt_one.value;
        enum spl_pixel_format pixel_format = spl_in->basic_in.format;
 
@@ -894,7 +912,8 @@ static bool spl_get_isharp_en(struct spl_in *spl_in,
 static void spl_get_taps_non_adaptive_scaler(
                struct spl_scratch *spl_scratch,
                const struct spl_taps *in_taps,
-               bool is_subsampled)
+               bool is_horz_subsampled,
+               bool is_vert_subsampled)
 {
        bool check_max_downscale = false;
 
@@ -959,11 +978,10 @@ static void spl_get_taps_non_adaptive_scaler(
                spl_scratch->scl_data.taps.h_taps = 1;
        if (IDENTITY_RATIO(spl_scratch->scl_data.ratios.vert))
                spl_scratch->scl_data.taps.v_taps = 1;
-       if (IDENTITY_RATIO(spl_scratch->scl_data.ratios.horz_c) && 
!is_subsampled)
+       if (IDENTITY_RATIO(spl_scratch->scl_data.ratios.horz_c) && 
!is_horz_subsampled)
                spl_scratch->scl_data.taps.h_taps_c = 1;
-       if (IDENTITY_RATIO(spl_scratch->scl_data.ratios.vert_c) && 
!is_subsampled)
+       if (IDENTITY_RATIO(spl_scratch->scl_data.ratios.vert_c) && 
!is_vert_subsampled)
                spl_scratch->scl_data.taps.v_taps_c = 1;
-
 }
 
 /* Calculate optimal number of taps */
@@ -977,12 +995,13 @@ static bool spl_get_optimal_number_of_taps(
        unsigned int min_taps_y, min_taps_c;
        enum lb_memory_config lb_config;
        bool skip_easf          = false;
-       bool is_subsampled = spl_is_subsampled_format(spl_in->basic_in.format);
+       bool is_horz_subsampled = 
spl_is_subsampled_format(spl_in->basic_in.format);
+       bool is_vert_subsampled = spl_is_yuv420(spl_in->basic_in.format);
 
        if (spl_scratch->scl_data.viewport.width > 
spl_scratch->scl_data.h_active &&
                max_downscale_src_width != 0 &&
                spl_scratch->scl_data.viewport.width > max_downscale_src_width) 
{
-               spl_get_taps_non_adaptive_scaler(spl_scratch, in_taps, 
is_subsampled);
+               spl_get_taps_non_adaptive_scaler(spl_scratch, in_taps, 
is_horz_subsampled, is_vert_subsampled);
                *enable_easf_v = false;
                *enable_easf_h = false;
                *enable_isharp = false;
@@ -991,7 +1010,7 @@ static bool spl_get_optimal_number_of_taps(
 
        /* Disable adaptive scaler and sharpener when integer scaling is 
enabled */
        if (spl_in->scaling_quality.integer_scaling) {
-               spl_get_taps_non_adaptive_scaler(spl_scratch, in_taps, 
is_subsampled);
+               spl_get_taps_non_adaptive_scaler(spl_scratch, in_taps, 
is_horz_subsampled, is_vert_subsampled);
                *enable_easf_v = false;
                *enable_easf_h = false;
                *enable_isharp = false;
@@ -1007,15 +1026,15 @@ static bool spl_get_optimal_number_of_taps(
         * taps = 4 for upscaling
         */
        if (skip_easf) {
-               spl_get_taps_non_adaptive_scaler(spl_scratch, in_taps, 
is_subsampled);
+               spl_get_taps_non_adaptive_scaler(spl_scratch, in_taps, 
is_horz_subsampled, is_vert_subsampled);
        }
        else {
-               if (spl_is_video_format(spl_in->basic_in.format)) {
+               if (spl_is_subsampled_format(spl_in->basic_in.format)) {
                        spl_scratch->scl_data.taps.h_taps = 6;
                        spl_scratch->scl_data.taps.v_taps = 6;
                        spl_scratch->scl_data.taps.h_taps_c = 4;
                        spl_scratch->scl_data.taps.v_taps_c = 4;
-               } else { /* RGB */
+               } else { /* RGB / YUV444 */
                        spl_scratch->scl_data.taps.h_taps = 6;
                        spl_scratch->scl_data.taps.v_taps = 6;
                        spl_scratch->scl_data.taps.h_taps_c = 6;
@@ -1149,10 +1168,10 @@ static bool spl_get_optimal_number_of_taps(
                        (IDENTITY_RATIO(spl_scratch->scl_data.ratios.vert))) {
                        spl_scratch->scl_data.taps.h_taps = 1;
                        spl_scratch->scl_data.taps.v_taps = 1;
-                       if (IDENTITY_RATIO(spl_scratch->scl_data.ratios.horz_c) 
&& !is_subsampled)
+                       if (IDENTITY_RATIO(spl_scratch->scl_data.ratios.horz_c) 
&& !is_horz_subsampled)
                                spl_scratch->scl_data.taps.h_taps_c = 1;
 
-                       if (IDENTITY_RATIO(spl_scratch->scl_data.ratios.vert_c) 
&& !is_subsampled)
+                       if (IDENTITY_RATIO(spl_scratch->scl_data.ratios.vert_c) 
&& !is_vert_subsampled)
                                spl_scratch->scl_data.taps.v_taps_c = 1;
 
                        *enable_easf_v = false;
@@ -1166,11 +1185,11 @@ static bool spl_get_optimal_number_of_taps(
                                
(IDENTITY_RATIO(spl_scratch->scl_data.ratios.vert)))
                                spl_scratch->scl_data.taps.v_taps = 1;
 
-                       if ((!*enable_easf_h) && !is_subsampled &&
+                       if ((!*enable_easf_h) && !is_horz_subsampled &&
                                
(IDENTITY_RATIO(spl_scratch->scl_data.ratios.horz_c)))
                                spl_scratch->scl_data.taps.h_taps_c = 1;
 
-                       if ((!*enable_easf_v) && !is_subsampled &&
+                       if ((!*enable_easf_v) && !is_vert_subsampled &&
                                
(IDENTITY_RATIO(spl_scratch->scl_data.ratios.vert_c)))
                                spl_scratch->scl_data.taps.v_taps_c = 1;
 
@@ -1693,6 +1712,7 @@ static void spl_set_isharp_data(struct dscl_prog_data 
*dscl_prog_data,
                const struct spl_scaler_data *data, struct spl_fixed31_32 ratio,
                enum system_setup setup, enum scale_to_sharpness_policy 
scale_to_sharpness_policy)
 {
+       (void)format;
        /* Turn off sharpener if not required */
        if (!enable_isharp) {
                dscl_prog_data->isharp_en = 0;
@@ -1823,6 +1843,144 @@ static void spl_set_isharp_data(struct dscl_prog_data 
*dscl_prog_data,
        SPL_NAMESPACE(spl_set_blur_scale_data(dscl_prog_data, data));
 }
 
+static void determine_upsp_values(struct spl_in *spl_in, struct dscl_prog_data 
*dscl_prog_data)
+{
+       dscl_prog_data->upsp_mode = spl_in->upsp_mode;
+
+       if (dscl_prog_data->upsp_mode == UPSP_BYPASS) { //Set all UPSP register 
fields to 0 if bypass
+               dscl_prog_data->upsp_v_num_taps = UPSP_2_TAPS;
+               dscl_prog_data->upsp_h_num_taps = UPSP_2_TAPS;
+               dscl_prog_data->upsp_boundary_mode = UPSP_BOUNDARY_EDGE;
+               dscl_prog_data->upsp_v_init_int = 0x0;
+               dscl_prog_data->upsp_v_init_frac = 0x0;
+               dscl_prog_data->upsp_v_coef_tap0_p0 = 0x0;
+               dscl_prog_data->upsp_v_coef_tap1_p0 = 0x0;
+               dscl_prog_data->upsp_v_coef_tap2_p0 = 0x0;
+               dscl_prog_data->upsp_v_coef_tap3_p0 = 0x0;
+               dscl_prog_data->upsp_v_coef_tap0_p1 = 0x0;
+               dscl_prog_data->upsp_v_coef_tap1_p1 = 0x0;
+               dscl_prog_data->upsp_v_coef_tap2_p1 = 0x0;
+               dscl_prog_data->upsp_v_coef_tap3_p1 = 0x0;
+               dscl_prog_data->upsp_h_init_int = 0x0;
+               dscl_prog_data->upsp_h_init_frac = 0x0;
+               dscl_prog_data->upsp_h_coef_tap0_p0 = 0x0;
+               dscl_prog_data->upsp_h_coef_tap1_p0 = 0x0;
+               dscl_prog_data->upsp_h_coef_tap2_p0 = 0x0;
+               dscl_prog_data->upsp_h_coef_tap3_p0 = 0x0;
+               dscl_prog_data->upsp_h_coef_tap0_p1 = 0x0;
+               dscl_prog_data->upsp_h_coef_tap1_p1 = 0x0;
+               dscl_prog_data->upsp_h_coef_tap2_p1 = 0x0;
+               dscl_prog_data->upsp_h_coef_tap3_p1 = 0x0;
+               dscl_prog_data->upsp_clamp_max = 0x0;
+               dscl_prog_data->upsp_clamp_min = 0x0;
+       } else {
+               dscl_prog_data->upsp_v_num_taps = UPSP_4_TAPS;
+               dscl_prog_data->upsp_h_num_taps = UPSP_4_TAPS;
+               dscl_prog_data->upsp_boundary_mode = UPSP_BOUNDARY_EDGE;
+               dscl_prog_data->upsp_clamp_max = 0xFFF;//4095
+               dscl_prog_data->upsp_clamp_min = 0x0;
+
+               if (spl_in->basic_in.cositing == CHROMA_COSITING_TOPLEFT) { 
//Vertical Subsampling: Co-sited
+                       if (dscl_prog_data->upsp_v_num_taps == UPSP_4_TAPS) {
+                               dscl_prog_data->upsp_v_init_int = 0x3;
+                               dscl_prog_data->upsp_v_init_frac = 0x0;
+                               dscl_prog_data->upsp_v_coef_tap0_p0 = 0x00;
+                               dscl_prog_data->upsp_v_coef_tap1_p0 = 0x40;
+                               dscl_prog_data->upsp_v_coef_tap2_p0 = 0x00;
+                               dscl_prog_data->upsp_v_coef_tap3_p0 = 0x00;
+                               dscl_prog_data->upsp_v_coef_tap0_p1 = 0xFC;
+                               dscl_prog_data->upsp_v_coef_tap1_p1 = 0x24;
+                               dscl_prog_data->upsp_v_coef_tap2_p1 = 0x24;
+                               dscl_prog_data->upsp_v_coef_tap3_p1 = 0xFC;
+                       } else { //2 taps
+                               dscl_prog_data->upsp_v_init_int = 0x2;
+                               dscl_prog_data->upsp_v_init_frac = 0x0;
+                               dscl_prog_data->upsp_v_coef_tap0_p0 = 0x40;
+                               dscl_prog_data->upsp_v_coef_tap1_p0 = 0x00;
+                               dscl_prog_data->upsp_v_coef_tap2_p0 = 0x00;
+                               dscl_prog_data->upsp_v_coef_tap3_p0 = 0x00;
+                               dscl_prog_data->upsp_v_coef_tap0_p1 = 0x20;
+                               dscl_prog_data->upsp_v_coef_tap1_p1 = 0x20;
+                               dscl_prog_data->upsp_v_coef_tap2_p1 = 0x00;
+                               dscl_prog_data->upsp_v_coef_tap3_p1 = 0x00;
+                       }
+               } else { //Vertical Subsampling: Interstitial
+                       if (dscl_prog_data->upsp_v_num_taps == UPSP_4_TAPS) {
+                               dscl_prog_data->upsp_v_init_int = 0x2;
+                               dscl_prog_data->upsp_v_init_frac = 0x1;
+                               dscl_prog_data->upsp_v_coef_tap0_p0 = 0xFB;
+                               dscl_prog_data->upsp_v_coef_tap1_p0 = 0x2F;
+                               dscl_prog_data->upsp_v_coef_tap2_p0 = 0x19;
+                               dscl_prog_data->upsp_v_coef_tap3_p0 = 0xFD;
+                               dscl_prog_data->upsp_v_coef_tap0_p1 = 0xFD;
+                               dscl_prog_data->upsp_v_coef_tap1_p1 = 0x19;
+                               dscl_prog_data->upsp_v_coef_tap2_p1 = 0x2F;
+                               dscl_prog_data->upsp_v_coef_tap3_p1 = 0xFB;
+                       } else { //2 taps
+                               dscl_prog_data->upsp_v_init_int = 0x1;
+                               dscl_prog_data->upsp_v_init_frac = 0x1;
+                               dscl_prog_data->upsp_v_coef_tap0_p0 = 0x28;
+                               dscl_prog_data->upsp_v_coef_tap1_p0 = 0x18;
+                               dscl_prog_data->upsp_v_coef_tap2_p0 = 0x00;
+                               dscl_prog_data->upsp_v_coef_tap3_p0 = 0x00;
+                               dscl_prog_data->upsp_v_coef_tap0_p1 = 0x18;
+                               dscl_prog_data->upsp_v_coef_tap1_p1 = 0x28;
+                               dscl_prog_data->upsp_v_coef_tap2_p1 = 0x00;
+                               dscl_prog_data->upsp_v_coef_tap3_p1 = 0x00;
+                       }
+               }
+               if (spl_in->basic_in.cositing == CHROMA_COSITING_LEFT || 
spl_in->basic_in.cositing == CHROMA_COSITING_TOPLEFT) { //Horizontal 
Subsampling: Co-sited
+                       if (dscl_prog_data->upsp_h_num_taps == UPSP_4_TAPS) {
+                               dscl_prog_data->upsp_h_init_int = 0x3;
+                               dscl_prog_data->upsp_h_init_frac = 0x0;
+                               dscl_prog_data->upsp_h_coef_tap0_p0 = 0x00;
+                               dscl_prog_data->upsp_h_coef_tap1_p0 = 0x40;
+                               dscl_prog_data->upsp_h_coef_tap2_p0 = 0x00;
+                               dscl_prog_data->upsp_h_coef_tap3_p0 = 0x00;
+                               dscl_prog_data->upsp_h_coef_tap0_p1 = 0xFC;
+                               dscl_prog_data->upsp_h_coef_tap1_p1 = 0x24;
+                               dscl_prog_data->upsp_h_coef_tap2_p1 = 0x24;
+                               dscl_prog_data->upsp_h_coef_tap3_p1 = 0xFC;
+                       } else { //2 taps
+                               dscl_prog_data->upsp_h_init_int = 0x2;
+                               dscl_prog_data->upsp_h_init_frac = 0x0;
+                               dscl_prog_data->upsp_h_coef_tap0_p0 = 0x40;
+                               dscl_prog_data->upsp_h_coef_tap1_p0 = 0x00;
+                               dscl_prog_data->upsp_h_coef_tap2_p0 = 0x00;
+                               dscl_prog_data->upsp_h_coef_tap3_p0 = 0x00;
+                               dscl_prog_data->upsp_h_coef_tap0_p1 = 0x20;
+                               dscl_prog_data->upsp_h_coef_tap1_p1 = 0x20;
+                               dscl_prog_data->upsp_h_coef_tap2_p1 = 0x00;
+                               dscl_prog_data->upsp_h_coef_tap3_p1 = 0x00;
+                       }
+               } else { //Horizontal Subsampling: Interstitial
+                       if (dscl_prog_data->upsp_h_num_taps == UPSP_4_TAPS) {
+                               dscl_prog_data->upsp_h_init_int = 0x2;
+                               dscl_prog_data->upsp_h_init_frac = 0x1;
+                               dscl_prog_data->upsp_h_coef_tap0_p0 = 0xFB;
+                               dscl_prog_data->upsp_h_coef_tap1_p0 = 0x2F;
+                               dscl_prog_data->upsp_h_coef_tap2_p0 = 0x19;
+                               dscl_prog_data->upsp_h_coef_tap3_p0 = 0xFD;
+                               dscl_prog_data->upsp_h_coef_tap0_p1 = 0xFD;
+                               dscl_prog_data->upsp_h_coef_tap1_p1 = 0x19;
+                               dscl_prog_data->upsp_h_coef_tap2_p1 = 0x2F;
+                               dscl_prog_data->upsp_h_coef_tap3_p1 = 0xFB;
+                       } else { //2 taps
+                               dscl_prog_data->upsp_h_init_int = 0x1;
+                               dscl_prog_data->upsp_h_init_frac = 0x1;
+                               dscl_prog_data->upsp_h_coef_tap0_p0 = 0x28;
+                               dscl_prog_data->upsp_h_coef_tap1_p0 = 0x18;
+                               dscl_prog_data->upsp_h_coef_tap2_p0 = 0x00;
+                               dscl_prog_data->upsp_h_coef_tap3_p0 = 0x00;
+                               dscl_prog_data->upsp_h_coef_tap0_p1 = 0x18;
+                               dscl_prog_data->upsp_h_coef_tap1_p1 = 0x28;
+                               dscl_prog_data->upsp_h_coef_tap2_p1 = 0x00;
+                               dscl_prog_data->upsp_h_coef_tap3_p1 = 0x00;
+                       }
+               }
+       }
+}
+
 /* Calculate recout, scaling ratio, and viewport, then get optimal number of 
taps */
 static bool spl_calculate_number_of_taps(struct spl_in *spl_in, struct 
spl_scratch *spl_scratch, struct spl_out *spl_out,
        bool *enable_easf_v, bool *enable_easf_h, bool *enable_isharp)
@@ -1865,6 +2023,8 @@ bool SPL_NAMESPACE(spl_calculate_scaler_params(struct 
spl_in *spl_in, struct spl
        bool enable_isharp = false;
        const struct spl_scaler_data *data = &spl_scratch.scl_data;
 
+       determine_upsp_values(spl_in, spl_out->dscl_prog_data);
+
        res = spl_calculate_number_of_taps(spl_in, &spl_scratch, spl_out,
                &enable_easf_v, &enable_easf_h, &enable_isharp);
 
diff --git a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_types.h 
b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_types.h
index 20e4e52a77ac..b24f1ef3fe17 100644
--- a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_types.h
+++ b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_types.h
@@ -62,17 +62,21 @@ enum spl_pixel_format {
        /*video*/
        SPL_PIXEL_FORMAT_420BPP8,
        SPL_PIXEL_FORMAT_420BPP10,
+       SPL_PIXEL_FORMAT_422BPP8,
+       SPL_PIXEL_FORMAT_422BPP10,
+       SPL_PIXEL_FORMAT_422BPP12,
+       SPL_PIXEL_FORMAT_444BPP8,
+       SPL_PIXEL_FORMAT_444BPP10,
        /*end of pixel format definition*/
        SPL_PIXEL_FORMAT_GRPH_BEGIN = SPL_PIXEL_FORMAT_INDEX8,
        SPL_PIXEL_FORMAT_GRPH_END = SPL_PIXEL_FORMAT_FP16,
        SPL_PIXEL_FORMAT_SUBSAMPLED_BEGIN = SPL_PIXEL_FORMAT_420BPP8,
-       SPL_PIXEL_FORMAT_SUBSAMPLED_END = SPL_PIXEL_FORMAT_420BPP10,
+       SPL_PIXEL_FORMAT_SUBSAMPLED_END = SPL_PIXEL_FORMAT_422BPP12,
        SPL_PIXEL_FORMAT_VIDEO_BEGIN = SPL_PIXEL_FORMAT_420BPP8,
-       SPL_PIXEL_FORMAT_VIDEO_END = SPL_PIXEL_FORMAT_420BPP10,
+       SPL_PIXEL_FORMAT_VIDEO_END = SPL_PIXEL_FORMAT_444BPP10,
        SPL_PIXEL_FORMAT_INVALID,
        SPL_PIXEL_FORMAT_UNKNOWN
 };
-
 enum lb_memory_config {
        /* Enable all 3 pieces of memory */
        LB_MEMORY_CONFIG_0 = 0,
@@ -88,7 +92,6 @@ enum lb_memory_config {
         */
        LB_MEMORY_CONFIG_3 = 3
 };
-
 /* Rotation angle */
 enum spl_rotation_angle {
        SPL_ROTATION_ANGLE_0 = 0,
@@ -128,6 +131,23 @@ enum chroma_cositing {
        CHROMA_COSITING_COUNT
 };
 
+enum upsp_mode {
+       UPSP_BYPASS = 0,
+       UPSP_HORIZONTAL_UPSAMPLING_ONLY,
+       UPSP_VERTICAL_UPSAMPLING_ONLY,
+       UPSP_HORIZONTAL_VERTICAL_UPSAMPLING
+};
+
+enum upsp_num_taps {
+       UPSP_2_TAPS,
+       UPSP_4_TAPS
+};
+
+enum upsp_boundary_mode {
+       UPSP_BOUNDARY_EDGE, //Replace out of bound samples with the edge samples
+       UPSP_BOUNDARY_BLACK //Replace out of bound samples with black as 
12bpc(0x800)
+};
+
 // Scratch space for calculating scaler params
 struct spl_scaler_data {
        int h_active;
@@ -253,7 +273,7 @@ enum isharp_en      {
 #define ISHARP_LUT_TABLE_SIZE 32
 // Below struct holds values that can be directly used to program
 // hardware registers. No conversion/clamping is required
-struct dscl_prog_data {
+struct dscl_prog_data  {
        struct spl_rect recout; // RECOUT - set based on scl_data.recout
        struct mpc_size mpc_size;
        uint32_t dscl_mode;
@@ -395,6 +415,33 @@ struct dscl_prog_data {
        uint32_t easf_matrix_c1;
        uint32_t easf_matrix_c2;
        uint32_t easf_matrix_c3;
+       // UPSP registers
+       uint32_t upsp_mode;//UPSP_MODE
+       uint32_t upsp_v_num_taps;
+       uint32_t upsp_v_init_int;
+       uint32_t upsp_v_init_frac;
+       uint32_t upsp_h_num_taps;
+       uint32_t upsp_h_init_int;
+       uint32_t upsp_h_init_frac;
+       uint32_t upsp_boundary_mode;
+       uint32_t upsp_v_coef_tap0_p0;//UPSP_V_COEF_P0
+       uint32_t upsp_v_coef_tap1_p0;
+       uint32_t upsp_v_coef_tap2_p0;
+       uint32_t upsp_v_coef_tap3_p0;
+       uint32_t upsp_v_coef_tap0_p1;//UPSP_V_COEF_P1
+       uint32_t upsp_v_coef_tap1_p1;
+       uint32_t upsp_v_coef_tap2_p1;
+       uint32_t upsp_v_coef_tap3_p1;
+       uint32_t upsp_h_coef_tap0_p0;//UPSP_H_COEF_P0
+       uint32_t upsp_h_coef_tap1_p0;
+       uint32_t upsp_h_coef_tap2_p0;
+       uint32_t upsp_h_coef_tap3_p0;
+       uint32_t upsp_h_coef_tap0_p1;//UPSP_H_COEF_P1
+       uint32_t upsp_h_coef_tap1_p1;
+       uint32_t upsp_h_coef_tap2_p1;
+       uint32_t upsp_h_coef_tap3_p1;
+       uint32_t upsp_clamp_max;//UPSP_CLAMP
+       uint32_t upsp_clamp_min;
        // iSharp
        uint32_t isharp_en;     //      ISHARP_EN
        struct isharp_noise_det isharp_noise_det;       //      ISHARP_NOISEDET
@@ -554,6 +601,7 @@ struct spl_in       {
        int min_viewport_size;
        int sdr_white_level_nits;
        enum sharpen_policy sharpen_policy;
+       enum upsp_mode upsp_mode;
 };
 // end of SPL inputs
 
-- 
2.43.0

Reply via email to