| .. | .. |
|---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-only */ |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. |
|---|
| 3 | 4 | * Copyright (C) 2017 Linaro Ltd. |
|---|
| 4 | | - * |
|---|
| 5 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 6 | | - * it under the terms of the GNU General Public License version 2 and |
|---|
| 7 | | - * only version 2 as published by the Free Software Foundation. |
|---|
| 8 | | - * |
|---|
| 9 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 10 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 11 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 12 | | - * GNU General Public License for more details. |
|---|
| 13 | | - * |
|---|
| 14 | 5 | */ |
|---|
| 15 | 6 | |
|---|
| 16 | 7 | #ifndef __VENUS_CORE_H_ |
|---|
| .. | .. |
|---|
| 21 | 12 | #include <media/v4l2-ctrls.h> |
|---|
| 22 | 13 | #include <media/v4l2-device.h> |
|---|
| 23 | 14 | |
|---|
| 15 | +#include "dbgfs.h" |
|---|
| 24 | 16 | #include "hfi.h" |
|---|
| 25 | 17 | |
|---|
| 26 | | -#define VIDC_CLKS_NUM_MAX 4 |
|---|
| 18 | +#define VDBGL "VenusLow : " |
|---|
| 19 | +#define VDBGM "VenusMed : " |
|---|
| 20 | +#define VDBGH "VenusHigh: " |
|---|
| 21 | +#define VDBGFW "VenusFW : " |
|---|
| 22 | + |
|---|
| 23 | +#define VIDC_CLKS_NUM_MAX 4 |
|---|
| 24 | +#define VIDC_VCODEC_CLKS_NUM_MAX 2 |
|---|
| 25 | +#define VIDC_PMDOMAINS_NUM_MAX 3 |
|---|
| 26 | + |
|---|
| 27 | +extern int venus_fw_debug; |
|---|
| 27 | 28 | |
|---|
| 28 | 29 | struct freq_tbl { |
|---|
| 29 | 30 | unsigned int load; |
|---|
| .. | .. |
|---|
| 35 | 36 | u32 value; |
|---|
| 36 | 37 | }; |
|---|
| 37 | 38 | |
|---|
| 39 | +struct codec_freq_data { |
|---|
| 40 | + u32 pixfmt; |
|---|
| 41 | + u32 session_type; |
|---|
| 42 | + unsigned long vpp_freq; |
|---|
| 43 | + unsigned long vsp_freq; |
|---|
| 44 | +}; |
|---|
| 45 | + |
|---|
| 46 | +struct bw_tbl { |
|---|
| 47 | + u32 mbs_per_sec; |
|---|
| 48 | + u32 avg; |
|---|
| 49 | + u32 peak; |
|---|
| 50 | + u32 avg_10bit; |
|---|
| 51 | + u32 peak_10bit; |
|---|
| 52 | +}; |
|---|
| 53 | + |
|---|
| 38 | 54 | struct venus_resources { |
|---|
| 39 | 55 | u64 dma_mask; |
|---|
| 40 | 56 | const struct freq_tbl *freq_tbl; |
|---|
| 41 | 57 | unsigned int freq_tbl_size; |
|---|
| 58 | + const struct bw_tbl *bw_tbl_enc; |
|---|
| 59 | + unsigned int bw_tbl_enc_size; |
|---|
| 60 | + const struct bw_tbl *bw_tbl_dec; |
|---|
| 61 | + unsigned int bw_tbl_dec_size; |
|---|
| 42 | 62 | const struct reg_val *reg_tbl; |
|---|
| 43 | 63 | unsigned int reg_tbl_size; |
|---|
| 64 | + const struct codec_freq_data *codec_freq_data; |
|---|
| 65 | + unsigned int codec_freq_data_size; |
|---|
| 44 | 66 | const char * const clks[VIDC_CLKS_NUM_MAX]; |
|---|
| 45 | 67 | unsigned int clks_num; |
|---|
| 68 | + const char * const vcodec0_clks[VIDC_VCODEC_CLKS_NUM_MAX]; |
|---|
| 69 | + const char * const vcodec1_clks[VIDC_VCODEC_CLKS_NUM_MAX]; |
|---|
| 70 | + unsigned int vcodec_clks_num; |
|---|
| 71 | + const char * const vcodec_pmdomains[VIDC_PMDOMAINS_NUM_MAX]; |
|---|
| 72 | + unsigned int vcodec_pmdomains_num; |
|---|
| 73 | + const char **opp_pmdomain; |
|---|
| 74 | + unsigned int vcodec_num; |
|---|
| 46 | 75 | enum hfi_version hfi_version; |
|---|
| 47 | 76 | u32 max_load; |
|---|
| 48 | 77 | unsigned int vmem_id; |
|---|
| 49 | 78 | u32 vmem_size; |
|---|
| 50 | 79 | u32 vmem_addr; |
|---|
| 80 | + u32 cp_start; |
|---|
| 81 | + u32 cp_size; |
|---|
| 82 | + u32 cp_nonpixel_start; |
|---|
| 83 | + u32 cp_nonpixel_size; |
|---|
| 51 | 84 | const char *fwname; |
|---|
| 52 | 85 | }; |
|---|
| 53 | 86 | |
|---|
| .. | .. |
|---|
| 55 | 88 | u32 pixfmt; |
|---|
| 56 | 89 | unsigned int num_planes; |
|---|
| 57 | 90 | u32 type; |
|---|
| 91 | + u32 flags; |
|---|
| 58 | 92 | }; |
|---|
| 59 | 93 | |
|---|
| 60 | 94 | #define MAX_PLANES 4 |
|---|
| .. | .. |
|---|
| 87 | 121 | * @base: IO memory base address |
|---|
| 88 | 122 | * @irq: Venus irq |
|---|
| 89 | 123 | * @clks: an array of struct clk pointers |
|---|
| 90 | | - * @core0_clk: a struct clk pointer for core0 |
|---|
| 91 | | - * @core1_clk: a struct clk pointer for core1 |
|---|
| 92 | | - * @core0_bus_clk: a struct clk pointer for core0 bus clock |
|---|
| 93 | | - * @core1_bus_clk: a struct clk pointer for core1 bus clock |
|---|
| 124 | + * @vcodec0_clks: an array of vcodec0 struct clk pointers |
|---|
| 125 | + * @vcodec1_clks: an array of vcodec1 struct clk pointers |
|---|
| 126 | + * @pmdomains: an array of pmdomains struct device pointers |
|---|
| 94 | 127 | * @vdev_dec: a reference to video device structure for decoder instances |
|---|
| 95 | 128 | * @vdev_enc: a reference to video device structure for encoder instances |
|---|
| 96 | 129 | * @v4l2_dev: a holder for v4l2 device structure |
|---|
| .. | .. |
|---|
| 98 | 131 | * @dev: convenience struct device pointer |
|---|
| 99 | 132 | * @dev_dec: convenience struct device pointer for decoder device |
|---|
| 100 | 133 | * @dev_enc: convenience struct device pointer for encoder device |
|---|
| 134 | + * @use_tz: a flag that suggests presence of trustzone |
|---|
| 101 | 135 | * @lock: a lock for this strucure |
|---|
| 102 | 136 | * @instances: a list_head of all instances |
|---|
| 103 | 137 | * @insts_count: num of instances |
|---|
| .. | .. |
|---|
| 106 | 140 | * @error: an error returned during last HFI sync operations |
|---|
| 107 | 141 | * @sys_error: an error flag that signal system error event |
|---|
| 108 | 142 | * @core_ops: the core operations |
|---|
| 143 | + * @pm_lock: a lock for PM operations |
|---|
| 109 | 144 | * @enc_codecs: encoders supported by this core |
|---|
| 110 | 145 | * @dec_codecs: decoders supported by this core |
|---|
| 111 | 146 | * @max_sessions_supported: holds the maximum number of sessions |
|---|
| .. | .. |
|---|
| 113 | 148 | * @priv: a private filed for HFI operations |
|---|
| 114 | 149 | * @ops: the core HFI operations |
|---|
| 115 | 150 | * @work: a delayed work for handling system fatal error |
|---|
| 151 | + * @root: debugfs root directory |
|---|
| 116 | 152 | */ |
|---|
| 117 | 153 | struct venus_core { |
|---|
| 118 | 154 | void __iomem *base; |
|---|
| 119 | 155 | int irq; |
|---|
| 120 | 156 | struct clk *clks[VIDC_CLKS_NUM_MAX]; |
|---|
| 121 | | - struct clk *core0_clk; |
|---|
| 122 | | - struct clk *core1_clk; |
|---|
| 123 | | - struct clk *core0_bus_clk; |
|---|
| 124 | | - struct clk *core1_bus_clk; |
|---|
| 157 | + struct clk *vcodec0_clks[VIDC_VCODEC_CLKS_NUM_MAX]; |
|---|
| 158 | + struct clk *vcodec1_clks[VIDC_VCODEC_CLKS_NUM_MAX]; |
|---|
| 159 | + struct icc_path *video_path; |
|---|
| 160 | + struct icc_path *cpucfg_path; |
|---|
| 161 | + struct opp_table *opp_table; |
|---|
| 162 | + bool has_opp_table; |
|---|
| 163 | + struct device *pmdomains[VIDC_PMDOMAINS_NUM_MAX]; |
|---|
| 164 | + struct device_link *opp_dl_venus; |
|---|
| 165 | + struct device *opp_pmdomain; |
|---|
| 125 | 166 | struct video_device *vdev_dec; |
|---|
| 126 | 167 | struct video_device *vdev_enc; |
|---|
| 127 | 168 | struct v4l2_device v4l2_dev; |
|---|
| .. | .. |
|---|
| 129 | 170 | struct device *dev; |
|---|
| 130 | 171 | struct device *dev_dec; |
|---|
| 131 | 172 | struct device *dev_enc; |
|---|
| 173 | + unsigned int use_tz; |
|---|
| 174 | + struct video_firmware { |
|---|
| 175 | + struct device *dev; |
|---|
| 176 | + struct iommu_domain *iommu_domain; |
|---|
| 177 | + size_t mapped_mem_size; |
|---|
| 178 | + } fw; |
|---|
| 132 | 179 | struct mutex lock; |
|---|
| 133 | 180 | struct list_head instances; |
|---|
| 134 | 181 | atomic_t insts_count; |
|---|
| .. | .. |
|---|
| 137 | 184 | unsigned int error; |
|---|
| 138 | 185 | bool sys_error; |
|---|
| 139 | 186 | const struct hfi_core_ops *core_ops; |
|---|
| 187 | + const struct venus_pm_ops *pm_ops; |
|---|
| 188 | + struct mutex pm_lock; |
|---|
| 140 | 189 | unsigned long enc_codecs; |
|---|
| 141 | 190 | unsigned long dec_codecs; |
|---|
| 142 | 191 | unsigned int max_sessions_supported; |
|---|
| .. | .. |
|---|
| 150 | 199 | struct delayed_work work; |
|---|
| 151 | 200 | struct venus_caps caps[MAX_CODEC_NUM]; |
|---|
| 152 | 201 | unsigned int codecs_count; |
|---|
| 202 | + unsigned int core0_usage_count; |
|---|
| 203 | + unsigned int core1_usage_count; |
|---|
| 204 | + struct dentry *root; |
|---|
| 153 | 205 | }; |
|---|
| 154 | 206 | |
|---|
| 155 | 207 | struct vdec_controls { |
|---|
| .. | .. |
|---|
| 165 | 217 | u32 bitrate_mode; |
|---|
| 166 | 218 | u32 bitrate; |
|---|
| 167 | 219 | u32 bitrate_peak; |
|---|
| 220 | + u32 rc_enable; |
|---|
| 221 | + u32 const_quality; |
|---|
| 222 | + u32 frame_skip_mode; |
|---|
| 168 | 223 | |
|---|
| 169 | 224 | u32 h264_i_period; |
|---|
| 170 | 225 | u32 h264_entropy_mode; |
|---|
| .. | .. |
|---|
| 187 | 242 | u32 header_mode; |
|---|
| 188 | 243 | |
|---|
| 189 | 244 | struct { |
|---|
| 190 | | - u32 mpeg4; |
|---|
| 191 | 245 | u32 h264; |
|---|
| 192 | | - u32 vpx; |
|---|
| 246 | + u32 mpeg4; |
|---|
| 193 | 247 | u32 hevc; |
|---|
| 248 | + u32 vp8; |
|---|
| 249 | + u32 vp9; |
|---|
| 194 | 250 | } profile; |
|---|
| 195 | 251 | struct { |
|---|
| 196 | | - u32 mpeg4; |
|---|
| 197 | 252 | u32 h264; |
|---|
| 253 | + u32 mpeg4; |
|---|
| 198 | 254 | u32 hevc; |
|---|
| 255 | + u32 vp9; |
|---|
| 199 | 256 | } level; |
|---|
| 200 | 257 | }; |
|---|
| 201 | 258 | |
|---|
| .. | .. |
|---|
| 209 | 266 | struct list_head ref_list; |
|---|
| 210 | 267 | }; |
|---|
| 211 | 268 | |
|---|
| 269 | +struct clock_data { |
|---|
| 270 | + u32 core_id; |
|---|
| 271 | + unsigned long freq; |
|---|
| 272 | + const struct codec_freq_data *codec_freq_data; |
|---|
| 273 | +}; |
|---|
| 274 | + |
|---|
| 212 | 275 | #define to_venus_buffer(ptr) container_of(ptr, struct venus_buffer, vb) |
|---|
| 213 | 276 | |
|---|
| 277 | +enum venus_dec_state { |
|---|
| 278 | + VENUS_DEC_STATE_DEINIT = 0, |
|---|
| 279 | + VENUS_DEC_STATE_INIT = 1, |
|---|
| 280 | + VENUS_DEC_STATE_CAPTURE_SETUP = 2, |
|---|
| 281 | + VENUS_DEC_STATE_STOPPED = 3, |
|---|
| 282 | + VENUS_DEC_STATE_SEEK = 4, |
|---|
| 283 | + VENUS_DEC_STATE_DRAIN = 5, |
|---|
| 284 | + VENUS_DEC_STATE_DECODING = 6, |
|---|
| 285 | + VENUS_DEC_STATE_DRC = 7, |
|---|
| 286 | + VENUS_DEC_STATE_DRC_FLUSH_DONE = 8, |
|---|
| 287 | +}; |
|---|
| 288 | + |
|---|
| 289 | +struct venus_ts_metadata { |
|---|
| 290 | + bool used; |
|---|
| 291 | + u64 ts_ns; |
|---|
| 292 | + u64 ts_us; |
|---|
| 293 | + u32 flags; |
|---|
| 294 | + struct v4l2_timecode tc; |
|---|
| 295 | +}; |
|---|
| 296 | + |
|---|
| 214 | 297 | /** |
|---|
| 215 | | - * struct venus_inst - holds per instance paramerters |
|---|
| 298 | + * struct venus_inst - holds per instance parameters |
|---|
| 216 | 299 | * |
|---|
| 217 | 300 | * @list: used for attach an instance to the core |
|---|
| 218 | 301 | * @lock: instance lock |
|---|
| .. | .. |
|---|
| 234 | 317 | * @colorspace: current color space |
|---|
| 235 | 318 | * @quantization: current quantization |
|---|
| 236 | 319 | * @xfer_func: current xfer function |
|---|
| 320 | + * @codec_state: current codec API state (see DEC/ENC_STATE_) |
|---|
| 321 | + * @reconf_wait: wait queue for resolution change event |
|---|
| 322 | + * @subscriptions: used to hold current events subscriptions |
|---|
| 323 | + * @buf_count: used to count number of buffers (reqbuf(0)) |
|---|
| 237 | 324 | * @fps: holds current FPS |
|---|
| 238 | 325 | * @timeperframe: holds current time per frame structure |
|---|
| 239 | 326 | * @fmt_out: a reference to output format structure |
|---|
| .. | .. |
|---|
| 248 | 335 | * @opb_buftype: output picture buffer type |
|---|
| 249 | 336 | * @opb_fmt: output picture buffer raw format |
|---|
| 250 | 337 | * @reconfig: a flag raised by decoder when the stream resolution changed |
|---|
| 251 | | - * @reconfig_width: holds the new width |
|---|
| 252 | | - * @reconfig_height: holds the new height |
|---|
| 253 | 338 | * @hfi_codec: current codec for this instance in HFI space |
|---|
| 254 | 339 | * @sequence_cap: a sequence counter for capture queue |
|---|
| 255 | 340 | * @sequence_out: a sequence counter for output queue |
|---|
| .. | .. |
|---|
| 263 | 348 | * @priv: a private for HFI operations callbacks |
|---|
| 264 | 349 | * @session_type: the type of the session (decoder or encoder) |
|---|
| 265 | 350 | * @hprop: a union used as a holder by get property |
|---|
| 351 | + * @last_buf: last capture buffer for dynamic-resoluton-change |
|---|
| 266 | 352 | */ |
|---|
| 267 | 353 | struct venus_inst { |
|---|
| 268 | 354 | struct list_head list; |
|---|
| 269 | 355 | struct mutex lock; |
|---|
| 270 | 356 | struct venus_core *core; |
|---|
| 357 | + struct clock_data clk_data; |
|---|
| 271 | 358 | struct list_head dpbbufs; |
|---|
| 272 | 359 | struct list_head internalbufs; |
|---|
| 273 | 360 | struct list_head registeredbufs; |
|---|
| .. | .. |
|---|
| 289 | 376 | u8 ycbcr_enc; |
|---|
| 290 | 377 | u8 quantization; |
|---|
| 291 | 378 | u8 xfer_func; |
|---|
| 379 | + enum venus_dec_state codec_state; |
|---|
| 380 | + wait_queue_head_t reconf_wait; |
|---|
| 381 | + unsigned int subscriptions; |
|---|
| 382 | + int buf_count; |
|---|
| 383 | + struct venus_ts_metadata tss[VIDEO_MAX_FRAME]; |
|---|
| 384 | + unsigned long payloads[VIDEO_MAX_FRAME]; |
|---|
| 292 | 385 | u64 fps; |
|---|
| 293 | 386 | struct v4l2_fract timeperframe; |
|---|
| 294 | 387 | const struct venus_format *fmt_out; |
|---|
| .. | .. |
|---|
| 303 | 396 | u32 opb_buftype; |
|---|
| 304 | 397 | u32 opb_fmt; |
|---|
| 305 | 398 | bool reconfig; |
|---|
| 306 | | - u32 reconfig_width; |
|---|
| 307 | | - u32 reconfig_height; |
|---|
| 308 | 399 | u32 hfi_codec; |
|---|
| 309 | 400 | u32 sequence_cap; |
|---|
| 310 | 401 | u32 sequence_out; |
|---|
| .. | .. |
|---|
| 317 | 408 | const struct hfi_inst_ops *ops; |
|---|
| 318 | 409 | u32 session_type; |
|---|
| 319 | 410 | union hfi_get_property hprop; |
|---|
| 411 | + unsigned int core_acquired: 1; |
|---|
| 412 | + unsigned int bit_depth; |
|---|
| 413 | + struct vb2_buffer *last_buf; |
|---|
| 320 | 414 | }; |
|---|
| 321 | 415 | |
|---|
| 322 | 416 | #define IS_V1(core) ((core)->res->hfi_version == HFI_VERSION_1XX) |
|---|