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 "common.h"
26 #include "vpe_priv.h"
27 #include "vpe10_cdc.h"
28 #include "reg_helper.h"
29
30 #define CTX_BASE cdc
31 #define CTX vpe10_cdc
32
33 enum mux_sel {
34 MUX_SEL_ALPHA = 0,
35 MUX_SEL_Y_G = 1,
36 MUX_SEL_CB_B = 2,
37 MUX_SEL_CR_R = 3
38 };
39
40 static struct cdc_funcs cdc_func = {
41 .check_input_format = vpe10_cdc_check_input_format,
42 .check_output_format = vpe10_cdc_check_output_format,
43
44 .program_surface_config = vpe10_cdc_program_surface_config,
45 .program_crossbar_config = vpe10_cdc_program_crossbar_config,
46 .program_global_sync = vpe10_cdc_program_global_sync,
47 .program_p2b_config = vpe10_cdc_program_p2b_config,
48 .program_viewport = vpe10_cdc_program_viewport,
49 };
50
vpe10_construct_cdc(struct vpe_priv * vpe_priv,struct cdc * cdc)51 void vpe10_construct_cdc(struct vpe_priv *vpe_priv, struct cdc *cdc)
52 {
53 cdc->vpe_priv = vpe_priv;
54 cdc->funcs = &cdc_func;
55 }
56
vpe10_cdc_check_input_format(struct cdc * cdc,enum vpe_surface_pixel_format format)57 bool vpe10_cdc_check_input_format(struct cdc *cdc, enum vpe_surface_pixel_format format)
58 {
59 if (vpe_is_32bit_packed_rgb(format))
60 return true;
61
62 if (format == VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr ||
63 format == VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb)
64 return true;
65
66 if (format == VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr ||
67 format == VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb)
68 return true;
69
70 return false;
71 }
72
vpe10_cdc_check_output_format(struct cdc * cdc,enum vpe_surface_pixel_format format)73 bool vpe10_cdc_check_output_format(struct cdc *cdc, enum vpe_surface_pixel_format format)
74 {
75 if (vpe_is_32bit_packed_rgb(format))
76 return true;
77 if (vpe_is_fp16(format))
78 return true;
79
80 return false;
81 }
82
vpe10_cdc_program_surface_config(struct cdc * cdc,enum vpe_surface_pixel_format format,enum vpe_rotation_angle rotation,bool horizontal_mirror,enum vpe_swizzle_mode_values swizzle)83 void vpe10_cdc_program_surface_config(struct cdc *cdc, enum vpe_surface_pixel_format format,
84 enum vpe_rotation_angle rotation, bool horizontal_mirror, enum vpe_swizzle_mode_values swizzle)
85 {
86 uint32_t rotation_angle = 0, surface_linear;
87 uint32_t surf_format = 8;
88
89 PROGRAM_ENTRY();
90
91 /* Program rotation angle and horz mirror - no mirror */
92 if (rotation == VPE_ROTATION_ANGLE_0)
93 rotation_angle = 0;
94 else if (rotation == VPE_ROTATION_ANGLE_90)
95 rotation_angle = 1;
96 else if (rotation == VPE_ROTATION_ANGLE_180)
97 rotation_angle = 2;
98 else if (rotation == VPE_ROTATION_ANGLE_270)
99 rotation_angle = 3;
100
101 if (swizzle == VPE_SW_LINEAR)
102 surface_linear = 1;
103 else
104 surface_linear = 0;
105
106 switch (format) {
107 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
108 surf_format = 1;
109 break;
110 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGB565:
111 surf_format = 3;
112 break;
113 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
114 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
115 case VPE_SURFACE_PIXEL_FORMAT_GRPH_XRGB8888:
116 case VPE_SURFACE_PIXEL_FORMAT_GRPH_XBGR8888:
117 surf_format = 8;
118 break;
119 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA8888:
120 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA8888:
121 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBX8888:
122 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRX8888:
123 surf_format = 9;
124 break;
125 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
126 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
127 surf_format = 10;
128 break;
129 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA1010102:
130 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA1010102:
131 surf_format = 11;
132 break;
133 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
134 surf_format = 22;
135 break;
136 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
137 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F: /* use crossbar */
138 surf_format = 24;
139 break;
140 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA16161616F:
141 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616F:
142 surf_format = 25;
143 break;
144 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
145 surf_format = 65;
146 break;
147 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
148 surf_format = 64;
149 break;
150 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
151 surf_format = 67;
152 break;
153 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
154 surf_format = 66;
155 break;
156 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888:
157 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCbCr8888: // use crossbar
158 surf_format = 12;
159 break;
160 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FIX:
161 surf_format = 112;
162 break;
163 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FIX:
164 surf_format = 113;
165 break;
166 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010:
167 surf_format = 114;
168 break;
169 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FLOAT:
170 surf_format = 118;
171 break;
172 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FLOAT:
173 surf_format = 119;
174 break;
175 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBE:
176 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA:
177 default:
178 vpe_log("cdc: invalid pixel format %d\n", (int)format);
179 break;
180 }
181
182 REG_SET_4(VPCDC_FE0_SURFACE_CONFIG, 0, SURFACE_PIXEL_FORMAT_FE0, surf_format,
183 ROTATION_ANGLE_FE0, rotation_angle, H_MIRROR_EN_FE0, (unsigned)horizontal_mirror,
184 PIX_SURFACE_LINEAR_FE0, surface_linear);
185 }
186
vpe10_cdc_program_crossbar_config(struct cdc * cdc,enum vpe_surface_pixel_format format)187 void vpe10_cdc_program_crossbar_config(struct cdc *cdc, enum vpe_surface_pixel_format format)
188 {
189 uint32_t alpha_bar = (uint32_t)MUX_SEL_ALPHA;
190 uint32_t green_bar = (uint32_t)MUX_SEL_Y_G;
191 uint32_t red_bar = (uint32_t)MUX_SEL_CR_R;
192 uint32_t blue_bar = (uint32_t)MUX_SEL_CB_B;
193
194 PROGRAM_ENTRY();
195
196 if (format == VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR8888 ||
197 format == VPE_SURFACE_PIXEL_FORMAT_GRPH_XBGR8888 ||
198 format == VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010 ||
199 format == VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F ||
200 format == VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA8888 ||
201 format == VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRX8888 ||
202 format == VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA1010102 ||
203 format == VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616F ||
204 format == VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCbCr8888) {
205 red_bar = MUX_SEL_CB_B;
206 blue_bar = MUX_SEL_CR_R;
207 }
208
209 REG_SET_4(VPCDC_FE0_CROSSBAR_CONFIG, 0, CROSSBAR_SRC_ALPHA_FE0, alpha_bar,
210 CROSSBAR_SRC_CR_R_FE0, red_bar, CROSSBAR_SRC_Y_G_FE0, green_bar, CROSSBAR_SRC_CB_B_FE0,
211 blue_bar);
212 }
213
vpe10_cdc_program_global_sync(struct cdc * cdc,uint32_t vupdate_offset,uint32_t vupdate_width,uint32_t vready_offset)214 void vpe10_cdc_program_global_sync(
215 struct cdc *cdc, uint32_t vupdate_offset, uint32_t vupdate_width, uint32_t vready_offset)
216 {
217 PROGRAM_ENTRY();
218
219 REG_SET_3(VPCDC_BE0_GLOBAL_SYNC_CONFIG, 0, BE0_VUPDATE_OFFSET, vupdate_offset,
220 BE0_VUPDATE_WIDTH, vupdate_width, BE0_VREADY_OFFSET, vready_offset);
221 }
222
vpe10_cdc_program_p2b_config(struct cdc * cdc,enum vpe_surface_pixel_format format)223 void vpe10_cdc_program_p2b_config(struct cdc *cdc, enum vpe_surface_pixel_format format)
224 {
225 uint32_t bar_sel0 = (uint32_t)MUX_SEL_CB_B;
226 uint32_t bar_sel1 = (uint32_t)MUX_SEL_Y_G;
227 uint32_t bar_sel2 = (uint32_t)MUX_SEL_CR_R;
228 uint32_t bar_sel3 = (uint32_t)MUX_SEL_ALPHA;
229 uint32_t p2b_format_sel = 0;
230
231 PROGRAM_ENTRY();
232
233 switch (format) {
234 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
235 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA8888:
236 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
237 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA8888:
238 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBX8888:
239 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRX8888:
240 case VPE_SURFACE_PIXEL_FORMAT_GRPH_XRGB8888:
241 case VPE_SURFACE_PIXEL_FORMAT_GRPH_XBGR8888:
242 p2b_format_sel = 0;
243 break;
244 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
245 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA1010102:
246 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
247 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA1010102:
248 p2b_format_sel = 1;
249 break;
250 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
251 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA16161616F:
252 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
253 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616F:
254 p2b_format_sel = 2;
255 break;
256 default:
257 VPE_ASSERT(0);
258 break;
259 }
260
261 switch (format) {
262 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA8888:
263 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBX8888:
264 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA1010102:
265 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA16161616F:
266 bar_sel3 = (uint32_t)MUX_SEL_CR_R;
267 bar_sel2 = (uint32_t)MUX_SEL_Y_G;
268 bar_sel1 = (uint32_t)MUX_SEL_CB_B;
269 bar_sel0 = (uint32_t)MUX_SEL_ALPHA;
270 break;
271 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
272 case VPE_SURFACE_PIXEL_FORMAT_GRPH_XBGR8888:
273 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
274 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
275 bar_sel3 = (uint32_t)MUX_SEL_ALPHA;
276 bar_sel2 = (uint32_t)MUX_SEL_CB_B;
277 bar_sel1 = (uint32_t)MUX_SEL_Y_G;
278 bar_sel0 = (uint32_t)MUX_SEL_CR_R;
279 break;
280 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA8888:
281 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRX8888:
282 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA1010102:
283 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616F:
284 bar_sel3 = (uint32_t)MUX_SEL_CB_B;
285 bar_sel2 = (uint32_t)MUX_SEL_Y_G;
286 bar_sel1 = (uint32_t)MUX_SEL_CR_R;
287 bar_sel0 = (uint32_t)MUX_SEL_ALPHA;
288 break;
289 default:
290 break;
291 }
292
293 REG_SET_5(VPCDC_BE0_P2B_CONFIG, 0, VPCDC_BE0_P2B_XBAR_SEL0, bar_sel0, VPCDC_BE0_P2B_XBAR_SEL1,
294 bar_sel1, VPCDC_BE0_P2B_XBAR_SEL2, bar_sel2, VPCDC_BE0_P2B_XBAR_SEL3, bar_sel3,
295 VPCDC_BE0_P2B_FORMAT_SEL, p2b_format_sel);
296 }
297
298 /** segment specific */
vpe10_cdc_program_viewport(struct cdc * cdc,const struct vpe_rect * viewport,const struct vpe_rect * viewport_c)299 void vpe10_cdc_program_viewport(
300 struct cdc *cdc, const struct vpe_rect *viewport, const struct vpe_rect *viewport_c)
301 {
302
303 PROGRAM_ENTRY();
304
305 REG_SET_2(VPCDC_FE0_VIEWPORT_START_CONFIG, 0, VIEWPORT_X_START_FE0, viewport->x,
306 VIEWPORT_Y_START_FE0, viewport->y);
307
308 REG_SET_2(VPCDC_FE0_VIEWPORT_DIMENSION_CONFIG, 0, VIEWPORT_WIDTH_FE0, viewport->width,
309 VIEWPORT_HEIGHT_FE0, viewport->height);
310
311 REG_SET_2(VPCDC_FE0_VIEWPORT_START_C_CONFIG, 0, VIEWPORT_X_START_C_FE0, viewport_c->x,
312 VIEWPORT_Y_START_C_FE0, viewport_c->y);
313
314 REG_SET_2(VPCDC_FE0_VIEWPORT_DIMENSION_C_CONFIG, 0, VIEWPORT_WIDTH_C_FE0, viewport_c->width,
315 VIEWPORT_HEIGHT_C_FE0, viewport_c->height);
316 }
317
318