| .. | .. |
|---|
| 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 |
|---|
| .. | .. |
|---|
| 85 | 119 | * struct venus_core - holds core parameters valid for all instances |
|---|
| 86 | 120 | * |
|---|
| 87 | 121 | * @base: IO memory base address |
|---|
| 122 | + * @vbif_base IO memory vbif base address |
|---|
| 123 | + * @cpu_base IO memory cpu base address |
|---|
| 124 | + * @cpu_cs_base IO memory cpu_cs base address |
|---|
| 125 | + * @cpu_ic_base IO memory cpu_ic base address |
|---|
| 126 | + * @wrapper_base IO memory wrapper base address |
|---|
| 88 | 127 | * @irq: Venus irq |
|---|
| 89 | 128 | * @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 |
|---|
| 129 | + * @vcodec0_clks: an array of vcodec0 struct clk pointers |
|---|
| 130 | + * @vcodec1_clks: an array of vcodec1 struct clk pointers |
|---|
| 131 | + * @pmdomains: an array of pmdomains struct device pointers |
|---|
| 94 | 132 | * @vdev_dec: a reference to video device structure for decoder instances |
|---|
| 95 | 133 | * @vdev_enc: a reference to video device structure for encoder instances |
|---|
| 96 | 134 | * @v4l2_dev: a holder for v4l2 device structure |
|---|
| .. | .. |
|---|
| 98 | 136 | * @dev: convenience struct device pointer |
|---|
| 99 | 137 | * @dev_dec: convenience struct device pointer for decoder device |
|---|
| 100 | 138 | * @dev_enc: convenience struct device pointer for encoder device |
|---|
| 139 | + * @use_tz: a flag that suggests presence of trustzone |
|---|
| 101 | 140 | * @lock: a lock for this strucure |
|---|
| 102 | 141 | * @instances: a list_head of all instances |
|---|
| 103 | 142 | * @insts_count: num of instances |
|---|
| .. | .. |
|---|
| 106 | 145 | * @error: an error returned during last HFI sync operations |
|---|
| 107 | 146 | * @sys_error: an error flag that signal system error event |
|---|
| 108 | 147 | * @core_ops: the core operations |
|---|
| 148 | + * @pm_lock: a lock for PM operations |
|---|
| 109 | 149 | * @enc_codecs: encoders supported by this core |
|---|
| 110 | 150 | * @dec_codecs: decoders supported by this core |
|---|
| 111 | 151 | * @max_sessions_supported: holds the maximum number of sessions |
|---|
| .. | .. |
|---|
| 113 | 153 | * @priv: a private filed for HFI operations |
|---|
| 114 | 154 | * @ops: the core HFI operations |
|---|
| 115 | 155 | * @work: a delayed work for handling system fatal error |
|---|
| 156 | + * @root: debugfs root directory |
|---|
| 116 | 157 | */ |
|---|
| 117 | 158 | struct venus_core { |
|---|
| 118 | 159 | void __iomem *base; |
|---|
| 160 | + void __iomem *vbif_base; |
|---|
| 161 | + void __iomem *cpu_base; |
|---|
| 162 | + void __iomem *cpu_cs_base; |
|---|
| 163 | + void __iomem *cpu_ic_base; |
|---|
| 164 | + void __iomem *wrapper_base; |
|---|
| 119 | 165 | int irq; |
|---|
| 120 | 166 | 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; |
|---|
| 167 | + struct clk *vcodec0_clks[VIDC_VCODEC_CLKS_NUM_MAX]; |
|---|
| 168 | + struct clk *vcodec1_clks[VIDC_VCODEC_CLKS_NUM_MAX]; |
|---|
| 169 | + struct icc_path *video_path; |
|---|
| 170 | + struct icc_path *cpucfg_path; |
|---|
| 171 | + struct opp_table *opp_table; |
|---|
| 172 | + bool has_opp_table; |
|---|
| 173 | + struct device *pmdomains[VIDC_PMDOMAINS_NUM_MAX]; |
|---|
| 174 | + struct device_link *opp_dl_venus; |
|---|
| 175 | + struct device *opp_pmdomain; |
|---|
| 125 | 176 | struct video_device *vdev_dec; |
|---|
| 126 | 177 | struct video_device *vdev_enc; |
|---|
| 127 | 178 | struct v4l2_device v4l2_dev; |
|---|
| .. | .. |
|---|
| 129 | 180 | struct device *dev; |
|---|
| 130 | 181 | struct device *dev_dec; |
|---|
| 131 | 182 | struct device *dev_enc; |
|---|
| 183 | + unsigned int use_tz; |
|---|
| 184 | + struct video_firmware { |
|---|
| 185 | + struct device *dev; |
|---|
| 186 | + struct iommu_domain *iommu_domain; |
|---|
| 187 | + size_t mapped_mem_size; |
|---|
| 188 | + } fw; |
|---|
| 132 | 189 | struct mutex lock; |
|---|
| 133 | 190 | struct list_head instances; |
|---|
| 134 | 191 | atomic_t insts_count; |
|---|
| .. | .. |
|---|
| 137 | 194 | unsigned int error; |
|---|
| 138 | 195 | bool sys_error; |
|---|
| 139 | 196 | const struct hfi_core_ops *core_ops; |
|---|
| 197 | + const struct venus_pm_ops *pm_ops; |
|---|
| 198 | + struct mutex pm_lock; |
|---|
| 140 | 199 | unsigned long enc_codecs; |
|---|
| 141 | 200 | unsigned long dec_codecs; |
|---|
| 142 | 201 | unsigned int max_sessions_supported; |
|---|
| .. | .. |
|---|
| 150 | 209 | struct delayed_work work; |
|---|
| 151 | 210 | struct venus_caps caps[MAX_CODEC_NUM]; |
|---|
| 152 | 211 | unsigned int codecs_count; |
|---|
| 212 | + unsigned int core0_usage_count; |
|---|
| 213 | + unsigned int core1_usage_count; |
|---|
| 214 | + struct dentry *root; |
|---|
| 153 | 215 | }; |
|---|
| 154 | 216 | |
|---|
| 155 | 217 | struct vdec_controls { |
|---|
| .. | .. |
|---|
| 165 | 227 | u32 bitrate_mode; |
|---|
| 166 | 228 | u32 bitrate; |
|---|
| 167 | 229 | u32 bitrate_peak; |
|---|
| 230 | + u32 rc_enable; |
|---|
| 231 | + u32 const_quality; |
|---|
| 232 | + u32 frame_skip_mode; |
|---|
| 168 | 233 | |
|---|
| 169 | 234 | u32 h264_i_period; |
|---|
| 170 | 235 | u32 h264_entropy_mode; |
|---|
| .. | .. |
|---|
| 187 | 252 | u32 header_mode; |
|---|
| 188 | 253 | |
|---|
| 189 | 254 | struct { |
|---|
| 190 | | - u32 mpeg4; |
|---|
| 191 | 255 | u32 h264; |
|---|
| 192 | | - u32 vpx; |
|---|
| 256 | + u32 mpeg4; |
|---|
| 193 | 257 | u32 hevc; |
|---|
| 258 | + u32 vp8; |
|---|
| 259 | + u32 vp9; |
|---|
| 194 | 260 | } profile; |
|---|
| 195 | 261 | struct { |
|---|
| 196 | | - u32 mpeg4; |
|---|
| 197 | 262 | u32 h264; |
|---|
| 263 | + u32 mpeg4; |
|---|
| 198 | 264 | u32 hevc; |
|---|
| 265 | + u32 vp9; |
|---|
| 199 | 266 | } level; |
|---|
| 200 | 267 | }; |
|---|
| 201 | 268 | |
|---|
| .. | .. |
|---|
| 209 | 276 | struct list_head ref_list; |
|---|
| 210 | 277 | }; |
|---|
| 211 | 278 | |
|---|
| 279 | +struct clock_data { |
|---|
| 280 | + u32 core_id; |
|---|
| 281 | + unsigned long freq; |
|---|
| 282 | + const struct codec_freq_data *codec_freq_data; |
|---|
| 283 | +}; |
|---|
| 284 | + |
|---|
| 212 | 285 | #define to_venus_buffer(ptr) container_of(ptr, struct venus_buffer, vb) |
|---|
| 213 | 286 | |
|---|
| 287 | +enum venus_dec_state { |
|---|
| 288 | + VENUS_DEC_STATE_DEINIT = 0, |
|---|
| 289 | + VENUS_DEC_STATE_INIT = 1, |
|---|
| 290 | + VENUS_DEC_STATE_CAPTURE_SETUP = 2, |
|---|
| 291 | + VENUS_DEC_STATE_STOPPED = 3, |
|---|
| 292 | + VENUS_DEC_STATE_SEEK = 4, |
|---|
| 293 | + VENUS_DEC_STATE_DRAIN = 5, |
|---|
| 294 | + VENUS_DEC_STATE_DECODING = 6, |
|---|
| 295 | + VENUS_DEC_STATE_DRC = 7, |
|---|
| 296 | +}; |
|---|
| 297 | + |
|---|
| 298 | +struct venus_ts_metadata { |
|---|
| 299 | + bool used; |
|---|
| 300 | + u64 ts_ns; |
|---|
| 301 | + u64 ts_us; |
|---|
| 302 | + u32 flags; |
|---|
| 303 | + struct v4l2_timecode tc; |
|---|
| 304 | +}; |
|---|
| 305 | + |
|---|
| 214 | 306 | /** |
|---|
| 215 | | - * struct venus_inst - holds per instance paramerters |
|---|
| 307 | + * struct venus_inst - holds per instance parameters |
|---|
| 216 | 308 | * |
|---|
| 217 | 309 | * @list: used for attach an instance to the core |
|---|
| 218 | 310 | * @lock: instance lock |
|---|
| .. | .. |
|---|
| 234 | 326 | * @colorspace: current color space |
|---|
| 235 | 327 | * @quantization: current quantization |
|---|
| 236 | 328 | * @xfer_func: current xfer function |
|---|
| 329 | + * @codec_state: current codec API state (see DEC/ENC_STATE_) |
|---|
| 330 | + * @reconf_wait: wait queue for resolution change event |
|---|
| 331 | + * @subscriptions: used to hold current events subscriptions |
|---|
| 332 | + * @buf_count: used to count number of buffers (reqbuf(0)) |
|---|
| 237 | 333 | * @fps: holds current FPS |
|---|
| 238 | 334 | * @timeperframe: holds current time per frame structure |
|---|
| 239 | 335 | * @fmt_out: a reference to output format structure |
|---|
| .. | .. |
|---|
| 248 | 344 | * @opb_buftype: output picture buffer type |
|---|
| 249 | 345 | * @opb_fmt: output picture buffer raw format |
|---|
| 250 | 346 | * @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 | 347 | * @hfi_codec: current codec for this instance in HFI space |
|---|
| 254 | 348 | * @sequence_cap: a sequence counter for capture queue |
|---|
| 255 | 349 | * @sequence_out: a sequence counter for output queue |
|---|
| .. | .. |
|---|
| 263 | 357 | * @priv: a private for HFI operations callbacks |
|---|
| 264 | 358 | * @session_type: the type of the session (decoder or encoder) |
|---|
| 265 | 359 | * @hprop: a union used as a holder by get property |
|---|
| 360 | + * @next_buf_last: a flag to mark next queued capture buffer as last |
|---|
| 266 | 361 | */ |
|---|
| 267 | 362 | struct venus_inst { |
|---|
| 268 | 363 | struct list_head list; |
|---|
| 269 | 364 | struct mutex lock; |
|---|
| 270 | 365 | struct venus_core *core; |
|---|
| 366 | + struct clock_data clk_data; |
|---|
| 271 | 367 | struct list_head dpbbufs; |
|---|
| 272 | 368 | struct list_head internalbufs; |
|---|
| 273 | 369 | struct list_head registeredbufs; |
|---|
| .. | .. |
|---|
| 289 | 385 | u8 ycbcr_enc; |
|---|
| 290 | 386 | u8 quantization; |
|---|
| 291 | 387 | u8 xfer_func; |
|---|
| 388 | + enum venus_dec_state codec_state; |
|---|
| 389 | + wait_queue_head_t reconf_wait; |
|---|
| 390 | + unsigned int subscriptions; |
|---|
| 391 | + int buf_count; |
|---|
| 392 | + struct venus_ts_metadata tss[VIDEO_MAX_FRAME]; |
|---|
| 393 | + unsigned long payloads[VIDEO_MAX_FRAME]; |
|---|
| 292 | 394 | u64 fps; |
|---|
| 293 | 395 | struct v4l2_fract timeperframe; |
|---|
| 294 | 396 | const struct venus_format *fmt_out; |
|---|
| .. | .. |
|---|
| 303 | 405 | u32 opb_buftype; |
|---|
| 304 | 406 | u32 opb_fmt; |
|---|
| 305 | 407 | bool reconfig; |
|---|
| 306 | | - u32 reconfig_width; |
|---|
| 307 | | - u32 reconfig_height; |
|---|
| 308 | 408 | u32 hfi_codec; |
|---|
| 309 | 409 | u32 sequence_cap; |
|---|
| 310 | 410 | u32 sequence_out; |
|---|
| .. | .. |
|---|
| 317 | 417 | const struct hfi_inst_ops *ops; |
|---|
| 318 | 418 | u32 session_type; |
|---|
| 319 | 419 | union hfi_get_property hprop; |
|---|
| 420 | + unsigned int core_acquired: 1; |
|---|
| 421 | + unsigned int bit_depth; |
|---|
| 422 | + bool next_buf_last; |
|---|
| 423 | + bool drain_active; |
|---|
| 320 | 424 | }; |
|---|
| 321 | 425 | |
|---|
| 322 | 426 | #define IS_V1(core) ((core)->res->hfi_version == HFI_VERSION_1XX) |
|---|
| 323 | 427 | #define IS_V3(core) ((core)->res->hfi_version == HFI_VERSION_3XX) |
|---|
| 324 | 428 | #define IS_V4(core) ((core)->res->hfi_version == HFI_VERSION_4XX) |
|---|
| 429 | +#define IS_V6(core) ((core)->res->hfi_version == HFI_VERSION_6XX) |
|---|
| 325 | 430 | |
|---|
| 326 | 431 | #define ctrl_to_inst(ctrl) \ |
|---|
| 327 | 432 | container_of((ctrl)->handler, struct venus_inst, ctrl_handler) |
|---|