xref: /aosp_15_r20/external/mesa3d/src/amd/vpelib/src/chip/vpe10/vpe10_opp.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /* Copyright 2022 Advanced Micro Devices, Inc.
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining a
4  * copy of this software and associated documentation files (the "Software"),
5  * to deal in the Software without restriction, including without limitation
6  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
7  * and/or sell copies of the Software, and to permit persons to whom the
8  * Software is furnished to do so, subject to the following conditions:
9  *
10  * The above copyright notice and this permission notice shall be included in
11  * all copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
16  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
17  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
18  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
19  * OTHER DEALINGS IN THE SOFTWARE.
20  *
21  * Authors: AMD
22  *
23  */
24 
25 #include <string.h>
26 #include "common.h"
27 #include "vpe_priv.h"
28 #include "vpe10_opp.h"
29 #include "vpe10_command.h"
30 #include "hw_shared.h"
31 #include "reg_helper.h"
32 
33 #define CTX_BASE opp
34 #define CTX      vpe10_opp
35 
36 static struct opp_funcs opp_funcs = {
37     .program_pipe_alpha          = vpe10_opp_program_pipe_alpha,
38     .program_pipe_bypass         = vpe10_opp_program_pipe_bypass,
39     .program_pipe_crc            = vpe10_opp_program_pipe_crc,
40     .set_clamping                = vpe10_opp_set_clamping,
41     .set_truncation              = vpe10_opp_set_truncation,
42     .set_spatial_dither          = vpe10_opp_set_spatial_dither,
43     .program_bit_depth_reduction = vpe10_opp_program_bit_depth_reduction,
44     .set_dyn_expansion           = vpe10_opp_set_dyn_expansion,
45     .program_fmt                 = vpe10_opp_program_fmt,
46 };
47 
vpe10_construct_opp(struct vpe_priv * vpe_priv,struct opp * opp)48 void vpe10_construct_opp(struct vpe_priv *vpe_priv, struct opp *opp)
49 {
50     opp->vpe_priv = vpe_priv;
51     opp->funcs    = &opp_funcs;
52 }
53 
vpe10_opp_set_clamping(struct opp * opp,const struct clamping_and_pixel_encoding_params * params)54 void vpe10_opp_set_clamping(
55     struct opp *opp, const struct clamping_and_pixel_encoding_params *params)
56 {
57     PROGRAM_ENTRY();
58 
59     //OCSC operations are handled in output gamma sequence to allow
60     // full range bg color fill. Hence, no clamping should be done on the output.
61     switch (params->clamping_level) {
62     case CLAMPING_LIMITED_RANGE_8BPC:
63     case CLAMPING_LIMITED_RANGE_10BPC:
64     case CLAMPING_LIMITED_RANGE_12BPC:
65     case CLAMPING_LIMITED_RANGE_PROGRAMMABLE:
66     case CLAMPING_FULL_RANGE:
67     default:
68         REG_SET_2(VPFMT_CLAMP_CNTL, 0, VPFMT_CLAMP_DATA_EN, 0, VPFMT_CLAMP_COLOR_FORMAT, 0);
69         break;
70     }
71 }
72 
vpe10_opp_set_dyn_expansion(struct opp * opp,bool enable,enum color_depth color_dpth)73 void vpe10_opp_set_dyn_expansion(struct opp *opp, bool enable, enum color_depth color_dpth)
74 {
75     PROGRAM_ENTRY();
76 
77     if (!enable) {
78         REG_SET_2(VPFMT_DYNAMIC_EXP_CNTL, 0, VPFMT_DYNAMIC_EXP_EN, 0, VPFMT_DYNAMIC_EXP_MODE, 0);
79         return;
80     }
81 
82     /*00 - 10-bit -> 12-bit dynamic expansion*/
83     /*01 - 8-bit  -> 12-bit dynamic expansion*/
84     switch (color_dpth) {
85     case COLOR_DEPTH_888:
86         REG_SET_2(VPFMT_DYNAMIC_EXP_CNTL, 0, VPFMT_DYNAMIC_EXP_EN, 1, VPFMT_DYNAMIC_EXP_MODE, 1);
87         break;
88     case COLOR_DEPTH_101010:
89         REG_SET_2(VPFMT_DYNAMIC_EXP_CNTL, 0, VPFMT_DYNAMIC_EXP_EN, 1, VPFMT_DYNAMIC_EXP_MODE, 0);
90         break;
91     case COLOR_DEPTH_121212:
92         REG_SET_2(VPFMT_DYNAMIC_EXP_CNTL, 0, VPFMT_DYNAMIC_EXP_EN,
93             1, /*otherwise last two bits are zero*/
94             VPFMT_DYNAMIC_EXP_MODE, 0);
95         break;
96     default:
97         REG_SET_2(VPFMT_DYNAMIC_EXP_CNTL, 0, VPFMT_DYNAMIC_EXP_EN, 0, VPFMT_DYNAMIC_EXP_MODE, 0);
98         break;
99     }
100 }
101 
vpe10_opp_set_truncation(struct opp * opp,const struct bit_depth_reduction_params * params)102 void vpe10_opp_set_truncation(struct opp *opp, const struct bit_depth_reduction_params *params)
103 {
104     PROGRAM_ENTRY();
105 
106     REG_UPDATE_3(VPFMT_BIT_DEPTH_CONTROL, VPFMT_TRUNCATE_EN, params->flags.TRUNCATE_ENABLED,
107         VPFMT_TRUNCATE_DEPTH, params->flags.TRUNCATE_DEPTH, VPFMT_TRUNCATE_MODE,
108         params->flags.TRUNCATE_MODE);
109 }
110 
vpe10_opp_set_spatial_dither(struct opp * opp,const struct bit_depth_reduction_params * params)111 void vpe10_opp_set_spatial_dither(struct opp *opp, const struct bit_depth_reduction_params *params)
112 {
113     PROGRAM_ENTRY();
114 
115     /*Disable spatial (random) dithering*/
116     REG_UPDATE_6(VPFMT_BIT_DEPTH_CONTROL, VPFMT_SPATIAL_DITHER_EN, 0, VPFMT_SPATIAL_DITHER_MODE, 0,
117         VPFMT_SPATIAL_DITHER_DEPTH, 0, VPFMT_HIGHPASS_RANDOM_ENABLE, 0, VPFMT_FRAME_RANDOM_ENABLE,
118         0, VPFMT_RGB_RANDOM_ENABLE, 0);
119 
120     if (params->flags.SPATIAL_DITHER_ENABLED == 0)
121         return;
122 
123     /* only use FRAME_COUNTER_MAX if frameRandom == 1*/
124     if (params->flags.FRAME_RANDOM == 1) {
125         if (params->flags.SPATIAL_DITHER_DEPTH == 0 || params->flags.SPATIAL_DITHER_DEPTH == 1) {
126             REG_UPDATE_2(VPFMT_CONTROL, VPFMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, 15,
127                 VPFMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, 2);
128         } else if (params->flags.SPATIAL_DITHER_DEPTH == 2) {
129             REG_UPDATE_2(VPFMT_CONTROL, VPFMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, 3,
130                 VPFMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, 1);
131         } else
132             return;
133     } else {
134         REG_UPDATE_2(VPFMT_CONTROL, VPFMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, 0,
135             VPFMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, 0);
136     }
137 
138     /* Set seed for random values for
139      * spatial dithering for R,G,B channels
140      */
141     REG_SET(VPFMT_DITHER_RAND_R_SEED, 0, VPFMT_RAND_R_SEED, params->r_seed_value);
142 
143     REG_SET(VPFMT_DITHER_RAND_G_SEED, 0, VPFMT_RAND_G_SEED, params->g_seed_value);
144 
145     REG_SET(VPFMT_DITHER_RAND_B_SEED, 0, VPFMT_RAND_B_SEED, params->b_seed_value);
146 
147     /* FMT_OFFSET_R_Cr  31:16 0x0 Setting the zero
148      * offset for the R/Cr channel, lower 4LSB
149      * is forced to zeros. Typically set to 0
150      * RGB and 0x80000 YCbCr.
151      */
152     /* FMT_OFFSET_G_Y   31:16 0x0 Setting the zero
153      * offset for the G/Y  channel, lower 4LSB is
154      * forced to zeros. Typically set to 0 RGB
155      * and 0x80000 YCbCr.
156      */
157     /* FMT_OFFSET_B_Cb  31:16 0x0 Setting the zero
158      * offset for the B/Cb channel, lower 4LSB is
159      * forced to zeros. Typically set to 0 RGB and
160      * 0x80000 YCbCr.
161      */
162 
163     REG_UPDATE_6(VPFMT_BIT_DEPTH_CONTROL,
164         /*Enable spatial dithering*/
165         VPFMT_SPATIAL_DITHER_EN, params->flags.SPATIAL_DITHER_ENABLED,
166         /* Set spatial dithering mode
167          * (default is Seed patterrn AAAA...)
168          */
169         VPFMT_SPATIAL_DITHER_MODE, params->flags.SPATIAL_DITHER_MODE,
170         /*Set spatial dithering bit depth*/
171         VPFMT_SPATIAL_DITHER_DEPTH, params->flags.SPATIAL_DITHER_DEPTH,
172         /*Disable High pass filter*/
173         VPFMT_HIGHPASS_RANDOM_ENABLE, params->flags.HIGHPASS_RANDOM,
174         /*Reset only at startup*/
175         VPFMT_FRAME_RANDOM_ENABLE, params->flags.FRAME_RANDOM,
176         /*Set RGB data dithered with x^28+x^3+1*/
177         VPFMT_RGB_RANDOM_ENABLE, params->flags.RGB_RANDOM);
178 }
179 
vpe10_opp_program_bit_depth_reduction(struct opp * opp,const struct bit_depth_reduction_params * fmt_bit_depth)180 void vpe10_opp_program_bit_depth_reduction(
181     struct opp *opp, const struct bit_depth_reduction_params *fmt_bit_depth)
182 {
183     opp->funcs->set_truncation(opp, fmt_bit_depth);
184     opp->funcs->set_spatial_dither(opp, fmt_bit_depth);
185 }
186 
vpe10_opp_program_fmt(struct opp * opp,struct bit_depth_reduction_params * fmt_bit_depth,struct clamping_and_pixel_encoding_params * clamping)187 void vpe10_opp_program_fmt(struct opp *opp, struct bit_depth_reduction_params *fmt_bit_depth,
188     struct clamping_and_pixel_encoding_params *clamping)
189 {
190     opp->funcs->program_bit_depth_reduction(opp, fmt_bit_depth);
191     opp->funcs->set_clamping(opp, clamping);
192 }
193 
vpe10_opp_program_pipe_alpha(struct opp * opp,uint16_t alpha)194 void vpe10_opp_program_pipe_alpha(struct opp *opp, uint16_t alpha)
195 {
196     PROGRAM_ENTRY();
197     REG_UPDATE(VPOPP_PIPE_CONTROL, VPOPP_PIPE_ALPHA, alpha);
198 }
199 
vpe10_opp_program_pipe_bypass(struct opp * opp,bool enable)200 void vpe10_opp_program_pipe_bypass(struct opp *opp, bool enable)
201 {
202     PROGRAM_ENTRY();
203     REG_UPDATE(VPOPP_PIPE_CONTROL, VPOPP_PIPE_DIGITAL_BYPASS_EN, enable);
204 }
205 
vpe10_opp_program_pipe_crc(struct opp * opp,bool enable)206 void vpe10_opp_program_pipe_crc(struct opp *opp, bool enable)
207 {
208     PROGRAM_ENTRY();
209     REG_UPDATE(VPOPP_PIPE_CRC_CONTROL, VPOPP_PIPE_CRC_EN, enable);
210 }
211 
212