• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2023 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 #include <string.h>
25 #include "vpe_priv.h"
26 #include "common.h"
27 #include "vpe11_resource.h"
28 #include "vpe10_resource.h"
29 #include "vpe11_cmd_builder.h"
30 #include "vpe10_vpec.h"
31 #include "vpe10_cdc_be.h"
32 #include "vpe10_cdc_fe.h"
33 #include "vpe10_dpp.h"
34 #include "vpe10_mpc.h"
35 #include "vpe10_opp.h"
36 #include "vpe11_command.h"
37 #include "vpe10_background.h"
38 #include "vpe10_plane_desc_writer.h"
39 #include "vpe11_vpe_desc_writer.h"
40 #include "vpe10_config_writer.h"
41 #include "background.h"
42 
43 #define LUT_NUM_ENTRIES   (17 * 17 * 17)
44 #define LUT_ENTRY_SIZE    (2)
45 #define LUT_NUM_COMPONENT (3)
46 #define LUT_BUFFER_SIZE   (LUT_NUM_ENTRIES * LUT_ENTRY_SIZE * LUT_NUM_COMPONENT)
47 
48 // set field/register/bitfield name
49 #define SFRB(field_name, reg_name, post_fix) .field_name = reg_name##__##field_name##post_fix
50 
51 #define BASE_INNER(seg_id) VPE_BASE__INST0_SEG##seg_id
52 
53 #define BASE(seg_id) BASE_INNER(seg_id)
54 
55 // set register with block id and default val, init lastWrittenVal as default while isWritten set to
56 // false
57 #define SRIDFVL(reg_name, block, id)                                                               \
58     .reg_name = {BASE(reg##reg_name##_BASE_IDX) + reg##reg_name, reg##reg_name##_##DEFAULT,        \
59         reg##reg_name##_##DEFAULT, false}
60 
61 static struct vpe_caps caps = {
62     .lut_size               = LUT_BUFFER_SIZE,
63     .rotation_support       = 0,
64     .h_mirror_support       = 1,
65     .v_mirror_support       = 0,
66     .is_apu                 = 1,
67     .bg_color_check_support = 0,
68     .resource_caps =
69         {
70             .num_dpp       = 1,
71             .num_opp       = 1,
72             .num_mpc_3dlut = 1,
73             .num_queue     = 8,
74             .num_cdc_be    = 1,
75         },
76     .color_caps = {.dpp =
77                        {
78                            .pre_csc    = 1,
79                            .luma_key   = 0,
80                            .color_key  = 1,
81                            .dgam_ram   = 0,
82                            .post_csc   = 1,
83                            .gamma_corr = 1,
84                            .hw_3dlut   = 1,
85                            .ogam_ram   = 1, /**< programmable gam in output -> gamma_corr */
86                            .ocsc       = 0,
87                            .dgam_rom_caps =
88                                {
89                                    .srgb     = 1,
90                                    .bt2020   = 1,
91                                    .gamma2_2 = 1,
92                                    .pq       = 1,
93                                    .hlg      = 1,
94                                },
95                        },
96         .mpc =
97             {
98                 .gamut_remap         = 1,
99                 .ogam_ram            = 1,
100                 .ocsc                = 1,
101                 .shared_3d_lut       = 1,
102                 .global_alpha        = 1,
103                 .top_bottom_blending = 0,
104             }},
105     .plane_caps =
106         {
107             .per_pixel_alpha = 1,
108             .input_pixel_format_support =
109                 {
110                     .argb_packed_32b = 1,
111                     .nv12            = 1,
112                     .fp16            = 0,
113                     .p010            = 1, /**< planar 4:2:0 10-bit */
114                     .p016            = 0, /**< planar 4:2:0 16-bit */
115                     .ayuv            = 0, /**< packed 4:4:4 */
116                     .yuy2 = 0
117                 },
118             .output_pixel_format_support =
119                 {
120                     .argb_packed_32b = 1,
121                     .nv12            = 0,
122                     .fp16            = 1,
123                     .p010            = 0, /**< planar 4:2:0 10-bit */
124                     .p016            = 0, /**< planar 4:2:0 16-bit */
125                     .ayuv            = 0, /**< packed 4:4:4 */
126                     .yuy2 = 0
127                 },
128             .max_upscale_factor = 64000,
129 
130             // 6:1 downscaling ratio: 1000/6 = 166.666
131             .max_downscale_factor = 167,
132 
133             .pitch_alignment    = 256,
134             .addr_alignment     = 256,
135             .max_viewport_width = 1024,
136         },
137 };
138 
139 static struct vpe_cap_funcs cap_funcs =
140 {
141     .get_dcc_compression_output_cap = vpe10_get_dcc_compression_output_cap,
142     .get_dcc_compression_input_cap  = vpe10_get_dcc_compression_input_cap
143 };
144 
vpe11_construct_resource(struct vpe_priv * vpe_priv,struct resource * res)145 enum vpe_status vpe11_construct_resource(struct vpe_priv *vpe_priv, struct resource *res)
146 {
147     struct vpe *vpe = &vpe_priv->pub;
148 
149     vpe->caps      = &caps;
150     vpe->cap_funcs = &cap_funcs;
151 
152     vpe10_construct_vpec(vpe_priv, &res->vpec);
153 
154     res->cdc_fe[0] = vpe10_cdc_fe_create(vpe_priv, 0);
155     if (!res->cdc_fe[0])
156         goto err;
157 
158     res->dpp[0] = vpe10_dpp_create(vpe_priv, 0);
159     if (!res->dpp[0])
160         goto err;
161 
162     res->mpc[0] = vpe10_mpc_create(vpe_priv, 0);
163     if (!res->mpc[0])
164         goto err;
165 
166     res->cdc_be[0] = vpe10_cdc_be_create(vpe_priv, 0);
167     if (!res->cdc_be[0])
168         goto err;
169 
170     res->opp[0] = vpe10_opp_create(vpe_priv, 0);
171     if (!res->opp[0])
172         goto err;
173 
174     vpe11_construct_cmd_builder(vpe_priv, &res->cmd_builder);
175     vpe10_construct_plane_desc_writer(&vpe_priv->plane_desc_writer);
176     vpe11_construct_vpe_desc_writer(&vpe_priv->vpe_desc_writer);
177     vpe10_config_writer_init(&vpe_priv->config_writer);
178 
179     vpe_priv->num_pipe = 1;
180 
181     res->internal_hdr_normalization = 1;
182 
183     res->check_input_color_space           = vpe10_check_input_color_space;
184     res->check_output_color_space          = vpe10_check_output_color_space;
185     res->check_h_mirror_support            = vpe10_check_h_mirror_support;
186     res->calculate_segments                = vpe10_calculate_segments;
187     res->set_num_segments                  = vpe11_set_num_segments;
188     res->split_bg_gap                      = vpe10_split_bg_gap;
189     res->calculate_dst_viewport_and_active = vpe10_calculate_dst_viewport_and_active;
190     res->find_bg_gaps                      = vpe_find_bg_gaps;
191     res->create_bg_segments                = vpe_create_bg_segments;
192     res->populate_cmd_info                 = vpe10_populate_cmd_info;
193     res->program_frontend                  = vpe10_program_frontend;
194     res->program_backend                   = vpe10_program_backend;
195     res->get_bufs_req                      = vpe10_get_bufs_req;
196     res->check_bg_color_support            = vpe10_check_bg_color_support;
197     res->check_mirror_rotation_support     = vpe10_check_mirror_rotation_support;
198     res->update_blnd_gamma                 = vpe10_update_blnd_gamma;
199 
200     return VPE_STATUS_OK;
201 err:
202     vpe11_destroy_resource(vpe_priv, res);
203     return VPE_STATUS_ERROR;
204 }
205 
vpe11_destroy_resource(struct vpe_priv * vpe_priv,struct resource * res)206 void vpe11_destroy_resource(struct vpe_priv *vpe_priv, struct resource *res)
207 {
208     if (res->cdc_fe[0] != NULL) {
209         vpe_free(container_of(res->cdc_fe[0], struct vpe10_cdc_fe, base));
210         res->cdc_fe[0] = NULL;
211     }
212 
213     if (res->dpp[0] != NULL) {
214         vpe_free(container_of(res->dpp[0], struct vpe10_dpp, base));
215         res->dpp[0] = NULL;
216     }
217 
218     if (res->mpc[0] != NULL) {
219         vpe_free(container_of(res->mpc[0], struct vpe10_mpc, base));
220         res->mpc[0] = NULL;
221     }
222 
223     if (res->cdc_be[0] != NULL) {
224         vpe_free(container_of(res->cdc_be[0], struct vpe10_cdc_be, base));
225         res->cdc_be[0] = NULL;
226     }
227 
228     if (res->opp[0] != NULL) {
229         vpe_free(container_of(res->opp[0], struct vpe10_opp, base));
230         res->opp[0] = NULL;
231     }
232 }
233 
vpe11_set_num_segments(struct vpe_priv * vpe_priv,struct stream_ctx * stream_ctx,struct scaler_data * scl_data,struct vpe_rect * src_rect,struct vpe_rect * dst_rect,uint32_t * max_seg_width)234 enum vpe_status vpe11_set_num_segments(struct vpe_priv *vpe_priv, struct stream_ctx *stream_ctx,
235     struct scaler_data *scl_data, struct vpe_rect *src_rect, struct vpe_rect *dst_rect,
236     uint32_t *max_seg_width)
237 {
238 
239     uint16_t       num_segs;
240     struct dpp    *dpp         = vpe_priv->resource.dpp[0];
241     const uint32_t max_lb_size = dpp->funcs->get_line_buffer_size();
242 
243     *max_seg_width = min(*max_seg_width, max_lb_size / scl_data->taps.v_taps);
244 
245     num_segs = vpe_get_num_segments(vpe_priv, src_rect, dst_rect, *max_seg_width);
246     if ((src_rect->width >= (uint32_t)(vpe_priv->vpe_num_instance * VPE_MIN_VIEWPORT_SIZE)) &&
247         ((num_segs % vpe_priv->vpe_num_instance) != 0)) {
248         num_segs += (vpe_priv->vpe_num_instance - (num_segs % vpe_priv->vpe_num_instance));
249     }
250 
251     stream_ctx->segment_ctx = vpe_alloc_segment_ctx(vpe_priv, num_segs);
252     if (!stream_ctx->segment_ctx)
253         return VPE_STATUS_NO_MEMORY;
254 
255     stream_ctx->num_segments = num_segs;
256 
257     return VPE_STATUS_OK;
258 }
259