• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "hw_shared.h"
30 #include "reg_helper.h"
31 
32 #define CTX_BASE opp
33 #define CTX      vpe10_opp
34 
35 static struct opp_funcs opp_funcs = {
36     .program_pipe_alpha          = vpe10_opp_program_pipe_alpha,
37     .program_pipe_bypass         = vpe10_opp_program_pipe_bypass,
38     .program_pipe_crc            = vpe10_opp_program_pipe_crc,
39     .set_clamping                = vpe10_opp_set_clamping,
40     .set_truncation              = vpe10_opp_set_truncation,
41     .set_spatial_dither          = vpe10_opp_set_spatial_dither,
42     .program_bit_depth_reduction = vpe10_opp_program_bit_depth_reduction,
43     .set_dyn_expansion           = vpe10_opp_set_dyn_expansion,
44     .program_fmt                 = vpe10_opp_program_fmt,
45 };
46 
vpe10_construct_opp(struct vpe_priv * vpe_priv,struct opp * opp)47 void vpe10_construct_opp(struct vpe_priv *vpe_priv, struct opp *opp)
48 {
49     opp->vpe_priv = vpe_priv;
50     opp->funcs    = &opp_funcs;
51 }
52 
vpe10_opp_set_clamping(struct opp * opp,const struct clamping_and_pixel_encoding_params * params)53 void vpe10_opp_set_clamping(
54     struct opp *opp, const struct clamping_and_pixel_encoding_params *params)
55 {
56     PROGRAM_ENTRY();
57 
58     //OCSC operations are handled in output gamma sequence to allow
59     // full range bg color fill. Hence, no clamping should be done on the output.
60     switch (params->clamping_level) {
61     case CLAMPING_LIMITED_RANGE_8BPC:
62     case CLAMPING_LIMITED_RANGE_10BPC:
63     case CLAMPING_LIMITED_RANGE_12BPC:
64     case CLAMPING_LIMITED_RANGE_PROGRAMMABLE:
65     case CLAMPING_FULL_RANGE:
66     default:
67         REG_SET_2(VPFMT_CLAMP_CNTL, 0, VPFMT_CLAMP_DATA_EN, 0, VPFMT_CLAMP_COLOR_FORMAT, 0);
68         break;
69     }
70 }
71 
vpe10_opp_set_dyn_expansion(struct opp * opp,bool enable,enum color_depth color_dpth)72 void vpe10_opp_set_dyn_expansion(struct opp *opp, bool enable, enum color_depth color_dpth)
73 {
74     PROGRAM_ENTRY();
75 
76     if (!enable) {
77         REG_SET_2(VPFMT_DYNAMIC_EXP_CNTL, 0, VPFMT_DYNAMIC_EXP_EN, 0, VPFMT_DYNAMIC_EXP_MODE, 0);
78         return;
79     }
80 
81     /*00 - 10-bit -> 12-bit dynamic expansion*/
82     /*01 - 8-bit  -> 12-bit dynamic expansion*/
83     switch (color_dpth) {
84     case COLOR_DEPTH_888:
85         REG_SET_2(VPFMT_DYNAMIC_EXP_CNTL, 0, VPFMT_DYNAMIC_EXP_EN, 1, VPFMT_DYNAMIC_EXP_MODE, 1);
86         break;
87     case COLOR_DEPTH_101010:
88         REG_SET_2(VPFMT_DYNAMIC_EXP_CNTL, 0, VPFMT_DYNAMIC_EXP_EN, 1, VPFMT_DYNAMIC_EXP_MODE, 0);
89         break;
90     case COLOR_DEPTH_121212:
91         REG_SET_2(VPFMT_DYNAMIC_EXP_CNTL, 0, VPFMT_DYNAMIC_EXP_EN,
92             1, /*otherwise last two bits are zero*/
93             VPFMT_DYNAMIC_EXP_MODE, 0);
94         break;
95     default:
96         REG_SET_2(VPFMT_DYNAMIC_EXP_CNTL, 0, VPFMT_DYNAMIC_EXP_EN, 0, VPFMT_DYNAMIC_EXP_MODE, 0);
97         break;
98     }
99 }
100 
vpe10_opp_set_truncation(struct opp * opp,const struct bit_depth_reduction_params * params)101 void vpe10_opp_set_truncation(struct opp *opp, const struct bit_depth_reduction_params *params)
102 {
103     PROGRAM_ENTRY();
104 
105     REG_UPDATE_3(VPFMT_BIT_DEPTH_CONTROL, VPFMT_TRUNCATE_EN, params->flags.TRUNCATE_ENABLED,
106         VPFMT_TRUNCATE_DEPTH, params->flags.TRUNCATE_DEPTH, VPFMT_TRUNCATE_MODE,
107         params->flags.TRUNCATE_MODE);
108 }
109 
vpe10_opp_set_spatial_dither(struct opp * opp,const struct bit_depth_reduction_params * params)110 void vpe10_opp_set_spatial_dither(struct opp *opp, const struct bit_depth_reduction_params *params)
111 {
112     PROGRAM_ENTRY();
113 
114     /*Disable spatial (random) dithering*/
115     REG_UPDATE_6(VPFMT_BIT_DEPTH_CONTROL, VPFMT_SPATIAL_DITHER_EN, 0, VPFMT_SPATIAL_DITHER_MODE, 0,
116         VPFMT_SPATIAL_DITHER_DEPTH, 0, VPFMT_HIGHPASS_RANDOM_ENABLE, 0, VPFMT_FRAME_RANDOM_ENABLE,
117         0, VPFMT_RGB_RANDOM_ENABLE, 0);
118 
119     if (params->flags.SPATIAL_DITHER_ENABLED == 0)
120         return;
121 
122     /* only use FRAME_COUNTER_MAX if frameRandom == 1*/
123     if (params->flags.FRAME_RANDOM == 1) {
124         if (params->flags.SPATIAL_DITHER_DEPTH == 0 || params->flags.SPATIAL_DITHER_DEPTH == 1) {
125             REG_UPDATE_2(VPFMT_CONTROL, VPFMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, 15,
126                 VPFMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, 2);
127         } else if (params->flags.SPATIAL_DITHER_DEPTH == 2) {
128             REG_UPDATE_2(VPFMT_CONTROL, VPFMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, 3,
129                 VPFMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, 1);
130         } else
131             return;
132     } else {
133         REG_UPDATE_2(VPFMT_CONTROL, VPFMT_SPATIAL_DITHER_FRAME_COUNTER_MAX, 0,
134             VPFMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP, 0);
135     }
136 
137     /* Set seed for random values for
138      * spatial dithering for R,G,B channels
139      */
140     REG_SET(VPFMT_DITHER_RAND_R_SEED, 0, VPFMT_RAND_R_SEED, params->r_seed_value);
141 
142     REG_SET(VPFMT_DITHER_RAND_G_SEED, 0, VPFMT_RAND_G_SEED, params->g_seed_value);
143 
144     REG_SET(VPFMT_DITHER_RAND_B_SEED, 0, VPFMT_RAND_B_SEED, params->b_seed_value);
145 
146     /* FMT_OFFSET_R_Cr  31:16 0x0 Setting the zero
147      * offset for the R/Cr channel, lower 4LSB
148      * is forced to zeros. Typically set to 0
149      * RGB and 0x80000 YCbCr.
150      */
151     /* FMT_OFFSET_G_Y   31:16 0x0 Setting the zero
152      * offset for the G/Y  channel, lower 4LSB is
153      * forced to zeros. Typically set to 0 RGB
154      * and 0x80000 YCbCr.
155      */
156     /* FMT_OFFSET_B_Cb  31:16 0x0 Setting the zero
157      * offset for the B/Cb channel, lower 4LSB is
158      * forced to zeros. Typically set to 0 RGB and
159      * 0x80000 YCbCr.
160      */
161 
162     REG_UPDATE_6(VPFMT_BIT_DEPTH_CONTROL,
163         /*Enable spatial dithering*/
164         VPFMT_SPATIAL_DITHER_EN, params->flags.SPATIAL_DITHER_ENABLED,
165         /* Set spatial dithering mode
166          * (default is Seed patterrn AAAA...)
167          */
168         VPFMT_SPATIAL_DITHER_MODE, params->flags.SPATIAL_DITHER_MODE,
169         /*Set spatial dithering bit depth*/
170         VPFMT_SPATIAL_DITHER_DEPTH, params->flags.SPATIAL_DITHER_DEPTH,
171         /*Disable High pass filter*/
172         VPFMT_HIGHPASS_RANDOM_ENABLE, params->flags.HIGHPASS_RANDOM,
173         /*Reset only at startup*/
174         VPFMT_FRAME_RANDOM_ENABLE, params->flags.FRAME_RANDOM,
175         /*Set RGB data dithered with x^28+x^3+1*/
176         VPFMT_RGB_RANDOM_ENABLE, params->flags.RGB_RANDOM);
177 }
178 
vpe10_opp_program_bit_depth_reduction(struct opp * opp,const struct bit_depth_reduction_params * fmt_bit_depth)179 void vpe10_opp_program_bit_depth_reduction(
180     struct opp *opp, const struct bit_depth_reduction_params *fmt_bit_depth)
181 {
182     opp->funcs->set_truncation(opp, fmt_bit_depth);
183     opp->funcs->set_spatial_dither(opp, fmt_bit_depth);
184 }
185 
vpe10_opp_program_fmt(struct opp * opp,struct bit_depth_reduction_params * fmt_bit_depth,struct clamping_and_pixel_encoding_params * clamping)186 void vpe10_opp_program_fmt(struct opp *opp, struct bit_depth_reduction_params *fmt_bit_depth,
187     struct clamping_and_pixel_encoding_params *clamping)
188 {
189     opp->funcs->program_bit_depth_reduction(opp, fmt_bit_depth);
190     opp->funcs->set_clamping(opp, clamping);
191 }
192 
vpe10_opp_program_pipe_alpha(struct opp * opp,uint16_t alpha)193 void vpe10_opp_program_pipe_alpha(struct opp *opp, uint16_t alpha)
194 {
195     PROGRAM_ENTRY();
196     REG_UPDATE(VPOPP_PIPE_CONTROL, VPOPP_PIPE_ALPHA, alpha);
197 }
198 
vpe10_opp_program_pipe_bypass(struct opp * opp,bool enable)199 void vpe10_opp_program_pipe_bypass(struct opp *opp, bool enable)
200 {
201     PROGRAM_ENTRY();
202     REG_UPDATE(VPOPP_PIPE_CONTROL, VPOPP_PIPE_DIGITAL_BYPASS_EN, enable);
203 }
204 
vpe10_opp_program_pipe_crc(struct opp * opp,bool enable)205 void vpe10_opp_program_pipe_crc(struct opp *opp, bool enable)
206 {
207     PROGRAM_ENTRY();
208     REG_UPDATE(VPOPP_PIPE_CRC_CONTROL, VPOPP_PIPE_CRC_EN, enable);
209 }
210 
211